Btrfs: fix recursive auto-defrag
PATCH 1/1 Btrfs: fix recursive auto-defrag
Follow those steps:
# mount -o autodefrag /dev/sda7 /mnt # dd if=/dev/urandom of=/mnt/tmp bs=200K count=1 # sync # dd if=/dev/urandom of=/mnt/tmp bs=8K count=1 conv=notrunc
and then it'll go into a loop: writeback -> defrag -> writeback ...
It's because writeback writes [8K, 200K] and then writes [0, 8K].
I tried to make writeback know if the pages are dirtied by defrag, but the patch was a bit intrusive. Here I simply set writeback_index when we defrag a file.
--- fs/btrfs/ioctl.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
fs/btrfs/ioctl.c +7 -0
@@ -1047,6 +1047,13 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,if (!max_to_defrag) max_to_defrag = last_index -1 ; +/* +* make writeback starts from i, so the defrag range can be +* written sequentially. +*/ +if (i < inode->i_mapping->writeback_index) + inode->i_mapping->writeback_index = i; +while (i <= last_index && defrag_count < max_to_defrag) {/* * make sure we stop running if someone unmounts
-- 1.7.3.1
Quoted 9 lines · Li Zefan
Follow those steps:
# mount -o autodefrag /dev/sda7 /mnt # dd if=/dev/urandom of=/mnt/tmp bs=200K count=1 # sync # dd if=/dev/urandom of=/mnt/tmp bs=8K count=1 conv=notruncand then it'll go into a loop: writeback -> defrag -> writeback ...
Quoted 7 lines
It's because writeback writes [8K, 200K] and then writes [0, 8K].
I tried to make writeback know if the pages are dirtied by defrag, but the patch was a bit intrusive. Here I simply set
writeback_indexwhen we defrag a file.Signed-off-by Li Zefan <[email protected]>
Quoted 27 lines
--- fs/btrfs/ioctl.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)fs/btrfs/ioctl.c +7
-2@@ -1047,6 +1047,13 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,if (!max_to_defrag) max_to_defrag = last_index -1 ; +/* +* make writeback starts from i, so the defrag range can be +* written sequentially. +*/ +if (i < inode->i_mapping->writeback_index) + inode->i_mapping->writeback_index = i; +while (i <= last_index && defrag_count < max_to_defrag) {/* * make sure we stop running if someone unmounts -- 1.7.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 7 lines · Li Zefan
Follow those steps:
# mount -o autodefrag /dev/sda7 /mnt # dd if=/dev/urandom of=/mnt/tmp bs=200K count=1 # sync # dd if=/dev/urandom of=/mnt/tmp bs=8K count=1 conv=notrunc
Quoted 7 lines
and then it'll go into a loop: writeback -> defrag -> writeback ...
It's because writeback writes [8K, 200K] and then writes [0, 8K].
I tried to make writeback know if the pages are dirtied by defrag, but the patch was a bit intrusive. Here I simply set
writeback_indexwhen we defrag a file.
Really nice and small fix. I'll definitely send this for 3.1
-chris