diff options
-rw-r--r-- | fs/sysfs/dir.c | 52 | ||||
-rw-r--r-- | fs/sysfs/file.c | 4 | ||||
-rw-r--r-- | fs/sysfs/inode.c | 2 | ||||
-rw-r--r-- | fs/sysfs/symlink.c | 6 | ||||
-rw-r--r-- | fs/sysfs/sysfs.h | 10 |
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 | */ |
420 | void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, | 418 | void 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 | */ |
449 | int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) | 447 | int __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 | */ |
512 | int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) | 512 | int 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 | */ |
578 | void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt) | 579 | void 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 | */ |
122 | struct sysfs_addrm_cxt { | 122 | struct 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; | |||
154 | struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd); | 153 | struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd); |
155 | struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd); | 154 | struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd); |
156 | void sysfs_put_active(struct sysfs_dirent *sd); | 155 | void sysfs_put_active(struct sysfs_dirent *sd); |
157 | void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, | 156 | void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt); |
158 | struct sysfs_dirent *parent_sd); | 157 | int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd, |
159 | int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); | 158 | struct sysfs_dirent *parent_sd); |
160 | int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); | 159 | int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd, |
160 | struct sysfs_dirent *parent_sd); | ||
161 | void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); | 161 | void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); |
162 | void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); | 162 | void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); |
163 | 163 | ||