linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] Introduce device delete by devid
@ 2015-10-06 15:19 Anand Jain
  2015-10-06 15:19 ` [PATCH V2 1/7] Btrfs: create helper function __check_raid_min_devices() Anand Jain
                   ` (7 more replies)
  0 siblings, 8 replies; 10+ messages in thread
From: Anand Jain @ 2015-10-06 15:19 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba

The operation of device replace and device delete follows same steps
upto some depths, however they don't share codes.
This set of enhancement will help device replace and device delete to
share codes.
And at the end add support to delete device using devid.

Anand Jain (7):
  Btrfs: create helper function __check_raid_min_devices()
  Btrfs: clean up and optimize __check_raid_min_device()
  Btrfs: create helper btrfs_find_device_by_user_input()
  Btrfs: make use of btrfs_find_device_by_user_input()
  Btrfs: enhance btrfs_find_device_by_user_input() to check device path
  Btrfs: make use of btrfs_scratch_superblocks() in btrfs_rm_device()
  Btrfs: Introduce device delete by devid

 fs/btrfs/dev-replace.c     |  28 +-----
 fs/btrfs/ioctl.c           |  58 +++++++++++-
 fs/btrfs/volumes.c         | 214 ++++++++++++++++++---------------------------
 fs/btrfs/volumes.h         |   5 +-
 include/uapi/linux/btrfs.h |  14 ++-
 5 files changed, 159 insertions(+), 160 deletions(-)

-- 
2.4.1


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

* [PATCH V2 1/7] Btrfs: create helper function __check_raid_min_devices()
  2015-10-06 15:19 [PATCH 0/7] Introduce device delete by devid Anand Jain
@ 2015-10-06 15:19 ` Anand Jain
  2015-10-06 15:19 ` [PATCH 2/7] Btrfs: clean up and optimize __check_raid_min_device() Anand Jain
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Anand Jain @ 2015-10-06 15:19 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba

move a section of btrfs_rm_device() code to check for min number
of the devices into the function __check_raid_min_devices()

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
v2: commit update and title renamed from
    Btrfs: move check for min number of devices to a function

 fs/btrfs/volumes.c | 51 ++++++++++++++++++++++++++++++++-------------------
 1 file changed, 32 insertions(+), 19 deletions(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 4af0cf6..6be21ff 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1629,23 +1629,20 @@ out:
 	return ret;
 }
 
