All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] device delete by devid
@ 2015-04-20 10:29 Anand Jain
  2015-04-20 10:29 ` [PATCH] Btrfs: " Anand Jain
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Anand Jain @ 2015-04-20 10:29 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba, m_btrfs

Current method to identify and verify the user provided device_path
needs device SB to be accessible. In situations where SB isn't accessible
or read fails. Using devid will help.

Anand Jain (1):
  Btrfs: device delete by devid

 fs/btrfs/ioctl.c           | 50 +++++++++++++++++++++++++++++++++++++++++++++-
 fs/btrfs/volumes.c         | 33 +++++++++++++++++++++---------
 fs/btrfs/volumes.h         |  2 +-
 include/uapi/linux/btrfs.h |  8 ++++++++
 4 files changed, 82 insertions(+), 11 deletions(-)

Anand Jain (2):
  btrfs-progs: move is_numerical to utils-lib.h and make it non static
  btrfs-progs: device delete to accept devid

 Documentation/btrfs-device.txt |  2 +-
 cmds-device.c                  | 47 ++++++++++++++++++++++++++++++++----------
 cmds-replace.c                 | 11 ----------
 ioctl.h                        |  8 +++++++
 utils-lib.c                    | 11 ++++++++++
 utils.h                        |  1 +
 6 files changed, 57 insertions(+), 23 deletions(-)

-- 
2.0.0.153.g79dcccc


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

* [PATCH] Btrfs: device delete by devid
  2015-04-20 10:29 [PATCH] device delete by devid Anand Jain
@ 2015-04-20 10:29 ` Anand Jain
  2015-04-27  7:34   ` [PATCH 0/8 v2] " Anand Jain
  2015-04-20 10:29 ` [PATCH 1/2] btrfs-progs: move is_numerical to utils-lib.h and make it non static Anand Jain
  2015-04-20 10:29 ` [PATCH 2/2] btrfs-progs: device delete to accept devid Anand Jain
  2 siblings, 1 reply; 14+ messages in thread
From: Anand Jain @ 2015-04-20 10:29 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba, m_btrfs

This introduces BTRFS_IOC_RM_DEV_V2, which can accept devid as
an argument to delete the device.

Current only choice to is to pass device path for the device delete
cli, but if btrfs is unable to read device SB, then cli fails. And
user won't be able to delete the device.

With this patch now the user can specify devid as the device
to delete.

The patch won't delete the old interface so that kernel will
remain compatible with the older user-interface programs like
btrfs-progs.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Reported-by: Martin <m_btrfs@ml1.co.uk>
---
 fs/btrfs/ioctl.c           | 50 +++++++++++++++++++++++++++++++++++++++++++++-
 fs/btrfs/volumes.c         | 33 +++++++++++++++++++++---------
 fs/btrfs/volumes.h         |  2 +-
 include/uapi/linux/btrfs.h |  8 ++++++++
 4 files changed, 82 insertions(+), 11 deletions(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index d49fe8a..f04be02 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2624,6 +2624,52 @@ 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_v3 *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;
+	}
+
+	vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
+
+	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);
+	ret = btrfs_rm_device(root, vol_args->name, vol_args->devid);
+	mutex_unlock(&root->fs_info->volume_mutex);
+	atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0);
+
+	if (!ret) {
+		if (vol_args->devid)
+			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;
@@ -2652,7 +2698,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);
 
@@ -5236,6 +5282,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 c505123..aaf1a3b 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1609,16 +1609,15 @@ out:
 	return ret;
 }
 
-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;
-	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 all_avail;
-	u64 devid;
 	u64 num_devices;
 	u8 *dev_uuid;
 	unsigned seq;
@@ -1664,7 +1663,15 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 		goto out;
 	}
 
-	if (strcmp(device_path, "missing") == 0) {
+	if (devid) {
+		device = btrfs_find_device(root->fs_info, devid,
+				NULL, NULL);
+		if (!device) {
+			ret = -ENOENT;
+			goto out;
+		}
+		device_path = rcu_str_deref(device->name);
+	} else if (strcmp(device_path, "missing") == 0) {
 		struct list_head *devices;
 		struct btrfs_device *tmp;
 
@@ -1682,9 +1689,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 				break;
 			}
 		}
-		bdev = NULL;
-		bh = NULL;
-		disk_super = NULL;
 		if (!device) {
 			ret = BTRFS_ERROR_DEV_MISSING_NOT_FOUND;
 			goto out;
@@ -1805,10 +1809,20 @@ 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(rcu_str_deref(device->name),
+					    FMODE_WRITE | FMODE_EXCL,
+					    root->fs_info->bdev_holder, 0,
+					    &bdev, &bh);
+			if (ret)
+				goto done;
+
+			disk_super = (struct btrfs_super_block *)bh->b_data;
+		}
 		/* make sure this device isn't detected as part of
 		 * the FS anymore
 		 */
@@ -1845,6 +1859,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 		}
 	}
 
+done:
 	ret = 0;
 
 	if (bdev) {
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index d7bb29f..8d956b8 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -445,7 +445,7 @@ int btrfs_find_device_missing_or_by_path(struct btrfs_root *root,
 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..074affe 100644
--- a/include/uapi/linux/btrfs.h
+++ b/include/uapi/linux/btrfs.h
@@ -31,6 +31,12 @@ struct btrfs_ioctl_vol_args {
 	char name[BTRFS_PATH_NAME_MAX + 1];
 };
 
+struct btrfs_ioctl_vol_args_v3 {
+	__s64 fd;
+	char name[BTRFS_PATH_NAME_MAX + 1];
+	__u64 devid;
+};
+
 #define BTRFS_DEVICE_PATH_NAME_MAX 1024
 
 #define BTRFS_SUBVOL_CREATE_ASYNC	(1ULL << 0)
@@ -634,5 +640,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_v3)
 
 #endif /* _UAPI_LINUX_BTRFS_H */
-- 
2.0.0.153.g79dcccc


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

* [PATCH 1/2] btrfs-progs: move is_numerical to utils-lib.h and make it non static
  2015-04-20 10:29 [PATCH] device delete by devid Anand Jain
  2015-04-20 10:29 ` [PATCH] Btrfs: " Anand Jain
