linux/fs/exofs/sys.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2012
   3 * Sachin Bhamare <sbhamare@panasas.com>
   4 * Boaz Harrosh <bharrosh@panasas.com>
   5 *
   6 * This file is part of exofs.
   7 *
   8 * exofs is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License 2 as published by
  10 * the Free Software Foundation.
  11 *
  12 * exofs is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with exofs; if not, write to the:
  19 *      Free Software Foundation <licensing@fsf.org>
  20 */
  21
  22#include <linux/kobject.h>
  23#include <linux/device.h>
  24
  25#include "exofs.h"
  26
  27struct odev_attr {
  28        struct attribute attr;
  29        ssize_t (*show)(struct exofs_dev *, char *);
  30        ssize_t (*store)(struct exofs_dev *, const char *, size_t);
  31};
  32
  33static ssize_t odev_attr_show(struct kobject *kobj, struct attribute *attr,
  34                char *buf)
  35{
  36        struct exofs_dev *edp = container_of(kobj, struct exofs_dev, ed_kobj);
  37        struct odev_attr *a = container_of(attr, struct odev_attr, attr);
  38
  39        return a->show ? a->show(edp, buf) : 0;
  40}
  41
  42static ssize_t odev_attr_store(struct kobject *kobj, struct attribute *attr,
  43                const char *buf, size_t len)
  44{
  45        struct exofs_dev *edp = container_of(kobj, struct exofs_dev, ed_kobj);
  46        struct odev_attr *a = container_of(attr, struct odev_attr, attr);
  47
  48        return a->store ? a->store(edp, buf, len) : len;
  49}
  50
  51static const struct sysfs_ops odev_attr_ops = {
  52        .show  = odev_attr_show,
  53        .store = odev_attr_store,
  54};
  55
  56
  57static struct kset *exofs_kset;
  58
  59static ssize_t osdname_show(struct exofs_dev *edp, char *buf)
  60{
  61        struct osd_dev *odev = edp->ored.od;
  62        const struct osd_dev_info *odi = osduld_device_info(odev);
  63
  64        return snprintf(buf, odi->osdname_len + 1, "%s", odi->osdname);
  65}
  66
  67static ssize_t systemid_show(struct exofs_dev *edp, char *buf)
  68{
  69        struct osd_dev *odev = edp->ored.od;
  70        const struct osd_dev_info *odi = osduld_device_info(odev);
  71
  72        memcpy(buf, odi->systemid, odi->systemid_len);
  73        return odi->systemid_len;
  74}
  75
  76static ssize_t uri_show(struct exofs_dev *edp, char *buf)
  77{
  78        return snprintf(buf, edp->urilen, "%s", edp->uri);
  79}
  80
  81static ssize_t uri_store(struct exofs_dev *edp, const char *buf, size_t len)
  82{
  83        edp->urilen = strlen(buf) + 1;
  84        edp->uri = krealloc(edp->uri, edp->urilen, GFP_KERNEL);
  85        strncpy(edp->uri, buf, edp->urilen);
  86        return edp->urilen;
  87}
  88
  89#define OSD_ATTR(name, mode, show, store) \
  90        static struct odev_attr odev_attr_##name = \
  91                                        __ATTR(name, mode, show, store)
  92
  93OSD_ATTR(osdname, S_IRUGO, osdname_show, NULL);
  94OSD_ATTR(systemid, S_IRUGO, systemid_show, NULL);
  95OSD_ATTR(uri, S_IRWXU, uri_show, uri_store);
  96
  97static struct attribute *odev_attrs[] = {
  98        &odev_attr_osdname.attr,
  99        &odev_attr_systemid.attr,
 100        &odev_attr_uri.attr,
 101        NULL,
 102};
 103
 104static struct kobj_type odev_ktype = {
 105        .default_attrs  = odev_attrs,
 106        .sysfs_ops      = &odev_attr_ops,
 107};
 108
 109static struct kobj_type uuid_ktype = {
 110};
 111
 112void exofs_sysfs_dbg_print(void)
 113{
 114#ifdef CONFIG_EXOFS_DEBUG
 115        struct kobject *k_name, *k_tmp;
 116
 117        list_for_each_entry_safe(k_name, k_tmp, &exofs_kset->list, entry) {
 118                printk(KERN_INFO "%s: name %s ref %d\n",
 119                        __func__, kobject_name(k_name),
 120                        (int)atomic_read(&k_name->kref.refcount));
 121        }
 122#endif
 123}
 124/*
 125 * This function removes all kobjects under exofs_kset
 126 * At the end of it, exofs_kset kobject will have a refcount
 127 * of 1 which gets decremented only on exofs module unload
 128 */
 129void exofs_sysfs_sb_del(struct exofs_sb_info *sbi)
 130{
 131        struct kobject *k_name, *k_tmp;
 132        struct kobject *s_kobj = &sbi->s_kobj;
 133
 134        list_for_each_entry_safe(k_name, k_tmp, &exofs_kset->list, entry) {
 135                /* Remove all that are children of this SBI */
 136                if (k_name->parent == s_kobj)
 137                        kobject_put(k_name);
 138        }
 139        kobject_put(s_kobj);
 140}
 141
 142/*
 143 * This function creates sysfs entries to hold the current exofs cluster
 144 * instance (uniquely identified by osdname,pid tuple).
 145 * This function gets called once per exofs mount instance.
 146 */
 147int exofs_sysfs_sb_add(struct exofs_sb_info *sbi,
 148                       struct exofs_dt_device_info *dt_dev)
 149{
 150        struct kobject *s_kobj;
 151        int retval = 0;
 152        uint64_t pid = sbi->one_comp.obj.partition;
 153
 154        /* allocate new uuid dirent */
 155        s_kobj = &sbi->s_kobj;
 156        s_kobj->kset = exofs_kset;
 157        retval = kobject_init_and_add(s_kobj, &uuid_ktype,
 158                        &exofs_kset->kobj,  "%s_%llx", dt_dev->osdname, pid);
 159        if (retval) {
 160                EXOFS_ERR("ERROR: Failed to create sysfs entry for "
 161                          "uuid-%s_%llx => %d\n", dt_dev->osdname, pid, retval);
 162                return -ENOMEM;
 163        }
 164        return 0;
 165}
 166
 167int exofs_sysfs_odev_add(struct exofs_dev *edev, struct exofs_sb_info *sbi)
 168{
 169        struct kobject *d_kobj;
 170        int retval = 0;
 171
 172        /* create osd device group which contains following attributes
 173         * osdname, systemid & uri
 174         */
 175        d_kobj = &edev->ed_kobj;
 176        d_kobj->kset = exofs_kset;
 177        retval = kobject_init_and_add(d_kobj, &odev_ktype,
 178                        &sbi->s_kobj, "dev%u", edev->did);
 179        if (retval) {
 180                EXOFS_ERR("ERROR: Failed to create sysfs entry for "
 181                                "device dev%u\n", edev->did);
 182                return retval;
 183        }
 184        return 0;
 185}
 186
 187int exofs_sysfs_init(void)
 188{
 189        exofs_kset = kset_create_and_add("exofs", NULL, fs_kobj);
 190        if (!exofs_kset) {
 191                EXOFS_ERR("ERROR: kset_create_and_add exofs failed\n");
 192                return -ENOMEM;
 193        }
 194        return 0;
 195}
 196
 197void exofs_sysfs_uninit(void)
 198{
 199        kset_unregister(exofs_kset);
 200}
 201
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.