-int btrfs_rm_device(struct btrfs_root *root, char *device_path)
+static int __check_raid_min_devices(struct btrfs_root *root)
 {
-	struct btrfs_device *device;
-	struct btrfs_device *next_device;
-	struct block_device *bdev;
-	struct buffer_head *bh = NULL;
-	struct btrfs_super_block *disk_super;
-	struct btrfs_fs_devices *cur_devices;
 	u64 all_avail;
-	u64 devid;
 	u64 num_devices;
-	u8 *dev_uuid;
 	unsigned seq;
 	int ret = 0;
-	bool clear_super = false;
 
-	mutex_lock(&uuid_mutex);
+	num_devices = root->fs_info->fs_devices->num_devices;
+	btrfs_dev_replace_lock(&root->fs_info->dev_replace);
+	if (btrfs_dev_replace_is_ongoing(&root->fs_info->dev_replace)) {
+		WARN_ON(num_devices < 1);
+		num_devices--;
+	}
+	btrfs_dev_replace_unlock(&root->fs_info->dev_replace);
 
 	do {
 		seq = read_seqbegin(&root->fs_info->profiles_lock);
@@ -1655,14 +1652,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 			    root->fs_info->avail_metadata_alloc_bits;
 	} while (read_seqretry(&root->fs_info->profiles_lock, seq));
 
-	num_devices = root->fs_info->fs_devices->num_devices;
-	btrfs_dev_replace_lock(&root->fs_info->dev_replace);
-	if (btrfs_dev_replace_is_ongoing(&root->fs_info->dev_replace)) {
-		WARN_ON(num_devices < 1);
-		num_devices--;
-	}
-	btrfs_dev_replace_unlock(&root->fs_info->dev_replace);
-
 	if ((all_avail & BTRFS_BLOCK_GROUP_RAID10) && num_devices <= 4) {
 		ret = BTRFS_ERROR_DEV_RAID10_MIN_NOT_MET;
 		goto out;
@@ -1684,6 +1673,30 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 		goto out;
 	}
 
+out:
+	return ret;
+}
+
+int btrfs_rm_device(struct btrfs_root *root, char *device_path)
+{
+	struct btrfs_device *device;
+	struct btrfs_device *next_device;
+	struct block_device *bdev;
+	struct buffer_head *bh = NULL;
+	struct btrfs_super_block *disk_super;
+	struct btrfs_fs_devices *cur_devices;
+	u64 devid;
+	u64 num_devices;
+	u8 *dev_uuid;
+	int ret = 0;
+	bool clear_super = false;
+
+	mutex_lock(&uuid_mutex);
+
+	ret = __check_raid_min_devices(root);
+	if (ret)
+		goto out;
+
 	if (strcmp(device_path, "missing") == 0) {
 		struct list_head *devices;
 		struct btrfs_device *tmp;
-- 
2.4.1


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

* [PATCH 2/7] Btrfs: clean up and optimize __check_raid_min_device()
  2015-10-06 15:19 [PATCH 0/7] Introduce device delete by devid Anand Jain
  2015-10-06 15:19 ` [PATCH V2 1/7] Btrfs: create helper function __check_raid_min_devices() Anand Jain
@ 2015-10-06 15:19 ` Anand Jain
  2015-10-06 15:19 ` [PATCH V2 3/7] Btrfs: create helper btrfs_find_device_by_user_input() Anand Jain
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Anand Jain @ 2015-10-06 15:19 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba

__check_raid_min_device() which was pealed from btrfs_rm_device()
maintianed its original code to show the block move. This patch
cleans up __check_raid_min_device().

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

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 6be21ff..35ee3ca 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1629,52 +1629,47 @@ out:
 	return ret;
 }
 
-static int __check_raid_min_devices(struct btrfs_root *root)
+static int __check_raid_min_devices(struct btrfs_fs_info *fs_info)
 {
 	u64 all_avail;
 	u64 num_devices;
 	unsigned seq;
-	int ret = 0;
 
-	num_devices = root->fs_info->fs_devices->num_devices;
-	btrfs_dev_replace_lock(&root->fs_info->dev_replace);
-	if (btrfs_dev_replace_is_ongoing(&root->fs_info->dev_replace)) {
+	num_devices = fs_info->fs_devices->num_devices;
+	btrfs_dev_replace_lock(&fs_info->dev_replace);
+	if (btrfs_dev_replace_is_ongoing(&fs_info->dev_replace)) {
 		WARN_ON(num_devices < 1);
 		num_devices--;
 	}
-	btrfs_dev_replace_unlock(&root->fs_info->dev_replace);
+	btrfs_dev_replace_unlock(&fs_info->dev_replace);
 
 	do {
-		seq = read_seqbegin(&root->fs_info->profiles_lock);
+		seq = read_seqbegin(&fs_info->profiles_lock);
 
-		all_avail = root->fs_info->avail_data_alloc_bits |
-			    root->fs_info->avail_system_alloc_bits |
-			    root->fs_info->avail_metadata_alloc_bits;
-	} while (read_seqretry(&root->fs_info->profiles_lock, seq));
+		all_avail = fs_info->avail_data_alloc_bits |
+			    fs_info->avail_system_alloc_bits |
+			    fs_info->avail_metadata_alloc_bits;
+	} while (read_seqretry(&fs_info->profiles_lock, seq));
 
 	if ((all_avail & BTRFS_BLOCK_GROUP_RAID10) && num_devices <= 4) {
-		ret = BTRFS_ERROR_DEV_RAID10_MIN_NOT_MET;
-		goto out;
+		return BTRFS_ERROR_DEV_RAID10_MIN_NOT_MET;
 	}
 
 	if ((all_avail & BTRFS_BLOCK_GROUP_RAID1) && num_devices <= 2) {
-		ret = BTRFS_ERROR_DEV_RAID1_MIN_NOT_MET;
-		goto out;
+		return BTRFS_ERROR_DEV_RAID1_MIN_NOT_MET;
 	}
 
 	if ((all_avail & BTRFS_BLOCK_GROUP_RAID5) &&
-	    root->fs_info->fs_devices->rw_devices <= 2) {
-		ret = BTRFS_ERROR_DEV_RAID5_MIN_NOT_MET;
-		goto out;
+	    fs_info->fs_devices->rw_devices <= 2) {
+		return BTRFS_ERROR_DEV_RAID5_MIN_NOT_MET;
 	}
+
 	if ((all_avail & BTRFS_BLOCK_GROUP_RAID6) &&
-	    root->fs_info->fs_devices->rw_devices <= 3) {
-		ret = BTRFS_ERROR_DEV_RAID6_MIN_NOT_MET;
-		goto out;
+	    fs_info->fs_devices->rw_devices <= 3) {
+		return BTRFS_ERROR_DEV_RAID6_MIN_NOT_MET;
 	}
 
-out:
-	return ret;
+	return 0;
 }
 
 int btrfs_rm_device(struct btrfs_root *root, char *device_path)
@@ -1693,7 +1688,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 
 	mutex_lock(&uuid_mutex);
 
-	ret = __check_raid_min_devices(root);
+	ret = __check_raid_min_devices(root->fs_info);
 	if (ret)
 		goto out;
 
-- 
2.4.1


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

* [PATCH V2 3/7] Btrfs: create helper btrfs_find_device_by_user_input()
  2015-10-06 15:19 [PATCH 0/7] Introduce device delete by devid Anand Jain
  2015-10-06 15:19 ` [PATCH V2 1/7] Btrfs: create helper function __check_raid_min_devices() Anand Jain
  2015-10-06 15:19 ` [PATCH 2/7] Btrfs: clean up and optimize __check_raid_min_device() Anand Jain
@ 2015-10-06 15:19 ` Anand Jain
  2015-10-06 15:19 ` [PATCH 4/7] Btrfs: make use of btrfs_find_device_by_user_input() Anand Jain
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Anand Jain @ 2015-10-06 15:19 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba

The patch renames btrfs_dev_replace_find_srcdev() to
btrfs_find_device_by_user_input() and moves it to volumes.c.
so that delete device can use it.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
v2: changed title from
    'Btrfs: rename btrfs_dev_replace_find_srcdev()'
    and commit update

 fs/btrfs/dev-replace.c | 24 +-----------------------
 fs/btrfs/volumes.c     | 19 +++++++++++++++++++
 fs/btrfs/volumes.h     |  3 +++
 3 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index 3a1a920..c093f49 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -44,9 +44,6 @@ static void btrfs_dev_replace_update_device_in_mapping_tree(
 						struct btrfs_fs_info *fs_info,
 						struct btrfs_device *srcdev,
 						struct btrfs_device *tgtdev);
-static int btrfs_dev_replace_find_srcdev(struct btrfs_root *root, u64 srcdevid,
-					 char *srcdev_name,
-					 struct btrfs_device **device);
 static u64 __btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info);
 static int btrfs_dev_replace_kthread(void *data);
 static int btrfs_dev_replace_continue_on_mount(struct btrfs_fs_info *fs_info);
@@ -329,7 +326,7 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
 
 	/* the disk copy procedure reuses the scrub code */
 	mutex_lock(&fs_info->volume_mutex);
-	ret = btrfs_dev_replace_find_srcdev(root, args->start.srcdevid,
+	ret = btrfs_find_device_by_user_input(root, args->start.srcdevid,
 					    args->start.srcdev_name,
 					    &src_device);
 	if (ret) {
@@ -628,25 +625,6 @@ static void btrfs_dev_replace_update_device_in_mapping_tree(
 	write_unlock(&em_tree->lock);
 }
 
-static int btrfs_dev_replace_find_srcdev(struct btrfs_root *root, u64 srcdevid,
-					 char *srcdev_name,
-					 struct btrfs_device **device)
-{
-	int ret;
-
-	if (srcdevid) {
-		ret = 0;
-		*device = btrfs_find_device(root->fs_info, srcdevid, NULL,
-					    NULL);
-		if (!*device)
-			ret = -ENOENT;
-	} else {
-		ret = btrfs_find_device_missing_or_by_path(root, srcdev_name,
-							   device);
-	}
-	return ret;
-}
-
 void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info,
 			      struct btrfs_ioctl_dev_replace_args *args)
 {
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 35ee3ca..9243f8e 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2052,6 +2052,25 @@ int btrfs_find_device_missing_or_by_path(struct btrfs_root *root,
 	}
 }
 
+int btrfs_find_device_by_user_input(struct btrfs_root *root, u64 srcdevid,
+					 char *srcdev_name,
+					 struct btrfs_device **device)
+{
+	int ret;
+
+	if (srcdevid) {
+		ret = 0;
+		*device = btrfs_find_device(root->fs_info, srcdevid, NULL,
+					    NULL);
+		if (!*device)
+			ret = -ENOENT;
+	} else {
+		ret = btrfs_find_device_missing_or_by_path(root, srcdev_name,
+							   device);
+	}
+	return ret;
+}
+
 /*
  * does all the dirty work required for changing file system's UUID.
  */
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index a6e3b37..15ee0dd 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -430,6 +430,9 @@ void btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices, int step);
 int btrfs_find_device_missing_or_by_path(struct btrfs_root *root,
 					 char *device_path,
 					 struct btrfs_device **device);
+int btrfs_find_device_by_user_input(struct btrfs_root *root, u64 srcdevid,
+					 char *srcdev_name,
+					 struct btrfs_device **device);
 struct btrfs_device *btrfs_alloc_device(struct btrfs_fs_info *fs_info,
 					const u64 *devid,
 					const u8 *uuid);
-- 
2.4.1


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

* [PATCH 4/7] Btrfs: make use of btrfs_find_device_by_user_input()
  2015-10-06 15:19 [PATCH 0/7] Introduce device delete by devid Anand Jain
                   ` (2 preceding siblings ...)
  2015-10-06 15:19 ` [PATCH V2 3/7] Btrfs: create helper btrfs_find_device_by_user_input() Anand Jain
@ 2015-10-06 15:19 ` Anand Jain
  2015-10-06 15:19 ` [PATCH V2 5/7] Btrfs: enhance btrfs_find_device_by_user_input() to check device path Anand Jain
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Anand Jain @ 2015-10-06 15:19 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba

btrfs_rm_device() has a section of the code which can be replaced
btrfs_find_device_by_user_input()

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

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 9243f8e..fbbe3fe 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1676,13 +1676,11 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 {
 	struct btrfs_device *device;
 	struct btrfs_device *next_device;
-	struct block_device *bdev;
+	struct block_device *bdev = NULL;
 	struct buffer_head *bh = NULL;
-	struct btrfs_super_block *disk_super;
+	struct btrfs_super_block *disk_super = NULL;
 	struct btrfs_fs_devices *cur_devices;
-	u64 devid;
 	u64 num_devices;
-	u8 *dev_uuid;
 	int ret = 0;
 	bool clear_super = false;
 
@@ -1692,57 +1690,19 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 	if (ret)
 		goto out;
 
-	if (strcmp(device_path, "missing") == 0) {
-		struct list_head *devices;
-		struct btrfs_device *tmp;
-
-		device = NULL;
-		devices = &root->fs_info->fs_devices->devices;
-		/*
-		 * It is safe to read the devices since the volume_mutex
-		 * is held.
-		 */
-		list_for_each_entry(tmp, devices, dev_list) {
-			if (tmp->in_fs_metadata &&
-			    !tmp->is_tgtdev_for_dev_replace &&
-			    !tmp->bdev) {
-				device = tmp;
-				break;
-			}
-		}
-		bdev = NULL;
-		bh = NULL;
-		disk_super = NULL;
-		if (!device) {
-			ret = BTRFS_ERROR_DEV_MISSING_NOT_FOUND;
-			goto out;
-		}
-	} else {
-		ret = btrfs_get_bdev_and_sb(device_path,
-					    FMODE_WRITE | FMODE_EXCL,
-					    root->fs_info->bdev_holder, 0,
-					    &bdev, &bh);
-		if (ret)
-			goto out;
-		disk_super = (struct btrfs_super_block *)bh->b_data;
-		devid = btrfs_stack_device_id(&disk_super->dev_item);
-		dev_uuid = disk_super->dev_item.uuid;
-		device = btrfs_find_device(root->fs_info, devid, dev_uuid,
-					   disk_super->fsid);
-		if (!device) {
-			ret = -ENOENT;
-			goto error_brelse;
-		}
-	}
+	ret = btrfs_find_device_by_user_input(root, 0, device_path,
+				&device);
+	if (ret)
+		goto out;
 
 	if (device->is_tgtdev_for_dev_replace) {
 		ret = BTRFS_ERROR_DEV_TGT_REPLACE;
-		goto error_brelse;
+		goto out;
 	}
 
 	if (device->writeable && root->fs_info->fs_devices->rw_devices == 1) {
 		ret = BTRFS_ERROR_DEV_ONLY_WRITABLE;
-		goto error_brelse;
+		goto out;
 	}
 
 	if (device->writeable) {
@@ -1832,16 +1792,33 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 	 * at this point, the device is zero sized.  We want to
 	 * remove it from the devices list and zero out the old super
 	 */
-	if (clear_super && disk_super) {
+	if (clear_super) {
 		u64 bytenr;
 		int i;
 
+		if (!disk_super) {
+			ret = btrfs_get_bdev_and_sb(device_path,
+					FMODE_WRITE | FMODE_EXCL,
+					root->fs_info->bdev_holder, 0,
+					&bdev, &bh);
+			if (ret) {
+				/*
+				 * It could be a failed device ok for clear_super
+				 * to fail. So return success
+				 */
+				ret = 0;
+				goto out;
+			}
+
+			disk_super = (struct btrfs_super_block *)bh->b_data;
+		}
 		/* make sure this device isn't detected as part of
 		 * the FS anymore
 		 */
 		memset(&disk_super->magic, 0, sizeof(disk_super->magic));
 		set_buffer_dirty(bh);
 		sync_dirty_buffer(bh);
+		brelse(bh);
 
 		/* clear the mirror copies of super block on the disk
 		 * being removed, 0th copy is been taken care above and
@@ -1853,7 +1830,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 					i_size_read(bdev->bd_inode))
 				break;
 
-			brelse(bh);
 			bh = __bread(bdev, bytenr / 4096,
 					BTRFS_SUPER_INFO_SIZE);
 			if (!bh)
@@ -1863,32 +1839,30 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 
 			if (btrfs_super_bytenr(disk_super) != bytenr ||
 				btrfs_super_magic(disk_super) != BTRFS_MAGIC) {
+				brelse(bh);
 				continue;
 			}
 			memset(&disk_super->magic, 0,
 						sizeof(disk_super->magic));
 			set_buffer_dirty(bh);
 			sync_dirty_buffer(bh);
+			brelse(bh);
 		}
-	}
 
-	ret = 0;
-
-	if (bdev) {
-		/* Notify udev that device has changed */
-		btrfs_kobject_uevent(bdev, KOBJ_CHANGE);
+		if (bdev) {
+			/* Notify udev that device has changed */
+			btrfs_kobject_uevent(bdev, KOBJ_CHANGE);
 
-		/* Update ctime/mtime for device path for libblkid */
-		update_dev_time(device_path);
+			/* Update ctime/mtime for device path for libblkid */
+			update_dev_time(device_path);
+			blkdev_put(bdev, FMODE_READ | FMODE_EXCL);
+		}
 	}
 
-error_brelse:
-	brelse(bh);
-	if (bdev)
-		blkdev_put(bdev, FMODE_READ | FMODE_EXCL);
 out:
 	mutex_unlock(&uuid_mutex);
 	return ret;
+
 error_undo:
 	if (device->writeable) {
 		lock_chunks(root);
@@ -1897,7 +1871,7 @@ error_undo:
 		device->fs_devices->rw_devices++;
 		unlock_chunks(root);
 	}
-	goto error_brelse;
+	goto out;
 }
 
 void btrfs_rm_dev_replace_remove_srcdev(struct btrfs_fs_info *fs_info,
-- 
2.4.1


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

* [PATCH V2 5/7] Btrfs: enhance btrfs_find_device_by_user_input() to check device path
  2015-10-06 15:19 [PATCH 0/7] Introduce device delete by devid Anand Jain
                   ` (3 preceding siblings ...)
  2015-10-06 15:19 ` [PATCH 4/7] Btrfs: make use of btrfs_find_device_by_user_input() Anand Jain
@ 2015-10-06 15:19 ` Anand Jain
  2015-10-06 15:19 ` [PATCH V2 6/7] Btrfs: make use of btrfs_scratch_superblocks() in btrfs_rm_device() Anand Jain
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Anand Jain @ 2015-10-06 15:19 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba

The operation of device replace and device delete follows same steps
upto some depth with in btrfs kernel, however they don't share codes.
This enhancement will help replace and delete to share codes.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
v2: reword subject from
    Btrfs: check device_path in btrfs_find_device_by_user_input()

 fs/btrfs/dev-replace.c | 4 ----
 fs/btrfs/volumes.c     | 3 +++
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index c093f49..02df419 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -320,10 +320,6 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
 		return -EINVAL;
 	}
 
-	if ((args->start.srcdevid == 0 && args->start.srcdev_name[0] == '\0') ||
-	    args->start.tgtdev_name[0] == '\0')
-		return -EINVAL;
-
 	/* the disk copy procedure reuses the scrub code */
 	mutex_lock(&fs_info->volume_mutex);
 	ret = btrfs_find_device_by_user_input(root, args->start.srcdevid,
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index fbbe3fe..e929211 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2039,6 +2039,9 @@ int btrfs_find_device_by_user_input(struct btrfs_root *root, u64 srcdevid,
 		if (!*device)
 			ret = -ENOENT;
 	} else {
+		if (!srcdev_name || !srcdev_name[0])
+			return -EINVAL;
+
 		ret = btrfs_find_device_missing_or_by_path(root, srcdev_name,
 							   device);
 	}
-- 
2.4.1


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

* [PATCH V2 6/7] Btrfs: make use of btrfs_scratch_superblocks() in btrfs_rm_device()
  2015-10-06 15:19 [PATCH 0/7] Introduce device delete by devid Anand Jain
                   ` (4 preceding siblings ...)
  2015-10-06 15:19 ` [PATCH V2 5/7] Btrfs: enhance btrfs_find_device_by_user_input() to check device path Anand Jain
@ 2015-10-06 15:19 ` Anand Jain
  2015-10-06 15:19 ` [PATCH V4 7/7] Btrfs: Introduce device delete by devid Anand Jain
  2016-02-12 18:22 ` [PATCH 0/7] " David Sterba
  7 siblings, 0 replies; 10+ messages in thread
From: Anand Jain @ 2015-10-06 15:19 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba

With the previous patches now the btrfs_scratch_superblocks()
is ready to be used in btrfs_rm_device() so use it.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
v2: changelog update

 fs/btrfs/volumes.c | 78 ++++++++++--------------------------------------------
 1 file changed, 14 insertions(+), 64 deletions(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index e929211..69d311c 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1676,13 +1676,11 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 {
 	struct btrfs_device *device;
 	struct btrfs_device *next_device;
-	struct block_device *bdev = NULL;
-	struct buffer_head *bh = NULL;
-	struct btrfs_super_block *disk_super = NULL;
 	struct btrfs_fs_devices *cur_devices;
 	u64 num_devices;
 	int ret = 0;
 	bool clear_super = false;
+	char *dev_name = NULL;
 
 	mutex_lock(&uuid_mutex);
 
@@ -1710,6 +1708,11 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 		list_del_init(&device->dev_alloc_list);
 		device->fs_devices->rw_devices--;
 		unlock_chunks(root);
+		dev_name = kstrdup(device->name->str, GFP_NOFS);
+		if (!dev_name) {
+			ret = -ENOMEM;
+			goto error_undo;
+		}
 		clear_super = true;
 	}
 
@@ -1793,73 +1796,20 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 	 * remove it from the devices list and zero out the old super
 	 */
 	if (clear_super) {
-		u64 bytenr;
-		int i;
-
-		if (!disk_super) {
-			ret = btrfs_get_bdev_and_sb(device_path,
-					FMODE_WRITE | FMODE_EXCL,
-					root->fs_info->bdev_holder, 0,
-					&bdev, &bh);
-			if (ret) {
-				/*
-				 * It could be a failed device ok for clear_super
-				 * to fail. So return success
-				 */
-				ret = 0;
-				goto out;
-			}
-
-			disk_super = (struct btrfs_super_block *)bh->b_data;
-		}
-		/* make sure this device isn't detected as part of
-		 * the FS anymore
-		 */
-		memset(&disk_super->magic, 0, sizeof(disk_super->magic));
-		set_buffer_dirty(bh);
-		sync_dirty_buffer(bh);
-		brelse(bh);
-
-		/* clear the mirror copies of super block on the disk
-		 * being removed, 0th copy is been taken care above and
-		 * the below would take of the rest
-		 */
-		for (i = 1; i < BTRFS_SUPER_MIRROR_MAX; i++) {
-			bytenr = btrfs_sb_offset(i);
-			if (bytenr + BTRFS_SUPER_INFO_SIZE >=
-					i_size_read(bdev->bd_inode))
-				break;
-
-			bh = __bread(bdev, bytenr / 4096,
-					BTRFS_SUPER_INFO_SIZE);
-			if (!bh)
-				continue;
+		struct block_device *bdev;
 
-			disk_super = (struct btrfs_super_block *)bh->b_data;
-
-			if (btrfs_super_bytenr(disk_super) != bytenr ||
-				btrfs_super_magic(disk_super) != BTRFS_MAGIC) {
-				brelse(bh);
-				continue;
-			}
-			memset(&disk_super->magic, 0,
-						sizeof(disk_super->magic));
-			set_buffer_dirty(bh);
-			sync_dirty_buffer(bh);
-			brelse(bh);
-		}
-
-		if (bdev) {
-			/* Notify udev that device has changed */
-			btrfs_kobject_uevent(bdev, KOBJ_CHANGE);
-
-			/* Update ctime/mtime for device path for libblkid */
-			update_dev_time(device_path);
+		bdev = blkdev_get_by_path(dev_name, FMODE_READ | FMODE_EXCL,
+						root->fs_info->bdev_holder);
+		if (!IS_ERR(bdev)) {
+			btrfs_scratch_superblocks(bdev, dev_name);
 			blkdev_put(bdev, FMODE_READ | FMODE_EXCL);
 		}
 	}
 
 out:
+	if (dev_name)
+		kfree(dev_name);
+
 	mutex_unlock(&uuid_mutex);
 	return ret;
 
-- 
2.4.1


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

* [PATCH V4 7/7] Btrfs: Introduce device delete by devid
  2015-10-06 15:19 [PATCH 0/7] Introduce device delete by devid Anand Jain
                   ` (5 preceding siblings ...)
  2015-10-06 15:19 ` [PATCH V2 6/7] Btrfs: make use of btrfs_scratch_superblocks() in btrfs_rm_device() Anand Jain
@ 2015-10-06 15:19 ` Anand Jain
  2016-02-12 18:22 ` [PATCH 0/7] " David Sterba
  7 siblings, 0 replies; 10+ messages in thread
From: Anand Jain @ 2015-10-06 15:19 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba

This introduces new ioctl BTRFS_IOC_RM_DEV_V2, which uses
enhanced struct btrfs_ioctl_vol_args_v2 to carry devid as
an user argument.

The patch won't delete the old ioctl interface and remains
backward compatible with user land progs.

Test case/script:
echo "0 $(blockdev --getsz /dev/sdf) linear /dev/sdf 0" | dmsetup create bad_disk
mkfs.btrfs -f -d raid1 -m raid1 /dev/sdd /dev/sde /dev/mapper/bad_disk
mount /dev/sdd /btrfs
dmsetup suspend bad_disk
echo "0 $(blockdev --getsz /dev/sdf) error /dev/sdf 0" | dmsetup load bad_disk
dmsetup resume bad_disk
echo "bad disk failed. now deleting/replacing"
btrfs dev del  3  /btrfs
echo $?
btrfs fi show /btrfs
umount /btrfs
btrfs-show-super /dev/sdd | egrep num_device
dmsetup remove bad_disk
wipefs -a /dev/sdf

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Reported-by: Martin <m_btrfs@ml1.co.uk>
---
v4: enahnced btrfs_ioctl_vol_args_v2 to accept devid instead of
    creating a new structure. Thanks to David.
    commit update and title changed from..
    Btrfs: device delete by devid

v3: commit update, included test case

v2: don't use device->name after free

 fs/btrfs/ioctl.c           | 58 +++++++++++++++++++++++++++++++++++++++++++++-
 fs/btrfs/volumes.c         |  4 ++--
 fs/btrfs/volumes.h         |  2 +-
 include/uapi/linux/btrfs.h | 14 ++++++++++-
 4 files changed, 73 insertions(+), 5 deletions(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index f43a104..f3aa37c 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2653,6 +2653,60 @@ out:
 	return ret;
 }
 
+static long btrfs_ioctl_rm_dev_v2(struct file *file, void __user *arg)
+{
+	struct btrfs_root *root = BTRFS_I(file_inode(file))->root;
+	struct btrfs_ioctl_vol_args_v2 *vol_args;
+	int ret;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	ret = mnt_want_write_file(file);
+	if (ret)
+		return ret;
+
+	vol_args = memdup_user(arg, sizeof(*vol_args));
+	if (IS_ERR(vol_args)) {
+		ret = PTR_ERR(vol_args);
+		goto err_drop;
+	}
+
+	/* Check for compatibility reject unknown flags */
+	if (vol_args->flags & ~BTRFS_VOL_ARG_V2_FLAGS)
+		return -ENOTTY;
+
+	if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running,
+			1)) {
+		ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS;
+		goto out;
+	}
+
+	mutex_lock(&root->fs_info->volume_mutex);
+	if (vol_args->flags & BTRFS_DEVICE_BY_ID) {
+		ret = btrfs_rm_device(root, NULL, vol_args->devid);
+	} else {
+		vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
+		ret = btrfs_rm_device(root, vol_args->name, 0);
+	}
+
+	mutex_unlock(&root->fs_info->volume_mutex);
+	atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0);
+
+	if (!ret) {
+		if (vol_args->flags & BTRFS_DEVICE_BY_ID)
+			btrfs_info(root->fs_info, "disk devid %llu deleted",
+								vol_args->devid);
+		else
+			btrfs_info(root->fs_info, "disk deleted - %s", vol_args->name);
+	}
+out:
+	kfree(vol_args);
+err_drop:
+	mnt_drop_write_file(file);
+	return ret;
+}
+
 static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
 {
 	struct btrfs_root *root = BTRFS_I(file_inode(file))->root;
@@ -2681,7 +2735,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
 	}
 
 	mutex_lock(&root->fs_info->volume_mutex);
-	ret = btrfs_rm_device(root, vol_args->name);
+	ret = btrfs_rm_device(root, vol_args->name, 0);
 	mutex_unlock(&root->fs_info->volume_mutex);
 	atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0);
 
