浏览代码

Btrfs: Add flush barriers on commit

Signed-off-by: Chris Mason <chris.mason@oracle.com>
Chris Mason 17 年之前
父节点
当前提交
21ad10cf3e
共有 3 个文件被更改,包括 16 次插入3 次删除
  1. 3 2
      fs/btrfs/ctree.h
  2. 5 0
      fs/btrfs/disk-io.c
  3. 8 1
      fs/btrfs/super.c

+ 3 - 2
fs/btrfs/ctree.h

@@ -440,8 +440,9 @@ struct btrfs_root {
  */
 #define BTRFS_STRING_ITEM_KEY	253
 
-#define BTRFS_MOUNT_NODATASUM		0x1
-#define BTRFS_MOUNT_NODATACOW		0x2
+#define BTRFS_MOUNT_NODATASUM		(1 << 0)
+#define BTRFS_MOUNT_NODATACOW		(1 << 1)
+#define BTRFS_MOUNT_NOBARRIER		(1 << 2)
 
 #define btrfs_clear_opt(o, opt)		((o) &= ~BTRFS_MOUNT_##opt)
 #define btrfs_set_opt(o, opt)		((o) |= BTRFS_MOUNT_##opt)

+ 5 - 0
fs/btrfs/disk-io.c

@@ -762,10 +762,15 @@ int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root
 	int ret;
 	struct extent_buffer *super = root->fs_info->sb_buffer;
 	struct inode *btree_inode = root->fs_info->btree_inode;
+	struct super_block *sb = root->fs_info->sb;
 
+	if (!btrfs_test_opt(root, NOBARRIER))
+		blkdev_issue_flush(sb->s_bdev, NULL);
 	set_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, super);
 	ret = sync_page_range_nolock(btree_inode, btree_inode->i_mapping,
 				     super->start, super->len);
+	if (!btrfs_test_opt(root, NOBARRIER))
+		blkdev_issue_flush(sb->s_bdev, NULL);
 	return ret;
 }
 

+ 8 - 1
fs/btrfs/super.c

@@ -64,13 +64,14 @@ static void btrfs_put_super (struct super_block * sb)
 
 enum {
 	Opt_subvol, Opt_nodatasum, Opt_nodatacow, Opt_max_extent,
-	Opt_alloc_start, Opt_err,
+	Opt_alloc_start, Opt_nobarrier, Opt_err,
 };
 
 static match_table_t tokens = {
 	{Opt_subvol, "subvol=%s"},
 	{Opt_nodatasum, "nodatasum"},
 	{Opt_nodatacow, "nodatacow"},
+	{Opt_nobarrier, "nobarrier"},
 	{Opt_max_extent, "max_extent=%s"},
 	{Opt_alloc_start, "alloc_start=%s"},
 	{Opt_err, NULL}
@@ -148,6 +149,12 @@ static int parse_options (char * options,
 				btrfs_set_opt(info->mount_opt, NODATASUM);
 			}
 			break;
+		case Opt_nobarrier:
+			if (info) {
+				printk("btrfs: turning off barriers\n");
+				btrfs_set_opt(info->mount_opt, NOBARRIER);
+			}
+			break;
 		case Opt_max_extent:
 			if (info) {
 				char *num = match_strdup(&args[0]);