@ 2015-04-20 10:29 ` Anand Jain
  2015-04-20 10:29 ` [PATCH 2/2] btrfs-progs: device delete to accept devid Anand Jain
  2 siblings, 0 replies; 14+ messages in thread
From: Anand Jain @ 2015-04-20 10:29 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba, m_btrfs

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 cmds-replace.c | 11 -----------
 utils-lib.c    | 11 +++++++++++
 utils.h        |  1 +
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/cmds-replace.c b/cmds-replace.c
index 63d34f9..6ea7c61 100644
--- a/cmds-replace.c
+++ b/cmds-replace.c
@@ -65,17 +65,6 @@ static const char * const replace_cmd_group_usage[] = {
 	NULL
 };
 
-static int is_numerical(const char *str)
-{
-	if (!(*str >= '0' && *str <= '9'))
-		return 0;
-	while (*str >= '0' && *str <= '9')
-		str++;
-	if (*str != '\0')
-		return 0;
-	return 1;
-}
-
 static int dev_replace_cancel_fd = -1;
 static void dev_replace_sigint_handler(int signal)
 {
diff --git a/utils-lib.c b/utils-lib.c
index 79ef35e..9ac0b7b 100644
--- a/utils-lib.c
+++ b/utils-lib.c
@@ -38,3 +38,14 @@ u64 arg_strtou64(const char *str)
 	}
 	return value;
 }
+
+int is_numerical(const char *str)
+{
+	if (!(*str >= '0' && *str <= '9'))
+		return 0;
+	while (*str >= '0' && *str <= '9')
+		str++;
+	if (*str != '\0')
+		return 0;
+	return 1;
+}
diff --git a/utils.h b/utils.h
index 6a39ada..f734a57 100644
--- a/utils.h
+++ b/utils.h
@@ -211,5 +211,6 @@ static inline u64 div_factor(u64 num, int factor)
 
 int btrfs_tree_search2_ioctl_supported(int fd);
 int btrfs_check_node_or_leaf_size(u32 size, u32 sectorsize);
+int is_numerical(const char *str);
 
 #endif
-- 
2.0.0.153.g79dcccc


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

* [PATCH 2/2] btrfs-progs: device delete to accept devid
  2015-04-20 10:29 [PATCH] device delete by devid Anand Jain
  2015-04-20 10:29 ` [PATCH] Btrfs: " Anand Jain
  2015-04-20 10:29 ` [PATCH 1/2] btrfs-progs: move is_numerical to utils-lib.h and make it non static Anand Jain
@ 2015-04-20 10:29 ` Anand Jain
  2015-07-13  2:28   ` [PATCH 2/2 v2] " Anand Jain
  2 siblings, 1 reply; 14+ messages in thread
From: Anand Jain @ 2015-04-20 10:29 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba, m_btrfs

This patch introduces new option <devid> for the command

  btrfs device delete <device_path|devid>[..]  <mnt>

In a user reported issue on a 3-disk-RAID1, one disk failed with its
SB unreadable. Now with this patch user will have a choice to delete
the device using devid.

The other method we could do, is to match the input device_path
to the available device_paths with in the kernel. But that won't
work in all the cases, like what if user provided mapper path
when the path within the kernel is a non-mapper path.

This patch depends on the below kernel patch for the new feature to work,
however it will fail-back to the old interface for the kernel without the
patch

  Btrfs: device delete by devid

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 Documentation/btrfs-device.txt |  2 +-
 cmds-device.c                  | 47 ++++++++++++++++++++++++++++++++----------
 ioctl.h                        |  8 +++++++
 3 files changed, 45 insertions(+), 12 deletions(-)

diff --git a/Documentation/btrfs-device.txt b/Documentation/btrfs-device.txt
index 66be6b3..4bb5ea5 100644
--- a/Documentation/btrfs-device.txt
+++ b/Documentation/btrfs-device.txt
@@ -74,7 +74,7 @@ do not perform discard by default
 -f|--force::::
 force overwrite of existing filesystem on the given disk(s)
 
-*delete* <dev> [<dev>...] <path>::
+*delete* <dev>|<devid> [<dev>|<devid>...] <path>::
 Remove device(s) from a filesystem identified by <path>.
 
 *ready* <device>::
diff --git a/cmds-device.c b/cmds-device.c
index 1c32771..69e79d4 100644
--- a/cmds-device.c
+++ b/cmds-device.c
@@ -145,7 +145,7 @@ error_out:
 }
 
 static const char * const cmd_rm_dev_usage[] = {
-	"btrfs device delete <device> [<device>...] <path>",
+	"btrfs device delete <device>|<devid> [<device>|<devid>...] <path>",
 	"Remove a device from a filesystem",
 	NULL
 };
