3 * Sachin Bhamare <sbhamare@panasas.com>
4 * Boaz Harrosh <ooo@electrozaur.com>
6 * This file is part of exofs.
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.
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.
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>
22 #include <linux/kobject.h>
23 #include <linux/device.h>
28 struct attribute attr
;
29 ssize_t (*show
)(struct exofs_dev
*, char *);
30 ssize_t (*store
)(struct exofs_dev
*, const char *, size_t);
33 static ssize_t
odev_attr_show(struct kobject
*kobj
, struct attribute
*attr
,
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
);
39 return a
->show
? a
->show(edp
, buf
) : 0;
42 static ssize_t
odev_attr_store(struct kobject
*kobj
, struct attribute
*attr
,
43 const char *buf
, size_t len
)
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
);
48 return a
->store
? a
->store(edp
, buf
, len
) : len
;
51 static const struct sysfs_ops odev_attr_ops
= {
52 .show
= odev_attr_show
,
53 .store
= odev_attr_store
,
57 static struct kset
*exofs_kset
;
59 static ssize_t
osdname_show(struct exofs_dev
*edp
, char *buf
)
61 struct osd_dev
*odev
= edp
->ored
.od
;
62 const struct osd_dev_info
*odi
= osduld_device_info(odev
);
64 return snprintf(buf
, odi
->osdname_len
+ 1, "%s", odi
->osdname
);
67 static ssize_t
systemid_show(struct exofs_dev
*edp
, char *buf
)
69 struct osd_dev
*odev
= edp
->ored
.od
;
70 const struct osd_dev_info
*odi
= osduld_device_info(odev
);
72 memcpy(buf
, odi
->systemid
, odi
->systemid_len
);
73 return odi
->systemid_len
;
76 static ssize_t
uri_show(struct exofs_dev
*edp
, char *buf
)
78 return snprintf(buf
, edp
->urilen
, "%s", edp
->uri
);
81 static ssize_t
uri_store(struct exofs_dev
*edp
, const char *buf
, size_t len
)
85 edp
->urilen
= strlen(buf
) + 1;
86 new_uri
= krealloc(edp
->uri
, edp
->urilen
, GFP_KERNEL
);
90 strncpy(edp
->uri
, buf
, edp
->urilen
);
94 #define OSD_ATTR(name, mode, show, store) \
95 static struct odev_attr odev_attr_##name = \
96 __ATTR(name, mode, show, store)
98 OSD_ATTR(osdname
, S_IRUGO
, osdname_show
, NULL
);
99 OSD_ATTR(systemid
, S_IRUGO
, systemid_show
, NULL
);
100 OSD_ATTR(uri
, S_IRWXU
, uri_show
, uri_store
);
102 static struct attribute
*odev_attrs
[] = {
103 &odev_attr_osdname
.attr
,
104 &odev_attr_systemid
.attr
,
109 static struct kobj_type odev_ktype
= {
110 .default_attrs
= odev_attrs
,
111 .sysfs_ops
= &odev_attr_ops
,
114 static struct kobj_type uuid_ktype
= {
117 void exofs_sysfs_dbg_print(void)
119 #ifdef CONFIG_EXOFS_DEBUG
120 struct kobject
*k_name
, *k_tmp
;
122 list_for_each_entry_safe(k_name
, k_tmp
, &exofs_kset
->list
, entry
) {
123 printk(KERN_INFO
"%s: name %s ref %d\n",
124 __func__
, kobject_name(k_name
),
125 (int)atomic_read(&k_name
->kref
.refcount
));
130 * This function removes all kobjects under exofs_kset
131 * At the end of it, exofs_kset kobject will have a refcount
132 * of 1 which gets decremented only on exofs module unload
134 void exofs_sysfs_sb_del(struct exofs_sb_info
*sbi
)
136 struct kobject
*k_name
, *k_tmp
;
137 struct kobject
*s_kobj
= &sbi
->s_kobj
;
139 list_for_each_entry_safe(k_name
, k_tmp
, &exofs_kset
->list
, entry
) {
140 /* Remove all that are children of this SBI */
141 if (k_name
->parent
== s_kobj
)
148 * This function creates sysfs entries to hold the current exofs cluster
149 * instance (uniquely identified by osdname,pid tuple).
150 * This function gets called once per exofs mount instance.
152 int exofs_sysfs_sb_add(struct exofs_sb_info
*sbi
,
153 struct exofs_dt_device_info
*dt_dev
)
155 struct kobject
*s_kobj
;
157 uint64_t pid
= sbi
->one_comp
.obj
.partition
;
159 /* allocate new uuid dirent */
160 s_kobj
= &sbi
->s_kobj
;
161 s_kobj
->kset
= exofs_kset
;
162 retval
= kobject_init_and_add(s_kobj
, &uuid_ktype
,
163 &exofs_kset
->kobj
, "%s_%llx", dt_dev
->osdname
, pid
);
165 EXOFS_ERR("ERROR: Failed to create sysfs entry for "
166 "uuid-%s_%llx => %d\n", dt_dev
->osdname
, pid
, retval
);
172 int exofs_sysfs_odev_add(struct exofs_dev
*edev
, struct exofs_sb_info
*sbi
)
174 struct kobject
*d_kobj
;
177 /* create osd device group which contains following attributes
178 * osdname, systemid & uri
180 d_kobj
= &edev
->ed_kobj
;
181 d_kobj
->kset
= exofs_kset
;
182 retval
= kobject_init_and_add(d_kobj
, &odev_ktype
,
183 &sbi
->s_kobj
, "dev%u", edev
->did
);
185 EXOFS_ERR("ERROR: Failed to create sysfs entry for "
186 "device dev%u\n", edev
->did
);
192 int exofs_sysfs_init(void)
194 exofs_kset
= kset_create_and_add("exofs", NULL
, fs_kobj
);
196 EXOFS_ERR("ERROR: kset_create_and_add exofs failed\n");
202 void exofs_sysfs_uninit(void)
204 kset_unregister(exofs_kset
);