LCOV - code coverage report
Current view: top level - fs/btrfs - sysfs.c (source / functions) Hit Total Coverage
Test: btrfstest.info Lines: 84 236 35.6 %
Date: 2014-11-28 Functions: 11 37 29.7 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2007 Oracle.  All rights reserved.
       3             :  *
       4             :  * This program is free software; you can redistribute it and/or
       5             :  * modify it under the terms of the GNU General Public
       6             :  * License v2 as published by the Free Software Foundation.
       7             :  *
       8             :  * This program is distributed in the hope that it will be useful,
       9             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      10             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      11             :  * General Public License for more details.
      12             :  *
      13             :  * You should have received a copy of the GNU General Public
      14             :  * License along with this program; if not, write to the
      15             :  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      16             :  * Boston, MA 021110-1307, USA.
      17             :  */
      18             : 
      19             : #include <linux/sched.h>
      20             : #include <linux/slab.h>
      21             : #include <linux/spinlock.h>
      22             : #include <linux/completion.h>
      23             : #include <linux/buffer_head.h>
      24             : #include <linux/kobject.h>
      25             : #include <linux/bug.h>
      26             : #include <linux/genhd.h>
      27             : #include <linux/debugfs.h>
      28             : 
      29             : #include "ctree.h"
      30             : #include "disk-io.h"
      31             : #include "transaction.h"
      32             : #include "sysfs.h"
      33             : #include "volumes.h"
      34             : 
      35             : static inline struct btrfs_fs_info *to_fs_info(struct kobject *kobj);
      36             : 
      37             : static u64 get_features(struct btrfs_fs_info *fs_info,
      38             :                         enum btrfs_feature_set set)
      39             : {
      40             :         struct btrfs_super_block *disk_super = fs_info->super_copy;
      41        3315 :         if (set == FEAT_COMPAT)
      42             :                 return btrfs_super_compat_flags(disk_super);
      43        2873 :         else if (set == FEAT_COMPAT_RO)
      44             :                 return btrfs_super_compat_ro_flags(disk_super);
      45             :         else
      46             :                 return btrfs_super_incompat_flags(disk_super);
      47             : }
      48             : 
      49             : static void set_features(struct btrfs_fs_info *fs_info,
      50             :                          enum btrfs_feature_set set, u64 features)
      51             : {
      52             :         struct btrfs_super_block *disk_super = fs_info->super_copy;
      53           0 :         if (set == FEAT_COMPAT)
      54             :                 btrfs_set_super_compat_flags(disk_super, features);
      55           0 :         else if (set == FEAT_COMPAT_RO)
      56             :                 btrfs_set_super_compat_ro_flags(disk_super, features);
      57             :         else
      58             :                 btrfs_set_super_incompat_flags(disk_super, features);
      59             : }
      60             : 
      61        1989 : static int can_modify_feature(struct btrfs_feature_attr *fa)
      62             : {
      63             :         int val = 0;
      64             :         u64 set, clear;
      65        1989 :         switch (fa->feature_set) {
      66             :         case FEAT_COMPAT:
      67             :                 set = BTRFS_FEATURE_COMPAT_SAFE_SET;
      68             :                 clear = BTRFS_FEATURE_COMPAT_SAFE_CLEAR;
      69             :                 break;
      70             :         case FEAT_COMPAT_RO:
      71             :                 set = BTRFS_FEATURE_COMPAT_RO_SAFE_SET;
      72             :                 clear = BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR;
      73             :                 break;
      74             :         case FEAT_INCOMPAT:
      75             :                 set = BTRFS_FEATURE_INCOMPAT_SAFE_SET;
      76             :                 clear = BTRFS_FEATURE_INCOMPAT_SAFE_CLEAR;
      77             :                 break;
      78             :         default:
      79           0 :                 printk(KERN_WARNING "btrfs: sysfs: unknown feature set %d\n",
      80             :                                 fa->feature_set);
      81             :                 return 0;
      82             :         }
      83             : 
      84        1989 :         if (set & fa->feature_bit)
      85             :                 val |= 1;
      86             :         if (clear & fa->feature_bit)
      87             :                 val |= 2;
      88             : 
      89             :         return val;
      90             : }
      91             : 
      92           0 : static ssize_t btrfs_feature_attr_show(struct kobject *kobj,
      93             :                                        struct kobj_attribute *a, char *buf)
      94             : {
      95             :         int val = 0;
      96           0 :         struct btrfs_fs_info *fs_info = to_fs_info(kobj);
      97           0 :         struct btrfs_feature_attr *fa = to_btrfs_feature_attr(a);
      98           0 :         if (fs_info) {
      99           0 :                 u64 features = get_features(fs_info, fa->feature_set);
     100           0 :                 if (features & fa->feature_bit)
     101             :                         val = 1;
     102             :         } else
     103           0 :                 val = can_modify_feature(fa);
     104             : 
     105           0 :         return snprintf(buf, PAGE_SIZE, "%d\n", val);
     106             : }
     107             : 
     108           0 : static ssize_t btrfs_feature_attr_store(struct kobject *kobj,
     109             :                                         struct kobj_attribute *a,
     110             :                                         const char *buf, size_t count)
     111             : {
     112           0 :         struct btrfs_fs_info *fs_info;
     113             :         struct btrfs_feature_attr *fa = to_btrfs_feature_attr(a);
     114             :         struct btrfs_trans_handle *trans;
     115             :         u64 features, set, clear;
     116             :         unsigned long val;
     117             :         int ret;
     118             : 
     119             :         fs_info = to_fs_info(kobj);
     120           0 :         if (!fs_info)
     121             :                 return -EPERM;
     122             : 
     123           0 :         ret = kstrtoul(skip_spaces(buf), 0, &val);
     124           0 :         if (ret)
     125           0 :                 return ret;
     126             : 
     127           0 :         if (fa->feature_set == FEAT_COMPAT) {
     128             :                 set = BTRFS_FEATURE_COMPAT_SAFE_SET;
     129             :                 clear = BTRFS_FEATURE_COMPAT_SAFE_CLEAR;
     130           0 :         } else if (fa->feature_set == FEAT_COMPAT_RO) {
     131             :                 set = BTRFS_FEATURE_COMPAT_RO_SAFE_SET;
     132             :                 clear = BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR;
     133             :         } else {
     134             :                 set = BTRFS_FEATURE_INCOMPAT_SAFE_SET;
     135             :                 clear = BTRFS_FEATURE_INCOMPAT_SAFE_CLEAR;
     136             :         }
     137             : 
     138             :         features = get_features(fs_info, fa->feature_set);
     139             : 
     140             :         /* Nothing to do */
     141           0 :         if ((val && (features & fa->feature_bit)) ||
     142           0 :             (!val && !(features & fa->feature_bit)))
     143           0 :                 return count;
     144             : 
     145           0 :         if ((val && !(set & fa->feature_bit)) ||
     146             :             (!val && !(clear & fa->feature_bit))) {
     147           0 :                 btrfs_info(fs_info,
     148             :                         "%sabling feature %s on mounted fs is not supported.",
     149             :                         val ? "En" : "Dis", fa->kobj_attr.attr.name);
     150           0 :                 return -EPERM;
     151             :         }
     152             : 
     153           0 :         btrfs_info(fs_info, "%s %s feature flag",
     154             :                    val ? "Setting" : "Clearing", fa->kobj_attr.attr.name);
     155             : 
     156           0 :         trans = btrfs_start_transaction(fs_info->fs_root, 0);
     157           0 :         if (IS_ERR(trans))
     158           0 :                 return PTR_ERR(trans);
     159             : 
     160             :         spin_lock(&fs_info->super_lock);
     161           0 :         features = get_features(fs_info, fa->feature_set);
     162           0 :         if (val)
     163           0 :                 features |= fa->feature_bit;
     164             :         else
     165           0 :                 features &= ~fa->feature_bit;
     166             :         set_features(fs_info, fa->feature_set, features);
     167             :         spin_unlock(&fs_info->super_lock);
     168             : 
     169           0 :         ret = btrfs_commit_transaction(trans, fs_info->fs_root);
     170           0 :         if (ret)
     171           0 :                 return ret;
     172             : 
     173           0 :         return count;
     174             : }
     175             : 
     176        1989 : static umode_t btrfs_feature_visible(struct kobject *kobj,
     177             :                                      struct attribute *attr, int unused)
     178             : {
     179        1989 :         struct btrfs_fs_info *fs_info = to_fs_info(kobj);
     180        1989 :         umode_t mode = attr->mode;
     181             : 
     182        1989 :         if (fs_info) {
     183             :                 struct btrfs_feature_attr *fa;
     184             :                 u64 features;
     185             : 
     186             :                 fa = attr_to_btrfs_feature_attr(attr);
     187        1989 :                 features = get_features(fs_info, fa->feature_set);
     188             : 
     189        1989 :                 if (can_modify_feature(fa))
     190         221 :                         mode |= S_IWUSR;
     191        1768 :                 else if (!(features & fa->feature_bit))
     192             :                         mode = 0;
     193             :         }
     194             : 
     195        1989 :         return mode;
     196             : }
     197             : 
     198             : BTRFS_FEAT_ATTR_INCOMPAT(mixed_backref, MIXED_BACKREF);
     199             : BTRFS_FEAT_ATTR_INCOMPAT(default_subvol, DEFAULT_SUBVOL);
     200             : BTRFS_FEAT_ATTR_INCOMPAT(mixed_groups, MIXED_GROUPS);
     201             : BTRFS_FEAT_ATTR_INCOMPAT(compress_lzo, COMPRESS_LZO);
     202             : BTRFS_FEAT_ATTR_INCOMPAT(big_metadata, BIG_METADATA);
     203             : BTRFS_FEAT_ATTR_INCOMPAT(extended_iref, EXTENDED_IREF);
     204             : BTRFS_FEAT_ATTR_INCOMPAT(raid56, RAID56);
     205             : BTRFS_FEAT_ATTR_INCOMPAT(skinny_metadata, SKINNY_METADATA);
     206             : BTRFS_FEAT_ATTR_INCOMPAT(no_holes, NO_HOLES);
     207             : 
     208             : static struct attribute *btrfs_supported_feature_attrs[] = {
     209             :         BTRFS_FEAT_ATTR_PTR(mixed_backref),
     210             :         BTRFS_FEAT_ATTR_PTR(default_subvol),
     211             :         BTRFS_FEAT_ATTR_PTR(mixed_groups),
     212             :         BTRFS_FEAT_ATTR_PTR(compress_lzo),
     213             :         BTRFS_FEAT_ATTR_PTR(big_metadata),
     214             :         BTRFS_FEAT_ATTR_PTR(extended_iref),
     215             :         BTRFS_FEAT_ATTR_PTR(raid56),
     216             :         BTRFS_FEAT_ATTR_PTR(skinny_metadata),
     217             :         BTRFS_FEAT_ATTR_PTR(no_holes),
     218             :         NULL
     219             : };
     220             : 
     221             : static const struct attribute_group btrfs_feature_attr_group = {
     222             :         .name = "features",
     223             :         .is_visible = btrfs_feature_visible,
     224             :         .attrs = btrfs_supported_feature_attrs,
     225             : };
     226             : 
     227           0 : static ssize_t btrfs_show_u64(u64 *value_ptr, spinlock_t *lock, char *buf)
     228             : {
     229             :         u64 val;
     230           0 :         if (lock)
     231             :                 spin_lock(lock);
     232           0 :         val = *value_ptr;
     233           0 :         if (lock)
     234             :                 spin_unlock(lock);
     235           0 :         return snprintf(buf, PAGE_SIZE, "%llu\n", val);
     236             : }
     237             : 
     238           0 : static ssize_t global_rsv_size_show(struct kobject *kobj,
     239             :                                     struct kobj_attribute *ka, char *buf)
     240             : {
     241           0 :         struct btrfs_fs_info *fs_info = to_fs_info(kobj->parent);
     242             :         struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv;
     243           0 :         return btrfs_show_u64(&block_rsv->size, &block_rsv->lock, buf);
     244             : }
     245             : BTRFS_ATTR(global_rsv_size, 0444, global_rsv_size_show);
     246             : 
     247           0 : static ssize_t global_rsv_reserved_show(struct kobject *kobj,
     248             :                                         struct kobj_attribute *a, char *buf)
     249             : {
     250           0 :         struct btrfs_fs_info *fs_info = to_fs_info(kobj->parent);
     251             :         struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv;
     252           0 :         return btrfs_show_u64(&block_rsv->reserved, &block_rsv->lock, buf);
     253             : }
     254             : BTRFS_ATTR(global_rsv_reserved, 0444, global_rsv_reserved_show);
     255             : 
     256             : #define to_space_info(_kobj) container_of(_kobj, struct btrfs_space_info, kobj)
     257             : #define to_raid_kobj(_kobj) container_of(_kobj, struct raid_kobject, kobj)
     258             : 
     259             : static ssize_t raid_bytes_show(struct kobject *kobj,
     260             :                                struct kobj_attribute *attr, char *buf);
     261             : BTRFS_RAID_ATTR(total_bytes, raid_bytes_show);
     262             : BTRFS_RAID_ATTR(used_bytes, raid_bytes_show);
     263             : 
     264           0 : static ssize_t raid_bytes_show(struct kobject *kobj,
     265             :                                struct kobj_attribute *attr, char *buf)
     266             : 
     267             : {
     268           0 :         struct btrfs_space_info *sinfo = to_space_info(kobj->parent);
     269             :         struct btrfs_block_group_cache *block_group;
     270           0 :         int index = to_raid_kobj(kobj)->raid_type;
     271             :         u64 val = 0;
     272             : 
     273           0 :         down_read(&sinfo->groups_sem);
     274           0 :         list_for_each_entry(block_group, &sinfo->block_groups[index], list) {
     275           0 :                 if (&attr->attr == BTRFS_RAID_ATTR_PTR(total_bytes))
     276           0 :                         val += block_group->key.offset;
     277             :                 else
     278           0 :                         val += btrfs_block_group_used(&block_group->item);
     279             :         }
     280           0 :         up_read(&sinfo->groups_sem);
     281           0 :         return snprintf(buf, PAGE_SIZE, "%llu\n", val);
     282             : }
     283             : 
     284             : static struct attribute *raid_attributes[] = {
     285             :         BTRFS_RAID_ATTR_PTR(total_bytes),
     286             :         BTRFS_RAID_ATTR_PTR(used_bytes),
     287             :         NULL
     288             : };
     289             : 
     290        1090 : static void release_raid_kobj(struct kobject *kobj)
     291             : {
     292        1090 :         kfree(to_raid_kobj(kobj));
     293        1090 : }
     294             : 
     295             : struct kobj_type btrfs_raid_ktype = {
     296             :         .sysfs_ops = &kobj_sysfs_ops,
     297             :         .release = release_raid_kobj,
     298             :         .default_attrs = raid_attributes,
     299             : };
     300             : 
     301             : #define SPACE_INFO_ATTR(field)                                          \
     302             : static ssize_t btrfs_space_info_show_##field(struct kobject *kobj,      \
     303             :                                              struct kobj_attribute *a,  \
     304             :                                              char *buf)                 \
     305             : {                                                                       \
     306             :         struct btrfs_space_info *sinfo = to_space_info(kobj);           \
     307             :         return btrfs_show_u64(&sinfo->field, &sinfo->lock, buf);  \
     308             : }                                                                       \
     309             : BTRFS_ATTR(field, 0444, btrfs_space_info_show_##field)
     310             : 
     311           0 : static ssize_t btrfs_space_info_show_total_bytes_pinned(struct kobject *kobj,
     312             :                                                        struct kobj_attribute *a,
     313             :                                                        char *buf)
     314             : {
     315             :         struct btrfs_space_info *sinfo = to_space_info(kobj);
     316           0 :         s64 val = percpu_counter_sum(&sinfo->total_bytes_pinned);
     317           0 :         return snprintf(buf, PAGE_SIZE, "%lld\n", val);
     318             : }
     319             : 
     320           0 : SPACE_INFO_ATTR(flags);
     321           0 : SPACE_INFO_ATTR(total_bytes);
     322           0 : SPACE_INFO_ATTR(bytes_used);
     323           0 : SPACE_INFO_ATTR(bytes_pinned);
     324           0 : SPACE_INFO_ATTR(bytes_reserved);
     325           0 : SPACE_INFO_ATTR(bytes_may_use);
     326           0 : SPACE_INFO_ATTR(disk_used);
     327           0 : SPACE_INFO_ATTR(disk_total);
     328             : BTRFS_ATTR(total_bytes_pinned, 0444, btrfs_space_info_show_total_bytes_pinned);
     329             : 
     330             : static struct attribute *space_info_attrs[] = {
     331             :         BTRFS_ATTR_PTR(flags),
     332             :         BTRFS_ATTR_PTR(total_bytes),
     333             :         BTRFS_ATTR_PTR(bytes_used),
     334             :         BTRFS_ATTR_PTR(bytes_pinned),
     335             :         BTRFS_ATTR_PTR(bytes_reserved),
     336             :         BTRFS_ATTR_PTR(bytes_may_use),
     337             :         BTRFS_ATTR_PTR(disk_used),
     338             :         BTRFS_ATTR_PTR(disk_total),
     339             :         BTRFS_ATTR_PTR(total_bytes_pinned),
     340             :         NULL,
     341             : };
     342             : 
     343         657 : static void space_info_release(struct kobject *kobj)
     344             : {
     345         657 :         struct btrfs_space_info *sinfo = to_space_info(kobj);
     346         657 :         percpu_counter_destroy(&sinfo->total_bytes_pinned);
     347         657 :         kfree(sinfo);
     348         657 : }
     349             : 
     350             : struct kobj_type space_info_ktype = {
     351             :         .sysfs_ops = &kobj_sysfs_ops,
     352             :         .release = space_info_release,
     353             :         .default_attrs = space_info_attrs,
     354             : };
     355             : 
     356             : static const struct attribute *allocation_attrs[] = {
     357             :         BTRFS_ATTR_PTR(global_rsv_reserved),
     358             :         BTRFS_ATTR_PTR(global_rsv_size),
     359             :         NULL,
     360             : };
     361             : 
     362           0 : static ssize_t btrfs_label_show(struct kobject *kobj,
     363             :                                 struct kobj_attribute *a, char *buf)
     364             : {
     365             :         struct btrfs_fs_info *fs_info = to_fs_info(kobj);
     366           0 :         return snprintf(buf, PAGE_SIZE, "%s\n", fs_info->super_copy->label);
     367             : }
     368             : 
     369           0 : static ssize_t btrfs_label_store(struct kobject *kobj,
     370             :                                  struct kobj_attribute *a,
     371             :                                  const char *buf, size_t len)
     372             : {
     373             :         struct btrfs_fs_info *fs_info = to_fs_info(kobj);
     374             :         struct btrfs_trans_handle *trans;
     375           0 :         struct btrfs_root *root = fs_info->fs_root;
     376             :         int ret;
     377             : 
     378           0 :         if (len >= BTRFS_LABEL_SIZE)
     379             :                 return -EINVAL;
     380             : 
     381           0 :         trans = btrfs_start_transaction(root, 0);
     382           0 :         if (IS_ERR(trans))
     383           0 :                 return PTR_ERR(trans);
     384             : 
     385           0 :         spin_lock(&root->fs_info->super_lock);
     386           0 :         strcpy(fs_info->super_copy->label, buf);
     387           0 :         spin_unlock(&root->fs_info->super_lock);
     388           0 :         ret = btrfs_commit_transaction(trans, root);
     389             : 
     390           0 :         if (!ret)
     391           0 :                 return len;
     392             : 
     393           0 :         return ret;
     394             : }
     395             : BTRFS_ATTR_RW(label, 0644, btrfs_label_show, btrfs_label_store);
     396             : 
     397           0 : static ssize_t btrfs_no_store(struct kobject *kobj,
     398             :                                  struct kobj_attribute *a,
     399             :                                  const char *buf, size_t len)
     400             : {
     401           0 :         return -EPERM;
     402             : }
     403             : 
     404           0 : static ssize_t btrfs_nodesize_show(struct kobject *kobj,
     405             :                                 struct kobj_attribute *a, char *buf)
     406             : {
     407             :         struct btrfs_fs_info *fs_info = to_fs_info(kobj);
     408             : 
     409           0 :         return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->super_copy->nodesize);
     410             : }
     411             : 
     412             : BTRFS_ATTR_RW(nodesize, 0444, btrfs_nodesize_show, btrfs_no_store);
     413             : 
     414           0 : static ssize_t btrfs_sectorsize_show(struct kobject *kobj,
     415             :                                 struct kobj_attribute *a, char *buf)
     416             : {
     417             :         struct btrfs_fs_info *fs_info = to_fs_info(kobj);
     418             : 
     419           0 :         return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->super_copy->sectorsize);
     420             : }
     421             : 
     422             : BTRFS_ATTR_RW(sectorsize, 0444, btrfs_sectorsize_show, btrfs_no_store);
     423             : 
     424           0 : static ssize_t btrfs_clone_alignment_show(struct kobject *kobj,
     425             :                                 struct kobj_attribute *a, char *buf)
     426             : {
     427             :         struct btrfs_fs_info *fs_info = to_fs_info(kobj);
     428             : 
     429           0 :         return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->super_copy->sectorsize);
     430             : }
     431             : 
     432             : BTRFS_ATTR_RW(clone_alignment, 0444, btrfs_clone_alignment_show, btrfs_no_store);
     433             : 
     434             : static struct attribute *btrfs_attrs[] = {
     435             :         BTRFS_ATTR_PTR(label),
     436             :         BTRFS_ATTR_PTR(nodesize),
     437             :         BTRFS_ATTR_PTR(sectorsize),
     438             :         BTRFS_ATTR_PTR(clone_alignment),
     439             :         NULL,
     440             : };
     441             : 
     442         221 : static void btrfs_release_super_kobj(struct kobject *kobj)
     443             : {
     444             :         struct btrfs_fs_info *fs_info = to_fs_info(kobj);
     445         221 :         complete(&fs_info->kobj_unregister);
     446         221 : }
     447             : 
     448             : static struct kobj_type btrfs_ktype = {
     449             :         .sysfs_ops      = &kobj_sysfs_ops,
     450             :         .release        = btrfs_release_super_kobj,
     451             :         .default_attrs  = btrfs_attrs,
     452             : };
     453             : 
     454             : static inline struct btrfs_fs_info *to_fs_info(struct kobject *kobj)
     455             : {
     456        2210 :         if (kobj->ktype != &btrfs_ktype)
     457             :                 return NULL;
     458        2210 :         return container_of(kobj, struct btrfs_fs_info, super_kobj);
     459             : }
     460             : 
     461             : #define NUM_FEATURE_BITS 64
     462             : static char btrfs_unknown_feature_names[3][NUM_FEATURE_BITS][13];
     463             : static struct btrfs_feature_attr btrfs_feature_attrs[3][NUM_FEATURE_BITS];
     464             : 
     465             : static u64 supported_feature_masks[3] = {
     466             :         [FEAT_COMPAT]    = BTRFS_FEATURE_COMPAT_SUPP,
     467             :         [FEAT_COMPAT_RO] = BTRFS_FEATURE_COMPAT_RO_SUPP,
     468             :         [FEAT_INCOMPAT]  = BTRFS_FEATURE_INCOMPAT_SUPP,
     469             : };
     470             : 
     471        1768 : static int addrm_unknown_feature_attrs(struct btrfs_fs_info *fs_info, bool add)
     472             : {
     473             :         int set;
     474             : 
     475        1768 :         for (set = 0; set < FEAT_MAX; set++) {
     476             :                 int i;
     477             :                 struct attribute *attrs[2];
     478        1326 :                 struct attribute_group agroup = {
     479             :                         .name = "features",
     480             :                         .attrs = attrs,
     481             :                 };
     482        1326 :                 u64 features = get_features(fs_info, set);
     483        1326 :                 features &= ~supported_feature_masks[set];
     484             : 
     485        1326 :                 if (!features)
     486        1326 :                         continue;
     487             : 
     488           0 :                 attrs[1] = NULL;
     489           0 :                 for (i = 0; i < NUM_FEATURE_BITS; i++) {
     490             :                         struct btrfs_feature_attr *fa;
     491             : 
     492           0 :                         if (!(features & (1ULL << i)))
     493           0 :                                 continue;
     494             : 
     495           0 :                         fa = &btrfs_feature_attrs[set][i];
     496           0 :                         attrs[0] = &fa->kobj_attr.attr;
     497           0 :                         if (add) {
     498             :                                 int ret;
     499           0 :                                 ret = sysfs_merge_group(&fs_info->super_kobj,
     500             :                                                         &agroup);
     501           0 :                                 if (ret)
     502           0 :                                         return ret;
     503             :                         } else
     504           0 :                                 sysfs_unmerge_group(&fs_info->super_kobj,
     505             :                                                     &agroup);
     506             :                 }
     507             : 
     508             :         }
     509             :         return 0;
     510             : }
     511             : 
     512         221 : static void __btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info)
     513             : {
     514         221 :         kobject_del(&fs_info->super_kobj);
     515         221 :         kobject_put(&fs_info->super_kobj);
     516         221 :         wait_for_completion(&fs_info->kobj_unregister);
     517         221 : }
     518             : 
     519         221 : void btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info)
     520             : {
     521         221 :         if (fs_info->space_info_kobj) {
     522         221 :                 sysfs_remove_files(fs_info->space_info_kobj, allocation_attrs);
     523         221 :                 kobject_del(fs_info->space_info_kobj);
     524         221 :                 kobject_put(fs_info->space_info_kobj);
     525             :         }
     526         221 :         kobject_del(fs_info->device_dir_kobj);
     527         221 :         kobject_put(fs_info->device_dir_kobj);
     528         221 :         addrm_unknown_feature_attrs(fs_info, false);
     529         221 :         sysfs_remove_group(&fs_info->super_kobj, &btrfs_feature_attr_group);
     530         221 :         __btrfs_sysfs_remove_one(fs_info);
     531         221 : }
     532             : 
     533             : const char * const btrfs_feature_set_names[3] = {
     534             :         [FEAT_COMPAT]    = "compat",
     535             :         [FEAT_COMPAT_RO] = "compat_ro",
     536             :         [FEAT_INCOMPAT]  = "incompat",
     537             : };
     538             : 
     539           0 : char *btrfs_printable_features(enum btrfs_feature_set set, u64 flags)
     540             : {
     541             :         size_t bufsize = 4096; /* safe max, 64 names * 64 bytes */
     542             :         int len = 0;
     543             :         int i;
     544             :         char *str;
     545             : 
     546             :         str = kmalloc(bufsize, GFP_KERNEL);
     547           0 :         if (!str)
     548             :                 return str;
     549             : 
     550           0 :         for (i = 0; i < ARRAY_SIZE(btrfs_feature_attrs[set]); i++) {
     551             :                 const char *name;
     552             : 
     553           0 :                 if (!(flags & (1ULL << i)))
     554           0 :                         continue;
     555             : 
     556           0 :                 name = btrfs_feature_attrs[set][i].kobj_attr.attr.name;
     557           0 :                 len += snprintf(str + len, bufsize - len, "%s%s",
     558             :                                 len ? "," : "", name);
     559             :         }
     560             : 
     561             :         return str;
     562             : }
     563             : 
     564           0 : static void init_feature_attrs(void)
     565             : {
     566             :         struct btrfs_feature_attr *fa;
     567             :         int set, i;
     568             : 
     569             :         BUILD_BUG_ON(ARRAY_SIZE(btrfs_unknown_feature_names) !=
     570             :                      ARRAY_SIZE(btrfs_feature_attrs));
     571             :         BUILD_BUG_ON(ARRAY_SIZE(btrfs_unknown_feature_names[0]) !=
     572             :                      ARRAY_SIZE(btrfs_feature_attrs[0]));
     573             : 
     574           0 :         memset(btrfs_feature_attrs, 0, sizeof(btrfs_feature_attrs));
     575           0 :         memset(btrfs_unknown_feature_names, 0,
     576             :                sizeof(btrfs_unknown_feature_names));
     577             : 
     578           0 :         for (i = 0; btrfs_supported_feature_attrs[i]; i++) {
     579             :                 struct btrfs_feature_attr *sfa;
     580             :                 struct attribute *a = btrfs_supported_feature_attrs[i];
     581             :                 int bit;
     582             :                 sfa = attr_to_btrfs_feature_attr(a);
     583           0 :                 bit = ilog2(sfa->feature_bit);
     584           0 :                 fa = &btrfs_feature_attrs[sfa->feature_set][bit];
     585             : 
     586           0 :                 fa->kobj_attr.attr.name = sfa->kobj_attr.attr.name;
     587             :         }
     588             : 
     589           0 :         for (set = 0; set < FEAT_MAX; set++) {
     590           0 :                 for (i = 0; i < ARRAY_SIZE(btrfs_feature_attrs[set]); i++) {
     591           0 :                         char *name = btrfs_unknown_feature_names[set][i];
     592           0 :                         fa = &btrfs_feature_attrs[set][i];
     593             : 
     594           0 :                         if (fa->kobj_attr.attr.name)
     595           0 :                                 continue;
     596             : 
     597           0 :                         snprintf(name, 13, "%s:%u",
     598             :                                  btrfs_feature_set_names[set], i);
     599             : 
     600           0 :                         fa->kobj_attr.attr.name = name;
     601           0 :                         fa->kobj_attr.attr.mode = S_IRUGO;
     602           0 :                         fa->feature_set = set;
     603           0 :                         fa->feature_bit = 1ULL << i;
     604             :                 }
     605             :         }
     606           0 : }
     607             : 
     608           7 : int btrfs_kobj_rm_device(struct btrfs_fs_info *fs_info,
     609             :                 struct btrfs_device *one_device)
     610             : {
     611             :         struct hd_struct *disk;
     612             :         struct kobject *disk_kobj;
     613             : 
     614           7 :         if (!fs_info->device_dir_kobj)
     615             :                 return -EINVAL;
     616             : 
     617           7 :         if (one_device && one_device->bdev) {
     618           7 :                 disk = one_device->bdev->bd_part;
     619             :                 disk_kobj = &part_to_dev(disk)->kobj;
     620             : 
     621           7 :                 sysfs_remove_link(fs_info->device_dir_kobj,
     622             :                                                 disk_kobj->name);
     623             :         }
     624             : 
     625             :         return 0;
     626             : }
     627             : 
     628         228 : int btrfs_kobj_add_device(struct btrfs_fs_info *fs_info,
     629             :                 struct btrfs_device *one_device)
     630             : {
     631             :         int error = 0;
     632         228 :         struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
     633             :         struct btrfs_device *dev;
     634             : 
     635         228 :         if (!fs_info->device_dir_kobj)
     636         221 :                 fs_info->device_dir_kobj = kobject_create_and_add("devices",
     637             :                                                 &fs_info->super_kobj);
     638             : 
     639         228 :         if (!fs_info->device_dir_kobj)
     640             :                 return -ENOMEM;
     641             : 
     642         493 :         list_for_each_entry(dev, &fs_devices->devices, dev_list) {
     643             :                 struct hd_struct *disk;
     644             :                 struct kobject *disk_kobj;
     645             : 
     646         265 :                 if (!dev->bdev)
     647           0 :                         continue;
     648             : 
     649         265 :                 if (one_device && one_device != dev)
     650          10 :                         continue;
     651             : 
     652         255 :                 disk = dev->bdev->bd_part;
     653         255 :                 disk_kobj = &part_to_dev(disk)->kobj;
     654             : 
     655         255 :                 error = sysfs_create_link(fs_info->device_dir_kobj,
     656             :                                           disk_kobj, disk_kobj->name);
     657         255 :                 if (error)
     658             :                         break;
     659             :         }
     660             : 
     661         228 :         return error;
     662             : }
     663             : 
     664             : /* /sys/fs/btrfs/ entry */
     665             : static struct kset *btrfs_kset;
     666             : 
     667             : /* /sys/kernel/debug/btrfs */
     668             : static struct dentry *btrfs_debugfs_root_dentry;
     669             : 
     670             : /* Debugging tunables and exported data */
     671             : u64 btrfs_debugfs_test;
     672             : 
     673         221 : int btrfs_sysfs_add_one(struct btrfs_fs_info *fs_info)
     674             : {
     675             :         int error;
     676             : 
     677             :         init_completion(&fs_info->kobj_unregister);
     678         221 :         fs_info->super_kobj.kset = btrfs_kset;
     679         221 :         error = kobject_init_and_add(&fs_info->super_kobj, &btrfs_ktype, NULL,
     680         221 :                                      "%pU", fs_info->fsid);
     681         221 :         if (error)
     682             :                 return error;
     683             : 
     684         221 :         error = sysfs_create_group(&fs_info->super_kobj,
     685             :                                    &btrfs_feature_attr_group);
     686         221 :         if (error) {
     687           0 :                 __btrfs_sysfs_remove_one(fs_info);
     688           0 :                 return error;
     689             :         }
     690             : 
     691         221 :         error = addrm_unknown_feature_attrs(fs_info, true);
     692         221 :         if (error)
     693             :                 goto failure;
     694             : 
     695         221 :         error = btrfs_kobj_add_device(fs_info, NULL);
     696         221 :         if (error)
     697             :                 goto failure;
     698             : 
     699         221 :         fs_info->space_info_kobj = kobject_create_and_add("allocation",
     700             :                                                   &fs_info->super_kobj);
     701         221 :         if (!fs_info->space_info_kobj) {
     702             :                 error = -ENOMEM;
     703             :                 goto failure;
     704             :         }
     705             : 
     706         221 :         error = sysfs_create_files(fs_info->space_info_kobj, allocation_attrs);
     707         221 :         if (error)
     708             :                 goto failure;
     709             : 
     710             :         return 0;
     711             : failure:
     712           0 :         btrfs_sysfs_remove_one(fs_info);
     713           0 :         return error;
     714             : }
     715             : 
     716           0 : static int btrfs_init_debugfs(void)
     717             : {
     718             : #ifdef CONFIG_DEBUG_FS
     719           0 :         btrfs_debugfs_root_dentry = debugfs_create_dir("btrfs", NULL);
     720           0 :         if (!btrfs_debugfs_root_dentry)
     721             :                 return -ENOMEM;
     722             : 
     723           0 :         debugfs_create_u64("test", S_IRUGO | S_IWUGO, btrfs_debugfs_root_dentry,
     724             :                         &btrfs_debugfs_test);
     725             : #endif
     726           0 :         return 0;
     727             : }
     728             : 
     729           0 : int btrfs_init_sysfs(void)
     730             : {
     731             :         int ret;
     732             : 
     733           0 :         btrfs_kset = kset_create_and_add("btrfs", NULL, fs_kobj);
     734           0 :         if (!btrfs_kset)
     735             :                 return -ENOMEM;
     736             : 
     737           0 :         ret = btrfs_init_debugfs();
     738           0 :         if (ret)
     739             :                 return ret;
     740             : 
     741           0 :         init_feature_attrs();
     742           0 :         ret = sysfs_create_group(&btrfs_kset->kobj, &btrfs_feature_attr_group);
     743             : 
     744           0 :         return ret;
     745             : }
     746             : 
     747           0 : void btrfs_exit_sysfs(void)
     748             : {
     749           0 :         sysfs_remove_group(&btrfs_kset->kobj, &btrfs_feature_attr_group);
     750           0 :         kset_unregister(btrfs_kset);
     751           0 :         debugfs_remove_recursive(btrfs_debugfs_root_dentry);
     752           0 : }
     753             : 

Generated by: LCOV version 1.10