@@ -169,26 +169,51 @@ static int cmd_rm_dev(int argc, char **argv)
 
 	for(i=1 ; i < argc - 1; i++ ){
 		struct	btrfs_ioctl_vol_args arg;
+		struct	btrfs_ioctl_vol_args_v3 argv3 = {0};
 		int	res;
+		int 	its_num = false;
 
-		if (!is_block_device(argv[i])) {
+		if (is_numerical(argv[i])) {
+			argv3.devid = arg_strtou64(argv[i]);
+			its_num = true;
+		} else if (is_block_device(argv[i])) {
+			strncpy_null(argv3.name, argv[i]);
+		} else {
 			fprintf(stderr,
-				"ERROR: %s is not a block device\n", argv[i]);
+				"ERROR: %s is not a block device or devid\n", argv[i]);
 			ret++;
 			continue;
 		}
-		strncpy_null(arg.name, argv[i]);
-		res = ioctl(fdmnt, BTRFS_IOC_RM_DEV, &arg);
+		res = ioctl(fdmnt, BTRFS_IOC_RM_DEV_V2, &argv3);
 		e = errno;
+		if (res && e == ENOTTY) {
+			if (its_num) {
+				fprintf(stderr, "Error: Kernel does not support delete by devid\n");
+				continue;
+			}
+			strncpy_null(arg.name, argv[i]);
+			res = ioctl(fdmnt, BTRFS_IOC_RM_DEV, &arg);
+			e = errno;
+		}
 		if (res > 0) {
-			fprintf(stderr,
-				"ERROR: error removing the device '%s' - %s\n",
-				argv[i], btrfs_err_str(res));
+			if (its_num)
+				fprintf(stderr,
+					"ERROR: removing the devid '%llu' - %s\n",
+					argv3.devid, btrfs_err_str(res));
+			else
+				fprintf(stderr,
+					"ERROR: removing the device '%s' - %s\n",
+					argv[i], btrfs_err_str(res));
 			ret++;
 		} else if (res < 0) {
-			fprintf(stderr,
-				"ERROR: ioctl error removing the device '%s' - %s\n",
-				argv[i], strerror(e));
+			if (its_num)
+				fprintf(stderr,
+					"ERROR: ioctl removing the devid '%llu' - %s\n",
+					argv3.devid, strerror(e));
+			else
+				fprintf(stderr,
+					"ERROR: ioctl removing the device '%s' - %s\n",
+					argv[i], strerror(e));
 			ret++;
 		}
 	}
diff --git a/ioctl.h b/ioctl.h
index d550ca6..4354c37 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -37,6 +37,12 @@ struct btrfs_ioctl_vol_args {
 	char name[BTRFS_PATH_NAME_MAX + 1];
 };
 
+struct btrfs_ioctl_vol_args_v3 {
+	__s64 fd;
+	char name[BTRFS_PATH_NAME_MAX + 1];
+	__u64 devid;
+};
+
 #define BTRFS_DEVICE_PATH_NAME_MAX 1024
 
 #define BTRFS_SUBVOL_CREATE_ASYNC	(1ULL << 0)
@@ -621,6 +627,8 @@ struct btrfs_ioctl_clone_range_args {
                                   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_v3)
 #ifdef __cplusplus
 }
 #endif
-- 
2.0.0.153.g79dcccc


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

* [PATCH 0/8 v2] device delete by devid
  2015-04-20 10:29 ` [PATCH] Btrfs: " Anand Jain
@ 2015-04-27  7:34   ` Anand Jain
  2015-04-27  7:34     ` [PATCH V2 1/8] Btrfs: " Anand Jain
                       ` (7 more replies)
  0 siblings, 8 replies; 14+ messages in thread
From: Anand Jain @ 2015-04-27  7:34 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba, m_btrfs

Kernel patch of device delete by devid.
Now also includes possible code optimization.
Some of the codes are common between delete device and
replace device. This patch will use functions to reuse
those codes, mainly the get btrfs_device structure of
the source device, and scratch the source device at the end.

Anand Jain (8):
  Btrfs: device delete by devid
  Btrfs: move check for min number of devices to a function
  Btrfs: rename btrfs_dev_replace_find_srcdev()
  Btrfs: use BTRFS_ERROR_DEV_MISSING_NOT_FOUND when missing device is
    not found
  Btrfs: use btrfs_find_device_by_user_input()
  Btrfs: add btrfs_read_dev_one_super() to read one specific SB
  Btrfs: fix btrfs_scratch_superblock() with fixes from device delete
  Btrfs: use btrfs_scratch_superblock() in btrfs_rm_device()

 fs/btrfs/dev-replace.c     |  24 +----
 fs/btrfs/disk-io.c         |  54 ++++++----
 fs/btrfs/disk-io.h         |   2 +
 fs/btrfs/ioctl.c           |  50 ++++++++-
 fs/btrfs/volumes.c         | 257 ++++++++++++++++++++-------------------------
 fs/btrfs/volumes.h         |   7 +-
 include/uapi/linux/btrfs.h |   8 ++
 7 files changed, 210 insertions(+), 192 deletions(-)

-- 
2.0.0.153.g79dcccc


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

