aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/sysfs.c4
-rw-r--r--fs/dlm/lockspace.c2
-rw-r--r--fs/ext4/super.c2
-rw-r--r--fs/gfs2/sys.c4
-rw-r--r--fs/ocfs2/cluster/masklog.c2
-rw-r--r--fs/sysfs/bin.c50
-rw-r--r--fs/sysfs/dir.c132
-rw-r--r--fs/sysfs/file.c47
-rw-r--r--fs/sysfs/inode.c13
-rw-r--r--fs/sysfs/mount.c4
-rw-r--r--fs/sysfs/symlink.c38
-rw-r--r--fs/sysfs/sysfs.h17
12 files changed, 189 insertions, 126 deletions
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
index a240b6fa81df..4ce16ef702a3 100644
--- a/fs/btrfs/sysfs.c
+++ b/fs/btrfs/sysfs.c
@@ -164,12 +164,12 @@ static void btrfs_root_release(struct kobject *kobj)
164 complete(&root->kobj_unregister); 164 complete(&root->kobj_unregister);
165} 165}
166 166
167static struct sysfs_ops btrfs_super_attr_ops = { 167static const struct sysfs_ops btrfs_super_attr_ops = {
168 .show = btrfs_super_attr_show, 168 .show = btrfs_super_attr_show,
169 .store = btrfs_super_attr_store, 169 .store = btrfs_super_attr_store,
170}; 170};
171 171
172static struct sysfs_ops btrfs_root_attr_ops = { 172static const struct sysfs_ops btrfs_root_attr_ops = {
173 .show = btrfs_root_attr_show, 173 .show = btrfs_root_attr_show,
174 .store = btrfs_root_attr_store, 174 .store = btrfs_root_attr_store,
175}; 175};
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
index 26a8bd40400a..f994a7dfda85 100644
--- a/fs/dlm/lockspace.c
+++ b/fs/dlm/lockspace.c
@@ -148,7 +148,7 @@ static void lockspace_kobj_release(struct kobject *k)
148 kfree(ls); 148 kfree(ls);
149} 149}
150 150
151static struct sysfs_ops dlm_attr_ops = { 151static const struct sysfs_ops dlm_attr_ops = {
152 .show = dlm_attr_show, 152 .show = dlm_attr_show,
153 .store = dlm_attr_store, 153 .store = dlm_attr_store,
154}; 154};
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 2b83b96cb2eb..ce84a6ed4a48 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2358,7 +2358,7 @@ static void ext4_sb_release(struct kobject *kobj)
2358} 2358}
2359 2359
2360 2360
2361static struct sysfs_ops ext4_attr_ops = { 2361static const struct sysfs_ops ext4_attr_ops = {
2362 .show = ext4_attr_show, 2362 .show = ext4_attr_show,
2363 .store = ext4_attr_store, 2363 .store = ext4_attr_store,
2364}; 2364};
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index b5f1a46133c8..419042f7f0b6 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -49,7 +49,7 @@ static ssize_t gfs2_attr_store(struct kobject *kobj, struct attribute *attr,
49 return a->store ? a->store(sdp, buf, len) : len; 49 return a->store ? a->store(sdp, buf, len) : len;
50} 50}
51 51
52static struct sysfs_ops gfs2_attr_ops = { 52static const struct sysfs_ops gfs2_attr_ops = {
53 .show = gfs2_attr_show, 53 .show = gfs2_attr_show,
54 .store = gfs2_attr_store, 54 .store = gfs2_attr_store,
55}; 55};
@@ -574,7 +574,7 @@ static int gfs2_uevent(struct kset *kset, struct kobject *kobj,
574 return 0; 574 return 0;
575} 575}
576 576
577static struct kset_uevent_ops gfs2_uevent_ops = { 577static const struct kset_uevent_ops gfs2_uevent_ops = {
578 .uevent = gfs2_uevent, 578 .uevent = gfs2_uevent,
579}; 579};
580 580
diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c
index b39da877b12f..3bb928a2bf7d 100644
--- a/fs/ocfs2/cluster/masklog.c
+++ b/fs/ocfs2/cluster/masklog.c
@@ -136,7 +136,7 @@ static ssize_t mlog_store(struct kobject *obj, struct attribute *attr,
136 return mlog_mask_store(mlog_attr->mask, buf, count); 136 return mlog_mask_store(mlog_attr->mask, buf, count);
137} 137}
138 138
139static struct sysfs_ops mlog_attr_ops = { 139static const struct sysfs_ops mlog_attr_ops = {
140 .show = mlog_show, 140 .show = mlog_show,
141 .store = mlog_store, 141 .store = mlog_store,
142}; 142};
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index a0a500af24a1..e9d293593e52 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -54,14 +54,14 @@ fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count)
54 int rc; 54 int rc;
55 55
56 /* need attr_sd for attr, its parent for kobj */ 56 /* need attr_sd for attr, its parent for kobj */
57 if (!sysfs_get_active_two(attr_sd)) 57 if (!sysfs_get_active(attr_sd))
58 return -ENODEV; 58 return -ENODEV;
59 59
60 rc = -EIO; 60 rc = -EIO;
61 if (attr->read) 61 if (attr->read)
62 rc = attr->read(kobj, attr, buffer, off, count); 62 rc = attr->read(kobj, attr, buffer, off, count);
63 63
64 sysfs_put_active_two(attr_sd); 64 sysfs_put_active(attr_sd);
65 65
66 return rc; 66 return rc;
67} 67}
@@ -125,14 +125,14 @@ flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count)
125 int rc; 125 int rc;
126 126
127 /* need attr_sd for attr, its parent for kobj */ 127 /* need attr_sd for attr, its parent for kobj */
128 if (!sysfs_get_active_two(attr_sd)) 128 if (!sysfs_get_active(attr_sd))
129 return -ENODEV; 129 return -ENODEV;
130 130
131 rc = -EIO; 131 rc = -EIO;
132 if (attr->write) 132 if (attr->write)
133 rc = attr->write(kobj, attr, buffer, offset, count); 133 rc = attr->write(kobj, attr, buffer, offset, count);
134 134
135 sysfs_put_active_two(attr_sd); 135 sysfs_put_active(attr_sd);
136 136
137 return rc; 137 return rc;
138} 138}
@@ -184,12 +184,12 @@ static void bin_vma_open(struct vm_area_struct *vma)
184 if (!bb->vm_ops || !bb->vm_ops->open) 184 if (!bb->vm_ops || !bb->vm_ops->open)
185 return; 185 return;
186 186
187 if (!sysfs_get_active_two(attr_sd)) 187 if (!sysfs_get_active(attr_sd))
188 return; 188 return;
189 189
190 bb->vm_ops->open(vma); 190 bb->vm_ops->open(vma);
191 191
192 sysfs_put_active_two(attr_sd); 192 sysfs_put_active(attr_sd);
193} 193}
194 194
195static void bin_vma_close(struct vm_area_struct *vma) 195static void bin_vma_close(struct vm_area_struct *vma)
@@ -201,12 +201,12 @@ static void bin_vma_close(struct vm_area_struct *vma)
201 if (!bb->vm_ops || !bb->vm_ops->close) 201 if (!bb->vm_ops || !bb->vm_ops->close)
202 return; 202 return;
203 203
204 if (!sysfs_get_active_two(attr_sd)) 204 if (!sysfs_get_active(attr_sd))
205 return; 205 return;
206 206
207 bb->vm_ops->close(vma); 207 bb->vm_ops->close(vma);
208 208
209 sysfs_put_active_two(attr_sd); 209 sysfs_put_active(attr_sd);
210} 210}
211 211
212static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf) 212static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
@@ -219,12 +219,12 @@ static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
219 if (!bb->vm_ops || !bb->vm_ops->fault) 219 if (!bb->vm_ops || !bb->vm_ops->fault)
220 return VM_FAULT_SIGBUS; 220 return VM_FAULT_SIGBUS;
221 221
222 if (!sysfs_get_active_two(attr_sd)) 222 if (!sysfs_get_active(attr_sd))
223 return VM_FAULT_SIGBUS; 223 return VM_FAULT_SIGBUS;
224 224
225 ret = bb->vm_ops->fault(vma, vmf); 225 ret = bb->vm_ops->fault(vma, vmf);
226 226
227 sysfs_put_active_two(attr_sd); 227 sysfs_put_active(attr_sd);
228 return ret; 228 return ret;
229} 229}
230 230
@@ -241,12 +241,12 @@ static int bin_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
241 if (!bb->vm_ops->page_mkwrite) 241 if (!bb->vm_ops->page_mkwrite)
242 return 0; 242 return 0;
243 243
244 if (!sysfs_get_active_two(attr_sd)) 244 if (!sysfs_get_active(attr_sd))
245 return VM_FAULT_SIGBUS; 245 return VM_FAULT_SIGBUS;
246 246
247 ret = bb->vm_ops->page_mkwrite(vma, vmf); 247 ret = bb->vm_ops->page_mkwrite(vma, vmf);
248 248
249 sysfs_put_active_two(attr_sd); 249 sysfs_put_active(attr_sd);
250 return ret; 250 return ret;
251} 251}
252 252
@@ -261,12 +261,12 @@ static int bin_access(struct vm_area_struct *vma, unsigned long addr,
261 if (!bb->vm_ops || !bb->vm_ops->access) 261 if (!bb->vm_ops || !bb->vm_ops->access)
262 return -EINVAL; 262 return -EINVAL;
263 263
264 if (!sysfs_get_active_two(attr_sd)) 264 if (!sysfs_get_active(attr_sd))
265 return -EINVAL; 265 return -EINVAL;
266 266
267 ret = bb->vm_ops->access(vma, addr, buf, len, write); 267 ret = bb->vm_ops->access(vma, addr, buf, len, write);
268 268
269 sysfs_put_active_two(attr_sd); 269 sysfs_put_active(attr_sd);
270 return ret; 270 return ret;
271} 271}
272 272
@@ -281,12 +281,12 @@ static int bin_set_policy(struct vm_area_struct *vma, struct mempolicy *new)
281 if (!bb->vm_ops || !bb->vm_ops->set_policy) 281 if (!bb->vm_ops || !bb->vm_ops->set_policy)
282 return 0; 282 return 0;
283 283
284 if (!sysfs_get_active_two(attr_sd)) 284 if (!sysfs_get_active(attr_sd))
285 return -EINVAL; 285 return -EINVAL;
286 286
287 ret = bb->vm_ops->set_policy(vma, new); 287 ret = bb->vm_ops->set_policy(vma, new);
288 288
289 sysfs_put_active_two(attr_sd); 289 sysfs_put_active(attr_sd);
290 return ret; 290 return ret;
291} 291}
292 292
@@ -301,12 +301,12 @@ static struct mempolicy *bin_get_policy(struct vm_area_struct *vma,
301 if (!bb->vm_ops || !bb->vm_ops->get_policy) 301 if (!bb->vm_ops || !bb->vm_ops->get_policy)
302 return vma->vm_policy; 302 return vma->vm_policy;
303 303
304 if (!sysfs_get_active_two(attr_sd)) 304 if (!sysfs_get_active(attr_sd))
305 return vma->vm_policy; 305 return vma->vm_policy;
306 306
307 pol = bb->vm_ops->get_policy(vma, addr); 307 pol = bb->vm_ops->get_policy(vma, addr);
308 308
309 sysfs_put_active_two(attr_sd); 309 sysfs_put_active(attr_sd);
310 return pol; 310 return pol;
311} 311}
312 312
@@ -321,12 +321,12 @@ static int bin_migrate(struct vm_area_struct *vma, const nodemask_t *from,
321 if (!bb->vm_ops || !bb->vm_ops->migrate) 321 if (!bb->vm_ops || !bb->vm_ops->migrate)
322 return 0; 322 return 0;
323 323
324 if (!sysfs_get_active_two(attr_sd)) 324 if (!sysfs_get_active(attr_sd))
325 return 0; 325 return 0;
326 326
327 ret = bb->vm_ops->migrate(vma, from, to, flags); 327 ret = bb->vm_ops->migrate(vma, from, to, flags);
328 328
329 sysfs_put_active_two(attr_sd); 329 sysfs_put_active(attr_sd);
330 return ret; 330 return ret;
331} 331}
332#endif 332#endif
@@ -356,7 +356,7 @@ static int mmap(struct file *file, struct vm_area_struct *vma)
356 356
357 /* need attr_sd for attr, its parent for kobj */ 357 /* need attr_sd for attr, its parent for kobj */
358 rc = -ENODEV; 358 rc = -ENODEV;
359 if (!sysfs_get_active_two(attr_sd)) 359 if (!sysfs_get_active(attr_sd))
360 goto out_unlock; 360 goto out_unlock;
361 361
362 rc = -EINVAL; 362 rc = -EINVAL;
@@ -384,7 +384,7 @@ static int mmap(struct file *file, struct vm_area_struct *vma)
384 bb->vm_ops = vma->vm_ops; 384 bb->vm_ops = vma->vm_ops;
385 vma->vm_ops = &bin_vm_ops; 385 vma->vm_ops = &bin_vm_ops;
386out_put: 386out_put:
387 sysfs_put_active_two(attr_sd); 387 sysfs_put_active(attr_sd);
388out_unlock: 388out_unlock:
389 mutex_unlock(&bb->mutex); 389 mutex_unlock(&bb->mutex);
390 390
@@ -399,7 +399,7 @@ static int open(struct inode * inode, struct file * file)
399 int error; 399 int error;
400 400
401 /* binary file operations requires both @sd and its parent */ 401 /* binary file operations requires both @sd and its parent */
402 if (!sysfs_get_active_two(attr_sd)) 402 if (!sysfs_get_active(attr_sd))
403 return -ENODEV; 403 return -ENODEV;
404 404
405 error = -EACCES; 405 error = -EACCES;
@@ -426,11 +426,11 @@ static int open(struct inode * inode, struct file * file)
426 mutex_unlock(&sysfs_bin_lock); 426 mutex_unlock(&sysfs_bin_lock);
427 427
428 /* open succeeded, put active references */ 428 /* open succeeded, put active references */
429 sysfs_put_active_two(attr_sd); 429 sysfs_put_active(attr_sd);
430 return 0; 430 return 0;
431 431
432 err_out: 432 err_out:
433 sysfs_put_active_two(attr_sd); 433 sysfs_put_active(attr_sd);
434 kfree(bb); 434 kfree(bb);
435 return error; 435 return error;
436} 436}
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 699f371b9f12..590717861c7a 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -93,7 +93,7 @@ static void sysfs_unlink_sibling(struct sysfs_dirent *sd)
93 * RETURNS: 93 * RETURNS:
94 * Pointer to @sd on success, NULL on failure. 94 * Pointer to @sd on success, NULL on failure.
95 */ 95 */
96static struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd) 96struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
97{ 97{
98 if (unlikely(!sd)) 98 if (unlikely(!sd))
99 return NULL; 99 return NULL;
@@ -124,7 +124,7 @@ static struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
124 * Put an active reference to @sd. This function is noop if @sd 124 * Put an active reference to @sd. This function is noop if @sd
125 * is NULL. 125 * is NULL.
126 */ 126 */
127static void sysfs_put_active(struct sysfs_dirent *sd) 127void sysfs_put_active(struct sysfs_dirent *sd)
128{ 128{
129 struct completion *cmpl; 129 struct completion *cmpl;
130 int v; 130 int v;
@@ -145,45 +145,6 @@ static void sysfs_put_active(struct sysfs_dirent *sd)
145} 145}
146 146
147/** 147/**
148 * sysfs_get_active_two - get active references to sysfs_dirent and parent
149 * @sd: sysfs_dirent of interest
150 *
151 * Get active reference to @sd and its parent. Parent's active
152 * reference is grabbed first. This function is noop if @sd is
153 * NULL.
154 *
155 * RETURNS:
156 * Pointer to @sd on success, NULL on failure.
157 */
158struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd)
159{
160 if (sd) {
161 if (sd->s_parent && unlikely(!sysfs_get_active(sd->s_parent)))
162 return NULL;
163 if (unlikely(!sysfs_get_active(sd))) {
164 sysfs_put_active(sd->s_parent);
165 return NULL;
166 }
167 }
168 return sd;
169}
170
171/**
172 * sysfs_put_active_two - put active references to sysfs_dirent and parent
173 * @sd: sysfs_dirent of interest
174 *
175 * Put active references to @sd and its parent. This function is
176 * noop if @sd is NULL.
177 */
178void sysfs_put_active_two(struct sysfs_dirent *sd)
179{
180 if (sd) {
181 sysfs_put_active(sd);
182 sysfs_put_active(sd->s_parent);
183 }
184}
185
186/**
187 * sysfs_deactivate - deactivate sysfs_dirent 148 * sysfs_deactivate - deactivate sysfs_dirent
188 * @sd: sysfs_dirent to deactivate 149 * @sd: sysfs_dirent to deactivate
189 * 150 *
@@ -195,6 +156,10 @@ static void sysfs_deactivate(struct sysfs_dirent *sd)
195 int v; 156 int v;
196 157
197 BUG_ON(sd->s_sibling || !(sd->s_flags & SYSFS_FLAG_REMOVED)); 158 BUG_ON(sd->s_sibling || !(sd->s_flags & SYSFS_FLAG_REMOVED));
159
160 if (!(sysfs_type(sd) & SYSFS_ACTIVE_REF))
161 return;
162
198 sd->s_sibling = (void *)&wait; 163 sd->s_sibling = (void *)&wait;
199 164
200 rwsem_acquire(&sd->dep_map, 0, 0, _RET_IP_); 165 rwsem_acquire(&sd->dep_map, 0, 0, _RET_IP_);
@@ -354,7 +319,6 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
354 319
355 atomic_set(&sd->s_count, 1); 320 atomic_set(&sd->s_count, 1);
356 atomic_set(&sd->s_active, 0); 321 atomic_set(&sd->s_active, 0);
357 sysfs_dirent_init_lockdep(sd);
358 322
359 sd->s_name = name; 323 sd->s_name = name;
360 sd->s_mode = mode; 324 sd->s_mode = mode;
@@ -681,7 +645,7 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
681 } 645 }
682 646
683 /* attach dentry and inode */ 647 /* attach dentry and inode */
684 inode = sysfs_get_inode(sd); 648 inode = sysfs_get_inode(dir->i_sb, sd);
685 if (!inode) { 649 if (!inode) {
686 ret = ERR_PTR(-ENOMEM); 650 ret = ERR_PTR(-ENOMEM);
687 goto out_unlock; 651 goto out_unlock;
@@ -837,11 +801,46 @@ static inline unsigned char dt_type(struct sysfs_dirent *sd)
837 return (sd->s_mode >> 12) & 15; 801 return (sd->s_mode >> 12) & 15;
838} 802}
839 803
804static int sysfs_dir_release(struct inode *inode, struct file *filp)
805{
806 sysfs_put(filp->private_data);
807 return 0;
808}
809
810static struct sysfs_dirent *sysfs_dir_pos(struct sysfs_dirent *parent_sd,
811 ino_t ino, struct sysfs_dirent *pos)
812{
813 if (pos) {
814 int valid = !(pos->s_flags & SYSFS_FLAG_REMOVED) &&
815 pos->s_parent == parent_sd &&
816 ino == pos->s_ino;
817 sysfs_put(pos);
818 if (valid)
819 return pos;
820 }
821 pos = NULL;
822 if ((ino > 1) && (ino < INT_MAX)) {
823 pos = parent_sd->s_dir.children;
824 while (pos && (ino > pos->s_ino))
825 pos = pos->s_sibling;
826 }
827 return pos;
828}
829
830static struct sysfs_dirent *sysfs_dir_next_pos(struct sysfs_dirent *parent_sd,
831 ino_t ino, struct sysfs_dirent *pos)
832{
833 pos = sysfs_dir_pos(parent_sd, ino, pos);
834 if (pos)
835 pos = pos->s_sibling;
836 return pos;
837}
838
840static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) 839static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
841{ 840{
842 struct dentry *dentry = filp->f_path.dentry; 841 struct dentry *dentry = filp->f_path.dentry;
843 struct sysfs_dirent * parent_sd = dentry->d_fsdata; 842 struct sysfs_dirent * parent_sd = dentry->d_fsdata;
844 struct sysfs_dirent *pos; 843 struct sysfs_dirent *pos = filp->private_data;
845 ino_t ino; 844 ino_t ino;
846 845
847 if (filp->f_pos == 0) { 846 if (filp->f_pos == 0) {
@@ -857,29 +856,31 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
857 if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) == 0) 856 if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) == 0)
858 filp->f_pos++; 857 filp->f_pos++;
859 } 858 }
860 if ((filp->f_pos > 1) && (filp->f_pos < INT_MAX)) { 859 mutex_lock(&sysfs_mutex);
861 mutex_lock(&sysfs_mutex); 860 for (pos = sysfs_dir_pos(parent_sd, filp->f_pos, pos);
862 861 pos;
863 /* Skip the dentries we have already reported */ 862 pos = sysfs_dir_next_pos(parent_sd, filp->f_pos, pos)) {
864 pos = parent_sd->s_dir.children; 863 const char * name;
865 while (pos && (filp->f_pos > pos->s_ino)) 864 unsigned int type;
866 pos = pos->s_sibling; 865 int len, ret;
867 866
868 for ( ; pos; pos = pos->s_sibling) { 867 name = pos->s_name;
869 const char * name; 868 len = strlen(name);
870 int len; 869 ino = pos->s_ino;
871 870 type = dt_type(pos);
872 name = pos->s_name; 871 filp->f_pos = ino;
873 len = strlen(name); 872 filp->private_data = sysfs_get(pos);
874 filp->f_pos = ino = pos->s_ino;
875 873
876 if (filldir(dirent, name, len, filp->f_pos, ino,
877 dt_type(pos)) < 0)
878 break;
879 }
880 if (!pos)
881 filp->f_pos = INT_MAX;
882 mutex_unlock(&sysfs_mutex); 874 mutex_unlock(&sysfs_mutex);
875 ret = filldir(dirent, name, len, filp->f_pos, ino, type);
876 mutex_lock(&sysfs_mutex);
877 if (ret < 0)
878 break;
879 }
880 mutex_unlock(&sysfs_mutex);
881 if ((filp->f_pos > 1) && !pos) { /* EOF */
882 filp->f_pos = INT_MAX;
883 filp->private_data = NULL;
883 } 884 }
884 return 0; 885 return 0;
885} 886}
@@ -888,5 +889,6 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
888const struct file_operations sysfs_dir_operations = { 889const struct file_operations sysfs_dir_operations = {
889 .read = generic_read_dir, 890 .read = generic_read_dir,
890 .readdir = sysfs_readdir, 891 .readdir = sysfs_readdir,
892 .release = sysfs_dir_release,
891 .llseek = generic_file_llseek, 893 .llseek = generic_file_llseek,
892}; 894};
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index dc30d9e31683..e222b2582746 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -53,7 +53,7 @@ struct sysfs_buffer {
53 size_t count; 53 size_t count;
54 loff_t pos; 54 loff_t pos;
55 char * page; 55 char * page;
56 struct sysfs_ops * ops; 56 const struct sysfs_ops * ops;
57 struct mutex mutex; 57 struct mutex mutex;
58 int needs_read_fill; 58 int needs_read_fill;
59 int event; 59 int event;
@@ -75,7 +75,7 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer
75{ 75{
76 struct sysfs_dirent *attr_sd = dentry->d_fsdata; 76 struct sysfs_dirent *attr_sd = dentry->d_fsdata;
77 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; 77 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
78 struct sysfs_ops * ops = buffer->ops; 78 const struct sysfs_ops * ops = buffer->ops;
79 int ret = 0; 79 int ret = 0;
80 ssize_t count; 80 ssize_t count;
81 81
@@ -85,13 +85,13 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer
85 return -ENOMEM; 85 return -ENOMEM;
86 86
87 /* need attr_sd for attr and ops, its parent for kobj */ 87 /* need attr_sd for attr and ops, its parent for kobj */
88 if (!sysfs_get_active_two(attr_sd)) 88 if (!sysfs_get_active(attr_sd))
89 return -ENODEV; 89 return -ENODEV;
90 90
91 buffer->event = atomic_read(&attr_sd->s_attr.open->event); 91 buffer->event = atomic_read(&attr_sd->s_attr.open->event);
92 count = ops->show(kobj, attr_sd->s_attr.attr, buffer->page); 92 count = ops->show(kobj, attr_sd->s_attr.attr, buffer->page);
93 93
94 sysfs_put_active_two(attr_sd); 94 sysfs_put_active(attr_sd);
95 95
96 /* 96 /*
97 * The code works fine with PAGE_SIZE return but it's likely to 97 * The code works fine with PAGE_SIZE return but it's likely to
@@ -199,16 +199,16 @@ flush_write_buffer(struct dentry * dentry, struct sysfs_buffer * buffer, size_t
199{ 199{
200 struct sysfs_dirent *attr_sd = dentry->d_fsdata; 200 struct sysfs_dirent *attr_sd = dentry->d_fsdata;
201 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; 201 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
202 struct sysfs_ops * ops = buffer->ops; 202 const struct sysfs_ops * ops = buffer->ops;
203 int rc; 203 int rc;
204 204
205 /* need attr_sd for attr and ops, its parent for kobj */ 205 /* need attr_sd for attr and ops, its parent for kobj */
206 if (!sysfs_get_active_two(attr_sd)) 206 if (!sysfs_get_active(attr_sd))
207 return -ENODEV; 207 return -ENODEV;
208 208
209 rc = ops->store(kobj, attr_sd->s_attr.attr, buffer->page, count); 209 rc = ops->store(kobj, attr_sd->s_attr.attr, buffer->page, count);
210 210
211 sysfs_put_active_two(attr_sd); 211 sysfs_put_active(attr_sd);
212 212
213 return rc; 213 return rc;
214} 214}
@@ -335,7 +335,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
335 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; 335 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
336 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; 336 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
337 struct sysfs_buffer *buffer; 337 struct sysfs_buffer *buffer;
338 struct sysfs_ops *ops; 338 const struct sysfs_ops *ops;
339 int error = -EACCES; 339 int error = -EACCES;
340 char *p; 340 char *p;
341 341
@@ -344,7 +344,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
344 memmove(last_sysfs_file, p, strlen(p) + 1); 344 memmove(last_sysfs_file, p, strlen(p) + 1);
345 345
346 /* need attr_sd for attr and ops, its parent for kobj */ 346 /* need attr_sd for attr and ops, its parent for kobj */
347 if (!sysfs_get_active_two(attr_sd)) 347 if (!sysfs_get_active(attr_sd))
348 return -ENODEV; 348 return -ENODEV;
349 349
350 /* every kobject with an attribute needs a ktype assigned */ 350 /* every kobject with an attribute needs a ktype assigned */
@@ -393,13 +393,13 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
393 goto err_free; 393 goto err_free;
394 394
395 /* open succeeded, put active references */ 395 /* open succeeded, put active references */
396 sysfs_put_active_two(attr_sd); 396 sysfs_put_active(attr_sd);
397 return 0; 397 return 0;
398 398
399 err_free: 399 err_free:
400 kfree(buffer); 400 kfree(buffer);
401 err_out: 401 err_out:
402 sysfs_put_active_two(attr_sd); 402 sysfs_put_active(attr_sd);
403 return error; 403 return error;
404} 404}
405 405
@@ -437,12 +437,12 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
437 struct sysfs_open_dirent *od = attr_sd->s_attr.open; 437 struct sysfs_open_dirent *od = attr_sd->s_attr.open;
438 438
439 /* need parent for the kobj, grab both */ 439 /* need parent for the kobj, grab both */
440 if (!sysfs_get_active_two(attr_sd)) 440 if (!sysfs_get_active(attr_sd))
441 goto trigger; 441 goto trigger;
442 442
443 poll_wait(filp, &od->poll, wait); 443 poll_wait(filp, &od->poll, wait);
444 444
445 sysfs_put_active_two(attr_sd); 445 sysfs_put_active(attr_sd);
446 446
447 if (buffer->event != atomic_read(&od->event)) 447 if (buffer->event != atomic_read(&od->event))
448 goto trigger; 448 goto trigger;
@@ -509,6 +509,7 @@ int sysfs_add_file_mode(struct sysfs_dirent *dir_sd,
509 if (!sd) 509 if (!sd)
510 return -ENOMEM; 510 return -ENOMEM;
511 sd->s_attr.attr = (void *)attr; 511 sd->s_attr.attr = (void *)attr;
512 sysfs_dirent_init_lockdep(sd);
512 513
513 sysfs_addrm_start(&acxt, dir_sd); 514 sysfs_addrm_start(&acxt, dir_sd);
514 rc = sysfs_add_one(&acxt, sd); 515 rc = sysfs_add_one(&acxt, sd);
@@ -542,6 +543,18 @@ int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)
542 543
543} 544}
544 545
546int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr)
547{
548 int err = 0;
549 int i;
550
551 for (i = 0; ptr[i] && !err; i++)
552 err = sysfs_create_file(kobj, ptr[i]);
553 if (err)
554 while (--i >= 0)
555 sysfs_remove_file(kobj, ptr[i]);
556 return err;
557}
545 558
546/** 559/**
547 * sysfs_add_file_to_group - add an attribute file to a pre-existing group. 560 * sysfs_add_file_to_group - add an attribute file to a pre-existing group.
@@ -614,6 +627,12 @@ void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
614 sysfs_hash_and_remove(kobj->sd, attr->name); 627 sysfs_hash_and_remove(kobj->sd, attr->name);
615} 628}
616 629
630void sysfs_remove_files(struct kobject * kobj, const struct attribute **ptr)
631{
632 int i;
633 for (i = 0; ptr[i]; i++)
634 sysfs_remove_file(kobj, ptr[i]);
635}
617 636
618/** 637/**
619 * sysfs_remove_file_from_group - remove an attribute file from a group. 638 * sysfs_remove_file_from_group - remove an attribute file from a group.
@@ -732,3 +751,5 @@ EXPORT_SYMBOL_GPL(sysfs_schedule_callback);
732 751
733EXPORT_SYMBOL_GPL(sysfs_create_file); 752EXPORT_SYMBOL_GPL(sysfs_create_file);
734EXPORT_SYMBOL_GPL(sysfs_remove_file); 753EXPORT_SYMBOL_GPL(sysfs_remove_file);
754EXPORT_SYMBOL_GPL(sysfs_remove_files);
755EXPORT_SYMBOL_GPL(sysfs_create_files);
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 6a06a1d1ea7b..082daaecac1b 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -111,20 +111,20 @@ int sysfs_setattr(struct dentry *dentry, struct iattr *iattr)
111 if (!sd) 111 if (!sd)
112 return -EINVAL; 112 return -EINVAL;
113 113
114 mutex_lock(&sysfs_mutex);
114 error = inode_change_ok(inode, iattr); 115 error = inode_change_ok(inode, iattr);
115 if (error) 116 if (error)
116 return error; 117 goto out;
117 118
118 iattr->ia_valid &= ~ATTR_SIZE; /* ignore size changes */ 119 iattr->ia_valid &= ~ATTR_SIZE; /* ignore size changes */
119 120
120 error = inode_setattr(inode, iattr); 121 error = inode_setattr(inode, iattr);
121 if (error) 122 if (error)
122 return error; 123 goto out;
123 124
124 mutex_lock(&sysfs_mutex);
125 error = sysfs_sd_setattr(sd, iattr); 125 error = sysfs_sd_setattr(sd, iattr);
126out:
126 mutex_unlock(&sysfs_mutex); 127 mutex_unlock(&sysfs_mutex);
127
128 return error; 128 return error;
129} 129}
130 130
@@ -283,6 +283,7 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
283 283
284/** 284/**
285 * sysfs_get_inode - get inode for sysfs_dirent 285 * sysfs_get_inode - get inode for sysfs_dirent
286 * @sb: super block
286 * @sd: sysfs_dirent to allocate inode for 287 * @sd: sysfs_dirent to allocate inode for
287 * 288 *
288 * Get inode for @sd. If such inode doesn't exist, a new inode 289 * Get inode for @sd. If such inode doesn't exist, a new inode
@@ -295,11 +296,11 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
295 * RETURNS: 296 * RETURNS:
296 * Pointer to allocated inode on success, NULL on failure. 297 * Pointer to allocated inode on success, NULL on failure.
297 */ 298 */
298struct inode * sysfs_get_inode(struct sysfs_dirent *sd) 299struct inode * sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd)
299{ 300{
300 struct inode *inode; 301 struct inode *inode;
301 302
302 inode = iget_locked(sysfs_sb, sd->s_ino); 303 inode = iget_locked(sb, sd->s_ino);
303 if (inode && (inode->i_state & I_NEW)) 304 if (inode && (inode->i_state & I_NEW))
304 sysfs_init_inode(sd, inode); 305 sysfs_init_inode(sd, inode);
305 306
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index 49749955ccaf..0cb10884a2fc 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -23,7 +23,6 @@
23 23
24 24
25static struct vfsmount *sysfs_mount; 25static struct vfsmount *sysfs_mount;
26struct super_block * sysfs_sb = NULL;
27struct kmem_cache *sysfs_dir_cachep; 26struct kmem_cache *sysfs_dir_cachep;
28 27
29static const struct super_operations sysfs_ops = { 28static const struct super_operations sysfs_ops = {
@@ -50,11 +49,10 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
50 sb->s_magic = SYSFS_MAGIC; 49 sb->s_magic = SYSFS_MAGIC;
51 sb->s_op = &sysfs_ops; 50 sb->s_op = &sysfs_ops;
52 sb->s_time_gran = 1; 51 sb->s_time_gran = 1;
53 sysfs_sb = sb;
54 52
55 /* get root inode, initialize and unlock it */ 53 /* get root inode, initialize and unlock it */
56 mutex_lock(&sysfs_mutex); 54 mutex_lock(&sysfs_mutex);
57 inode = sysfs_get_inode(&sysfs_root); 55 inode = sysfs_get_inode(sb, &sysfs_root);
58 mutex_unlock(&sysfs_mutex); 56 mutex_unlock(&sysfs_mutex);
59 if (!inode) { 57 if (!inode) {
60 pr_debug("sysfs: could not get root inode\n"); 58 pr_debug("sysfs: could not get root inode\n");
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index c5eff49fa41b..1b9a3a1e8a17 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -123,6 +123,44 @@ void sysfs_remove_link(struct kobject * kobj, const char * name)
123 sysfs_hash_and_remove(parent_sd, name); 123 sysfs_hash_and_remove(parent_sd, name);
124} 124}
125 125
126/**
127 * sysfs_rename_link - rename symlink in object's directory.
128 * @kobj: object we're acting for.
129 * @targ: object we're pointing to.
130 * @old: previous name of the symlink.
131 * @new: new name of the symlink.
132 *
133 * A helper function for the common rename symlink idiom.
134 */
135int sysfs_rename_link(struct kobject *kobj, struct kobject *targ,
136 const char *old, const char *new)
137{
138 struct sysfs_dirent *parent_sd, *sd = NULL;
139 int result;
140
141 if (!kobj)
142 parent_sd = &sysfs_root;
143 else
144 parent_sd = kobj->sd;
145
146 result = -ENOENT;
147 sd = sysfs_get_dirent(parent_sd, old);
148 if (!sd)
149 goto out;
150
151 result = -EINVAL;
152 if (sysfs_type(sd) != SYSFS_KOBJ_LINK)
153 goto out;
154 if (sd->s_symlink.target_sd->s_dir.kobj != targ)
155 goto out;
156
157 result = sysfs_rename(sd, parent_sd, new);
158
159out:
160 sysfs_put(sd);
161 return result;
162}
163
126static int sysfs_get_target_path(struct sysfs_dirent *parent_sd, 164static int sysfs_get_target_path(struct sysfs_dirent *parent_sd,
127 struct sysfs_dirent *target_sd, char *path) 165 struct sysfs_dirent *target_sd, char *path)
128{ 166{
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index cdd9377a6e06..30f5a44fb5d3 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -66,8 +66,8 @@ struct sysfs_dirent {
66 }; 66 };
67 67
68 unsigned int s_flags; 68 unsigned int s_flags;
69 unsigned short s_mode;
69 ino_t s_ino; 70 ino_t s_ino;
70 umode_t s_mode;
71 struct sysfs_inode_attrs *s_iattr; 71 struct sysfs_inode_attrs *s_iattr;
72}; 72};
73 73
@@ -79,6 +79,7 @@ struct sysfs_dirent {
79#define SYSFS_KOBJ_BIN_ATTR 0x0004 79#define SYSFS_KOBJ_BIN_ATTR 0x0004
80#define SYSFS_KOBJ_LINK 0x0008 80#define SYSFS_KOBJ_LINK 0x0008
81#define SYSFS_COPY_NAME (SYSFS_DIR | SYSFS_KOBJ_LINK) 81#define SYSFS_COPY_NAME (SYSFS_DIR | SYSFS_KOBJ_LINK)
82#define SYSFS_ACTIVE_REF (SYSFS_KOBJ_ATTR | SYSFS_KOBJ_BIN_ATTR)
82 83
83#define SYSFS_FLAG_MASK ~SYSFS_TYPE_MASK 84#define SYSFS_FLAG_MASK ~SYSFS_TYPE_MASK
84#define SYSFS_FLAG_REMOVED 0x0200 85#define SYSFS_FLAG_REMOVED 0x0200
@@ -91,9 +92,12 @@ static inline unsigned int sysfs_type(struct sysfs_dirent *sd)
91#ifdef CONFIG_DEBUG_LOCK_ALLOC 92#ifdef CONFIG_DEBUG_LOCK_ALLOC
92#define sysfs_dirent_init_lockdep(sd) \ 93#define sysfs_dirent_init_lockdep(sd) \
93do { \ 94do { \
94 static struct lock_class_key __key; \ 95 struct attribute *attr = sd->s_attr.attr; \
96 struct lock_class_key *key = attr->key; \
97 if (!key) \
98 key = &attr->skey; \
95 \ 99 \
96 lockdep_init_map(&sd->dep_map, "s_active", &__key, 0); \ 100 lockdep_init_map(&sd->dep_map, "s_active", key, 0); \
97} while(0) 101} while(0)
98#else 102#else
99#define sysfs_dirent_init_lockdep(sd) do {} while(0) 103#define sysfs_dirent_init_lockdep(sd) do {} while(0)
@@ -111,7 +115,6 @@ struct sysfs_addrm_cxt {
111 * mount.c 115 * mount.c
112 */ 116 */
113extern struct sysfs_dirent sysfs_root; 117extern struct sysfs_dirent sysfs_root;
114extern struct super_block *sysfs_sb;
115extern struct kmem_cache *sysfs_dir_cachep; 118extern struct kmem_cache *sysfs_dir_cachep;
116 119
117/* 120/*
@@ -124,8 +127,8 @@ extern const struct file_operations sysfs_dir_operations;
124extern const struct inode_operations sysfs_dir_inode_operations; 127extern const struct inode_operations sysfs_dir_inode_operations;
125 128
126struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd); 129struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd);
127struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd); 130struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd);
128void sysfs_put_active_two(struct sysfs_dirent *sd); 131void sysfs_put_active(struct sysfs_dirent *sd);
129void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, 132void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
130 struct sysfs_dirent *parent_sd); 133 struct sysfs_dirent *parent_sd);
131int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); 134int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);
@@ -168,7 +171,7 @@ static inline void __sysfs_put(struct sysfs_dirent *sd)
168/* 171/*
169 * inode.c 172 * inode.c
170 */ 173 */
171struct inode *sysfs_get_inode(struct sysfs_dirent *sd); 174struct inode *sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd);
172void sysfs_delete_inode(struct inode *inode); 175void sysfs_delete_inode(struct inode *inode);
173int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr); 176int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr);
174int sysfs_permission(struct inode *inode, int mask); 177int sysfs_permission(struct inode *inode, int mask);