From patchwork Mon Mar 14 08:31:49 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anand Jain X-Patchwork-Id: 8577361 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 7903F9F54C for ; Mon, 14 Mar 2016 08:32:25 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 58BC22015E for ; Mon, 14 Mar 2016 08:32:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 96EC52045A for ; Mon, 14 Mar 2016 08:32:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755255AbcCNIcM (ORCPT ); Mon, 14 Mar 2016 04:32:12 -0400 Received: from userp1040.oracle.com ([156.151.31.81]:42027 "EHLO userp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755253AbcCNIcI (ORCPT ); Mon, 14 Mar 2016 04:32:08 -0400 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u2E8Vv0K029313 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 14 Mar 2016 08:31:57 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id u2E8VvDn003057 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Mon, 14 Mar 2016 08:31:57 GMT Received: from abhmp0011.oracle.com (abhmp0011.oracle.com [141.146.116.17]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id u2E8VvGi007660; Mon, 14 Mar 2016 08:31:57 GMT Received: from arch2.sg.oracle.com (/10.186.101.133) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 14 Mar 2016 01:31:56 -0700 From: Anand Jain To: linux-btrfs@vger.kernel.org Cc: dsterba@suse.cz Subject: [PATCH v5 2/2] btrfs-progs: Introduce device delete by devid Date: Mon, 14 Mar 2016 16:31:49 +0800 Message-Id: <1457944309-448-1-git-send-email-anand.jain@oracle.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1444123990-8832-1-git-send-email-anand.jain@oracle.com> References: <1444123990-8832-1-git-send-email-anand.jain@oracle.com> X-Source-IP: userv0021.oracle.com [156.151.31.71] Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Anand Jain This patch introduces new option for the command btrfs device delete [..] 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: Introduce device delete by devid Signed-off-by: Anand Jain [ refresh on top of current code, sync with latest kernel patches, other minor changes ] Signed-off-by: David Sterba --- v5: as below but on devel branch v4: a. For future benefit we should check for EOPNOTSUPP errno as well. b. Update the changes to be inline with kernel that is BTRFS_DEVICE_SPEC_BY_ID and BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED naming changes. and c. As I remember David Sterba renamed its_num to is_devid but in the devel branch I don't see it, so add it back. d. reword error string and use strerror v3: enahnced btrfs_ioctl_vol_args_v2 to accept devid instead of creating a new structure. Thanks to David. Changed subject from btrfs-progs: device delete to accept devid v2: update the missed Documentation for delete (not just remove) as well. Thanks to Goffredo. Documentation/btrfs-device.asciidoc | 4 ++-- cmds-device.c | 47 ++++++++++++++++++++++++++++++------- ioctl.h | 15 +++++++++++- 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/Documentation/btrfs-device.asciidoc b/Documentation/btrfs-device.asciidoc index 2827598a37f5..bd878f4c33e1 100644 --- a/Documentation/btrfs-device.asciidoc +++ b/Documentation/btrfs-device.asciidoc @@ -74,10 +74,10 @@ do not perform discard by default -f|--force:::: force overwrite of existing filesystem on the given disk(s) -*remove* [...] :: +*remove* | [|...] :: Remove device(s) from a filesystem identified by . -*delete* [...] :: +*delete* | [|...] :: Alias of remove kept for backwards compatability *ready* :: diff --git a/cmds-device.c b/cmds-device.c index 50c1c5dfb394..c0f6e681bf40 100644 --- a/cmds-device.c +++ b/cmds-device.c @@ -157,20 +157,46 @@ static int _cmd_device_remove(int argc, char **argv, for(i=1 ; i < argc - 1; i++ ){ struct btrfs_ioctl_vol_args arg; + struct btrfs_ioctl_vol_args_v2 argv2 = {0}; + int is_devid = 0; int res; - if (is_block_device(argv[i]) != 1 && strcmp(argv[i], "missing")) { + if (string_is_numerical(argv[i])) { + argv2.devid = arg_strtou64(argv[i]); + argv2.flags = BTRFS_DEVICE_SPEC_BY_ID; + is_devid = 1; + } else if (is_block_device(argv[i]) == 1 || + strcmp(argv[i], "missing") == 0) { + strncpy_null(argv2.name, argv[i]); + } else { error("not a block device: %s", argv[i]); ret++; continue; } - memset(&arg, 0, sizeof(arg)); - strncpy_null(arg.name, argv[i]); + /* * Positive values are from BTRFS_ERROR_DEV_*, * otherwise it's a generic error, one of errnos */ - res = ioctl(fdmnt, BTRFS_IOC_RM_DEV, &arg); + res = ioctl(fdmnt, BTRFS_IOC_RM_DEV_V2, &argv2); + + /* + * if BTRFS_IOC_RM_DEV_V2 is not supported we get ENOTTY and if + * argv2.flags includes a flag which kernel don't understand then + * we shall get EOPNOTSUPP + */ + if (res < 0 && (errno == ENOTTY || errno == EOPNOTSUPP)) { + if (is_devid) { + error("device delete by id failed: %s", + strerror(errno)); + ret++; + continue; + } + memset(&arg, 0, sizeof(arg)); + strncpy_null(arg.name, argv[i]); + res = ioctl(fdmnt, BTRFS_IOC_RM_DEV, &arg); + } + if (res) { const char *msg; @@ -178,8 +204,13 @@ static int _cmd_device_remove(int argc, char **argv, msg = btrfs_err_str(res); else msg = strerror(errno); - error("error removing device '%s': %s", - argv[i], msg); + if (is_devid) { + error("error removing devid %llu: %s", + (unsigned long long)argv2.devid, msg); + } else { + error("error removing device '%s': %s", + argv[i], msg); + } ret++; } } @@ -189,7 +220,7 @@ static int _cmd_device_remove(int argc, char **argv, } static const char * const cmd_device_remove_usage[] = { - "btrfs device remove [...] ", + "btrfs device remove | [|...] ", "Remove a device from a filesystem", NULL }; @@ -200,7 +231,7 @@ static int cmd_device_remove(int argc, char **argv) } static const char * const cmd_device_delete_usage[] = { - "btrfs device delete [...] ", + "btrfs device delete | [|...] ", "Remove a device from a filesystem", NULL }; diff --git a/ioctl.h b/ioctl.h index 771da23160f3..cab9ec2d5501 100644 --- a/ioctl.h +++ b/ioctl.h @@ -45,6 +45,14 @@ 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_SPEC_BY_ID (1ULL << 3) + +#define BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED \ + (BTRFS_SUBVOL_CREATE_ASYNC | \ + BTRFS_SUBVOL_RDONLY | \ + BTRFS_SUBVOL_QGROUP_INHERIT | \ + BTRFS_DEVICE_SPEC_BY_ID) + #define BTRFS_FSID_SIZE 16 #define BTRFS_UUID_SIZE 16 @@ -84,7 +92,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; + }; }; /* @@ -709,6 +720,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_v2) #ifdef __cplusplus } #endif