@@ -5424,6 +5478,8 @@ long btrfs_ioctl(struct file *file, unsigned int
 		return btrfs_ioctl_add_dev(root, argp);
 	case BTRFS_IOC_RM_DEV:
 		return btrfs_ioctl_rm_dev(file, argp);
+	case BTRFS_IOC_RM_DEV_V2:
+		return btrfs_ioctl_rm_dev_v2(file, argp);
 	case BTRFS_IOC_FS_INFO:
 		return btrfs_ioctl_fs_info(root, argp);
 	case BTRFS_IOC_DEV_INFO:
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 69d311c..a384b65 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1672,7 +1672,7 @@ static int __check_raid_min_devices(struct btrfs_fs_info *fs_info)
 	return 0;
 }
 
-int btrfs_rm_device(struct btrfs_root *root, char *device_path)
+int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
 {
 	struct btrfs_device *device;
 	struct btrfs_device *next_device;
@@ -1688,7 +1688,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 	if (ret)
 		goto out;
 
-	ret = btrfs_find_device_by_user_input(root, 0, device_path,
+	ret = btrfs_find_device_by_user_input(root, devid, device_path,
 				&device);
 	if (ret)
 		goto out;
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 15ee0dd..4150d9d 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -436,7 +436,7 @@ int btrfs_find_device_by_user_input(struct btrfs_root *root, u64 srcdevid,
 struct btrfs_device *btrfs_alloc_device(struct btrfs_fs_info *fs_info,
 					const u64 *devid,
 					const u8 *uuid);
-int btrfs_rm_device(struct btrfs_root *root, char *device_path);
+int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid);
 void btrfs_cleanup_fs_uuids(void);
 int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len);
 int btrfs_grow_device(struct btrfs_trans_handle *trans,
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
index b6dec05..ff40c48 100644
--- a/include/uapi/linux/btrfs.h
+++ b/include/uapi/linux/btrfs.h
@@ -36,6 +36,13 @@ struct btrfs_ioctl_vol_args {
 #define BTRFS_SUBVOL_CREATE_ASYNC	(1ULL << 0)
 #define BTRFS_SUBVOL_RDONLY		(1ULL << 1)
 #define BTRFS_SUBVOL_QGROUP_INHERIT	(1ULL << 2)
+#define BTRFS_DEVICE_BY_ID		(1ULL << 3)
+#define BTRFS_VOL_ARG_V2_FLAGS				\
+			(BTRFS_SUBVOL_CREATE_ASYNC |	\
+			BTRFS_SUBVOL_RDONLY |		\
+			BTRFS_SUBVOL_QGROUP_INHERIT |	\
+			BTRFS_DEVICE_BY_ID)
+
 #define BTRFS_FSID_SIZE 16
 #define BTRFS_UUID_SIZE 16
 #define BTRFS_UUID_UNPARSED_SIZE	37
@@ -76,7 +83,10 @@ struct btrfs_ioctl_vol_args_v2 {
 		};
 		__u64 unused[4];
 	};
-	char name[BTRFS_SUBVOL_NAME_MAX + 1];
+	union {
+		char name[BTRFS_SUBVOL_NAME_MAX + 1];
+		u64 devid;
+	};
 };
 
 /*
@@ -634,5 +644,7 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
 				   struct btrfs_ioctl_feature_flags[2])
 #define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \
 				   struct btrfs_ioctl_feature_flags[3])
+#define BTRFS_IOC_RM_DEV_V2 _IOW(BTRFS_IOCTL_MAGIC, 58, \
+				   struct btrfs_ioctl_vol_args_v2)
 
 #endif /* _UAPI_LINUX_BTRFS_H */
-- 
2.4.1


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

* Re: [PATCH 0/7] Introduce device delete by devid
  2015-10-06 15:19 [PATCH 0/7] Introduce device delete by devid Anand Jain
                   ` (6 preceding siblings ...)
  2015-10-06 15:19 ` [PATCH V4 7/7] Btrfs: Introduce device delete by devid Anand Jain
@ 2016-02-12 18:22 ` David Sterba
  2016-02-13  2:09   ` Anand Jain
  7 siblings, 1 reply; 10+ messages in thread
From: David Sterba @ 2016-02-12 18:22 UTC (permalink / raw)
  To: Anand Jain; +Cc: linux-btrfs, dsterba

On Tue, Oct 06, 2015 at 11:19:17PM +0800, Anand Jain wrote:
> The operation of device replace and device delete follows same steps
> upto some depths, however they don't share codes.
> This set of enhancement will help device replace and device delete to
> share codes.
> And at the end add support to delete device using devid.

I'd like to get this rolling again, do you have an updated branch? I'm
not sure what's the latest status of the 'number of devices vs raid
constraints' problem. Qu did some patches, I hope either of you can let
me know. Thanks.

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

* Re: [PATCH 0/7] Introduce device delete by devid
  2016-02-12 18:22 ` [PATCH 0/7] " David Sterba
@ 2016-02-13  2:09   ` Anand Jain
  0 siblings, 0 replies; 10+ messages in thread
From: Anand Jain @ 2016-02-13  2:09 UTC (permalink / raw)
  To: dsterba, linux-btrfs



On 02/13/2016 02:22 AM, David Sterba wrote:
> On Tue, Oct 06, 2015 at 11:19:17PM +0800, Anand Jain wrote:
>> The operation of device replace and device delete follows same steps
>> upto some depths, however they don't share codes.
>> This set of enhancement will help device replace and device delete to
>> share codes.
>> And at the end add support to delete device using devid.
>
> I'd like to get this rolling again, do you have an updated branch? I'm
> not sure what's the latest status of the



> 'number of devices vs raid
> constraints' problem. Qu did some patches, I hope either of you can let
> me know. Thanks.

  Hi Dave,

    Qu patch is required with my patch set titled
      'btrfs: Hot spare and Auto replace'
    I can send that again. pls let me know.

    However I think you are looking for the patch set
      'Introduce device delete by devid'
    here these patch does not depend on Qu patches.
    I have sent them again in a separate thread.

Thanks, Anand

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

end of thread, other threads:[~2016-02-13  2:09 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-06 15:19 [PATCH 0/7] Introduce device delete by devid Anand Jain
2015-10-06 15:19 ` [PATCH V2 1/7] Btrfs: create helper function __check_raid_min_devices() Anand Jain
2015-10-06 15:19 ` [PATCH 2/7] Btrfs: clean up and optimize __check_raid_min_device() Anand Jain
2015-10-06 15:19 ` [PATCH V2 3/7] Btrfs: create helper btrfs_find_device_by_user_input() Anand Jain
2015-10-06 15:19 ` [PATCH 4/7] Btrfs: make use of btrfs_find_device_by_user_input() Anand Jain
2015-10-06 15:19 ` [PATCH V2 5/7] Btrfs: enhance btrfs_find_device_by_user_input() to check device path Anand Jain
2015-10-06 15:19 ` [PATCH V2 6/7] Btrfs: make use of btrfs_scratch_superblocks() in btrfs_rm_device() Anand Jain
2015-10-06 15:19 ` [PATCH V4 7/7] Btrfs: Introduce device delete by devid Anand Jain
2016-02-12 18:22 ` [PATCH 0/7] " David Sterba
2016-02-13  2:09   ` 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).