diff options
Diffstat (limited to 'fs/sysfs')
| -rw-r--r-- | fs/sysfs/dir.c | 34 | ||||
| -rw-r--r-- | fs/sysfs/file.c | 8 | ||||
| -rw-r--r-- | fs/sysfs/group.c | 3 | ||||
| -rw-r--r-- | fs/sysfs/symlink.c | 41 | ||||
| -rw-r--r-- | fs/sysfs/sysfs.h | 1 |
5 files changed, 72 insertions, 15 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 8c0e4b92574f..aedaeba82ae5 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
| @@ -398,7 +398,7 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, | |||
| 398 | } | 398 | } |
| 399 | 399 | ||
| 400 | /** | 400 | /** |
| 401 | * sysfs_add_one - add sysfs_dirent to parent | 401 | * __sysfs_add_one - add sysfs_dirent to parent without warning |
| 402 | * @acxt: addrm context to use | 402 | * @acxt: addrm context to use |
| 403 | * @sd: sysfs_dirent to be added | 403 | * @sd: sysfs_dirent to be added |
| 404 | * | 404 | * |
| @@ -417,7 +417,7 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, | |||
| 417 | * 0 on success, -EEXIST if entry with the given name already | 417 | * 0 on success, -EEXIST if entry with the given name already |
| 418 | * exists. | 418 | * exists. |
| 419 | */ | 419 | */ |
| 420 | int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) | 420 | int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) |
| 421 | { | 421 | { |
| 422 | if (sysfs_find_dirent(acxt->parent_sd, sd->s_name)) | 422 | if (sysfs_find_dirent(acxt->parent_sd, sd->s_name)) |
| 423 | return -EEXIST; | 423 | return -EEXIST; |
| @@ -435,6 +435,36 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) | |||
| 435 | } | 435 | } |
| 436 | 436 | ||
| 437 | /** | 437 | /** |
| 438 | * sysfs_add_one - add sysfs_dirent to parent | ||
| 439 | * @acxt: addrm context to use | ||
| 440 | * @sd: sysfs_dirent to be added | ||
| 441 | * | ||
| 442 | * Get @acxt->parent_sd and set sd->s_parent to it and increment | ||
| 443 | * nlink of parent inode if @sd is a directory and link into the | ||
| 444 | * children list of the parent. | ||
| 445 | * | ||
| 446 | * This function should be called between calls to | ||
| 447 | * sysfs_addrm_start() and sysfs_addrm_finish() and should be | ||
| 448 | * passed the same @acxt as passed to sysfs_addrm_start(). | ||
| 449 | * | ||
| 450 | * LOCKING: | ||
| 451 | * Determined by sysfs_addrm_start(). | ||
| 452 | * | ||
| 453 | * RETURNS: | ||
| 454 | * 0 on success, -EEXIST if entry with the given name already | ||
| 455 | * exists. | ||
| 456 | */ | ||
| 457 | int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) | ||
| 458 | { | ||
| 459 | int ret; | ||
| 460 | |||
| 461 | ret = __sysfs_add_one(acxt, sd); | ||
| 462 | WARN(ret == -EEXIST, KERN_WARNING "sysfs: duplicate filename '%s' " | ||
| 463 | "can not be created\n", sd->s_name); | ||
| 464 | return ret; | ||
| 465 | } | ||
| 466 | |||
| 467 | /** | ||
| 438 | * sysfs_remove_one - remove sysfs_dirent from parent | 468 | * sysfs_remove_one - remove sysfs_dirent from parent |
| 439 | * @acxt: addrm context to use | 469 | * @acxt: addrm context to use |
| 440 | * @sd: sysfs_dirent to be removed | 470 | * @sd: sysfs_dirent to be removed |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index e7735f643cd1..c9e4e5091da1 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/kobject.h> | 14 | #include <linux/kobject.h> |
| 15 | #include <linux/kallsyms.h> | 15 | #include <linux/kallsyms.h> |
| 16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
| 17 | #include <linux/fsnotify.h> | ||
| 17 | #include <linux/namei.h> | 18 | #include <linux/namei.h> |
| 18 | #include <linux/poll.h> | 19 | #include <linux/poll.h> |
| 19 | #include <linux/list.h> | 20 | #include <linux/list.h> |
| @@ -336,9 +337,8 @@ static int sysfs_open_file(struct inode *inode, struct file *file) | |||
| 336 | if (kobj->ktype && kobj->ktype->sysfs_ops) | 337 | if (kobj->ktype && kobj->ktype->sysfs_ops) |
| 337 | ops = kobj->ktype->sysfs_ops; | 338 | ops = kobj->ktype->sysfs_ops; |
| 338 | else { | 339 | else { |
| 339 | printk(KERN_ERR "missing sysfs attribute operations for " | 340 | WARN(1, KERN_ERR "missing sysfs attribute operations for " |
| 340 | "kobject: %s\n", kobject_name(kobj)); | 341 | "kobject: %s\n", kobject_name(kobj)); |
| 341 | WARN_ON(1); | ||
| 342 | goto err_out; | 342 | goto err_out; |
| 343 | } | 343 | } |
| 344 | 344 | ||
| @@ -585,9 +585,11 @@ int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode) | |||
| 585 | 585 | ||
| 586 | newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); | 586 | newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); |
| 587 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; | 587 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; |
| 588 | rc = notify_change(victim, &newattrs); | 588 | newattrs.ia_ctime = current_fs_time(inode->i_sb); |
| 589 | rc = sysfs_setattr(victim, &newattrs); | ||
| 589 | 590 | ||
| 590 | if (rc == 0) { | 591 | if (rc == 0) { |
| 592 | fsnotify_change(victim, newattrs.ia_valid); | ||
| 591 | mutex_lock(&sysfs_mutex); | 593 | mutex_lock(&sysfs_mutex); |
| 592 | victim_sd->s_mode = newattrs.ia_mode; | 594 | victim_sd->s_mode = newattrs.ia_mode; |
| 593 | mutex_unlock(&sysfs_mutex); | 595 | mutex_unlock(&sysfs_mutex); |
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index eeba38417b1d..fe611949a7f7 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c | |||
| @@ -134,9 +134,8 @@ void sysfs_remove_group(struct kobject * kobj, | |||
| 134 | if (grp->name) { | 134 | if (grp->name) { |
| 135 | sd = sysfs_get_dirent(dir_sd, grp->name); | 135 | sd = sysfs_get_dirent(dir_sd, grp->name); |
| 136 | if (!sd) { | 136 | if (!sd) { |
| 137 | printk(KERN_WARNING "sysfs group %p not found for " | 137 | WARN(!sd, KERN_WARNING "sysfs group %p not found for " |
| 138 | "kobject '%s'\n", grp, kobject_name(kobj)); | 138 | "kobject '%s'\n", grp, kobject_name(kobj)); |
| 139 | WARN_ON(!sd); | ||
| 140 | return; | 139 | return; |
| 141 | } | 140 | } |
| 142 | } else | 141 | } else |
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 817f5966edca..a3ba217fbe74 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c | |||
| @@ -19,13 +19,8 @@ | |||
| 19 | 19 | ||
| 20 | #include "sysfs.h" | 20 | #include "sysfs.h" |
| 21 | 21 | ||
| 22 | /** | 22 | static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target, |
| 23 | * sysfs_create_link - create symlink between two objects. | 23 | const char *name, int warn) |
| 24 | * @kobj: object whose directory we're creating the link in. | ||
| 25 | * @target: object we're pointing to. | ||
| 26 | * @name: name of the symlink. | ||
| 27 | */ | ||
| 28 | int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name) | ||
| 29 | { | 24 | { |
| 30 | struct sysfs_dirent *parent_sd = NULL; | 25 | struct sysfs_dirent *parent_sd = NULL; |
| 31 | struct sysfs_dirent *target_sd = NULL; | 26 | struct sysfs_dirent *target_sd = NULL; |
| @@ -65,7 +60,10 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char | |||
| 65 | target_sd = NULL; /* reference is now owned by the symlink */ | 60 | target_sd = NULL; /* reference is now owned by the symlink */ |
| 66 | 61 | ||
| 67 | sysfs_addrm_start(&acxt, parent_sd); | 62 | sysfs_addrm_start(&acxt, parent_sd); |
| 68 | error = sysfs_add_one(&acxt, sd); | 63 | if (warn) |
| 64 | error = sysfs_add_one(&acxt, sd); | ||
| 65 | else | ||
| 66 | error = __sysfs_add_one(&acxt, sd); | ||
| 69 | sysfs_addrm_finish(&acxt); | 67 | sysfs_addrm_finish(&acxt); |
| 70 | 68 | ||
| 71 | if (error) | 69 | if (error) |
| @@ -80,6 +78,33 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char | |||
| 80 | } | 78 | } |
| 81 | 79 | ||
| 82 | /** | 80 | /** |
| 81 | * sysfs_create_link - create symlink between two objects. | ||
| 82 | * @kobj: object whose directory we're creating the link in. | ||
| 83 | * @target: object we're pointing to. | ||
| 84 | * @name: name of the symlink. | ||
| 85 | */ | ||
| 86 | int sysfs_create_link(struct kobject *kobj, struct kobject *target, | ||
| 87 | const char *name) | ||
| 88 | { | ||
| 89 | return sysfs_do_create_link(kobj, target, name, 1); | ||
| 90 | } | ||
| 91 | |||
| 92 | /** | ||
| 93 | * sysfs_create_link_nowarn - create symlink between two objects. | ||
| 94 | * @kobj: object whose directory we're creating the link in. | ||
| 95 | * @target: object we're pointing to. | ||
| 96 | * @name: name of the symlink. | ||
| 97 | * | ||
| 98 | * This function does the same as sysf_create_link(), but it | ||
| 99 | * doesn't warn if the link already exists. | ||
| 100 | */ | ||
| 101 | int sysfs_create_link_nowarn(struct kobject *kobj, struct kobject *target, | ||
| 102 | const char *name) | ||
| 103 | { | ||
| 104 | return sysfs_do_create_link(kobj, target, name, 0); | ||
| 105 | } | ||
| 106 | |||
| 107 | /** | ||
| 83 | * sysfs_remove_link - remove symlink in object's directory. | 108 | * sysfs_remove_link - remove symlink in object's directory. |
| 84 | * @kobj: object we're acting for. | 109 | * @kobj: object we're acting for. |
| 85 | * @name: name of the symlink to remove. | 110 | * @name: name of the symlink to remove. |
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index ce4e15f8aaeb..a5db496f71c7 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h | |||
| @@ -107,6 +107,7 @@ struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd); | |||
| 107 | void sysfs_put_active_two(struct sysfs_dirent *sd); | 107 | void sysfs_put_active_two(struct sysfs_dirent *sd); |
| 108 | void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, | 108 | void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, |
| 109 | struct sysfs_dirent *parent_sd); | 109 | struct sysfs_dirent *parent_sd); |
| 110 | int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); | ||
| 110 | int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); | 111 | int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); |
| 111 | void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); | 112 | void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); |
| 112 | void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); | 113 | void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); |