* [PATCH V2 1/8] Btrfs: device delete by devid
  2015-04-27  7:34   ` [PATCH 0/8 v2] " Anand Jain
@ 2015-04-27  7:34     ` Anand Jain
  2015-04-27  7:34     ` [PATCH 2/8] Btrfs: move check for min number of devices to a function Anand Jain
                       ` (6 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Anand Jain @ 2015-04-27  7:34 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba, m_btrfs

This introduces BTRFS_IOC_RM_DEV_V2, which can accept devid as
an argument to delete the device.

Current only choice to is to pass device path for the device delete
cli, but if btrfs is unable to read device SB, then cli fails. And
user won't be able to delete the device.

With this patch now the user can specify devid as the device
to delete.

The patch won't delete the old interface so that kernel will
remain compatible with the older user-interface programs like
btrfs-progs.

Test case/script:

SZ=`blockdev --getsz /dev/sdf`
dmsetup create bad_disk --table='0 $SZ linear /dev/sdf 0'
blockdev --setra 0 /dev/mapper/bad_disk
mkfs.btrfs -f -d raid1 -m raid1 /dev/sdd /dev/sde /dev/mapper/bad_disk
mount /dev/sdd /btrfs
echo 3 > /proc/sys/vm/drop_caches
dmsetup suspend bad_disk
dmsetup load bad_disk --table='0 $SZ error /dev/sdf 0'
dmsetup resume bad_disk
disk read should fail
dd if=/dev/mapper/bad_disk of=/dev/null count=1 > /dev/null 2>&1 && exit
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_all
wipe -a /dev/sdf


Signed-off-by: Anand Jain <anand.jain@oracle.com>
Reported-by: Martin <m_btrfs@ml1.co.uk>
---
v1->v2:
commit update with the test script which I have been using
don't use device->name after free

 fs/btrfs/ioctl.c           | 50 ++++++++++++++++++++++++++++++++++++++++++++-
 fs/btrfs/volumes.c         | 51 ++++++++++++++++++++++++++++++++++++----------
 fs/btrfs/volumes.h         |  2 +-
 include/uapi/linux/btrfs.h |  8 ++++++++
 4 files changed, 98 insertions(+), 13 deletions(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index d49fe8a..f04be02 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2624,6 +2624,52 @@ 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_v3 *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;
+	}
+
+	vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
+
+	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);
+	ret = btrfs_rm_device(root, vol_args->name, vol_args->devid);
+	mutex_unlock(&root->fs_info->volume_mutex);
+	atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0);
+
+	if (!ret) {
+		if (vol_args->devid)
+			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;
@@ -2652,7 +2698,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);
 
@@ -5236,6 +5282,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 63c7a8b..c8b033e 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1612,21 +1612,21 @@ out:
 	return ret;
 }
 
-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;
-	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 all_avail;
-	u64 devid;
 	u64 num_devices;
 	u8 *dev_uuid;
 	unsigned seq;
 	int ret = 0;
 	bool clear_super = false;
+	char *dev_name = NULL;
 
 	mutex_lock(&uuid_mutex);
 
@@ -1667,7 +1667,15 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 		goto out;
 	}
 
-	if (strcmp(device_path, "missing") == 0) {
+	if (devid) {
+		device = btrfs_find_device(root->fs_info, devid,
+				NULL, NULL);
+		if (!device) {
+			ret = -ENOENT;
+			goto out;
+		}
+		device_path = rcu_str_deref(device->name);
+	} else if (strcmp(device_path, "missing") == 0) {
 		struct list_head *devices;
 		struct btrfs_device *tmp;
 
@@ -1685,9 +1693,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 				break;
 			}
 		}
-		bdev = NULL;
-		bh = NULL;
-		disk_super = NULL;
 		if (!device) {
 			ret = BTRFS_ERROR_DEV_MISSING_NOT_FOUND;
 			goto out;
@@ -1725,6 +1730,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;
 	}
 
@@ -1808,10 +1818,26 @@ 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(dev_name,
+					    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 done;
+			}
+
+			disk_super = (struct btrfs_super_block *)bh->b_data;
+		}
 		/* make sure this device isn't detected as part of
 		 * the FS anymore
 		 */
@@ -1848,14 +1874,14 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 		}
 	}
 
+done:
 	ret = 0;
-
 	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_dev_time(dev_name);
 	}
 
 error_brelse:
@@ -1863,6 +1889,9 @@ error_brelse:
 	if (bdev)
 		blkdev_put(bdev, FMODE_READ | FMODE_EXCL);
 out:
+	if (dev_name)
+		kfree(dev_name);
+
 	mutex_unlock(&uuid_mutex);
 	return ret;
 error_undo:
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index d7bb29f..8d956b8 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -445,7 +445,7 @@ int btrfs_find_device_missing_or_by_path(struct btrfs_root *root,
 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..074affe 100644
--- a/include/uapi/linux/btrfs.h
+++ b/include/uapi/linux/btrfs.h
@@ -31,6 +31,12 @@ struct btrfs_ioctl_vol_args {
 	char name[BTRFS_PATH_NAME_MAX + 1];
 };
 
+struct btrfs_ioctl_vol_args_v3 {
+	__s64 fd;
+	char name[BTRFS_PATH_NAME_MAX + 1];
+	__u64 devid;
+};
+
 #define BTRFS_DEVICE_PATH_NAME_MAX 1024
 
 #define BTRFS_SUBVOL_CREATE_ASYNC	(1ULL << 0)
@@ -634,5 +640,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_v3)
 
 #endif /* _UAPI_LINUX_BTRFS_H */
-- 
2.0.0.153.g79dcccc


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

* [PATCH 2/8] Btrfs: move check for min number of devices to a function
  2015-04-27  7:34   ` [PATCH 0/8 v2] " Anand Jain
  2015-04-27  7:34     ` [PATCH V2 1/8] Btrfs: " Anand Jain
@ 2015-04-27  7:34     ` Anand Jain
  2015-04-27  7:34     ` [PATCH 3/8] Btrfs: rename btrfs_dev_replace_find_srcdev() Anand Jain
                       ` (5 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Anand Jain @ 2015-04-27  7:34 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba, m_btrfs

btrfs_rm_device() has a section of the code to check for min number
of the devices required by various group profile. This patch move
that part of the code in the function __check_raid_min_devices()

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

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index c8b033e..9556f59 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1612,61 +1612,69 @@ out:
 	return ret;
 }
 
-int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
+static int __check_raid_min_devices(struct btrfs_fs_info *fs_info)
 {
-	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 all_avail;
 	u64 num_devices;
-	u8 *dev_uuid;
 	unsigned seq;
-	int ret = 0;
-	bool clear_super = false;
-	char *dev_name = NULL;
-
-	mutex_lock(&uuid_mutex);
 
-	do {
-		seq = read_seqbegin(&root->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));
-
-	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(&fs_info->profiles_lock);
+
+		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;
 	}
 
+	return 0;
+}
+
+int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
+{
+	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;
+	u8 *dev_uuid;
+	int ret = 0;
+	bool clear_super = false;
+	char *dev_name = NULL;
+
+	mutex_lock(&uuid_mutex);
+
+	ret = __check_raid_min_devices(root->fs_info);
+	if (ret)
+		goto out;
+
 	if (devid) {
 		device = btrfs_find_device(root->fs_info, devid,
 				NULL, NULL);
-- 
2.0.0.153.g79dcccc


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

* [PATCH 3/8] Btrfs: rename btrfs_dev_replace_find_srcdev()
  2015-04-27  7:34   ` [PATCH 0/8 v2] " Anand Jain
  2015-04-27  7:34     ` [PATCH V2 1/8] Btrfs: " Anand Jain
  2015-04-27  7:34     ` [PATCH 2/8] Btrfs: move check for min number of devices to a function Anand Jain
