[PATCH 1/2] sysfs: Introduce sysfs_{un,}break_active_protection()

2018-08-02 Thread Bart Van Assche
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 
Acked-by: Tejun Heo 
Acked-by: Greg Kroah-Hartman 
Cc: 
---
 fs/sysfs/file.c   | 44 +++
 include/linux/sysfs.h | 14 ++
 2 files changed, 58 insertions(+)

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
@@ -405,6 +405,50 @@ int sysfs_chmod_file(struct kobject *kobj, const struct 
attribute *attr,
 }
 EXPORT_SYMBOL_GPL(sysfs_chmod_file);
 
+/**
+ * sysfs_break_active_protection - break "active" protection
+ * @kobj: The kernel object @attr is associated with.
+ * @attr: The attribute to break the "active" protection for.
+ *
+ * With sysfs, just like kernfs, deletion of an attribute is postponed until
+ * all active .show() and .store() callbacks have finished unless this function
+ * is called. Hence this function is useful in methods that implement self
+ * deletion.
+ */
+struct kernfs_node *sysfs_break_active_protection(struct kobject *kobj,
+ const struct attribute *attr)
+{
+   struct kernfs_node *kn;
+
+   kobject_get(kobj);
+   kn = kernfs_find_and_get(kobj->sd, attr->name);
+   if (kn)
+   kernfs_break_active_protection(kn);
+   return kn;
+}
+EXPORT_SYMBOL_GPL(sysfs_break_active_protection);
+
+/**
+ * sysfs_unbreak_active_protection - restore "active" protection
+ * @kn: Pointer returned by sysfs_break_active_protection().
+ *
+ * Undo the effects of sysfs_break_active_protection(). Since this function
+ * calls kernfs_put() on the kernfs node that corresponds to the 'attr'
+ * argument passed to sysfs_break_active_protection() that attribute may have
+ * been removed between the sysfs_break_active_protection() and
+ * sysfs_unbreak_active_protection() calls, it is not safe to access @kn after
+ * this function has returned.
+ */
+void sysfs_unbreak_active_protection(struct kernfs_node *kn)
+{
+   struct kobject *kobj = kn->parent->priv;
+
+   kernfs_unbreak_active_protection(kn);
+   kernfs_put(kn);
+   kobject_put(kobj);
+}
+EXPORT_SYMBOL_GPL(sysfs_unbreak_active_protection);
+
 /**
  * sysfs_remove_file_ns - remove an object attribute with a custom ns tag
  * @kobj: object we're acting for
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,
   const struct attribute **attr);
 int __must_check sysfs_chmod_file(struct kobject *kobj,
  const struct attribute *attr, umode_t mode);
+struct kernfs_node *sysfs_break_active_protection(struct kobject *kobj,
+ const struct attribute *attr);
+void sysfs_unbreak_active_protection(struct kernfs_node *kn);
 void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr,
  const void *ns);
 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,
return 0;
 }
 
+static inline struct kernfs_node *
+sysfs_break_active_protection(struct kobject *kobj,
+ const struct attribute *attr)
+{
+   return NULL;
+}
+
+static inline void sysfs_unbreak_active_protection(struct kernfs_node *kn)
+{
+}
+
 static inline void sysfs_remove_file_ns(struct kobject *kobj,
const struct attribute *attr,
const void *ns)
-- 
2.18.0



Re: [PATCH 1/2] sysfs: Introduce sysfs_{un,}break_active_protection()

2018-08-02 Thread Greg Kroah-Hartman
On Mon, Jul 30, 2018 at 11:40:51AM -0700, Bart Van Assche wrote:
> 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 
> Cc: Greg Kroah-Hartman 
> Cc: Tejun Heo 
> Cc: 
> ---
>  fs/sysfs/file.c   | 44 +++
>  include/linux/sysfs.h | 14 ++
>  2 files changed, 58 insertions(+)

Acked-by: Greg Kroah-Hartman 


Re: [PATCH 1/2] sysfs: Introduce sysfs_{un,}break_active_protection()

2018-08-01 Thread Tejun Heo
On Mon, Jul 30, 2018 at 11:40:51AM -0700, Bart Van Assche wrote:
> 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 
> Cc: Greg Kroah-Hartman 
> Cc: Tejun Heo 
> Cc: 

Acked-by: Tejun Heo 

Thanks.

-- 
tejun


[PATCH 1/2] sysfs: Introduce sysfs_{un,}break_active_protection()

2018-07-30 Thread Bart Van Assche
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 
Cc: Greg Kroah-Hartman 
Cc: Tejun Heo 
Cc: 
---
 fs/sysfs/file.c   | 44 +++
 include/linux/sysfs.h | 14 ++
 2 files changed, 58 insertions(+)

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
@@ -405,6 +405,50 @@ int sysfs_chmod_file(struct kobject *kobj, const struct 
attribute *attr,
 }
 EXPORT_SYMBOL_GPL(sysfs_chmod_file);
 
+/**
+ * sysfs_break_active_protection - break "active" protection
+ * @kobj: The kernel object @attr is associated with.
+ * @attr: The attribute to break the "active" protection for.
+ *
+ * With sysfs, just like kernfs, deletion of an attribute is postponed until
+ * all active .show() and .store() callbacks have finished unless this function
+ * is called. Hence this function is useful in methods that implement self
+ * deletion.
+ */
+struct kernfs_node *sysfs_break_active_protection(struct kobject *kobj,
+ const struct attribute *attr)
+{
+   struct kernfs_node *kn;
+
+   kobject_get(kobj);
+   kn = kernfs_find_and_get(kobj->sd, attr->name);
+   if (kn)
+   kernfs_break_active_protection(kn);
+   return kn;
+}
+EXPORT_SYMBOL_GPL(sysfs_break_active_protection);
+
+/**
+ * sysfs_unbreak_active_protection - restore "active" protection
+ * @kn: Pointer returned by sysfs_break_active_protection().
+ *
+ * Undo the effects of sysfs_break_active_protection(). Since this function
+ * calls kernfs_put() on the kernfs node that corresponds to the 'attr'
+ * argument passed to sysfs_break_active_protection() that attribute may have
+ * been removed between the sysfs_break_active_protection() and
+ * sysfs_unbreak_active_protection() calls, it is not safe to access @kn after
+ * this function has returned.
+ */
+void sysfs_unbreak_active_protection(struct kernfs_node *kn)
+{
+   struct kobject *kobj = kn->parent->priv;
+
+   kernfs_unbreak_active_protection(kn);
+   kernfs_put(kn);
+   kobject_put(kobj);
+}
+EXPORT_SYMBOL_GPL(sysfs_unbreak_active_protection);
+
 /**
  * sysfs_remove_file_ns - remove an object attribute with a custom ns tag
  * @kobj: object we're acting for
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,
   const struct attribute **attr);
 int __must_check sysfs_chmod_file(struct kobject *kobj,
  const struct attribute *attr, umode_t mode);
+struct kernfs_node *sysfs_break_active_protection(struct kobject *kobj,
+ const struct attribute *attr);
+void sysfs_unbreak_active_protection(struct kernfs_node *kn);
 void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr,
  const void *ns);
 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,
return 0;
 }
 
+static inline struct kernfs_node *
+sysfs_break_active_protection(struct kobject *kobj,
+ const struct attribute *attr)
+{
+   return NULL;
+}
+
+static inline void sysfs_unbreak_active_protection(struct kernfs_node *kn)
+{
+}
+
 static inline void sysfs_remove_file_ns(struct kobject *kobj,
const struct attribute *attr,
const void *ns)
-- 
2.18.0