diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2022-06-06 10:20:01 -0600 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2022-06-06 10:20:01 -0600 |
commit | 28f09b784b5741f044b755dc7033a82075d2d98c (patch) | |
tree | db80cd6bfda920ec700fd20aee112eedf6e9dd7a /pkg/btrfs/io2_fs.go | |
parent | 20c21bf5ebc085f6f318e9199a1fee5f44c6ea61 (diff) |
write support
Diffstat (limited to 'pkg/btrfs/io2_fs.go')
-rw-r--r-- | pkg/btrfs/io2_fs.go | 57 |
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 +} |