]> Pileus Git - ~andy/linux/commitdiff
Revert "kernfs, sysfs, driver-core: implement kernfs_remove_self() and its wrappers"
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Jan 2014 22:05:13 +0000 (14:05 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Jan 2014 22:05:13 +0000 (14:05 -0800)
This reverts commit 1ae06819c77cff1ea2833c94f8c093fe8a5c79db.

Tejun writes:
        I'm sorry but can you please revert the whole series?
        get_active() waiting while a node is deactivated has potential
        to lead to deadlock and that deactivate/reactivate interface is
        something fundamentally flawed and that cgroup will have to work
        with the remove_self() like everybody else.  IOW, I think the
        first posting was correct.

Cc: Tejun Heo <tj@kernel.org>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/base/core.c
fs/kernfs/dir.c
fs/sysfs/file.c
include/linux/device.h
include/linux/kernfs.h
include/linux/sysfs.h

index 9db57afcf81f983b37fb6d5201243cbe287c1058..2b567177ef782973b7e1ad14c065154ca76a986e 100644 (file)
@@ -570,23 +570,6 @@ void device_remove_file(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(device_remove_file);
 
-/**
- * device_remove_file_self - remove sysfs attribute file from its own method.
- * @dev: device.
- * @attr: device attribute descriptor.
- *
- * See kernfs_remove_self() for details.
- */
-bool device_remove_file_self(struct device *dev,
-                            const struct device_attribute *attr)
-{
-       if (dev)
-               return sysfs_remove_file_self(&dev->kobj, &attr->attr);
-       else
-               return false;
-}
-EXPORT_SYMBOL_GPL(device_remove_file_self);
-
 /**
  * device_create_bin_file - create sysfs binary attribute file for device.
  * @dev: device.
index a8028be6cdb7ba25e7e59a2e87092e6f7ebeca5a..1aeb57969bffe70b8deb44d95c417b2e0a591827 100644 (file)
@@ -985,78 +985,6 @@ void kernfs_remove(struct kernfs_node *kn)
        mutex_unlock(&kernfs_mutex);
 }
 
-/**
- * kernfs_remove_self - remove a kernfs_node from its own method
- * @kn: the self kernfs_node to remove
- *
- * The caller must be running off of a kernfs operation which is invoked
- * with an active reference - e.g. one of kernfs_ops.  This can be used to
- * implement a file operation which deletes itself.
- *
- * For example, the "delete" file for a sysfs device directory can be
- * implemented by invoking kernfs_remove_self() on the "delete" file
- * itself.  This function breaks the circular dependency of trying to
- * deactivate self while holding an active ref itself.  It isn't necessary
- * to modify the usual removal path to use kernfs_remove_self().  The
- * "delete" implementation can simply invoke kernfs_remove_self() on self
- * before proceeding with the usual removal path.  kernfs will ignore later
- * kernfs_remove() on self.
- *
- * kernfs_remove_self() can be called multiple times concurrently on the
- * same kernfs_node.  Only the first one actually performs removal and
- * returns %true.  All others will wait until the kernfs operation which
- * won self-removal finishes and return %false.  Note that the losers wait
- * for the completion of not only the winning kernfs_remove_self() but also
- * the whole kernfs_ops which won the arbitration.  This can be used to
- * guarantee, for example, all concurrent writes to a "delete" file to
- * finish only after the whole operation is complete.
- */
-bool kernfs_remove_self(struct kernfs_node *kn)
-{
-       bool ret;
-
-       mutex_lock(&kernfs_mutex);
-       __kernfs_deactivate_self(kn);
-
-       /*
-        * SUICIDAL is used to arbitrate among competing invocations.  Only
-        * the first one will actually perform removal.  When the removal
-        * is complete, SUICIDED is set and the active ref is restored
-        * while holding kernfs_mutex.  The ones which lost arbitration
-        * waits for SUICDED && drained which can happen only after the
-        * enclosing kernfs operation which executed the winning instance
-        * of kernfs_remove_self() finished.
-        */
-       if (!(kn->flags & KERNFS_SUICIDAL)) {
-               kn->flags |= KERNFS_SUICIDAL;
-               __kernfs_remove(kn);
-               kn->flags |= KERNFS_SUICIDED;
-               ret = true;
-       } else {
-               wait_queue_head_t *waitq = &kernfs_root(kn)->deactivate_waitq;
-               DEFINE_WAIT(wait);
-
-               while (true) {
-                       prepare_to_wait(waitq, &wait, TASK_UNINTERRUPTIBLE);
-
-                       if ((kn->flags & KERNFS_SUICIDED) &&
-                           atomic_read(&kn->active) == KN_DEACTIVATED_BIAS)
-                               break;
-
-                       mutex_unlock(&kernfs_mutex);
-                       schedule();
-                       mutex_lock(&kernfs_mutex);
-               }
-               finish_wait(waitq, &wait);
-               WARN_ON_ONCE(!RB_EMPTY_NODE(&kn->rb));
-               ret = false;
-       }
-
-       __kernfs_reactivate_self(kn);
-       mutex_unlock(&kernfs_mutex);
-       return ret;
-}
-
 /**
  * kernfs_remove_by_name_ns - find a kernfs_node by name and remove it
  * @parent: parent of the target
index 1b8b91b67fdb7a4b192b9568ad1d85defdcd863a..810cf6e613e5142de7be542da24c34073fffc376 100644 (file)
@@ -372,29 +372,6 @@ void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr,
 }
 EXPORT_SYMBOL_GPL(sysfs_remove_file_ns);
 
-/**
- * sysfs_remove_file_self - remove an object attribute from its own method
- * @kobj: object we're acting for
- * @attr: attribute descriptor
- *
- * See kernfs_remove_self() for details.
- */
-bool sysfs_remove_file_self(struct kobject *kobj, const struct attribute *attr)
-{
-       struct kernfs_node *parent = kobj->sd;
-       struct kernfs_node *kn;
-       bool ret;
-
-       kn = kernfs_find_and_get(parent, attr->name);
-       if (WARN_ON_ONCE(!kn))
-               return false;
-
-       ret = kernfs_remove_self(kn);
-
-       kernfs_put(kn);
-       return ret;
-}
-
 void sysfs_remove_files(struct kobject *kobj, const struct attribute **ptr)
 {
        int i;
index 1ff3f16975131e702a4445e6cfc817803b074d3d..952b01033c32dedcf83349a988b920c1c5ed8aa8 100644 (file)
@@ -560,8 +560,6 @@ extern int device_create_file(struct device *device,
                              const struct device_attribute *entry);
 extern void device_remove_file(struct device *dev,
                               const struct device_attribute *attr);
-extern bool device_remove_file_self(struct device *dev,
-                                   const struct device_attribute *attr);
 extern int __must_check device_create_bin_file(struct device *dev,
                                        const struct bin_attribute *attr);
 extern void device_remove_bin_file(struct device *dev,
index 0b7b7cc352eb0898401363655416b12ac5cc7d65..ac8693027058b36a0cbbcef9fe0641f2da0bad28 100644 (file)
@@ -43,8 +43,6 @@ enum kernfs_node_flag {
        KERNFS_HAS_MMAP         = 0x0080,
        KERNFS_LOCKDEP          = 0x0100,
        KERNFS_STATIC_NAME      = 0x0200,
-       KERNFS_SUICIDAL         = 0x0400,
-       KERNFS_SUICIDED         = 0x0800,
 };
 
 /* type-specific structures for kernfs_node union members */
@@ -241,7 +239,6 @@ void kernfs_reactivate(struct kernfs_node *kn);
 void kernfs_deactivate_self(struct kernfs_node *kn);
 void kernfs_reactivate_self(struct kernfs_node *kn);
 void kernfs_remove(struct kernfs_node *kn);
-bool kernfs_remove_self(struct kernfs_node *kn);
 int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name,
                             const void *ns);
 int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
@@ -299,9 +296,6 @@ kernfs_create_link(struct kernfs_node *parent, const char *name,
 
 static inline void kernfs_remove(struct kernfs_node *kn) { }
 
-static inline bool kernfs_remove_self(struct kernfs_node *kn)
-{ return false; }
-
 static inline int kernfs_remove_by_name_ns(struct kernfs_node *kn,
                                           const char *name, const void *ns)
 { return -ENOSYS; }
index bd96c603ab6cc61b18e63f4b2f39ef2024bec7d8..30b2ebee643976e39f60c4fe3ff0a9618d5753e3 100644 (file)
@@ -198,7 +198,6 @@ int __must_check sysfs_chmod_file(struct kobject *kobj,
                                  const struct attribute *attr, umode_t mode);
 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);
 void sysfs_remove_files(struct kobject *kobj, const struct attribute **attr);
 
 int __must_check sysfs_create_bin_file(struct kobject *kobj,
@@ -302,12 +301,6 @@ static inline void sysfs_remove_file_ns(struct kobject *kobj,
 {
 }
 
-static inline bool sysfs_remove_file_self(struct kobject *kobj,
-                                         const struct attribute *attr)
-{
-       return false;
-}
-
 static inline void sysfs_remove_files(struct kobject *kobj,
                                     const struct attribute **attr)
 {