diff options
author | Bart Van Assche <bart.vanassche@wdc.com> | 2018-08-02 13:51:40 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2018-08-02 15:53:15 -0400 |
commit | 2afc9166f79b8f6da5f347f48515215ceee4ae37 (patch) | |
tree | 5d82e76262e17c762b7f75d156121087da8ee0e2 | |
parent | 7fa8512330ab7cbb394b3e42ee092f4ad2e8f906 (diff) |
scsi: sysfs: Introduce sysfs_{un,}break_active_protection()
Introduce these two functions and export them such that the next patch
can add calls to these functions from the SCSI core.
Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
Acked-by: Tejun Heo <tj@kernel.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | fs/sysfs/file.c | 44 | ||||
-rw-r--r-- | include/linux/sysfs.h | 14 |
2 files changed, 58 insertions, 0 deletions
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 5c13f29bfcdb..118fa197a35f 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -406,6 +406,50 @@ int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr, | |||
406 | EXPORT_SYMBOL_GPL(sysfs_chmod_file); | 406 | EXPORT_SYMBOL_GPL(sysfs_chmod_file); |
407 | 407 | ||
408 | /** | 408 | /** |
409 | * sysfs_break_active_protection - break "active" protection | ||
410 | * @kobj: The kernel object @attr is associated with. | ||
411 | * @attr: The attribute to break the "active" protection for. | ||
412 | * | ||
413 | * With sysfs, just like kernfs, deletion of an attribute is postponed until | ||
414 | * all active .show() and .store() callbacks have finished unless this function | ||
415 | * is called. Hence this function is useful in methods that implement self | ||
416 | * deletion. | ||
417 | */ | ||
418 | struct kernfs_node *sysfs_break_active_protection(struct kobject *kobj, | ||
419 | const struct attribute *attr) | ||
420 | { | ||
421 | struct kernfs_node *kn; | ||
422 | |||
423 | kobject_get(kobj); | ||
424 | kn = kernfs_find_and_get(kobj->sd, attr->name); | ||
425 | if (kn) | ||
426 | kernfs_break_active_protection(kn); | ||
427 | return kn; | ||
428 | } | ||
429 | EXPORT_SYMBOL_GPL(sysfs_break_active_protection); | ||
430 | |||
431 | /** | ||
432 | * sysfs_unbreak_active_protection - restore "active" protection | ||
433 | * @kn: Pointer returned by sysfs_break_active_protection(). | ||
434 | * | ||
435 | * Undo the effects of sysfs_break_active_protection(). Since this function | ||
436 | * calls kernfs_put() on the kernfs node that corresponds to the 'attr' | ||
437 | * argument passed to sysfs_break_active_protection() that attribute may have | ||
438 | * been removed between the sysfs_break_active_protection() and | ||
439 | * sysfs_unbreak_active_protection() calls, it is not safe to access @kn after | ||
440 | * this function has returned. | ||
441 | */ | ||
442 | void sysfs_unbreak_active_protection(struct kernfs_node *kn) | ||
443 | { | ||
444 | struct kobject *kobj = kn->parent->priv; | ||
445 | |||
446 | kernfs_unbreak_active_protection(kn); | ||
447 | kernfs_put(kn); | ||
448 | kobject_put(kobj); | ||
449 | } | ||
450 | EXPORT_SYMBOL_GPL(sysfs_unbreak_active_protection); | ||
451 | |||
452 | /** | ||
409 | * sysfs_remove_file_ns - remove an object attribute with a custom ns tag | 453 | * sysfs_remove_file_ns - remove an object attribute with a custom ns tag |
410 | * @kobj: object we're acting for | 454 | * @kobj: object we're acting for |
411 | * @attr: attribute descriptor | 455 | * @attr: attribute descriptor |
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index b8bfdc173ec0..3c12198c0103 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h | |||
@@ -237,6 +237,9 @@ int __must_check sysfs_create_files(struct kobject *kobj, | |||
237 | const struct attribute **attr); | 237 | const struct attribute **attr); |
238 | int __must_check sysfs_chmod_file(struct kobject *kobj, | 238 | int __must_check sysfs_chmod_file(struct kobject *kobj, |
239 | const struct attribute *attr, umode_t mode); | 239 | const struct attribute *attr, umode_t mode); |
240 | struct kernfs_node *sysfs_break_active_protection(struct kobject *kobj, | ||
241 | const struct attribute *attr); | ||
242 | void sysfs_unbreak_active_protection(struct kernfs_node *kn); | ||
240 | void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr, | 243 | void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr, |
241 | const void *ns); | 244 | const void *ns); |
242 | bool sysfs_remove_file_self(struct kobject *kobj, const struct attribute *attr); | 245 | bool sysfs_remove_file_self(struct kobject *kobj, const struct attribute *attr); |
@@ -350,6 +353,17 @@ static inline int sysfs_chmod_file(struct kobject *kobj, | |||
350 | return 0; | 353 | return 0; |
351 | } | 354 | } |
352 | 355 | ||
356 | static inline struct kernfs_node * | ||
357 | sysfs_break_active_protection(struct kobject *kobj, | ||
358 | const struct attribute *attr) | ||
359 | { | ||
360 | return NULL; | ||
361 | } | ||
362 | |||
363 | static inline void sysfs_unbreak_active_protection(struct kernfs_node *kn) | ||
364 | { | ||
365 | } | ||
366 | |||
353 | static inline void sysfs_remove_file_ns(struct kobject *kobj, | 367 | static inline void sysfs_remove_file_ns(struct kobject *kobj, |
354 | const struct attribute *attr, | 368 | const struct attribute *attr, |
355 | const void *ns) | 369 | const void *ns) |