[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 06/21] Btrfs: implement online profile changing



Profile changing is done by initializing target field in respective
btrfs_restripe_args structs and launching a balance.  Reducing code in
this mode will pick restriper's target profile if it's available instead
of doing a blind reduce.  If target profile is not yet available go back
to plain reducing.

Signed-off-by: Ilya Dryomov <idryomov@xxxxxxxxx>
---
 fs/btrfs/extent-tree.c |   54 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 53 insertions(+), 1 deletions(-)

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index a04f99b..05e55d1 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2968,6 +2968,34 @@ u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags)
 	u64 num_devices = root->fs_info->fs_devices->rw_devices +
 		root->fs_info->fs_devices->missing_devices;
 
+	/* pick restriper's target profile if it's available */
+	spin_lock(&root->fs_info->restripe_lock);
+	if (root->fs_info->restripe_ctl) {
+		struct restripe_control *rctl = root->fs_info->restripe_ctl;
+		u64 t = 0;
+
+		if ((flags & BTRFS_BLOCK_GROUP_DATA) &&
+		    (rctl->data.flags & BTRFS_RESTRIPE_ARGS_CONVERT) &&
+		    (flags & rctl->data.target)) {
+			t = BTRFS_BLOCK_GROUP_DATA | rctl->data.target;
+		} else if ((flags & BTRFS_BLOCK_GROUP_SYSTEM) &&
+			   (rctl->sys.flags & BTRFS_RESTRIPE_ARGS_CONVERT) &&
+			   (flags & rctl->sys.target)) {
+			t = BTRFS_BLOCK_GROUP_SYSTEM | rctl->sys.target;
+		} else if ((flags & BTRFS_BLOCK_GROUP_METADATA) &&
+			   (rctl->meta.flags & BTRFS_RESTRIPE_ARGS_CONVERT) &&
+			   (flags & rctl->meta.target)) {
+			t = BTRFS_BLOCK_GROUP_METADATA | rctl->meta.target;
+		}
+
+		if (t) {
+			spin_unlock(&root->fs_info->restripe_lock);
+			t &= ~BTRFS_AVAIL_ALLOC_BIT_SINGLE;
+			return t;
+		}
+	}
+	spin_unlock(&root->fs_info->restripe_lock);
+
 	if (num_devices == 1)
 		flags &= ~(BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID0);
 	if (num_devices < 4)
@@ -2987,8 +3015,9 @@ u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags)
 	if ((flags & BTRFS_BLOCK_GROUP_RAID0) &&
 	    ((flags & BTRFS_BLOCK_GROUP_RAID1) |
 	     (flags & BTRFS_BLOCK_GROUP_RAID10) |
-	     (flags & BTRFS_BLOCK_GROUP_DUP)))
+	     (flags & BTRFS_BLOCK_GROUP_DUP))) {
 		flags &= ~BTRFS_BLOCK_GROUP_RAID0;
+	}
 
 	/* in-memory -> on-disk */
 	flags &= ~BTRFS_AVAIL_ALLOC_BIT_SINGLE;
@@ -6519,6 +6548,29 @@ static u64 update_block_group_flags(struct btrfs_root *root, u64 flags)
 	u64 stripped = BTRFS_BLOCK_GROUP_RAID0 |
 		BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10;
 
+	if (root->fs_info->restripe_ctl) {
+		struct restripe_control *rctl = root->fs_info->restripe_ctl;
+		u64 t = 0;
+
+		/* pick restriper's target profile and return */
+		if (flags & BTRFS_BLOCK_GROUP_DATA &&
+		    rctl->data.flags & BTRFS_RESTRIPE_ARGS_CONVERT) {
+			t = BTRFS_BLOCK_GROUP_DATA | rctl->data.target;
+		} else if (flags & BTRFS_BLOCK_GROUP_SYSTEM &&
+			   rctl->sys.flags & BTRFS_RESTRIPE_ARGS_CONVERT) {
+			t = BTRFS_BLOCK_GROUP_SYSTEM | rctl->sys.target;
+		} else if (flags & BTRFS_BLOCK_GROUP_METADATA &&
+			   rctl->meta.flags & BTRFS_RESTRIPE_ARGS_CONVERT) {
+			t = BTRFS_BLOCK_GROUP_METADATA | rctl->meta.target;
+		}
+
+		if (t) {
+			/* in-memory -> on-disk */
+			t &= ~BTRFS_AVAIL_ALLOC_BIT_SINGLE;
+			return t;
+		}
+	}
+
 	/*
 	 * we add in the count of missing devices because we want
 	 * to make sure that any RAID levels on a degraded FS
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Free Online Dating]     [Linux Kernel]     [Linux SCSI]     [XFree86]

Add to Google Powered by Linux