summaryrefslogtreecommitdiff
path: root/pkg/btrfs/io2_fs.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/btrfs/io2_fs.go')
-rw-r--r--pkg/btrfs/io2_fs.go57
1 files changed, 45 insertions, 12 deletions
diff --git a/pkg/btrfs/io2_fs.go b/pkg/btrfs/io2_fs.go
index 035019c..5d1e343 100644
--- a/pkg/btrfs/io2_fs.go
+++ b/pkg/btrfs/io2_fs.go
@@ -153,18 +153,6 @@ func (fs *FS) Init() error {
return nil
}
-func (fs *FS) ReadAt(dat []byte, laddr LogicalAddr) (int, error) {
- done := 0
- for done < len(dat) {
- n, err := fs.maybeShortReadAt(dat[done:], laddr+LogicalAddr(done))
- done += n
- if err != nil {
- return done, err
- }
- }
- return done, nil
-}
-
type QualifiedPhysicalAddr struct {
Dev UUID
Addr PhysicalAddr
@@ -190,6 +178,18 @@ func (fs *FS) Resolve(laddr LogicalAddr) (paddrs map[QualifiedPhysicalAddr]struc
return paddrs, maxlen
}
+func (fs *FS) ReadAt(dat []byte, laddr LogicalAddr) (int, error) {
+ done := 0
+ for done < len(dat) {
+ n, err := fs.maybeShortReadAt(dat[done:], laddr+LogicalAddr(done))
+ done += n
+ if err != nil {
+ return done, err
+ }
+ }
+ return done, nil
+}
+
func (fs *FS) maybeShortReadAt(dat []byte, laddr LogicalAddr) (int, error) {
paddrs, maxlen := fs.Resolve(laddr)
if len(paddrs) == 0 {
@@ -219,3 +219,36 @@ func (fs *FS) maybeShortReadAt(dat []byte, laddr LogicalAddr) (int, error) {
}
return len(dat), nil
}
+
+func (fs *FS) WriteAt(dat []byte, laddr LogicalAddr) (int, error) {
+ done := 0
+ for done < len(dat) {
+ n, err := fs.maybeShortWriteAt(dat[done:], laddr+LogicalAddr(done))
+ done += n
+ if err != nil {
+ return done, err
+ }
+ }
+ return done, nil
+}
+
+func (fs *FS) maybeShortWriteAt(dat []byte, laddr LogicalAddr) (int, error) {
+ paddrs, maxlen := fs.Resolve(laddr)
+ if len(paddrs) == 0 {
+ return 0, fmt.Errorf("could not map logical address %v", laddr)
+ }
+ if uint64(len(dat)) > maxlen {
+ dat = dat[:maxlen]
+ }
+
+ for paddr := range paddrs {
+ dev, ok := fs.uuid2dev[paddr.Dev]
+ if !ok {
+ return 0, fmt.Errorf("device=%s does not exist", paddr.Dev)
+ }
+ if _, err := dev.WriteAt(dat, paddr.Addr); err != nil {
+ return 0, fmt.Errorf("write device=%s paddr=%v: %w", paddr.Dev, paddr.Addr, err)
+ }
+ }
+ return len(dat), nil
+}