@ 2015-04-27  7:34     ` Anand Jain
  2015-04-27  7:34     ` [PATCH 4/8] Btrfs: use BTRFS_ERROR_DEV_MISSING_NOT_FOUND when missing device is not found Anand Jain
                       ` (4 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Anand Jain @ 2015-04-27  7:34 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba, m_btrfs

The patch renames btrfs_dev_replace_find_srcdev() to
btrfs_find_device_by_user_input() so that it can be used
by btrfs_rm_device() as well in the next patches.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 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 17c7250..0019838 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);
@@ -343,7 +340,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) {
@@ -631,25 +628,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 9556f59..13b19c5 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2065,6 +2065,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 8d956b8..027d454 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -442,6 +442,9 @@ void btrfs_close_extra_devices(struct btrfs_fs_info *fs_info,
 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.0.0.153.g79dcccc


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

* [PATCH 4/8] Btrfs: use BTRFS_ERROR_DEV_MISSING_NOT_FOUND when missing device is not found
  2015-04-27  7:34   ` [PATCH 0/8 v2] " Anand Jain
                       ` (2 preceding siblings ...)
  2015-04-27  7:34     ` [PATCH 3/8] Btrfs: rename btrfs_dev_replace_find_srcdev() Anand Jain
@ 2015-04-27  7:34     ` Anand Jain
  2015-04-27  7:34     ` [PATCH 5/8] Btrfs: use btrfs_find_device_by_user_input() Anand Jain
                       ` (3 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Anand Jain @ 2015-04-27  7:34 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba, m_btrfs

use btrfs specific error code BTRFS_ERROR_DEV_MISSING_NOT_FOUND instead of -ENOENT.
Next this removes the logging when user specifies "missing" and we don't find
it in the kernel device list. logging are for system events not for user input errors.

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

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 13b19c5..7b16147 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2054,10 +2054,8 @@ int btrfs_find_device_missing_or_by_path(struct btrfs_root *root,
 			}
 		}
 
-		if (!*device) {
-			btrfs_err(root->fs_info, "no missing device found");
-			return -ENOENT;
-		}
+		if (!*device)
+			return BTRFS_ERROR_DEV_MISSING_NOT_FOUND;
 
 		return 0;
 	} else {
-- 
2.0.0.153.g79dcccc


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

* [PATCH 5/8] Btrfs: use btrfs_find_device_by_user_input()
  2015-04-27  7:34   ` [PATCH 0/8 v2] " Anand Jain
                       ` (3 preceding siblings ...)
  2015-04-27  7:34     ` [PATCH 4/8] Btrfs: use BTRFS_ERROR_DEV_MISSING_NOT_FOUND when missing device is not found Anand Jain
@ 2015-04-27  7:34     ` Anand Jain
  2015-04-27  7:34     ` [PATCH 6/8] Btrfs: add btrfs_read_dev_one_super() to read one specific SB Anand Jain
                       ` (2 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Anand Jain @ 2015-04-27  7:34 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba, m_btrfs

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 | 84 ++++++++++++------------------------------------------
 1 file changed, 19 insertions(+), 65 deletions(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 7b16147..e57dd60 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1664,7 +1664,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
 	struct btrfs_super_block *disk_super = NULL;
 	struct btrfs_fs_devices *cur_devices;
 	u64 num_devices;
-	u8 *dev_uuid;
 	int ret = 0;
 	bool clear_super = false;
 	char *dev_name = NULL;
@@ -1675,62 +1674,19 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
 	if (ret)
 		goto out;
 
-	if (devid) {
-		device = btrfs_find_device(root->fs_info, devid,
-				NULL, NULL);
-		if (!device) {
-			ret = -ENOENT;
-			goto out;
-		}
-		device_path = rcu_str_deref(device->name);
-	} else 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;
-			}
-		}
-		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, devid, 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) {
@@ -1841,7 +1797,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
 				 * to fail. So return success
 				 */
 				ret = 0;
-				goto done;
+				goto out;
 			}
 
 			disk_super = (struct btrfs_super_block *)bh->b_data;
@@ -1852,6 +1808,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
 		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
@@ -1863,7 +1820,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
 					i_size_read(bdev->bd_inode))
 				break;
 
-			brelse(bh);
 			bh = __bread(bdev, bytenr / 4096,
 					BTRFS_SUPER_INFO_SIZE);
 			if (!bh)
@@ -1873,35 +1829,33 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
 
 			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);
 		}
-	}
 
-done:
-	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(dev_name);
+			/* Update ctime/mtime for device path for libblkid */
+			update_dev_time(dev_name);
+			blkdev_put(bdev, FMODE_READ | FMODE_EXCL);
+		}
 	}
 
-error_brelse:
-	brelse(bh);
-	if (bdev)
-		blkdev_put(bdev, FMODE_READ | FMODE_EXCL);
 out:
 	if (dev_name)
 		kfree(dev_name);
 
 	mutex_unlock(&uuid_mutex);
 	return ret;
+
 error_undo:
 	if (device->writeable) {
 		lock_chunks(root);
@@ -1910,7 +1864,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.0.0.153.g79dcccc


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

* [PATCH 6/8] Btrfs: add btrfs_read_dev_one_super() to read one specific SB
  2015-04-27  7:34   ` [PATCH 0/8 v2] " Anand Jain
                       ` (4 preceding siblings ...)
  2015-04-27  7:34     ` [PATCH 5/8] Btrfs: use btrfs_find_device_by_user_input() Anand Jain
