mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 23:32:14 +00:00
Revert "kernfs, sysfs, driver-core: implement kernfs_remove_self() and its wrappers"
This reverts commit 1ae06819c7
.
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>
This commit is contained in:
parent
8634c422c1
commit
a9f138b0e5
6 changed files with 0 additions and 127 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue