aboutsummaryrefslogtreecommitdiffstats
path: root/fs/kernfs/dir.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-01-13 17:05:13 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-01-13 17:05:13 -0500
commita9f138b0e537de55933335d580ebd38c2bc53c47 (patch)
treef54235f920d392519bde975d42aa4b4534f9561a /fs/kernfs/dir.c
parent8634c422c1b7e50ca8e346f65afc140d93a3212c (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.c72
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 */
1014bool 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