Btrfs: fix a bug of snapshot-aware defrag to make it work on partial extents
authorLiu Bo <bo.li.liu@oracle.com>
Mon, 1 Jul 2013 14:13:26 +0000 (22:13 +0800)
committerChris Mason <chris.mason@fusionio.com>
Fri, 9 Aug 2013 23:29:17 +0000 (19:29 -0400)
commite68afa49aec5f0851e550ee1de48fcc3a9bf5ef7
tree7588f986736b53f7d6e3117a5c3afdff1f638e13
parent7cddc193924ef6ce679ef0977e01e96d0aedfd1d
Btrfs: fix a bug of snapshot-aware defrag to make it work on partial extents

For partial extents, snapshot-aware defrag does not work as expected,
since
a) we use the wrong logical offset to search for parents, which should be
   disk_bytenr + extent_offset, not just disk_bytenr,
b) 'offset' returned by the backref walking just refers to key.offset, not
   the 'offset' stored in btrfs_extent_data_ref which is
   (key.offset - extent_offset).

The reproducer:
$ mkfs.btrfs sda
$ mount sda /mnt
$ btrfs sub create /mnt/sub
$ for i in `seq 5 -1 1`; do dd if=/dev/zero of=/mnt/sub/foo bs=5k count=1 seek=$i conv=notrunc oflag=sync; done
$ btrfs sub snap /mnt/sub /mnt/snap1
$ btrfs sub snap /mnt/sub /mnt/snap2
$ sync; btrfs filesystem defrag /mnt/sub/foo;
$ umount /mnt
$ btrfs-debug-tree sda (Here we can check whether the defrag operation is snapshot-awared.

This addresses the above two problems.

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
fs/btrfs/inode.c