瀏覽代碼

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>
Chris Mason 15 年之前
父節點
當前提交
94b604429a
共有 1 個文件被更改,包括 11 次插入3 次删除
  1. 11 3
      fs/btrfs/inode.c

+ 11 - 3
fs/btrfs/inode.c

@@ -4308,10 +4308,18 @@ void btrfs_dirty_inode(struct inode *inode)
 	btrfs_set_trans_block_group(trans, inode);
 	btrfs_set_trans_block_group(trans, inode);
 
 
 	ret = btrfs_update_inode(trans, root, 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);
 	btrfs_end_transaction(trans, root);
 }
 }