diff options
Diffstat (limited to 'pkg/btrfs')
-rw-r--r-- | pkg/btrfs/io1_device.go | 4 | ||||
-rw-r--r-- | pkg/btrfs/io2_fs.go | 57 |
2 files changed, 49 insertions, 12 deletions
diff --git a/pkg/btrfs/io1_device.go b/pkg/btrfs/io1_device.go index 3b84fcc..978d388 100644 --- a/pkg/btrfs/io1_device.go +++ b/pkg/btrfs/io1_device.go @@ -33,6 +33,10 @@ func (dev *Device) ReadAt(dat []byte, paddr PhysicalAddr) (int, error) { return dev.File.ReadAt(dat, int64(paddr)) } +func (dev *Device) WriteAt(dat []byte, paddr PhysicalAddr) (int, error) { + return dev.File.WriteAt(dat, int64(paddr)) +} + func (dev *Device) Superblocks() ([]*util.Ref[PhysicalAddr, Superblock], error) { if dev.cacheSuperblocks != nil { return dev.cacheSuperblocks, nil 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 +} |