aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysfs/dir.c')
-rw-r--r--fs/sysfs/dir.c532
1 files changed, 201 insertions, 331 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index e0201837d244..590717861c7a 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -25,7 +25,6 @@
25#include "sysfs.h" 25#include "sysfs.h"
26 26
27DEFINE_MUTEX(sysfs_mutex); 27DEFINE_MUTEX(sysfs_mutex);
28DEFINE_MUTEX(sysfs_rename_mutex);
29DEFINE_SPINLOCK(sysfs_assoc_lock); 28DEFINE_SPINLOCK(sysfs_assoc_lock);
30 29
31static DEFINE_SPINLOCK(sysfs_ino_lock); 30static DEFINE_SPINLOCK(sysfs_ino_lock);
@@ -85,46 +84,6 @@ static void sysfs_unlink_sibling(struct sysfs_dirent *sd)
85} 84}
86 85
87/** 86/**
88 * sysfs_get_dentry - get dentry for the given sysfs_dirent
89 * @sd: sysfs_dirent of interest
90 *
91 * Get dentry for @sd. Dentry is looked up if currently not
92 * present. This function descends from the root looking up
93 * dentry for each step.
94 *
95 * LOCKING:
96 * mutex_lock(sysfs_rename_mutex)
97 *
98 * RETURNS:
99 * Pointer to found dentry on success, ERR_PTR() value on error.
100 */
101struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd)
102{
103 struct dentry *dentry = dget(sysfs_sb->s_root);
104
105 while (dentry->d_fsdata != sd) {
106 struct sysfs_dirent *cur;
107 struct dentry *parent;
108
109 /* find the first ancestor which hasn't been looked up */
110 cur = sd;
111 while (cur->s_parent != dentry->d_fsdata)
112 cur = cur->s_parent;
113
114 /* look it up */
115 parent = dentry;
116 mutex_lock(&parent->d_inode->i_mutex);
117 dentry = lookup_one_noperm(cur->s_name, parent);
118 mutex_unlock(&parent->d_inode->i_mutex);
119 dput(parent);
120
121 if (IS_ERR(dentry))
122 break;
123 }
124 return dentry;
125}
126
127/**
128 * sysfs_get_active - get an active reference to sysfs_dirent 87 * sysfs_get_active - get an active reference to sysfs_dirent
129 * @sd: sysfs_dirent to get an active reference to 88 * @sd: sysfs_dirent to get an active reference to
130 * 89 *
@@ -134,7 +93,7 @@ struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd)
134 * RETURNS: 93 * RETURNS:
135 * Pointer to @sd on success, NULL on failure. 94 * Pointer to @sd on success, NULL on failure.
136 */ 95 */
137static struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd) 96struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
138{ 97{
139 if (unlikely(!sd)) 98 if (unlikely(!sd))
140 return NULL; 99 return NULL;
@@ -147,8 +106,10 @@ static struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
147 return NULL; 106 return NULL;
148 107
149 t = atomic_cmpxchg(&sd->s_active, v, v + 1); 108 t = atomic_cmpxchg(&sd->s_active, v, v + 1);
150 if (likely(t == v)) 109 if (likely(t == v)) {
110 rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_);
151 return sd; 111 return sd;
112 }
152 if (t < 0) 113 if (t < 0)
153 return NULL; 114 return NULL;
154 115
@@ -163,7 +124,7 @@ static struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
163 * 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
164 * is NULL. 125 * is NULL.
165 */ 126 */
166static void sysfs_put_active(struct sysfs_dirent *sd) 127void sysfs_put_active(struct sysfs_dirent *sd)
167{ 128{
168 struct completion *cmpl; 129 struct completion *cmpl;
169 int v; 130 int v;
@@ -171,6 +132,7 @@ static void sysfs_put_active(struct sysfs_dirent *sd)
171 if (unlikely(!sd)) 132 if (unlikely(!sd))
172 return; 133 return;
173 134
135 rwsem_release(&sd->dep_map, 1, _RET_IP_);
174 v = atomic_dec_return(&sd->s_active); 136 v = atomic_dec_return(&sd->s_active);
175 if (likely(v != SD_DEACTIVATED_BIAS)) 137 if (likely(v != SD_DEACTIVATED_BIAS))
176 return; 138 return;
@@ -183,45 +145,6 @@ static void sysfs_put_active(struct sysfs_dirent *sd)
183} 145}
184 146
185/** 147/**
186 * sysfs_get_active_two - get active references to sysfs_dirent and parent
187 * @sd: sysfs_dirent of interest
188 *
189 * Get active reference to @sd and its parent. Parent's active
190 * reference is grabbed first. This function is noop if @sd is
191 * NULL.
192 *
193 * RETURNS:
194 * Pointer to @sd on success, NULL on failure.
195 */
196struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd)
197{
198 if (sd) {
199 if (sd->s_parent && unlikely(!sysfs_get_active(sd->s_parent)))
200 return NULL;
201 if (unlikely(!sysfs_get_active(sd))) {
202 sysfs_put_active(sd->s_parent);
203 return NULL;
204 }
205 }
206 return sd;
207}
208
209/**
210 * sysfs_put_active_two - put active references to sysfs_dirent and parent
211 * @sd: sysfs_dirent of interest
212 *
213 * Put active references to @sd and its parent. This function is
214 * noop if @sd is NULL.
215 */
216void sysfs_put_active_two(struct sysfs_dirent *sd)
217{
218 if (sd) {
219 sysfs_put_active(sd);
220 sysfs_put_active(sd->s_parent);
221 }
222}
223
224/**
225 * sysfs_deactivate - deactivate sysfs_dirent 148 * sysfs_deactivate - deactivate sysfs_dirent
226 * @sd: sysfs_dirent to deactivate 149 * @sd: sysfs_dirent to deactivate
227 * 150 *
@@ -233,17 +156,27 @@ static void sysfs_deactivate(struct sysfs_dirent *sd)
233 int v; 156 int v;
234 157
235 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
236 sd->s_sibling = (void *)&wait; 163 sd->s_sibling = (void *)&wait;
237 164
165 rwsem_acquire(&sd->dep_map, 0, 0, _RET_IP_);
238 /* atomic_add_return() is a mb(), put_active() will always see 166 /* atomic_add_return() is a mb(), put_active() will always see
239 * the updated sd->s_sibling. 167 * the updated sd->s_sibling.
240 */ 168 */
241 v = atomic_add_return(SD_DEACTIVATED_BIAS, &sd->s_active); 169 v = atomic_add_return(SD_DEACTIVATED_BIAS, &sd->s_active);
242 170
243 if (v != SD_DEACTIVATED_BIAS) 171 if (v != SD_DEACTIVATED_BIAS) {
172 lock_contended(&sd->dep_map, _RET_IP_);
244 wait_for_completion(&wait); 173 wait_for_completion(&wait);
174 }
245 175
246 sd->s_sibling = NULL; 176 sd->s_sibling = NULL;
177
178 lock_acquired(&sd->dep_map, _RET_IP_);
179 rwsem_release(&sd->dep_map, 1, _RET_IP_);
247} 180}
248 181
249static int sysfs_alloc_ino(ino_t *pino) 182static int sysfs_alloc_ino(ino_t *pino)
@@ -298,7 +231,61 @@ void release_sysfs_dirent(struct sysfs_dirent * sd)
298 goto repeat; 231 goto repeat;
299} 232}
300 233
301static void sysfs_d_iput(struct dentry * dentry, struct inode * inode) 234static int sysfs_dentry_delete(struct dentry *dentry)
235{
236 struct sysfs_dirent *sd = dentry->d_fsdata;
237 return !!(sd->s_flags & SYSFS_FLAG_REMOVED);
238}
239
240static int sysfs_dentry_revalidate(struct dentry *dentry, struct nameidata *nd)
241{
242 struct sysfs_dirent *sd = dentry->d_fsdata;
243 int is_dir;
244
245 mutex_lock(&sysfs_mutex);
246
247 /* The sysfs dirent has been deleted */
248 if (sd->s_flags & SYSFS_FLAG_REMOVED)
249 goto out_bad;
250
251 /* The sysfs dirent has been moved? */
252 if (dentry->d_parent->d_fsdata != sd->s_parent)
253 goto out_bad;
254
255 /* The sysfs dirent has been renamed */
256 if (strcmp(dentry->d_name.name, sd->s_name) != 0)
257 goto out_bad;
258
259 mutex_unlock(&sysfs_mutex);
260out_valid:
261 return 1;
262out_bad:
263 /* Remove the dentry from the dcache hashes.
264 * If this is a deleted dentry we use d_drop instead of d_delete
265 * so sysfs doesn't need to cope with negative dentries.
266 *
267 * If this is a dentry that has simply been renamed we
268 * use d_drop to remove it from the dcache lookup on its
269 * old parent. If this dentry persists later when a lookup
270 * is performed at its new name the dentry will be readded
271 * to the dcache hashes.
272 */
273 is_dir = (sysfs_type(sd) == SYSFS_DIR);
274 mutex_unlock(&sysfs_mutex);
275 if (is_dir) {
276 /* If we have submounts we must allow the vfs caches
277 * to lie about the state of the filesystem to prevent
278 * leaks and other nasty things.
279 */
280 if (have_submounts(dentry))
281 goto out_valid;
282 shrink_dcache_parent(dentry);
283 }
284 d_drop(dentry);
285 return 0;
286}
287
288static void sysfs_dentry_iput(struct dentry *dentry, struct inode *inode)
302{ 289{
303 struct sysfs_dirent * sd = dentry->d_fsdata; 290 struct sysfs_dirent * sd = dentry->d_fsdata;
304 291
@@ -307,7 +294,9 @@ static void sysfs_d_iput(struct dentry * dentry, struct inode * inode)
307} 294}
308 295
309static const struct dentry_operations sysfs_dentry_ops = { 296static const struct dentry_operations sysfs_dentry_ops = {
310 .d_iput = sysfs_d_iput, 297 .d_revalidate = sysfs_dentry_revalidate,
298 .d_delete = sysfs_dentry_delete,
299 .d_iput = sysfs_dentry_iput,
311}; 300};
312 301
313struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type) 302struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
@@ -344,12 +333,6 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
344 return NULL; 333 return NULL;
345} 334}
346 335
347static int sysfs_ilookup_test(struct inode *inode, void *arg)
348{
349 struct sysfs_dirent *sd = arg;
350 return inode->i_ino == sd->s_ino;
351}
352
353/** 336/**
354 * sysfs_addrm_start - prepare for sysfs_dirent add/remove 337 * sysfs_addrm_start - prepare for sysfs_dirent add/remove
355 * @acxt: pointer to sysfs_addrm_cxt to be used 338 * @acxt: pointer to sysfs_addrm_cxt to be used
@@ -357,47 +340,20 @@ static int sysfs_ilookup_test(struct inode *inode, void *arg)
357 * 340 *
358 * This function is called when the caller is about to add or 341 * This function is called when the caller is about to add or
359 * remove sysfs_dirent under @parent_sd. This function acquires 342 * remove sysfs_dirent under @parent_sd. This function acquires
360 * sysfs_mutex, grabs inode for @parent_sd if available and lock 343 * sysfs_mutex. @acxt is used to keep and pass context to
361 * i_mutex of it. @acxt is used to keep and pass context to
362 * other addrm functions. 344 * other addrm functions.
363 * 345 *
364 * LOCKING: 346 * LOCKING:
365 * Kernel thread context (may sleep). sysfs_mutex is locked on 347 * Kernel thread context (may sleep). sysfs_mutex is locked on
366 * return. i_mutex of parent inode is locked on return if 348 * return.
367 * available.
368 */ 349 */
369void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, 350void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
370 struct sysfs_dirent *parent_sd) 351 struct sysfs_dirent *parent_sd)
371{ 352{
372 struct inode *inode;
373
374 memset(acxt, 0, sizeof(*acxt)); 353 memset(acxt, 0, sizeof(*acxt));
375 acxt->parent_sd = parent_sd; 354 acxt->parent_sd = parent_sd;
376 355
377 /* Lookup parent inode. inode initialization is protected by
378 * sysfs_mutex, so inode existence can be determined by
379 * looking up inode while holding sysfs_mutex.
380 */
381 mutex_lock(&sysfs_mutex); 356 mutex_lock(&sysfs_mutex);
382
383 inode = ilookup5(sysfs_sb, parent_sd->s_ino, sysfs_ilookup_test,
384 parent_sd);
385 if (inode) {
386 WARN_ON(inode->i_state & I_NEW);
387
388 /* parent inode available */
389 acxt->parent_inode = inode;
390
391 /* sysfs_mutex is below i_mutex in lock hierarchy.
392 * First, trylock i_mutex. If fails, unlock
393 * sysfs_mutex and lock them in order.
394 */
395 if (!mutex_trylock(&inode->i_mutex)) {
396 mutex_unlock(&sysfs_mutex);
397 mutex_lock(&inode->i_mutex);
398 mutex_lock(&sysfs_mutex);
399 }
400 }
401} 357}
402 358
403/** 359/**
@@ -422,18 +378,22 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
422 */ 378 */
423int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) 379int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
424{ 380{
381 struct sysfs_inode_attrs *ps_iattr;
382
425 if (sysfs_find_dirent(acxt->parent_sd, sd->s_name)) 383 if (sysfs_find_dirent(acxt->parent_sd, sd->s_name))
426 return -EEXIST; 384 return -EEXIST;
427 385
428 sd->s_parent = sysfs_get(acxt->parent_sd); 386 sd->s_parent = sysfs_get(acxt->parent_sd);
429 387
430 if (sysfs_type(sd) == SYSFS_DIR && acxt->parent_inode)
431 inc_nlink(acxt->parent_inode);
432
433 acxt->cnt++;
434
435 sysfs_link_sibling(sd); 388 sysfs_link_sibling(sd);
436 389
390 /* Update timestamps on the parent */
391 ps_iattr = acxt->parent_sd->s_iattr;
392 if (ps_iattr) {
393 struct iattr *ps_iattrs = &ps_iattr->ia_iattr;
394 ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME;
395 }
396
437 return 0; 397 return 0;
438} 398}
439 399
@@ -512,70 +472,22 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
512 */ 472 */
513void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) 473void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
514{ 474{
475 struct sysfs_inode_attrs *ps_iattr;
476
515 BUG_ON(sd->s_flags & SYSFS_FLAG_REMOVED); 477 BUG_ON(sd->s_flags & SYSFS_FLAG_REMOVED);
516 478
517 sysfs_unlink_sibling(sd); 479 sysfs_unlink_sibling(sd);
518 480
481 /* Update timestamps on the parent */
482 ps_iattr = acxt->parent_sd->s_iattr;
483 if (ps_iattr) {
484 struct iattr *ps_iattrs = &ps_iattr->ia_iattr;
485 ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME;
486 }
487
519 sd->s_flags |= SYSFS_FLAG_REMOVED; 488 sd->s_flags |= SYSFS_FLAG_REMOVED;
520 sd->s_sibling = acxt->removed; 489 sd->s_sibling = acxt->removed;
521 acxt->removed = sd; 490 acxt->removed = sd;
522
523 if (sysfs_type(sd) == SYSFS_DIR && acxt->parent_inode)
524 drop_nlink(acxt->parent_inode);
525
526 acxt->cnt++;
527}
528
529/**
530 * sysfs_drop_dentry - drop dentry for the specified sysfs_dirent
531 * @sd: target sysfs_dirent
532 *
533 * Drop dentry for @sd. @sd must have been unlinked from its
534 * parent on entry to this function such that it can't be looked
535 * up anymore.
536 */
537static void sysfs_drop_dentry(struct sysfs_dirent *sd)
538{
539 struct inode *inode;
540 struct dentry *dentry;
541
542 inode = ilookup(sysfs_sb, sd->s_ino);
543 if (!inode)
544 return;
545
546 /* Drop any existing dentries associated with sd.
547 *
548 * For the dentry to be properly freed we need to grab a
549 * reference to the dentry under the dcache lock, unhash it,
550 * and then put it. The playing with the dentry count allows
551 * dput to immediately free the dentry if it is not in use.
552 */
553repeat:
554 spin_lock(&dcache_lock);
555 list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
556 if (d_unhashed(dentry))
557 continue;
558 dget_locked(dentry);
559 spin_lock(&dentry->d_lock);
560 __d_drop(dentry);
561 spin_unlock(&dentry->d_lock);
562 spin_unlock(&dcache_lock);
563 dput(dentry);
564 goto repeat;
565 }
566 spin_unlock(&dcache_lock);
567
568 /* adjust nlink and update timestamp */
569 mutex_lock(&inode->i_mutex);
570
571 inode->i_ctime = CURRENT_TIME;
572 drop_nlink(inode);
573 if (sysfs_type(sd) == SYSFS_DIR)
574 drop_nlink(inode);
575
576 mutex_unlock(&inode->i_mutex);
577
578 iput(inode);
579} 491}
580 492
581/** 493/**
@@ -584,25 +496,15 @@ repeat:
584 * 496 *
585 * Finish up sysfs_dirent add/remove. Resources acquired by 497 * Finish up sysfs_dirent add/remove. Resources acquired by
586 * sysfs_addrm_start() are released and removed sysfs_dirents are 498 * sysfs_addrm_start() are released and removed sysfs_dirents are
587 * cleaned up. Timestamps on the parent inode are updated. 499 * cleaned up.
588 * 500 *
589 * LOCKING: 501 * LOCKING:
590 * All mutexes acquired by sysfs_addrm_start() are released. 502 * sysfs_mutex is released.
591 */ 503 */
592void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt) 504void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
593{ 505{
594 /* release resources acquired by sysfs_addrm_start() */ 506 /* release resources acquired by sysfs_addrm_start() */
595 mutex_unlock(&sysfs_mutex); 507 mutex_unlock(&sysfs_mutex);
596 if (acxt->parent_inode) {
597 struct inode *inode = acxt->parent_inode;
598
599 /* if added/removed, update timestamps on the parent */
600 if (acxt->cnt)
601 inode->i_ctime = inode->i_mtime = CURRENT_TIME;
602
603 mutex_unlock(&inode->i_mutex);
604 iput(inode);
605 }
606 508
607 /* kill removed sysfs_dirents */ 509 /* kill removed sysfs_dirents */
608 while (acxt->removed) { 510 while (acxt->removed) {
@@ -611,7 +513,6 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
611 acxt->removed = sd->s_sibling; 513 acxt->removed = sd->s_sibling;
612 sd->s_sibling = NULL; 514 sd->s_sibling = NULL;
613 515
614 sysfs_drop_dentry(sd);
615 sysfs_deactivate(sd); 516 sysfs_deactivate(sd);
616 unmap_bin_file(sd); 517 unmap_bin_file(sd);
617 sysfs_put(sd); 518 sysfs_put(sd);
@@ -744,17 +645,22 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
744 } 645 }
745 646
746 /* attach dentry and inode */ 647 /* attach dentry and inode */
747 inode = sysfs_get_inode(sd); 648 inode = sysfs_get_inode(dir->i_sb, sd);
748 if (!inode) { 649 if (!inode) {
749 ret = ERR_PTR(-ENOMEM); 650 ret = ERR_PTR(-ENOMEM);
750 goto out_unlock; 651 goto out_unlock;
751 } 652 }
752 653
753 /* instantiate and hash dentry */ 654 /* instantiate and hash dentry */
754 dentry->d_op = &sysfs_dentry_ops; 655 ret = d_find_alias(inode);
755 dentry->d_fsdata = sysfs_get(sd); 656 if (!ret) {
756 d_instantiate(dentry, inode); 657 dentry->d_op = &sysfs_dentry_ops;
757 d_rehash(dentry); 658 dentry->d_fsdata = sysfs_get(sd);
659 d_add(dentry, inode);
660 } else {
661 d_move(ret, dentry);
662 iput(inode);
663 }
758 664
759 out_unlock: 665 out_unlock:
760 mutex_unlock(&sysfs_mutex); 666 mutex_unlock(&sysfs_mutex);
@@ -763,7 +669,9 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
763 669
764const struct inode_operations sysfs_dir_inode_operations = { 670const struct inode_operations sysfs_dir_inode_operations = {
765 .lookup = sysfs_lookup, 671 .lookup = sysfs_lookup,
672 .permission = sysfs_permission,
766 .setattr = sysfs_setattr, 673 .setattr = sysfs_setattr,
674 .getattr = sysfs_getattr,
767 .setxattr = sysfs_setxattr, 675 .setxattr = sysfs_setxattr,
768}; 676};
769 677
@@ -826,141 +734,65 @@ void sysfs_remove_dir(struct kobject * kobj)
826 __sysfs_remove_dir(sd); 734 __sysfs_remove_dir(sd);
827} 735}
828 736
829int sysfs_rename_dir(struct kobject * kobj, const char *new_name) 737int sysfs_rename(struct sysfs_dirent *sd,
738 struct sysfs_dirent *new_parent_sd, const char *new_name)
830{ 739{
831 struct sysfs_dirent *sd = kobj->sd;
832 struct dentry *parent = NULL;
833 struct dentry *old_dentry = NULL, *new_dentry = NULL;
834 const char *dup_name = NULL; 740 const char *dup_name = NULL;
835 int error; 741 int error;
836 742
837 mutex_lock(&sysfs_rename_mutex); 743 mutex_lock(&sysfs_mutex);
838 744
839 error = 0; 745 error = 0;
840 if (strcmp(sd->s_name, new_name) == 0) 746 if ((sd->s_parent == new_parent_sd) &&
747 (strcmp(sd->s_name, new_name) == 0))
841 goto out; /* nothing to rename */ 748 goto out; /* nothing to rename */
842 749
843 /* get the original dentry */
844 old_dentry = sysfs_get_dentry(sd);
845 if (IS_ERR(old_dentry)) {
846 error = PTR_ERR(old_dentry);
847 old_dentry = NULL;
848 goto out;
849 }
850
851 parent = old_dentry->d_parent;
852
853 /* lock parent and get dentry for new name */
854 mutex_lock(&parent->d_inode->i_mutex);
855 mutex_lock(&sysfs_mutex);
856
857 error = -EEXIST; 750 error = -EEXIST;
858 if (sysfs_find_dirent(sd->s_parent, new_name)) 751 if (sysfs_find_dirent(new_parent_sd, new_name))
859 goto out_unlock; 752 goto out;
860
861 error = -ENOMEM;
862 new_dentry = d_alloc_name(parent, new_name);
863 if (!new_dentry)
864 goto out_unlock;
865 753
866 /* rename sysfs_dirent */ 754 /* rename sysfs_dirent */
867 error = -ENOMEM; 755 if (strcmp(sd->s_name, new_name) != 0) {
868 new_name = dup_name = kstrdup(new_name, GFP_KERNEL); 756 error = -ENOMEM;
869 if (!new_name) 757 new_name = dup_name = kstrdup(new_name, GFP_KERNEL);
870 goto out_unlock; 758 if (!new_name)
871 759 goto out;
872 dup_name = sd->s_name; 760
873 sd->s_name = new_name; 761 dup_name = sd->s_name;
762 sd->s_name = new_name;
763 }
874 764
875 /* rename */ 765 /* Remove from old parent's list and insert into new parent's list. */
876 d_add(new_dentry, NULL); 766 if (sd->s_parent != new_parent_sd) {
877 d_move(old_dentry, new_dentry); 767 sysfs_unlink_sibling(sd);
768 sysfs_get(new_parent_sd);
769 sysfs_put(sd->s_parent);
770 sd->s_parent = new_parent_sd;
771 sysfs_link_sibling(sd);
772 }
878 773
879 error = 0; 774 error = 0;
880 out_unlock: 775 out:
881 mutex_unlock(&sysfs_mutex); 776 mutex_unlock(&sysfs_mutex);
882 mutex_unlock(&parent->d_inode->i_mutex);
883 kfree(dup_name); 777 kfree(dup_name);
884 dput(old_dentry);
885 dput(new_dentry);
886 out:
887 mutex_unlock(&sysfs_rename_mutex);
888 return error; 778 return error;
889} 779}
890 780
781int sysfs_rename_dir(struct kobject *kobj, const char *new_name)
782{
783 return sysfs_rename(kobj->sd, kobj->sd->s_parent, new_name);
784}
785
891int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj) 786int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj)
892{ 787{
893 struct sysfs_dirent *sd = kobj->sd; 788 struct sysfs_dirent *sd = kobj->sd;
894 struct sysfs_dirent *new_parent_sd; 789 struct sysfs_dirent *new_parent_sd;
895 struct dentry *old_parent, *new_parent = NULL;
896 struct dentry *old_dentry = NULL, *new_dentry = NULL;
897 int error;
898 790
899 mutex_lock(&sysfs_rename_mutex);
900 BUG_ON(!sd->s_parent); 791 BUG_ON(!sd->s_parent);
901 new_parent_sd = (new_parent_kobj && new_parent_kobj->sd) ? 792 new_parent_sd = new_parent_kobj && new_parent_kobj->sd ?
902 new_parent_kobj->sd : &sysfs_root; 793 new_parent_kobj->sd : &sysfs_root;
903 794
904 error = 0; 795 return sysfs_rename(sd, new_parent_sd, sd->s_name);
905 if (sd->s_parent == new_parent_sd)
906 goto out; /* nothing to move */
907
908 /* get dentries */
909 old_dentry = sysfs_get_dentry(sd);
910 if (IS_ERR(old_dentry)) {
911 error = PTR_ERR(old_dentry);
912 old_dentry = NULL;
913 goto out;
914 }
915 old_parent = old_dentry->d_parent;
916
917 new_parent = sysfs_get_dentry(new_parent_sd);
918 if (IS_ERR(new_parent)) {
919 error = PTR_ERR(new_parent);
920 new_parent = NULL;
921 goto out;
922 }
923
924again:
925 mutex_lock(&old_parent->d_inode->i_mutex);
926 if (!mutex_trylock(&new_parent->d_inode->i_mutex)) {
927 mutex_unlock(&old_parent->d_inode->i_mutex);
928 goto again;
929 }
930 mutex_lock(&sysfs_mutex);
931
932 error = -EEXIST;
933 if (sysfs_find_dirent(new_parent_sd, sd->s_name))
934 goto out_unlock;
935
936 error = -ENOMEM;
937 new_dentry = d_alloc_name(new_parent, sd->s_name);
938 if (!new_dentry)
939 goto out_unlock;
940
941 error = 0;
942 d_add(new_dentry, NULL);
943 d_move(old_dentry, new_dentry);
944
945 /* Remove from old parent's list and insert into new parent's list. */
946 sysfs_unlink_sibling(sd);
947 sysfs_get(new_parent_sd);
948 drop_nlink(old_parent->d_inode);
949 sysfs_put(sd->s_parent);
950 sd->s_parent = new_parent_sd;
951 inc_nlink(new_parent->d_inode);
952 sysfs_link_sibling(sd);
953
954 out_unlock:
955 mutex_unlock(&sysfs_mutex);
956 mutex_unlock(&new_parent->d_inode->i_mutex);
957 mutex_unlock(&old_parent->d_inode->i_mutex);
958 out:
959 dput(new_parent);
960 dput(old_dentry);
961 dput(new_dentry);
962 mutex_unlock(&sysfs_rename_mutex);
963 return error;
964} 796}
965 797
966/* Relationship between s_mode and the DT_xxx types */ 798/* Relationship between s_mode and the DT_xxx types */
@@ -969,11 +801,46 @@ static inline unsigned char dt_type(struct sysfs_dirent *sd)
969 return (sd->s_mode >> 12) & 15; 801 return (sd->s_mode >> 12) & 15;
970} 802}
971 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
972static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) 839static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
973{ 840{
974 struct dentry *dentry = filp->f_path.dentry; 841 struct dentry *dentry = filp->f_path.dentry;
975 struct sysfs_dirent * parent_sd = dentry->d_fsdata; 842 struct sysfs_dirent * parent_sd = dentry->d_fsdata;
976 struct sysfs_dirent *pos; 843 struct sysfs_dirent *pos = filp->private_data;
977 ino_t ino; 844 ino_t ino;
978 845
979 if (filp->f_pos == 0) { 846 if (filp->f_pos == 0) {
@@ -989,29 +856,31 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
989 if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) == 0) 856 if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) == 0)
990 filp->f_pos++; 857 filp->f_pos++;
991 } 858 }
992 if ((filp->f_pos > 1) && (filp->f_pos < INT_MAX)) { 859 mutex_lock(&sysfs_mutex);
993 mutex_lock(&sysfs_mutex); 860 for (pos = sysfs_dir_pos(parent_sd, filp->f_pos, pos);
994 861 pos;
995 /* Skip the dentries we have already reported */ 862 pos = sysfs_dir_next_pos(parent_sd, filp->f_pos, pos)) {
996 pos = parent_sd->s_dir.children; 863 const char * name;
997 while (pos && (filp->f_pos > pos->s_ino)) 864 unsigned int type;
998 pos = pos->s_sibling; 865 int len, ret;
999 866
1000 for ( ; pos; pos = pos->s_sibling) { 867 name = pos->s_name;
1001 const char * name; 868 len = strlen(name);
1002 int len; 869 ino = pos->s_ino;
1003 870 type = dt_type(pos);
1004 name = pos->s_name; 871 filp->f_pos = ino;
1005 len = strlen(name); 872 filp->private_data = sysfs_get(pos);
1006 filp->f_pos = ino = pos->s_ino;
1007 873
1008 if (filldir(dirent, name, len, filp->f_pos, ino,
1009 dt_type(pos)) < 0)
1010 break;
1011 }
1012 if (!pos)
1013 filp->f_pos = INT_MAX;
1014 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;
1015 } 884 }
1016 return 0; 885 return 0;
1017} 886}
@@ -1020,5 +889,6 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
1020const struct file_operations sysfs_dir_operations = { 889const struct file_operations sysfs_dir_operations = {
1021 .read = generic_read_dir, 890 .read = generic_read_dir,
1022 .readdir = sysfs_readdir, 891 .readdir = sysfs_readdir,
892 .release = sysfs_dir_release,
1023 .llseek = generic_file_llseek, 893 .llseek = generic_file_llseek,
1024}; 894};