linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] btrfs: handle volume split brain scenario
@ 2017-11-13  5:53 Anand Jain
  2017-11-13  5:53 ` [PATCH 2/2] btrfs: reset SB MOVED_ON flag for dynamically reappearing missing device Anand Jain
  0 siblings, 1 reply; 2+ messages in thread
From: Anand Jain @ 2017-11-13  5:53 UTC (permalink / raw)
  To: linux-btrfs

In two device configs of RAID1/RAID5 where one device can be missing
in the degraded mount, or in the configs such as four devices RAID6
where two devices can be missing, in these type of configs it can form
two separate set of devices where each of the set can be mounted without
the other set. And if user does that and writes the data, one set would
have to loose the data, as of now we just loose the data without the
user consent depending on the SB generation number which user won't have
any aware.

This patch introduces a new SB flag BTRFS_SUPER_FLAG_VOL_MOVED_ON which
will be set when RAID group is mounted with missing device, so when RAID
is mounted with no missing device and if all the devices contains this
flag then we know that each of these set are mounted without the other
set. In this scenario this patch will fail the mount so that user can
decide which set to keep the data.

Now the procedure to reassemble the disks would be to continue to mount
the good set first without the device set on which new data can be
ignored, and later on run btrfs device scan to bring-in the missing device
and complete the RAID group which then shall reset the flag
BTRFS_SUPER_FLAG_VOL_MOVED_ON.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 fs/btrfs/disk-io.c              | 53 ++++++++++++++++++++++++++++++++++++++++-
 fs/btrfs/volumes.c              | 14 +++++++++--
 include/uapi/linux/btrfs_tree.h |  1 +
 3 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index dfdab849037b..62b80226d157 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -59,7 +59,8 @@
 				 BTRFS_HEADER_FLAG_RELOC |\
 				 BTRFS_SUPER_FLAG_ERROR |\
 				 BTRFS_SUPER_FLAG_SEEDING |\
-				 BTRFS_SUPER_FLAG_METADUMP)
+				 BTRFS_SUPER_FLAG_METADUMP|\
+				 BTRFS_SUPER_FLAG_VOL_MOVED_ON)
 
 static const struct extent_io_ops btree_extent_io_ops;
 static void end_workqueue_fn(struct btrfs_work *work);
@@ -2552,6 +2553,43 @@ static int btrfs_read_roots(struct btrfs_fs_info *fs_info)
 	return 0;
 }
 
+bool volume_has_split_brain(struct btrfs_fs_info *fs_info)
+{
+	unsigned long devs_moved_on = 0;
+	struct btrfs_fs_devices *fs_devs = fs_info->fs_devices;
+	struct list_head *head = &fs_devs->devices;
+	struct btrfs_device *dev;
+
+again:
+	list_for_each_entry(dev, head, dev_list) {
+		struct buffer_head *bh;
+		struct btrfs_super_block *sb;
+
+		if (!dev->devid)
+			continue;
+
+		bh = btrfs_read_dev_super(dev->bdev);
+		if (IS_ERR(bh))
+			continue;
+
+		sb = (struct btrfs_super_block *)bh->b_data;
+		if (btrfs_super_flags(sb) & BTRFS_SUPER_FLAG_VOL_MOVED_ON)
+			devs_moved_on++;
+		brelse(bh);
+	}
+
+	fs_devs = fs_devs->seed;
+	if (fs_devs) {
+		head = &fs_devs->devices;
+		goto again;
+	}
+
+	if (devs_moved_on == fs_info->fs_devices->total_devices)
+		return true;
+	else
+		return false;
+}
+
 int open_ctree(struct super_block *sb,
 	       struct btrfs_fs_devices *fs_devices,
 	       char *options)
@@ -3044,6 +3082,19 @@ int open_ctree(struct super_block *sb,
 		goto fail_sysfs;
 	}
 
+	if (fs_info->fs_devices->missing_devices) {
+		btrfs_set_super_flags(fs_info->super_copy,
+			fs_info->super_copy->flags | BTRFS_SUPER_FLAG_VOL_MOVED_ON);
+	} else if (fs_info->super_copy->flags & BTRFS_SUPER_FLAG_VOL_MOVED_ON) {
+		if (volume_has_split_brain(fs_info)) {
+			btrfs_err(fs_info,
+				"Detected 'moved_on' flag on all device");
+			goto fail_sysfs;
+		}
+		btrfs_set_super_flags(fs_info->super_copy,
+			fs_info->super_copy->flags & ~BTRFS_SUPER_FLAG_VOL_MOVED_ON);
+	}
+
 	fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root,
 					       "btrfs-cleaner");
 	if (IS_ERR(fs_info->cleaner_kthread))
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index e7dd996831f2..ba32e2d73fbe 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1988,8 +1988,13 @@ int btrfs_rm_device(struct btrfs_fs_info *fs_info, const char *device_path,
 	device->fs_devices->num_devices--;
 	device->fs_devices->total_devices--;
 
-	if (device->missing)
+	if (device->missing) {
 		device->fs_devices->missing_devices--;
+		if (!device->missing)
+			btrfs_set_super_flags(fs_info->super_copy,
+				fs_info->super_copy->flags &
+				~BTRFS_SUPER_FLAG_VOL_MOVED_ON);
+	}
 
 	btrfs_assign_next_active_device(fs_info, device, NULL);
 
@@ -2062,8 +2067,13 @@ void btrfs_rm_dev_replace_remove_srcdev(struct btrfs_fs_info *fs_info,
 	list_del_rcu(&srcdev->dev_list);
 	list_del_rcu(&srcdev->dev_alloc_list);
 	fs_devices->num_devices--;
-	if (srcdev->missing)
+	if (srcdev->missing) {
 		fs_devices->missing_devices--;
+		if (!srcdev->missing)
+			btrfs_set_super_flags(fs_info->super_copy,
+				fs_info->super_copy->flags &
+				~BTRFS_SUPER_FLAG_VOL_MOVED_ON);
+	}
 
 	if (srcdev->writeable)
 		fs_devices->rw_devices--;
diff --git a/include/uapi/linux/btrfs_tree.h b/include/uapi/linux/btrfs_tree.h
index 10689e1fdf11..b53731b5b5a0 100644
--- a/include/uapi/linux/btrfs_tree.h
+++ b/include/uapi/linux/btrfs_tree.h
@@ -455,6 +455,7 @@ struct btrfs_free_space_header {
 
 #define BTRFS_SUPER_FLAG_SEEDING	(1ULL << 32)
 #define BTRFS_SUPER_FLAG_METADUMP	(1ULL << 33)
+#define BTRFS_SUPER_FLAG_VOL_MOVED_ON	(1ULL << 36)
 
 
 /*
-- 
2.13.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH 2/2] btrfs: reset SB MOVED_ON flag for dynamically reappearing missing device
  2017-11-13  5:53 [PATCH 1/2] btrfs: handle volume split brain scenario Anand Jain
@ 2017-11-13  5:53 ` Anand Jain
  0 siblings, 0 replies; 2+ messages in thread