@ 2015-04-27  7:34     ` Anand Jain
  2015-04-27  7:34     ` [PATCH 7/8] Btrfs: fix btrfs_scratch_superblock() with fixes from device delete Anand Jain
  2015-04-27  7:34     ` [PATCH 8/8] Btrfs: use btrfs_scratch_superblock() in btrfs_rm_device() Anand Jain
  7 siblings, 0 replies; 14+ messages in thread
From: Anand Jain @ 2015-04-27  7:34 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba, m_btrfs

This uses a chunk of code from btrfs_read_dev_super() and creates
a function called btrfs_read_dev_one_super() so that next patch
can use it for scratch superblock.

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

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index f47c643..3681e1e 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3085,6 +3085,37 @@ static void btrfs_end_buffer_write_sync(struct buffer_head *bh, int uptodate)
 	put_bh(bh);
 }
 
+int btrfs_read_dev_one_super(struct block_device *bdev, int copy_num,
+			struct buffer_head **bh)
+{
+	struct buffer_head *bufhead;
+	struct btrfs_super_block *super;
+	u64 bytenr;
+
+	bytenr = btrfs_sb_offset(copy_num);
+	if (bytenr + BTRFS_SUPER_INFO_SIZE >= i_size_read(bdev->bd_inode))
+		return -EINVAL;
+
+	bufhead = __bread(bdev, bytenr / 4096, BTRFS_SUPER_INFO_SIZE);
+	/*
+	 * If we fail to read from the underlaying drivers, as of now
+	 * the best option we have is to mark it EIO.
+	 */
+	if (!bufhead)
+		return -EIO;
+
+	super = (struct btrfs_super_block *)bufhead->b_data;
+	if (btrfs_super_bytenr(super) != bytenr ||
+		    btrfs_super_magic(super) != BTRFS_MAGIC) {
+		brelse(bufhead);
+		return -EINVAL;
+	}
+
+	*bh = bufhead;
+	return 0;
+}
+
+
 struct buffer_head *btrfs_read_dev_super(struct block_device *bdev)
 {
 	struct buffer_head *bh;
@@ -3092,7 +3123,6 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev)
 	struct btrfs_super_block *super;
 	int i;
 	u64 transid = 0;
-	u64 bytenr;
 	int ret = -EINVAL;
 
 	/* we would like to check all the supers, but that would make
@@ -3101,28 +3131,12 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev)
 	 * later supers, using BTRFS_SUPER_MIRROR_MAX instead
 	 */
 	for (i = 0; i < 1; 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 we fail to read from the underlaying drivers, as of now
-		 * the best option we have is to mark it EIO.
-		 */
-		if (!bh) {
-			ret = -EIO;
+
+		ret = btrfs_read_dev_one_super(bdev, i, &bh);
+		if (ret)
 			continue;
-		}
 
 		super = (struct btrfs_super_block *)bh->b_data;
-		if (btrfs_super_bytenr(super) != bytenr ||
-		    btrfs_super_magic(super) != BTRFS_MAGIC) {
-			brelse(bh);
-			ret = -EINVAL;
-			continue;
-		}
 
 		if (!latest || btrfs_super_generation(super) > transid) {
 			brelse(latest);
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index 27d44c0..36bd1fc 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -60,6 +60,8 @@ void close_ctree(struct btrfs_root *root);
 int write_ctree_super(struct btrfs_trans_handle *trans,
 		      struct btrfs_root *root, int max_mirrors);
 struct buffer_head *btrfs_read_dev_super(struct block_device *bdev);
+int btrfs_read_dev_one_super(struct block_device *bdev, int copy_num,
+			struct buffer_head **bh);
 int btrfs_commit_super(struct btrfs_root *root);
 struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
 					    u64 bytenr);
-- 
2.0.0.153.g79dcccc


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

* [PATCH 7/8] Btrfs: fix btrfs_scratch_superblock() with fixes from device delete
  2015-04-27  7:34   ` [PATCH 0/8 v2] " Anand Jain
                       ` (5 preceding siblings ...)
  2015-04-27  7:34     ` [PATCH 6/8] Btrfs: add btrfs_read_dev_one_super() to read one specific SB Anand Jain
@ 2015-04-27  7:34     ` Anand Jain
  2015-04-27  7:34     ` [PATCH 8/8] Btrfs: use btrfs_scratch_superblock() in btrfs_rm_device() Anand Jain
  7 siblings, 0 replies; 14+ messages in thread
From: Anand Jain @ 2015-04-27  7:34 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba, m_btrfs

This patch updates the btrfs_scratch_superblock(), (which is used
by the replace device thread), with those fixes from the
scratch superblock code section of btrfs_rm_device(). The fixes are:
  Scratch all copies of superblock
  Notify kobject that superblock has been changed
  Update time on the device

