diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-01-13 17:05:13 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-01-13 17:05:13 -0500 |
commit | a9f138b0e537de55933335d580ebd38c2bc53c47 (patch) | |
tree | f54235f920d392519bde975d42aa4b4534f9561a /fs/kernfs/dir.c | |
parent | 8634c422c1b7e50ca8e346f65afc140d93a3212c (diff) |
Revert "kernfs, sysfs, driver-core: implement kernfs_remove_self() and its wrappers"
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>
Diffstat (limited to 'fs/kernfs/dir.c')
-rw-r--r-- | fs/kernfs/dir.c | 72 |
1 files changed, 0 insertions, 72 deletions
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index a8028be6cdb7..1aeb57969bff 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c | |||
@@ -986,78 +986,6 @@ void kernfs_remove(struct kernfs_node *kn) | |||
986 | } | 986 | } |
987 | 987 | ||
988 | /** | 988 | /** |
989 | * kernfs_remove_self - remove a kernfs_node from its own method | ||
990 | * @kn: the self kernfs_node to remove | ||
991 | * | ||
992 | * The caller must be running off of a kernfs operation which is invoked | ||
993 | * with an active reference - e.g. one of kernfs_ops. This can be used to | ||
994 | * implement a file operation which deletes itself. | ||
995 | * | ||
996 | * For example, the "delete" file for a sysfs device directory can be | ||
997 | * implemented by invoking kernfs_remove_self() on the "delete" file | ||
998 | * itself. This function breaks the circular dependency of trying to | ||
999 | * deactivate self while holding an active ref itself. It isn't necessary | ||
1000 | * to modify the usual removal path to use kernfs_remove_self(). The | ||
1001 | * "delete" implementation can simply invoke kernfs_remove_self() on self | ||
1002 | * before proceeding with the usual removal path. kernfs will ignore later | ||
1003 | * kernfs_remove() on self. | ||
1004 | * | ||
1005 | * kernfs_remove_self() can be called multiple times concurrently on the | ||
1006 | * same kernfs_node. Only the first one actually performs removal and | ||
1007 | * returns %true. All others will wait until the kernfs operation which | ||
1008 | * won self-removal finishes and return %false. Note that the losers wait | ||
1009 | * for the completion of not only the winning kernfs_remove_self() but also | ||
1010 | * the whole kernfs_ops which won the arbitration. This can be used to | ||
1011 | * guarantee, for example, all concurrent writes to a "delete" file to | ||
1012 | * finish only after the whole operation is complete. | ||
1013 | */ | ||
1014 | bool kernfs_remove_self(struct kernfs_node *kn) | ||
1015 | { | ||
1016 | bool ret; | ||
1017 | |||
1018 | mutex_lock(&kernfs_mutex); | ||
1019 | __kernfs_deactivate_self(kn); | ||
1020 | |||
1021 | /* | ||
1022 | * SUICIDAL is used to arbitrate among competing invocations. Only | ||
1023 | * the first one will actually perform removal. When the removal | ||
1024 | * is complete, SUICIDED is set and the active ref is restored | ||
1025 | * while holding kernfs_mutex. The ones which lost arbitration | ||
1026 | * waits for SUICDED && drained which can happen only after the | ||
1027 | * enclosing kernfs operation which executed the winning instance | ||
1028 | * of kernfs_remove_self() finished. | ||
1029 | */ | ||
1030 | if (!(kn->flags & KERNFS_SUICIDAL)) { | ||
1031 | kn->flags |= KERNFS_SUICIDAL; | ||
1032 | __kernfs_remove(kn); | ||
1033 | kn->flags |= KERNFS_SUICIDED; | ||
1034 | ret = true; | ||
1035 | } else { | ||
1036 | wait_queue_head_t *waitq = &kernfs_root(kn)->deactivate_waitq; | ||
1037 | DEFINE_WAIT(wait); | ||
1038 | |||
1039 | while (true) { | ||
1040 | prepare_to_wait(waitq, &wait, TASK_UNINTERRUPTIBLE); | ||
1041 | |||
1042 | if ((kn->flags & KERNFS_SUICIDED) && | ||
1043 | atomic_read(&kn->active) == KN_DEACTIVATED_BIAS) | ||
1044 | break; | ||
1045 | |||
1046 | mutex_unlock(&kernfs_mutex); | ||
1047 | schedule(); | ||
1048 | mutex_lock(&kernfs_mutex); | ||
1049 | } | ||
1050 | finish_wait(waitq, &wait); | ||
1051 | WARN_ON_ONCE(!RB_EMPTY_NODE(&kn->rb)); | ||
1052 | ret = false; | ||
1053 | } | ||
1054 | |||
1055 | __kernfs_reactivate_self(kn); | ||
1056 | mutex_unlock(&kernfs_mutex); | ||
1057 | return ret; | ||
1058 | } | ||
1059 | |||
1060 | /** | ||
1061 | * kernfs_remove_by_name_ns - find a kernfs_node by name and remove it | 989 | * kernfs_remove_by_name_ns - find a kernfs_node by name and remove it |
1062 | * @parent: parent of the target | 990 | * @parent: parent of the target |
1063 | * @name: name of the kernfs_node to remove | 991 | * @name: name of the kernfs_node to remove |