From patchwork Wed Jul 8 07:32:54 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anand Jain X-Patchwork-Id: 6741421 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 36CF4C05AC for ; Wed, 8 Jul 2015 07:45:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D57E620782 for ; Wed, 8 Jul 2015 07:45:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 432F720768 for ; Wed, 8 Jul 2015 07:45:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934333AbbGHHmm (ORCPT ); Wed, 8 Jul 2015 03:42:42 -0400 Received: from userp1040.oracle.com ([156.151.31.81]:35123 "EHLO userp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933169AbbGHHmk (ORCPT ); Wed, 8 Jul 2015 03:42:40 -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 t687gbjt008285 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 8 Jul 2015 07:42:37 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t687gbYq019469 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 8 Jul 2015 07:42:37 GMT Received: from abhmp0010.oracle.com (abhmp0010.oracle.com [141.146.116.16]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t687gbYk009147; Wed, 8 Jul 2015 07:42:37 GMT Received: from arch2.sg.oracle.com (/10.186.101.54) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 08 Jul 2015 00:42:37 -0700 From: Anand Jain To: linux-btrfs@vger.kernel.org, dsterba@suse.cz Subject: [PATCH 6/6] Btrfs: sysfs: support seed devices in the sysfs layout Date: Wed, 8 Jul 2015 15:32:54 +0800 Message-Id: <1436340774-10909-7-git-send-email-anand.jain@oracle.com> X-Mailer: git-send-email 2.4.1 In-Reply-To: <1436340774-10909-1-git-send-email-anand.jain@oracle.com> References: <1436340774-10909-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=-7.6 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 This adds an enhancement to show the seed fsid and its devices on the btrfs sysfs. The way sprouting handles fs_devices: clone seed fs_devices and add to the fs_uuids mem copy seed fs_devices and assign to fs_devices->seed (move dev_list) evacuate seed fs_devices contents to hold sprout fs devices contents So to be inline with this fs_devices changes during seeding, represent seed fsid under the sprout fsid, this is achieved by using the kobject_move() The end result will be, /sys/fs/btrfs/sprout-fsid/seed/level-1-seed-fsid/seed/(if)level-2-seed-fsid Signed-off-by: Anand Jain --- fs/btrfs/dev-replace.c | 7 ++- fs/btrfs/disk-io.c | 6 +- fs/btrfs/sysfs.c | 150 +++++++++++++++++++++++++++++++++++++++++++------ fs/btrfs/sysfs.h | 12 ++-- fs/btrfs/volumes.c | 26 ++++----- fs/btrfs/volumes.h | 1 + 6 files changed, 160 insertions(+), 42 deletions(-) diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c index 31e0145..d0c9562 100644 --- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c @@ -376,7 +376,7 @@ int btrfs_dev_replace_start(struct btrfs_root *root, WARN_ON(!tgt_device); dev_replace->tgtdev = tgt_device; - ret = btrfs_sysfs_add_device_link(tgt_device->fs_devices, tgt_device); + ret = btrfs_sysfs_add_device_link(tgt_device->fs_devices, tgt_device, 0); if (ret) btrfs_error(root->fs_info, ret, "kobj add dev failed"); @@ -587,7 +587,10 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, mutex_unlock(&uuid_mutex); /* replace the sysfs entry */ - btrfs_sysfs_rm_device_link(fs_info->fs_devices, src_device); + btrfs_sysfs_rm_device_link(fs_info->fs_devices, src_device, 0); + if (src_device->fs_devices->seeding && + !src_device->fs_devices->num_devices) + btrfs_sysfs_remove_fsid(src_device->fs_devices); btrfs_rm_dev_replace_free_srcdev(fs_info, src_device); /* write back the superblocks */ diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 4eaa554..b3c9870 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -2876,13 +2876,13 @@ retry_root_backup: btrfs_close_extra_devices(fs_devices, 1); - ret = btrfs_sysfs_add_fsid(fs_devices, NULL); - if (ret) { + ret = btrfs_sysfs_add_fsid(fs_devices, NULL, 1); + if (ret && ret != -EEXIST) { pr_err("BTRFS: failed to init sysfs fsid interface: %d\n", ret); goto fail_block_groups; } - ret = btrfs_sysfs_add_device(fs_devices); + ret = btrfs_sysfs_add_device(fs_devices, 1); if (ret) { pr_err("BTRFS: failed to init sysfs device interface: %d\n", ret); goto fail_fsdev_sysfs; diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index e0ac859..3a45462 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c @@ -517,6 +517,11 @@ static int addrm_unknown_feature_attrs(struct btrfs_fs_info *fs_info, bool add) static void __btrfs_sysfs_remove_fsid(struct btrfs_fs_devices *fs_devs) { + if (fs_devs->seed) { + __btrfs_sysfs_remove_fsid(fs_devs->seed); + btrfs_sysfs_rm_seed_dir(fs_devs); + } + if (fs_devs->device_dir_kobj) { kobject_del(fs_devs->device_dir_kobj); kobject_put(fs_devs->device_dir_kobj); @@ -557,7 +562,7 @@ void btrfs_sysfs_remove_mounted(struct btrfs_fs_info *fs_info) addrm_unknown_feature_attrs(fs_info, false); sysfs_remove_group(&fs_info->fs_devices->fsid_kobj, &btrfs_feature_attr_group); sysfs_remove_files(&fs_info->fs_devices->fsid_kobj, btrfs_attrs); - btrfs_sysfs_rm_device_link(fs_info->fs_devices, NULL); + btrfs_sysfs_rm_device_link(fs_info->fs_devices, NULL, 1); } const char * const btrfs_feature_set_names[3] = { @@ -638,7 +643,7 @@ static void init_feature_attrs(void) /* when one_device is NULL, it removes all device links */ int btrfs_sysfs_rm_device_link(struct btrfs_fs_devices *fs_devices, - struct btrfs_device *one_device) + struct btrfs_device *one_device, int follow_seed) { struct hd_struct *disk; struct kobject *disk_kobj; @@ -668,27 +673,38 @@ int btrfs_sysfs_rm_device_link(struct btrfs_fs_devices *fs_devices, disk_kobj->name); } + if (follow_seed && fs_devices->seed) + btrfs_sysfs_rm_device_link(fs_devices->seed, NULL, follow_seed); + return 0; } -int btrfs_sysfs_add_device(struct btrfs_fs_devices *fs_devs) +int btrfs_sysfs_add_device(struct btrfs_fs_devices *fs_devs, int follow_seed) { - if (!fs_devs->device_dir_kobj) - fs_devs->device_dir_kobj = kobject_create_and_add("devices", - &fs_devs->fsid_kobj); + while (fs_devs) { + if (!fs_devs->device_dir_kobj) + fs_devs->device_dir_kobj = kobject_create_and_add( + "devices", &fs_devs->fsid_kobj); - if (!fs_devs->device_dir_kobj) - return -ENOMEM; + if (!fs_devs->device_dir_kobj) + return -ENOMEM; + + if (!follow_seed) + return 0; + + fs_devs = fs_devs->seed; + } return 0; } int btrfs_sysfs_add_device_link(struct btrfs_fs_devices *fs_devices, - struct btrfs_device *one_device) + struct btrfs_device *one_device, int follow_seed) { int error = 0; struct btrfs_device *dev; +again: list_for_each_entry(dev, &fs_devices->devices, dev_list) { struct hd_struct *disk; struct kobject *disk_kobj; @@ -708,9 +724,37 @@ int btrfs_sysfs_add_device_link(struct btrfs_fs_devices *fs_devices, break; } + if (follow_seed && fs_devices->seed) { + fs_devices = fs_devices->seed; + goto again; + } + return error; } +void btrfs_sysfs_rm_seed_dir(struct btrfs_fs_devices *fs_devs) +{ + if (fs_devs->seed_dir_kobj) { + kobject_del(fs_devs->seed_dir_kobj); + kobject_put(fs_devs->seed_dir_kobj); + fs_devs->seed_dir_kobj = NULL; + } +} + +int btrfs_sysfs_add_seed_dir(struct btrfs_fs_devices *fs_devs) +{ + if (!fs_devs->seed_dir_kobj) + fs_devs->seed_dir_kobj = kobject_create_and_add( + "seed", &fs_devs->fsid_kobj); + + if (!fs_devs->seed_dir_kobj) + return -ENOMEM; + + BUG_ON(!fs_devs->seed_dir_kobj->state_initialized); + + return 0; +} + /* /sys/fs/btrfs/ entry */ static struct kset *btrfs_kset; @@ -725,15 +769,29 @@ u64 btrfs_debugfs_test; * And parent can be specified for seed device */ int btrfs_sysfs_add_fsid(struct btrfs_fs_devices *fs_devs, - struct kobject *parent) + struct kobject *parent, int follow_seed) { - int error; + int error = 0; - init_completion(&fs_devs->kobj_unregister); - fs_devs->fsid_kobj.kset = btrfs_kset; - error = kobject_init_and_add(&fs_devs->fsid_kobj, - &btrfs_ktype, parent, "%pU", fs_devs->fsid); - return error; +add_seed: + if (!fs_devs->fsid_kobj.state_initialized) { + init_completion(&fs_devs->kobj_unregister); + fs_devs->fsid_kobj.kset = btrfs_kset; + error = kobject_init_and_add(&fs_devs->fsid_kobj, + &btrfs_ktype, parent, "%pU", fs_devs->fsid); + } else { + error = -EEXIST; + } + + if (!follow_seed || !fs_devs->seed) + return error; + + btrfs_sysfs_add_seed_dir(fs_devs); + + parent = fs_devs->seed_dir_kobj; + fs_devs = fs_devs->seed; + + goto add_seed; } int btrfs_sysfs_add_mounted(struct btrfs_fs_info *fs_info) @@ -744,13 +802,13 @@ int btrfs_sysfs_add_mounted(struct btrfs_fs_info *fs_info) btrfs_set_fs_info_ptr(fs_info); - error = btrfs_sysfs_add_device_link(fs_devs, NULL); + error = btrfs_sysfs_add_device_link(fs_devs, NULL, 1); if (error) return error; error = sysfs_create_files(fsid_kobj, btrfs_attrs); if (error) { - btrfs_sysfs_rm_device_link(fs_devs, NULL); + btrfs_sysfs_rm_device_link(fs_devs, NULL, 0); return error; } @@ -826,3 +884,59 @@ void btrfs_exit_sysfs(void) debugfs_remove_recursive(btrfs_debugfs_root_dentry); } +void btrfs_sysfs_prepare_sprout_reset(void) +{ + /* close call would anyway cleanup */ +} + +void btrfs_sysfs_prepare_sprout(struct btrfs_fs_devices *fs_devices, + struct btrfs_fs_devices *seed_devices) +{ + char fsid_buf[BTRFS_UUID_UNPARSED_SIZE]; + + /* + * Sprouting has changed fsid of the mounted root, + * so rename the fsid on the sysfs + */ + snprintf(fsid_buf, BTRFS_UUID_UNPARSED_SIZE, "%pU", fs_devices->fsid); + if (kobject_rename(&fs_devices->fsid_kobj, fsid_buf)) { + pr_warn("Btrfs: sysfs: kobject rename failed\n"); + } + + /* + * Create the seed fsid inside the sprout fsid + * but should not create devices dir, instead + * move it from the original fs_devices + */ + memset(&seed_devices->fsid_kobj, 0, sizeof(struct kobject)); + seed_devices->device_dir_kobj = NULL; + memset(&seed_devices->kobj_unregister, 0, + sizeof(struct completion)); + seed_devices->seed_dir_kobj = NULL; + + if (!fs_devices->seed_dir_kobj) + btrfs_sysfs_add_seed_dir(fs_devices); + + btrfs_sysfs_add_fsid(seed_devices, fs_devices->seed_dir_kobj, 0); + + if (kobject_move(fs_devices->device_dir_kobj, + &seed_devices->fsid_kobj)) + pr_warn("Btrfs: sysfs: dev kobject move failed\n"); + + seed_devices->device_dir_kobj = fs_devices->device_dir_kobj; + fs_devices->device_dir_kobj = NULL; + btrfs_sysfs_add_device(fs_devices, 0); + + /* + * the kobj dev and devices attribute will be created + * in the main function as part of the init_new_device + * If this is a nested seed, that is if there is seed's + * seed device then move that one level deep. + */ + if (seed_devices->seed) { + btrfs_sysfs_add_seed_dir(seed_devices); + if (kobject_move(&seed_devices->seed->fsid_kobj, + seed_devices->seed_dir_kobj)) + pr_warn("Btrfs: sysfs: kobject move failed\n"); + } +} diff --git a/fs/btrfs/sysfs.h b/fs/btrfs/sysfs.h index 9c09522..5ace289 100644 --- a/fs/btrfs/sysfs.h +++ b/fs/btrfs/sysfs.h @@ -83,11 +83,15 @@ extern const char * const btrfs_feature_set_names[3]; extern struct kobj_type space_info_ktype; extern struct kobj_type btrfs_raid_ktype; int btrfs_sysfs_add_device_link(struct btrfs_fs_devices *fs_devices, - struct btrfs_device *one_device); + struct btrfs_device *one_device, int follow_seed); int btrfs_sysfs_rm_device_link(struct btrfs_fs_devices *fs_devices, - struct btrfs_device *one_device); + struct btrfs_device *one_device, int follow_seed); int btrfs_sysfs_add_fsid(struct btrfs_fs_devices *fs_devs, - struct kobject *parent); -int btrfs_sysfs_add_device(struct btrfs_fs_devices *fs_devs); + struct kobject *parent, int follow_seed); void btrfs_sysfs_remove_fsid(struct btrfs_fs_devices *fs_devs); +int btrfs_sysfs_add_device(struct btrfs_fs_devices *fs_devs, int follow_seed); +int btrfs_sysfs_add_seed_dir(struct btrfs_fs_devices *fs_devs); +void btrfs_sysfs_rm_seed_dir(struct btrfs_fs_devices *fs_devs); +void btrfs_sysfs_prepare_sprout(struct btrfs_fs_devices *fs_devices, + struct btrfs_fs_devices *seed_devices); #endif /* _BTRFS_SYSFS_H_ */ diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 90340d0..47ec58c 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "ctree.h" #include "extent_map.h" @@ -1787,7 +1788,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) if (device->bdev) { device->fs_devices->open_devices--; /* remove sysfs entry */ - btrfs_sysfs_rm_device_link(root->fs_info->fs_devices, device); + btrfs_sysfs_rm_device_link(root->fs_info->fs_devices, device, 0); } call_rcu(&device->rcu, free_device); @@ -1957,7 +1958,7 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info, WARN_ON(!tgtdev); mutex_lock(&fs_info->fs_devices->device_list_mutex); - btrfs_sysfs_rm_device_link(fs_info->fs_devices, tgtdev); + btrfs_sysfs_rm_device_link(fs_info->fs_devices, tgtdev, 0); if (tgtdev->bdev) { btrfs_scratch_superblock(tgtdev); @@ -2087,6 +2088,9 @@ static int btrfs_prepare_sprout(struct btrfs_root *root) fs_devices->open_devices = 0; fs_devices->missing_devices = 0; fs_devices->rotating = 0; + if (fs_devices->seed) + seed_devices->seed = fs_devices->seed; + fs_devices->seed = seed_devices; generate_random_uuid(fs_devices->fsid); @@ -2098,6 +2102,8 @@ static int btrfs_prepare_sprout(struct btrfs_root *root) ~BTRFS_SUPER_FLAG_SEEDING; btrfs_set_super_flags(disk_super, super_flags); + btrfs_sysfs_prepare_sprout(fs_devices, seed_devices); + return 0; } @@ -2295,7 +2301,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) tmp + 1); /* add sysfs device entry */ - btrfs_sysfs_add_device_link(root->fs_info->fs_devices, device); + btrfs_sysfs_add_device_link(root->fs_info->fs_devices, device, 0); /* * we've got more storage, clear any full flags on the space @@ -2323,22 +2329,11 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) } if (seeding_dev) { - char fsid_buf[BTRFS_UUID_UNPARSED_SIZE]; - ret = btrfs_finish_sprout(trans, root); if (ret) { btrfs_abort_transaction(trans, root, ret); goto error_trans; } - - /* Sprouting would change fsid of the mounted root, - * so rename the fsid on the sysfs - */ - snprintf(fsid_buf, BTRFS_UUID_UNPARSED_SIZE, "%pU", - root->fs_info->fsid); - if (kobject_rename(&root->fs_info->fs_devices->fsid_kobj, - fsid_buf)) - pr_warn("BTRFS: sysfs: failed to create fsid for sprout\n"); } root->fs_info->num_tolerated_disk_barrier_failures = @@ -2374,7 +2369,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) error_trans: btrfs_end_transaction(trans, root); rcu_string_free(device->name); - btrfs_sysfs_rm_device_link(root->fs_info->fs_devices, device); + btrfs_sysfs_rm_device_link(root->fs_info->fs_devices, device, 0); kfree(device); error: blkdev_put(bdev, FMODE_EXCL); @@ -6286,6 +6281,7 @@ static struct btrfs_fs_devices *open_seed_devices(struct btrfs_root *root, fs_devices->seed = root->fs_info->fs_devices->seed; root->fs_info->fs_devices->seed = fs_devices; + out: return fs_devices; } diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 865d853..664e2cf2 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h @@ -246,6 +246,7 @@ struct btrfs_fs_devices { struct btrfs_fs_devices *seed; int seeding; + struct kobject *seed_dir_kobj; int opened;