aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/sysfs/dir.c52
-rw-r--r--fs/sysfs/file.c4
-rw-r--r--fs/sysfs/inode.c2
-rw-r--r--fs/sysfs/symlink.c6
-rw-r--r--fs/sysfs/sysfs.h10
5 files changed, 38 insertions, 36 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index d23e66dfba74..671868914b5b 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -406,22 +406,19 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
406/** 406/**
407 * sysfs_addrm_start - prepare for sysfs_dirent add/remove 407 * sysfs_addrm_start - prepare for sysfs_dirent add/remove
408 * @acxt: pointer to sysfs_addrm_cxt to be used 408 * @acxt: pointer to sysfs_addrm_cxt to be used
409 * @parent_sd: parent sysfs_dirent
410 * 409 *
411 * This function is called when the caller is about to add or 410 * This function is called when the caller is about to add or remove
412 * remove sysfs_dirent under @parent_sd. This function acquires 411 * sysfs_dirent. This function acquires sysfs_mutex. @acxt is used
413 * sysfs_mutex. @acxt is used to keep and pass context to 412 * to keep and pass context to other addrm functions.
414 * other addrm functions.
415 * 413 *
416 * LOCKING: 414 * LOCKING:
417 * Kernel thread context (may sleep). sysfs_mutex is locked on 415 * Kernel thread context (may sleep). sysfs_mutex is locked on
418 * return. 416 * return.
419 */ 417 */
420void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, 418void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt)
421 struct sysfs_dirent *parent_sd) 419 __acquires(sysfs_mutex)
422{ 420{
423 memset(acxt, 0, sizeof(*acxt)); 421 memset(acxt, 0, sizeof(*acxt));
424 acxt->parent_sd = parent_sd;
425 422
426 mutex_lock(&sysfs_mutex); 423 mutex_lock(&sysfs_mutex);
427} 424}
@@ -430,10 +427,11 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
430 * __sysfs_add_one - add sysfs_dirent to parent without warning 427 * __sysfs_add_one - add sysfs_dirent to parent without warning
431 * @acxt: addrm context to use 428 * @acxt: addrm context to use
432 * @sd: sysfs_dirent to be added 429 * @sd: sysfs_dirent to be added
430 * @parent_sd: the parent sysfs_dirent to add @sd to
433 * 431 *
434 * Get @acxt->parent_sd and set sd->s_parent to it and increment 432 * Get @parent_sd and set @sd->s_parent to it and increment nlink of
435 * nlink of parent inode if @sd is a directory and link into the 433 * the parent inode if @sd is a directory and link into the children
436 * children list of the parent. 434 * list of the parent.
437 * 435 *
438 * This function should be called between calls to 436 * This function should be called between calls to
439 * sysfs_addrm_start() and sysfs_addrm_finish() and should be 437 * sysfs_addrm_start() and sysfs_addrm_finish() and should be
@@ -446,20 +444,21 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
446 * 0 on success, -EEXIST if entry with the given name already 444 * 0 on success, -EEXIST if entry with the given name already
447 * exists. 445 * exists.
448 */ 446 */
449int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) 447int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd,
448 struct sysfs_dirent *parent_sd)
450{ 449{
451 struct sysfs_inode_attrs *ps_iattr; 450 struct sysfs_inode_attrs *ps_iattr;
452 int ret; 451 int ret;
453 452
454 sd->s_hash = sysfs_name_hash(sd->s_name, sd->s_ns); 453 sd->s_hash = sysfs_name_hash(sd->s_name, sd->s_ns);
455 sd->s_parent = sysfs_get(acxt->parent_sd); 454 sd->s_parent = sysfs_get(parent_sd);
456 455
457 ret = sysfs_link_sibling(sd); 456 ret = sysfs_link_sibling(sd);
458 if (ret) 457 if (ret)
459 return ret; 458 return ret;
460 459
461 /* Update timestamps on the parent */ 460 /* Update timestamps on the parent */
462 ps_iattr = acxt->parent_sd->s_iattr; 461 ps_iattr = parent_sd->s_iattr;
463 if (ps_iattr) { 462 if (ps_iattr) {
464 struct iattr *ps_iattrs = &ps_iattr->ia_iattr; 463 struct iattr *ps_iattrs = &ps_iattr->ia_iattr;
465 ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME; 464 ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME;
@@ -493,10 +492,11 @@ static char *sysfs_pathname(struct sysfs_dirent *sd, char *path)
493 * sysfs_add_one - add sysfs_dirent to parent 492 * sysfs_add_one - add sysfs_dirent to parent
494 * @acxt: addrm context to use 493 * @acxt: addrm context to use
495 * @sd: sysfs_dirent to be added 494 * @sd: sysfs_dirent to be added
495 * @parent_sd: the parent sysfs_dirent to add @sd to
496 * 496 *
497 * Get @acxt->parent_sd and set sd->s_parent to it and increment 497 * Get @parent_sd and set @sd->s_parent to it and increment nlink of
498 * nlink of parent inode if @sd is a directory and link into the 498 * the parent inode if @sd is a directory and link into the children
499 * children list of the parent. 499 * list of the parent.
500 * 500 *
501 * This function should be called between calls to 501 * This function should be called between calls to
502 * sysfs_addrm_start() and sysfs_addrm_finish() and should be 502 * sysfs_addrm_start() and sysfs_addrm_finish() and should be
@@ -509,17 +509,18 @@ static char *sysfs_pathname(struct sysfs_dirent *sd, char *path)
509 * 0 on success, -EEXIST if entry with the given name already 509 * 0 on success, -EEXIST if entry with the given name already
510 * exists. 510 * exists.
511 */ 511 */
512int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) 512int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd,
513 struct sysfs_dirent *parent_sd)
513{ 514{
514 int ret; 515 int ret;
515 516
516 ret = __sysfs_add_one(acxt, sd); 517 ret = __sysfs_add_one(acxt, sd, parent_sd);
517 if (ret == -EEXIST) { 518 if (ret == -EEXIST) {
518 char *path = kzalloc(PATH_MAX, GFP_KERNEL); 519 char *path = kzalloc(PATH_MAX, GFP_KERNEL);
519 WARN(1, KERN_WARNING 520 WARN(1, KERN_WARNING
520 "sysfs: cannot create duplicate filename '%s'\n", 521 "sysfs: cannot create duplicate filename '%s'\n",
521 (path == NULL) ? sd->s_name 522 (path == NULL) ? sd->s_name
522 : (sysfs_pathname(acxt->parent_sd, path), 523 : (sysfs_pathname(parent_sd, path),
523 strlcat(path, "/", PATH_MAX), 524 strlcat(path, "/", PATH_MAX),
524 strlcat(path, sd->s_name, PATH_MAX), 525 strlcat(path, sd->s_name, PATH_MAX),
525 path)); 526 path));
@@ -553,7 +554,7 @@ void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
553 sysfs_unlink_sibling(sd); 554 sysfs_unlink_sibling(sd);
554 555
555 /* Update timestamps on the parent */ 556 /* Update timestamps on the parent */
556 ps_iattr = acxt->parent_sd->s_iattr; 557 ps_iattr = sd->s_parent->s_iattr;
557 if (ps_iattr) { 558 if (ps_iattr) {
558 struct iattr *ps_iattrs = &ps_iattr->ia_iattr; 559 struct iattr *ps_iattrs = &ps_iattr->ia_iattr;
559 ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME; 560 ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME;
@@ -576,6 +577,7 @@ void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
576 * sysfs_mutex is released. 577 * sysfs_mutex is released.
577 */ 578 */
578void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt) 579void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
580 __releases(sysfs_mutex)
579{ 581{
580 /* release resources acquired by sysfs_addrm_start() */ 582 /* release resources acquired by sysfs_addrm_start() */
581 mutex_unlock(&sysfs_mutex); 583 mutex_unlock(&sysfs_mutex);
@@ -678,8 +680,8 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
678 sd->s_dir.kobj = kobj; 680 sd->s_dir.kobj = kobj;
679 681
680 /* link in */ 682 /* link in */
681 sysfs_addrm_start(&acxt, parent_sd); 683 sysfs_addrm_start(&acxt);
682 rc = sysfs_add_one(&acxt, sd); 684 rc = sysfs_add_one(&acxt, sd, parent_sd);
683 sysfs_addrm_finish(&acxt); 685 sysfs_addrm_finish(&acxt);
684 686
685 if (rc == 0) 687 if (rc == 0)
@@ -772,7 +774,7 @@ static void remove_dir(struct sysfs_dirent *sd)
772{ 774{
773 struct sysfs_addrm_cxt acxt; 775 struct sysfs_addrm_cxt acxt;
774 776
775 sysfs_addrm_start(&acxt, sd->s_parent); 777 sysfs_addrm_start(&acxt);
776 sysfs_remove_one(&acxt, sd); 778 sysfs_remove_one(&acxt, sd);
777 sysfs_addrm_finish(&acxt); 779 sysfs_addrm_finish(&acxt);
778} 780}
@@ -792,7 +794,7 @@ static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd)
792 return; 794 return;
793 795
794 pr_debug("sysfs %s: removing dir\n", dir_sd->s_name); 796 pr_debug("sysfs %s: removing dir\n", dir_sd->s_name);
795 sysfs_addrm_start(&acxt, dir_sd); 797 sysfs_addrm_start(&acxt);
796 pos = rb_first(&dir_sd->s_dir.children); 798 pos = rb_first(&dir_sd->s_dir.children);
797 while (pos) { 799 while (pos) {
798 struct sysfs_dirent *sd = to_sysfs_dirent(pos); 800 struct sysfs_dirent *sd = to_sysfs_dirent(pos);
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 4697019fafa3..1656a79ea6c0 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -502,8 +502,8 @@ int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd,
502 sd->s_attr.attr = (void *)attr; 502 sd->s_attr.attr = (void *)attr;
503 sysfs_dirent_init_lockdep(sd); 503 sysfs_dirent_init_lockdep(sd);
504 504
505 sysfs_addrm_start(&acxt, dir_sd); 505 sysfs_addrm_start(&acxt);
506 rc = sysfs_add_one(&acxt, sd); 506 rc = sysfs_add_one(&acxt, sd, dir_sd);
507 sysfs_addrm_finish(&acxt); 507 sysfs_addrm_finish(&acxt);
508 508
509 if (rc) 509 if (rc)
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 07193d720d92..364c8873fbda 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -326,7 +326,7 @@ int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name,
326 return -ENOENT; 326 return -ENOENT;
327 } 327 }
328 328
329 sysfs_addrm_start(&acxt, dir_sd); 329 sysfs_addrm_start(&acxt);
330 330
331 sd = sysfs_find_dirent(dir_sd, name, ns); 331 sd = sysfs_find_dirent(dir_sd, name, ns);
332 if (sd) 332 if (sd)
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index 88c8bc5e8911..22ea2f5796f5 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -53,11 +53,11 @@ static int sysfs_do_create_link_sd(struct sysfs_dirent *parent_sd,
53 sd->s_symlink.target_sd = target_sd; 53 sd->s_symlink.target_sd = target_sd;
54 target_sd = NULL; /* reference is now owned by the symlink */ 54 target_sd = NULL; /* reference is now owned by the symlink */
55 55
56 sysfs_addrm_start(&acxt, parent_sd); 56 sysfs_addrm_start(&acxt);
57 if (warn) 57 if (warn)
58 error = sysfs_add_one(&acxt, sd); 58 error = sysfs_add_one(&acxt, sd, parent_sd);
59 else 59 else
60 error = __sysfs_add_one(&acxt, sd); 60 error = __sysfs_add_one(&acxt, sd, parent_sd);
61 sysfs_addrm_finish(&acxt); 61 sysfs_addrm_finish(&acxt);
62 62
63 if (error) 63 if (error)
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index ee44fde199d0..4d1154411cdb 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -120,7 +120,6 @@ do { \
120 * Context structure to be used while adding/removing nodes. 120 * Context structure to be used while adding/removing nodes.
121 */ 121 */
122struct sysfs_addrm_cxt { 122struct sysfs_addrm_cxt {
123 struct sysfs_dirent *parent_sd;
124 struct sysfs_dirent *removed; 123 struct sysfs_dirent *removed;
125}; 124};
126 125
@@ -154,10 +153,11 @@ extern const struct inode_operations sysfs_dir_inode_operations;
154struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd); 153struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd);
155struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd); 154struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd);
156void sysfs_put_active(struct sysfs_dirent *sd); 155void sysfs_put_active(struct sysfs_dirent *sd);
157void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, 156void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt);
158 struct sysfs_dirent *parent_sd); 157int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd,
159int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); 158 struct sysfs_dirent *parent_sd);
160int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); 159int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd,
160 struct sysfs_dirent *parent_sd);
161void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); 161void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);
162void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); 162void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt);
163 163