aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLiu Bo <liubo2009@cn.fujitsu.com>2012-03-29 09:57:45 -0400
committerChris Mason <chris.mason@oracle.com>2012-03-29 09:57:45 -0400
commit4cb13e5d6ecc47b91b24a35f8fbc2c9f33d075fe (patch)
treec1654f1b2f029c8cfd5385568b37f90a0b47f3c4 /fs
parent1f12bd063285b059cb63315d1424dae1ddd87a64 (diff)
Btrfs: fix recursive defragment with autodefrag option
$ mkfs.btrfs disk $ mount disk /mnt -o autodefrag $ dd if=/dev/zero of=/mnt/foobar bs=4k count=10 2>/dev/null && sync $ for i in `seq 9 -2 0`; do dd if=/dev/zero of=/mnt/foobar bs=4k count=1 \ seek=$i conv=notrunc 2> /dev/null; done && sync then we'll get to defrag "foobar" again and again. So does option "-o autodefrag,compress". Reasons: When the cleaner kthread gets to fetch inodes from the defrag tree and defrag them, it will dirty pages and submit them, this will comes to another DATA COW where the processing inode will be inserted to the defrag tree again. This patch sets a rule for COW code, i.e. insert an inode when we're really going to make some defragments. Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/inode.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index eb6aec7bbacb..1be31368e881 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -347,8 +347,9 @@ static noinline int compress_file_range(struct inode *inode,
347 int will_compress; 347 int will_compress;
348 int compress_type = root->fs_info->compress_type; 348 int compress_type = root->fs_info->compress_type;
349 349
350 /* if this is a small write inside eof, kick off a defragbot */ 350 /* if this is a small write inside eof, kick off a defrag */
351 if (end <= BTRFS_I(inode)->disk_i_size && (end - start + 1) < 16 * 1024) 351 if ((end - start + 1) < 16 * 1024 &&
352 (start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size))
352 btrfs_add_inode_defrag(NULL, inode); 353 btrfs_add_inode_defrag(NULL, inode);
353 354
354 actual_end = min_t(u64, isize, end + 1); 355 actual_end = min_t(u64, isize, end + 1);
@@ -843,7 +844,8 @@ static noinline int cow_file_range(struct inode *inode,
843 ret = 0; 844 ret = 0;
844 845
845 /* if this is a small write inside eof, kick off defrag */ 846 /* if this is a small write inside eof, kick off defrag */
846 if (end <= BTRFS_I(inode)->disk_i_size && num_bytes < 64 * 1024) 847 if (num_bytes < 64 * 1024 &&
848 (start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size))
847 btrfs_add_inode_defrag(trans, inode); 849 btrfs_add_inode_defrag(trans, inode);
848 850
849 if (start == 0) { 851 if (start == 0) {