diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-01-13 14:27:16 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-01-13 14:27:16 -0800 |
commit | 55f6e30d0a6a8975cc0831e8a4a3715b815b6a2f (patch) | |
tree | 0316cdf73f1d42a386563dca5e9ff73f296d6ec4 /fs/kernfs/dir.c | |
parent | 7653fe9d6cddc3fc5e4220608079006d8ac0054c (diff) |
Revert "kernfs: invoke kernfs_unmap_bin_file() directly from __kernfs_remove()"
This reverts commit f601f9a2bf7dc1f7ee18feece4c4e2fc6845d6c4.
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/kernfs/dir.c')
-rw-r--r-- | fs/kernfs/dir.c | 42 |
1 files changed, 9 insertions, 33 deletions
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index f878e4f2efe..e565ec096ae 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -121,17 +121,13 @@ static int kernfs_link_sibling(struct kernfs_node *kn) * Locking: * mutex_lock(kernfs_mutex) */ -static bool kernfs_unlink_sibling(struct kernfs_node *kn) +static void kernfs_unlink_sibling(struct kernfs_node *kn) { - if (RB_EMPTY_NODE(&kn->rb)) - return false; - if (kernfs_type(kn) == KERNFS_DIR) kn->parent->dir.subdirs--; rb_erase(&kn->rb, &kn->parent->dir.children); RB_CLEAR_NODE(&kn->rb); - return true; } /** @@ -500,6 +496,7 @@ void kernfs_addrm_finish(struct kernfs_addrm_cxt *acxt) acxt->removed = kn->u.removed_list; + kernfs_unmap_bin_file(kn); kernfs_put(kn); } } @@ -857,44 +854,23 @@ static void __kernfs_remove(struct kernfs_addrm_cxt *acxt, /* unlink the subtree node-by-node */ do { - pos = kernfs_leftmost_descendant(kn); - - /* - * We're gonna release kernfs_mutex to unmap bin files, - * Make sure @pos doesn't go away inbetween. - */ - kernfs_get(pos); + struct kernfs_iattrs *ps_iattr; - /* - * This must be come before unlinking; otherwise, when - * there are multiple removers, some may finish before - * unmapping is complete. - */ - if (pos->flags & KERNFS_HAS_MMAP) { - mutex_unlock(&kernfs_mutex); - kernfs_unmap_file(pos); - mutex_lock(&kernfs_mutex); - } + pos = kernfs_leftmost_descendant(kn); - /* - * kernfs_unlink_sibling() succeeds once per node. Use it - * to decide who's responsible for cleanups. - */ - if (!pos->parent || kernfs_unlink_sibling(pos)) { - struct kernfs_iattrs *ps_iattr = - pos->parent ? pos->parent->iattr : NULL; + if (pos->parent) { + kernfs_unlink_sibling(pos); /* update timestamps on the parent */ + ps_iattr = pos->parent->iattr; if (ps_iattr) { ps_iattr->ia_iattr.ia_ctime = CURRENT_TIME; ps_iattr->ia_iattr.ia_mtime = CURRENT_TIME; } - - pos->u.removed_list = acxt->removed; - acxt->removed = pos; } - kernfs_put(pos); + pos->u.removed_list = acxt->removed; + acxt->removed = pos; } while (pos != kn); } |