diff mbox

[RFC,4/4] Btrfs: deal with filesystem state at mount, umount and remount

Message ID 4CEE32D9.8060207@cn.fujitsu.com (mailing list archive)
State New, archived
Headers show

Commit Message

Miao Xie Nov. 25, 2010, 9:56 a.m. UTC
None
diff mbox

Patch

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index fb827d0..15ff468 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -43,6 +43,8 @@ 
 static struct extent_io_ops btree_extent_io_ops;
 static void end_workqueue_fn(struct btrfs_work *work);
 static void free_fs_root(struct btrfs_root *root);
+static void btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
+				     int read_only);
 
 /*
  * end_io_wq structs are used to do processing in task context when an IO is
@@ -1700,6 +1702,11 @@  struct btrfs_root *open_ctree(struct super_block *sb,
 	if (!btrfs_super_root(disk_super))
 		goto fail_iput;
 
+	/* check filesystem state */
+	fs_info->fs_state |= btrfs_super_flags(disk_super);
+
+	btrfs_check_super_valid(fs_info, sb->s_flags & MS_RDONLY);
+
 	ret = btrfs_parse_options(tree_root, options);
 	if (ret) {
 		err = ret;
@@ -2409,6 +2416,7 @@  int btrfs_commit_super(struct btrfs_root *root)
 int close_ctree(struct btrfs_root *root)
 {
 	struct btrfs_fs_info *fs_info = root->fs_info;
+	struct btrfs_super_block *sb = &fs_info->super_for_commit;
 	int ret;
 
 	fs_info->closing = 1;
@@ -2416,6 +2424,7 @@  int close_ctree(struct btrfs_root *root)
 
 	btrfs_put_block_group_cache(fs_info);
 	if (!(fs_info->sb->s_flags & MS_RDONLY)) {
+		sb->flags |= cpu_to_le64(fs_info->fs_state);
 		ret =  btrfs_commit_super(root);
 		if (ret)
 			printk(KERN_ERR "btrfs: commit super ret %d\n", ret);
@@ -2592,6 +2601,20 @@  out:
 	return 0;
 }
 
+static void btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
+				     int read_only)
+{
+	if (read_only)
+		return;
+
+	if (!(fs_info->fs_state & BTRFS_SUPER_FLAG_VALID))
+		printk(KERN_WARNING "warning: mount unchecked fs, "
+		       "running btfsck is recommended\n");
+	else if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR)
+		printk(KERN_WARNING "warning: mount fs with errors, "
+		       "running btfsck is recommended\n");
+}
+
 static struct extent_io_ops btree_extent_io_ops = {
 	.write_cache_pages_lock_hook = btree_lock_page_hook,
 	.readpage_end_io_hook = btree_readpage_end_io_hook,
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 48fac6e..40130e8 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -771,6 +771,8 @@  error_free_subvol_name:
 static int btrfs_remount(struct super_block *sb, int *flags, char *data)
 {
 	struct btrfs_root *root = btrfs_sb(sb);
+	struct btrfs_fs_info *fs_info = root->fs_info;
+	struct btrfs_super_block *disk_super = &fs_info->super_copy;
 	int ret;
 
 	ret = btrfs_parse_options(root, data);
@@ -782,17 +784,21 @@  static int btrfs_remount(struct super_block *sb, int *flags, char *data)
 
 	if (*flags & MS_RDONLY) {
 		sb->s_flags |= MS_RDONLY;
+		if (!(disk_super->flags &
+		    cpu_to_le64(BTRFS_SUPER_FLAG_VALID)) &&
+		    (fs_info->fs_state & BTRFS_SUPER_FLAG_VALID))
+			disk_super->flags |= cpu_to_le64(fs_info->fs_state);
 
 		ret =  btrfs_commit_super(root);
 		WARN_ON(ret);
 	} else {
-		if (root->fs_info->fs_devices->rw_devices == 0)
+		if (fs_info->fs_devices->rw_devices == 0)
 			return -EACCES;
 
-		if (btrfs_super_log_root(&root->fs_info->super_copy) != 0)
+		if (btrfs_super_log_root(disk_super) != 0)
 			return -EINVAL;
 
-		ret = btrfs_cleanup_fs_roots(root->fs_info);
+		ret = btrfs_cleanup_fs_roots(fs_info);
 		WARN_ON(ret);
 
 		/* recover relocation */