github.com/yasker/longhorn-engine@v0.0.0-20160621014712-6ed6cfca0729/replica/extents.go (about) 1 package replica 2 3 import ( 4 "github.com/frostschutz/go-fibmap" 5 "github.com/rancher/longhorn/types" 6 ) 7 8 type UsedGenerator struct { 9 err error 10 disk types.DiffDisk 11 d *diffDisk 12 } 13 14 func newGenerator(diffDisk *diffDisk, disk types.DiffDisk) *UsedGenerator { 15 return &UsedGenerator{ 16 disk: disk, 17 d: diffDisk, 18 } 19 } 20 21 func (u *UsedGenerator) Err() error { 22 return u.err 23 } 24 25 func (u *UsedGenerator) Generate() <-chan int64 { 26 c := make(chan int64) 27 go u.findExtents(c) 28 return c 29 } 30 31 func (u *UsedGenerator) findExtents(c chan<- int64) { 32 defer close(c) 33 34 fd := u.disk.Fd() 35 36 // The backing file will have a Fd of 0 37 if fd == 0 { 38 return 39 } 40 41 start := uint64(0) 42 end := uint64(len(u.d.location)) * uint64(u.d.sectorSize) 43 for { 44 extents, errno := fibmap.Fiemap(fd, start, end-start, 1024) 45 if errno != 0 { 46 u.err = errno 47 return 48 } 49 50 if len(extents) == 0 { 51 return 52 } 53 54 for _, extent := range extents { 55 start = extent.Logical + extent.Length 56 for i := int64(0); i < int64(extent.Length); i += u.d.sectorSize { 57 c <- (int64(extent.Logical) + i) / u.d.sectorSize 58 } 59 if extent.Flags&fibmap.FIEMAP_EXTENT_LAST != 0 { 60 return 61 } 62 } 63 } 64 }