so that btrfs_rm_device() can use the function btrfs_scratch_superblock()
instead of its own scratch code. And further replace deivce code which
similarly releases device back to the system, will have the fixes from
the btrfs device delete.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 fs/btrfs/volumes.c | 40 ++++++++++++++++++++++++++++------------
 fs/btrfs/volumes.h |  2 +-
 2 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index e57dd60..4fd7010 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1891,7 +1891,8 @@ void btrfs_rm_dev_replace_remove_srcdev(struct btrfs_fs_info *fs_info,
 	if (srcdev->writeable) {
 		fs_devices->rw_devices--;
 		/* zero out the old super if it is writable */
-		btrfs_scratch_superblock(srcdev);
+		btrfs_scratch_superblock(srcdev->bdev,
+					rcu_str_deref(srcdev->name));
 	}
 
 	if (srcdev->bdev)
@@ -1941,7 +1942,8 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
 	btrfs_sysfs_rm_device_link(fs_info->fs_devices, tgtdev, 0);
 
 	if (tgtdev->bdev) {
-		btrfs_scratch_superblock(tgtdev);
+		btrfs_scratch_superblock(tgtdev->bdev,
+					rcu_str_deref(tgtdev->name));
 		fs_info->fs_devices->open_devices--;
 	}
 	fs_info->fs_devices->num_devices--;
@@ -6779,22 +6781,36 @@ int btrfs_get_dev_stats(struct btrfs_root *root,
 	return 0;
 }
 
-int btrfs_scratch_superblock(struct btrfs_device *device)
+void btrfs_scratch_superblock(struct block_device *bdev, char *device_path)
 {
 	struct buffer_head *bh;
 	struct btrfs_super_block *disk_super;
+	int copy_num;
 
-	bh = btrfs_read_dev_super(device->bdev);
-	if (IS_ERR(bh))
-		return PTR_ERR(bh);
-	disk_super = (struct btrfs_super_block *)bh->b_data;
+	if (!bdev)
+		return;
 
-	memset(&disk_super->magic, 0, sizeof(disk_super->magic));
-	set_buffer_dirty(bh);
-	sync_dirty_buffer(bh);
-	brelse(bh);
+	for (copy_num = 0; copy_num < BTRFS_SUPER_MIRROR_MAX;
+		copy_num++) {
 
-	return 0;
+		if (btrfs_read_dev_one_super(bdev, copy_num, &bh))
+			continue;
+
+		disk_super = (struct btrfs_super_block *)bh->b_data;
+
+		memset(&disk_super->magic, 0, sizeof(disk_super->magic));
+		set_buffer_dirty(bh);
+		sync_dirty_buffer(bh);
+		brelse(bh);
+	}
+
+	/* 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);
+
+	return;
 }
 
 /*
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 027d454..a9e4459 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -487,7 +487,7 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
 				      struct btrfs_device *tgtdev);
 void btrfs_init_dev_replace_tgtdev_for_resume(struct btrfs_fs_info *fs_info,
 					      struct btrfs_device *tgtdev);
-int btrfs_scratch_superblock(struct btrfs_device *device);
+void btrfs_scratch_superblock(struct block_device *bdev, char *device_path);
 int btrfs_is_parity_mirror(struct btrfs_mapping_tree *map_tree,
 			   u64 logical, u64 len, int mirror_num);
 unsigned long btrfs_full_stripe_len(struct btrfs_root *root,
-- 
2.0.0.153.g79dcccc


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

* [PATCH 8/8] Btrfs: use btrfs_scratch_superblock() in btrfs_rm_device()
  2015-04-27  7:34   ` [PATCH 0/8 v2] " Anand Jain
                       ` (6 preceding siblings ...)
  2015-04-27  7:34     ` [PATCH 7/8] Btrfs: fix btrfs_scratch_superblock() with fixes from device delete Anand Jain
@ 2015-04-27  7:34     ` Anand Jain
  7 siblings, 0 replies; 14+ messages in thread
From: Anand Jain @ 2015-04-27  7:34 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba, m_btrfs

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

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

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 4fd7010..d722ee5 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1659,9 +1659,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
 {
 	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;
@@ -1783,68 +1780,12 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
 	 * 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(dev_name,
-					    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;
-
-			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);
+		struct block_device *bdev;
 
-			/* Update ctime/mtime for device path for libblkid */
-			update_dev_time(dev_name);
+		bdev = blkdev_get_by_path(dev_name, FMODE_READ | FMODE_EXCL,
+						root->fs_info->bdev_holder);
+		if (!IS_ERR(bdev)) {
+			btrfs_scratch_superblock(bdev, dev_name);
 			blkdev_put(bdev, FMODE_READ | FMODE_EXCL);
 		}
 	}
-- 
2.0.0.153.g79dcccc


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

* [PATCH 2/2 v2] btrfs-progs: device delete to accept devid
  2015-04-20 10:29 ` [PATCH 2/2] btrfs-progs: device delete to accept devid Anand Jain
@ 2015-07-13  2:28   ` Anand Jain
  0 siblings, 0 replies; 14+ messages in thread
From: Anand Jain @ 2015-07-13  2:28 UTC (permalink / raw)
  To: linux-btrfs; +Cc: dsterba

This patch introduces new option <devid> for the command

  btrfs device delete <device_path|devid>[..]  <mnt>

In a user reported issue on a 3-disk-RAID1, one disk failed with its
SB unreadable. Now with this patch user will have a choice to delete
the device using devid.

The other method we could do, is to match the input device_path
to the available device_paths with in the kernel. But that won't
work in all the cases, like what if user provided mapper path
when the path within the kernel is a non-mapper path.

This patch depends on the below kernel patch for the new feature to work,
however it will fail-back to the old interface for the kernel without the
patch

  Btrfs: device delete by devid

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
v1->v2: rebase on latest devel

 Documentation/btrfs-device.asciidoc |  2 +-
 cmds-device.c                       | 43 +++++++++++++++++++++++++++++--------
 ioctl.h                             |  8 +++++++
 3 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/Documentation/btrfs-device.asciidoc b/Documentation/btrfs-device.asciidoc
index 2827598..61ede6e 100644
--- a/Documentation/btrfs-device.asciidoc
+++ b/Documentation/btrfs-device.asciidoc
@@ -74,7 +74,7 @@ do not perform discard by default
 -f|--force::::
 force overwrite of existing filesystem on the given disk(s)
 
-*remove* <dev> [<dev>...] <path>::
+*remove* <dev>|<devid> [<dev>|<devid>...] <path>::
 Remove device(s) from a filesystem identified by <path>.
 
 *delete* <dev> [<dev>...] <path>::
diff --git a/cmds-device.c b/cmds-device.c
index 0e60500..4c9b19a 100644
--- a/cmds-device.c
+++ b/cmds-device.c
@@ -164,16 +164,34 @@ static int _cmd_rm_dev(int argc, char **argv, const char * const *usagestr)
 		struct	btrfs_ioctl_vol_args arg;
 		int	res;
 
-		if (!is_block_device(argv[i])) {
+		struct  btrfs_ioctl_vol_args_v3 argv3 = {0};
+		int     its_num = false;
+
+		if (is_numerical(argv[i])) {
+			argv3.devid = arg_strtou64(argv[i]);
+			its_num = true;
+		} else if (is_block_device(argv[i])) {
+			strncpy_null(argv3.name, argv[i]);
+		} else {
 			fprintf(stderr,
-				"ERROR: %s is not a block device\n", argv[i]);
+				"ERROR: %s is not a block device or devid\n", argv[i]);
 			ret++;
 			continue;
 		}
-		memset(&arg, 0, sizeof(arg));
-		strncpy_null(arg.name, argv[i]);
-		res = ioctl(fdmnt, BTRFS_IOC_RM_DEV, &arg);
+		res = ioctl(fdmnt, BTRFS_IOC_RM_DEV_V2, &argv3);
 		e = errno;
+		if (res && e == ENOTTY) {
+			if (its_num) {
+				fprintf(stderr,
+				"Error: Kernel does not support delete by devid\n");
+				ret = 1;
+				continue;
+			}
+			memset(&arg, 0, sizeof(arg));
+			strncpy_null(arg.name, argv[i]);
+			res = ioctl(fdmnt, BTRFS_IOC_RM_DEV, &arg);
+			e = errno;
+		}
 		if (res) {
 			const char *msg;
 
@@ -181,9 +199,16 @@ static int _cmd_rm_dev(int argc, char **argv, const char * const *usagestr)
 				msg = btrfs_err_str(res);
 			else
 				msg = strerror(e);
-			fprintf(stderr,
-				"ERROR: error removing the device '%s' - %s\n",
-				argv[i], msg);
+
+			if (its_num)
+				fprintf(stderr,
+					"ERROR: error removing the devid '%llu' - %s\n",
+					argv3.devid, msg);
+			else
+				fprintf(stderr,
+					"ERROR: error removing the device '%s' - %s\n",
+					argv[i], msg);
+
 			ret++;
 		}
 	}
