[1/3] Btrfs: allow -o rw,degraded for single group profile
diff mbox

Message ID 1438699433-1581-2-git-send-email-anand.jain@oracle.com
State New
Headers show

Commit Message

Anand Jain Aug. 4, 2015, 2:43 p.m. UTC
As of now mount with missing device with degraded option is
allowed as long as number of missing devices is below the
number of device failure/missing that a group profile could
tolerate.

However there is feature/bug in the btrfs that when write
happens with least number of devices with which degraded mount
is possible, chunk allocation would default to single.

Which means any further mount with missing device will fail
even with degraded option as the number of device failure that
single group profile could tolerate is zero. Which also means
the user has to find the missing device to mount the FS RW able
to recover from this situation, which is not practical. A self
inflected problem.

test case eg:
 mkfs.btrfs -draid1 -mraid /dev/sdc /dev/sdd
 modprobe -r btrfs && modprobe btrfs  <== dev scan is cleared
 mount -o degraded /dev/sdc /btrfs <== sdd is not used
 dd if=/dev/zero of=/btrfs/tf1 count=1 <== creates single profile
 btrfs fi sync /btrfs
 umount /btrfs
 mount -o degraded /dev/sdc /btrfs  <== fails.
                    since single profile would need all the disks

This patch will let the RW mount to succeed with degraded option,
when the group profile tolerance is zero or below the number of
device missing. Now users have a choice to rebalance the group
profile back to their desired when missing device reappears during
the subsequent mounts.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 fs/btrfs/disk-io.c | 3 ++-
 fs/btrfs/super.c   | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

Patch
diff mbox

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 2593952..da7b7bf 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2897,7 +2897,8 @@  retry_root_backup:
 		btrfs_calc_num_tolerated_disk_barrier_failures(fs_info);
 	if (fs_info->fs_devices->missing_devices >
 	     fs_info->num_tolerated_disk_barrier_failures &&
-	    !(sb->s_flags & MS_RDONLY)) {
+	    !(sb->s_flags & MS_RDONLY ||
+		btrfs_test_opt(fs_info->dev_root, DEGRADED))) {
 		printk(KERN_WARNING "BTRFS: "
 			"too many missing devices, writable mount is not allowed\n");
 		goto fail_sysfs;
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 96a7857..16687c2 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1656,7 +1656,8 @@  static int btrfs_remount(struct super_block *sb, int *flags, char *data)
 
 		if (fs_info->fs_devices->missing_devices >
 		     fs_info->num_tolerated_disk_barrier_failures &&
-		    !(*flags & MS_RDONLY)) {
+		    !(*flags & MS_RDONLY ||
+			btrfs_test_opt(root, DEGRADED))) {
 			btrfs_warn(fs_info,
 				"too many missing devices, writable remount is not allowed");
 			ret = -EACCES;