aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2010-05-26 11:02:00 -0400
committerChris Mason <chris.mason@oracle.com>2010-05-26 11:02:00 -0400
commit94b604429a6cd94ddc128fa2772c57209bb1318f (patch)
tree700c5b9cb431bde48f07813224e6a5165a9d6540 /fs
parent3f7c579c41a3d20af76fd6ff1f6b949edf105fd1 (diff)
downloadkernel_samsung_tuna-94b604429a6cd94ddc128fa2772c57209bb1318f.zip
kernel_samsung_tuna-94b604429a6cd94ddc128fa2772c57209bb1318f.tar.gz
kernel_samsung_tuna-94b604429a6cd94ddc128fa2772c57209bb1318f.tar.bz2
Btrfs: avoid ENOSPC errors in btrfs_dirty_inode
btrfs_dirty_inode tries to sneak in without much waiting or space reservation, mostly for performance reasons. This usually works well but can cause problems when there are many many writers. When btrfs_update_inode fails with ENOSPC, we fallback to a slower btrfs_start_transaction call that will reserve some space. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/inode.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index ca9d550..5d62f21 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -4308,10 +4308,18 @@ void btrfs_dirty_inode(struct inode *inode)
btrfs_set_trans_block_group(trans, inode);
ret = btrfs_update_inode(trans, root, inode);
- if (ret)
- printk(KERN_ERR"btrfs: fail to dirty inode %lu error %d\n",
- inode->i_ino, ret);
+ if (ret && ret == -ENOSPC) {
+ /* whoops, lets try again with the full transaction */
+ btrfs_end_transaction(trans, root);
+ trans = btrfs_start_transaction(root, 1);
+ btrfs_set_trans_block_group(trans, inode);
+ ret = btrfs_update_inode(trans, root, inode);
+ if (ret) {
+ printk(KERN_ERR"btrfs: fail to dirty inode %lu error %d\n",
+ inode->i_ino, ret);
+ }
+ }
btrfs_end_transaction(trans, root);
}