@@ -193,7 +218,7 @@ static int _cmd_rm_dev(int argc, char **argv, const char * const *usagestr)
 }
 
 static const char * const cmd_rm_dev_usage[] = {
-	"btrfs device remove <device> [<device>...] <path>",
+	"btrfs device remove <device>|<devid> [<device>|<devid>...] <path>",
 	"Remove a device from a filesystem",
 	NULL
 };
diff --git a/ioctl.h b/ioctl.h
index dff015a..6870931 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -40,6 +40,12 @@ struct btrfs_ioctl_vol_args {
 	char name[BTRFS_PATH_NAME_MAX + 1];
 };
 
+struct btrfs_ioctl_vol_args_v3 {
+	__s64 fd;
+	char name[BTRFS_PATH_NAME_MAX + 1];
+	__u64 devid;
+};
+
 #define BTRFS_DEVICE_PATH_NAME_MAX 1024
 
 #define BTRFS_SUBVOL_CREATE_ASYNC	(1ULL << 0)
@@ -683,6 +689,8 @@ 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_v3)
 #ifdef __cplusplus
 }
 #endif
-- 
2.4.1


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

end of thread, other threads:[~2015-07-13  3:25 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-20 10:29 [PATCH] device delete by devid Anand Jain
2015-04-20 10:29 ` [PATCH] Btrfs: " Anand Jain
2015-04-27  7:34   ` [PATCH 0/8 v2] " Anand Jain
2015-04-27  7:34     ` [PATCH V2 1/8] Btrfs: " Anand Jain
2015-04-27  7:34     ` [PATCH 2/8] Btrfs: move check for min number of devices to a function Anand Jain
2015-04-27  7:34     ` [PATCH 3/8] Btrfs: rename btrfs_dev_replace_find_srcdev() Anand Jain
2015-04-27  7:34     ` [PATCH 4/8] Btrfs: use BTRFS_ERROR_DEV_MISSING_NOT_FOUND when missing device is not found Anand Jain
2015-04-27  7:34     ` [PATCH 5/8] Btrfs: use btrfs_find_device_by_user_input() Anand Jain
2015-04-27  7:34     ` [PATCH 6/8] Btrfs: add btrfs_read_dev_one_super() to read one specific SB Anand Jain
2015-04-27  7:34     ` [PATCH 7/8] Btrfs: fix btrfs_scratch_superblock() with fixes from device delete Anand Jain
2015-04-27  7:34     ` [PATCH 8/8] Btrfs: use btrfs_scratch_superblock() in btrfs_rm_device() Anand Jain
2015-04-20 10:29 ` [PATCH 1/2] btrfs-progs: move is_numerical to utils-lib.h and make it non static Anand Jain
2015-04-20 10:29 ` [PATCH 2/2] btrfs-progs: device delete to accept devid Anand Jain
2015-07-13  2:28   ` [PATCH 2/2 v2] " Anand Jain

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.