diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-28 16:10:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-28 16:10:41 -0400 |
commit | a01ee165a132fadb57659d26246e340d6ac53265 (patch) | |
tree | da452e660fed2bcf8c9021cac65166308ea2db56 /fs/exofs | |
parent | d766023eea566bb3c2a57a0567af5b271908fdc2 (diff) | |
parent | 8b56a30caaf9bc1850784f196636c5f550cc7577 (diff) |
Merge branch 'for-linus' of git://git.open-osd.org/linux-open-osd
Pull exofs updates from Boaz Harrosh:
"Just a couple of patches. The first is a BUG fix destined for stable
which missed the 3.4-rc7 Kernel. The second is just a fixture
addition so exofs is able to be better exported as a cluster file
system via pNFS."
* 'for-linus' of git://git.open-osd.org/linux-open-osd:
exofs: Add SYSFS info for autologin/pNFS export
exofs: Fix CRASH on very early IO errors.
Diffstat (limited to 'fs/exofs')
-rw-r--r-- | fs/exofs/Kbuild | 2 | ||||
-rw-r--r-- | fs/exofs/exofs.h | 14 | ||||
-rw-r--r-- | fs/exofs/super.c | 16 | ||||
-rw-r--r-- | fs/exofs/sys.c | 200 |
4 files changed, 230 insertions, 2 deletions
diff --git a/fs/exofs/Kbuild b/fs/exofs/Kbuild index 352ba149d23e..389ba8312d5d 100644 --- a/fs/exofs/Kbuild +++ b/fs/exofs/Kbuild | |||
@@ -16,5 +16,5 @@ | |||
16 | libore-y := ore.o ore_raid.o | 16 | libore-y := ore.o ore_raid.o |
17 | obj-$(CONFIG_ORE) += libore.o | 17 | obj-$(CONFIG_ORE) += libore.o |
18 | 18 | ||
19 | exofs-y := inode.o file.o symlink.o namei.o dir.o super.o | 19 | exofs-y := inode.o file.o symlink.o namei.o dir.o super.o sys.o |
20 | obj-$(CONFIG_EXOFS_FS) += exofs.o | 20 | obj-$(CONFIG_EXOFS_FS) += exofs.o |
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h index ca9d49665ef6..fffe86fd7a42 100644 --- a/fs/exofs/exofs.h +++ b/fs/exofs/exofs.h | |||
@@ -56,6 +56,9 @@ | |||
56 | struct exofs_dev { | 56 | struct exofs_dev { |
57 | struct ore_dev ored; | 57 | struct ore_dev ored; |
58 | unsigned did; | 58 | unsigned did; |
59 | unsigned urilen; | ||
60 | uint8_t *uri; | ||
61 | struct kobject ed_kobj; | ||
59 | }; | 62 | }; |
60 | /* | 63 | /* |
61 | * our extension to the in-memory superblock | 64 | * our extension to the in-memory superblock |
@@ -73,6 +76,7 @@ struct exofs_sb_info { | |||
73 | struct ore_layout layout; /* Default files layout */ | 76 | struct ore_layout layout; /* Default files layout */ |
74 | struct ore_comp one_comp; /* id & cred of partition id=0*/ | 77 | struct ore_comp one_comp; /* id & cred of partition id=0*/ |
75 | struct ore_components oc; /* comps for the partition */ | 78 | struct ore_components oc; /* comps for the partition */ |
79 | struct kobject s_kobj; /* holds per-sbi kobject */ | ||
76 | }; | 80 | }; |
77 | 81 | ||
78 | /* | 82 | /* |
@@ -176,6 +180,16 @@ void exofs_make_credential(u8 cred_a[OSD_CAP_LEN], | |||
176 | const struct osd_obj_id *obj); | 180 | const struct osd_obj_id *obj); |
177 | int exofs_sbi_write_stats(struct exofs_sb_info *sbi); | 181 | int exofs_sbi_write_stats(struct exofs_sb_info *sbi); |
178 | 182 | ||
183 | /* sys.c */ | ||
184 | int exofs_sysfs_init(void); | ||
185 | void exofs_sysfs_uninit(void); | ||
186 | int exofs_sysfs_sb_add(struct exofs_sb_info *sbi, | ||
187 | struct exofs_dt_device_info *dt_dev); | ||
188 | void exofs_sysfs_sb_del(struct exofs_sb_info *sbi); | ||
189 | int exofs_sysfs_odev_add(struct exofs_dev *edev, | ||
190 | struct exofs_sb_info *sbi); | ||
191 | void exofs_sysfs_dbg_print(void); | ||
192 | |||
179 | /********************* | 193 | /********************* |
180 | * operation vectors * | 194 | * operation vectors * |
181 | *********************/ | 195 | *********************/ |
diff --git a/fs/exofs/super.c b/fs/exofs/super.c index 735ca06430ac..433783624d10 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c | |||
@@ -472,6 +472,7 @@ static void exofs_put_super(struct super_block *sb) | |||
472 | _exofs_print_device("Unmounting", NULL, ore_comp_dev(&sbi->oc, 0), | 472 | _exofs_print_device("Unmounting", NULL, ore_comp_dev(&sbi->oc, 0), |
473 | sbi->one_comp.obj.partition); | 473 | sbi->one_comp.obj.partition); |
474 | 474 | ||
475 | exofs_sysfs_sb_del(sbi); | ||
475 | bdi_destroy(&sbi->bdi); | 476 | bdi_destroy(&sbi->bdi); |
476 | exofs_free_sbi(sbi); | 477 | exofs_free_sbi(sbi); |
477 | sb->s_fs_info = NULL; | 478 | sb->s_fs_info = NULL; |
@@ -632,6 +633,12 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi, | |||
632 | memcpy(&sbi->oc.ods[numdevs], &sbi->oc.ods[0], | 633 | memcpy(&sbi->oc.ods[numdevs], &sbi->oc.ods[0], |
633 | (numdevs - 1) * sizeof(sbi->oc.ods[0])); | 634 | (numdevs - 1) * sizeof(sbi->oc.ods[0])); |
634 | 635 | ||
636 | /* create sysfs subdir under which we put the device table | ||
637 | * And cluster layout. A Superblock is identified by the string: | ||
638 | * "dev[0].osdname"_"pid" | ||
639 | */ | ||
640 | exofs_sysfs_sb_add(sbi, &dt->dt_dev_table[0]); | ||
641 | |||
635 | for (i = 0; i < numdevs; i++) { | 642 | for (i = 0; i < numdevs; i++) { |
636 | struct exofs_fscb fscb; | 643 | struct exofs_fscb fscb; |
637 | struct osd_dev_info odi; | 644 | struct osd_dev_info odi; |
@@ -657,6 +664,7 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi, | |||
657 | eds[i].ored.od = fscb_od; | 664 | eds[i].ored.od = fscb_od; |
658 | ++sbi->oc.numdevs; | 665 | ++sbi->oc.numdevs; |
659 | fscb_od = NULL; | 666 | fscb_od = NULL; |
667 | exofs_sysfs_odev_add(&eds[i], sbi); | ||
660 | continue; | 668 | continue; |
661 | } | 669 | } |
662 | 670 | ||
@@ -682,6 +690,7 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi, | |||
682 | odi.osdname); | 690 | odi.osdname); |
683 | goto out; | 691 | goto out; |
684 | } | 692 | } |
693 | exofs_sysfs_odev_add(&eds[i], sbi); | ||
685 | 694 | ||
686 | /* TODO: verify other information is correct and FS-uuid | 695 | /* TODO: verify other information is correct and FS-uuid |
687 | * matches. Benny what did you say about device table | 696 | * matches. Benny what did you say about device table |
@@ -745,7 +754,6 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) | |||
745 | sbi->one_comp.obj.partition = opts->pid; | 754 | sbi->one_comp.obj.partition = opts->pid; |
746 | sbi->one_comp.obj.id = 0; | 755 | sbi->one_comp.obj.id = 0; |
747 | exofs_make_credential(sbi->one_comp.cred, &sbi->one_comp.obj); | 756 | exofs_make_credential(sbi->one_comp.cred, &sbi->one_comp.obj); |
748 | sbi->oc.numdevs = 1; | ||
749 | sbi->oc.single_comp = EC_SINGLE_COMP; | 757 | sbi->oc.single_comp = EC_SINGLE_COMP; |
750 | sbi->oc.comps = &sbi->one_comp; | 758 | sbi->oc.comps = &sbi->one_comp; |
751 | 759 | ||
@@ -804,6 +812,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) | |||
804 | goto free_sbi; | 812 | goto free_sbi; |
805 | 813 | ||
806 | ore_comp_set_dev(&sbi->oc, 0, od); | 814 | ore_comp_set_dev(&sbi->oc, 0, od); |
815 | sbi->oc.numdevs = 1; | ||
807 | } | 816 | } |
808 | 817 | ||
809 | __sbi_read_stats(sbi); | 818 | __sbi_read_stats(sbi); |
@@ -844,6 +853,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) | |||
844 | goto free_sbi; | 853 | goto free_sbi; |
845 | } | 854 | } |
846 | 855 | ||
856 | exofs_sysfs_dbg_print(); | ||
847 | _exofs_print_device("Mounting", opts->dev_name, | 857 | _exofs_print_device("Mounting", opts->dev_name, |
848 | ore_comp_dev(&sbi->oc, 0), | 858 | ore_comp_dev(&sbi->oc, 0), |
849 | sbi->one_comp.obj.partition); | 859 | sbi->one_comp.obj.partition); |
@@ -1023,6 +1033,9 @@ static int __init init_exofs(void) | |||
1023 | if (err) | 1033 | if (err) |
1024 | goto out_d; | 1034 | goto out_d; |
1025 | 1035 | ||
1036 | /* We don't fail if sysfs creation failed */ | ||
1037 | exofs_sysfs_init(); | ||
1038 | |||
1026 | return 0; | 1039 | return 0; |
1027 | out_d: | 1040 | out_d: |
1028 | destroy_inodecache(); | 1041 | destroy_inodecache(); |
@@ -1032,6 +1045,7 @@ out: | |||
1032 | 1045 | ||
1033 | static void __exit exit_exofs(void) | 1046 | static void __exit exit_exofs(void) |
1034 | { | 1047 | { |
1048 | exofs_sysfs_uninit(); | ||
1035 | unregister_filesystem(&exofs_type); | 1049 | unregister_filesystem(&exofs_type); |
1036 | destroy_inodecache(); | 1050 | destroy_inodecache(); |
1037 | } | 1051 | } |
diff --git a/fs/exofs/sys.c b/fs/exofs/sys.c new file mode 100644 index 000000000000..e32bc919e4e3 --- /dev/null +++ b/fs/exofs/sys.c | |||
@@ -0,0 +1,200 @@ | |||
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 | |||
27 | struct 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 | |||
33 | static 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 | |||
42 | static 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 | |||
51 | static const struct sysfs_ops odev_attr_ops = { | ||
52 | .show = odev_attr_show, | ||
53 | .store = odev_attr_store, | ||
54 | }; | ||
55 | |||
56 | |||
57 | static struct kset *exofs_kset; | ||
58 | |||
59 | static 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 | |||
67 | static 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 | |||
76 | static ssize_t uri_show(struct exofs_dev *edp, char *buf) | ||
77 | { | ||
78 | return snprintf(buf, edp->urilen, "%s", edp->uri); | ||
79 | } | ||
80 | |||
81 | static 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 | |||
93 | OSD_ATTR(osdname, S_IRUGO, osdname_show, NULL); | ||
94 | OSD_ATTR(systemid, S_IRUGO, systemid_show, NULL); | ||
95 | OSD_ATTR(uri, S_IRWXU, uri_show, uri_store); | ||
96 | |||
97 | static struct attribute *odev_attrs[] = { | ||
98 | &odev_attr_osdname.attr, | ||
99 | &odev_attr_systemid.attr, | ||
100 | &odev_attr_uri.attr, | ||
101 | NULL, | ||
102 | }; | ||
103 | |||
104 | static struct kobj_type odev_ktype = { | ||
105 | .default_attrs = odev_attrs, | ||
106 | .sysfs_ops = &odev_attr_ops, | ||
107 | }; | ||
108 | |||
109 | static struct kobj_type uuid_ktype = { | ||
110 | }; | ||
111 | |||
112 | void exofs_sysfs_dbg_print() | ||
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 | */ | ||
129 | void 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 | */ | ||
147 | int 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 | |||
167 | int 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 | |||
187 | int 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 | |||
197 | void exofs_sysfs_uninit(void) | ||
198 | { | ||
199 | kset_unregister(exofs_kset); | ||
200 | } | ||