From: Anand Jain @ 2017-11-13  5:53 UTC (permalink / raw)
  To: linux-btrfs

When the missing device reappears and joins the RAID group, and if there
are no more missing device at the volume level, then reset the
BTRFS_SUPER_FLAG_VOL_MOVED_ON flag.

This patch is on top of the patch [1] in the ML.
[1] btrfs: handle dynamically reappearing missing device

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 fs/btrfs/volumes.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index ba32e2d73fbe..8bac1cf17048 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -798,6 +798,10 @@ static noinline int device_list_add(const char *path,
 				btrfs_warn(fs_info,
 					"BTRFS: device %s devid %llu uuid %pU joined\n",
 					path, devid, device->uuid);
+				if (!fs_devices->missing_devices)
+					btrfs_set_super_flags(fs_info->super_copy,
+						fs_info->super_copy->flags &
+						~BTRFS_SUPER_FLAG_VOL_MOVED_ON);
 			}
 
 			if (device->writeable &&
-- 
2.13.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2017-11-13  5:54 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-13  5:53 [PATCH 1/2] btrfs: handle volume split brain scenario Anand Jain
2017-11-13  5:53 ` [PATCH 2/2] btrfs: reset SB MOVED_ON flag for dynamically reappearing missing device Anand Jain

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).