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  }