lkml.org 
[lkml]   [2010]   [Sep]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 13/34] union-mount: Free union stack on removal of topmost dentry from dcache
    Date
    From: Jan Blunck <jblunck@suse.de>

    If a dentry is removed from dentry cache because its usage count drops
    to zero, its union stack is freed too.

    Signed-off-by: Valerie Aurora <vaurora@redhat.com>
    ---
    fs/dcache.c | 11 +++++++++++
    fs/namespace.c | 2 ++
    2 files changed, 13 insertions(+), 0 deletions(-)

    diff --git a/fs/dcache.c b/fs/dcache.c
    index 85e2737..0910ce7 100644
    --- a/fs/dcache.c
    +++ b/fs/dcache.c
    @@ -34,6 +34,7 @@
    #include <linux/fs_struct.h>
    #include <linux/hardirq.h>
    #include "internal.h"
    +#include "union.h"

    int sysctl_vfs_cache_pressure __read_mostly = 100;
    EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure);
    @@ -175,6 +176,7 @@ static struct dentry *d_kill(struct dentry *dentry)
    dentry_stat.nr_dentry--; /* For d_free, below */
    /*drops the locks, at that point nobody can reach this dentry */
    dentry_iput(dentry);
    + d_free_unions(dentry);
    if (IS_ROOT(dentry))
    parent = NULL;
    else
    @@ -695,6 +697,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
    iput(inode);
    }

    + d_free_unions(dentry);
    d_free(dentry);

    /* finished when we fall off the top of the tree,
    @@ -1535,6 +1538,7 @@ void d_delete(struct dentry * dentry)
    if (atomic_read(&dentry->d_count) == 1) {
    dentry->d_flags &= ~DCACHE_CANT_MOUNT;
    dentry_iput(dentry);
    + d_free_unions(dentry);
    fsnotify_nameremove(dentry, isdir);
    return;
    }
    @@ -1545,6 +1549,13 @@ void d_delete(struct dentry * dentry)
    spin_unlock(&dentry->d_lock);
    spin_unlock(&dcache_lock);

    + /*
    + * Remove any associated unions. While someone still has this
    + * directory open (ref count > 0), we could not have deleted
    + * it unless it was empty, and therefore has no references to
    + * directories below it. So we don't need the unions.
    + */
    + d_free_unions(dentry);
    fsnotify_nameremove(dentry, isdir);
    }
    EXPORT_SYMBOL(d_delete);
    diff --git a/fs/namespace.c b/fs/namespace.c
    index f8d7d11..ffa5ed7 100644
    --- a/fs/namespace.c
    +++ b/fs/namespace.c
    @@ -33,6 +33,7 @@
    #include <asm/unistd.h>
    #include "pnode.h"
    #include "internal.h"
    +#include "union.h"

    #define HASH_SHIFT ilog2(PAGE_SIZE / sizeof(struct list_head))
    #define HASH_SIZE (1UL << HASH_SHIFT)
    @@ -1065,6 +1066,7 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill)
    propagate_umount(kill);

    list_for_each_entry(p, kill, mnt_hash) {
    + d_free_unions(p->mnt_root);
    list_del_init(&p->mnt_expire);
    list_del_init(&p->mnt_list);
    __touch_mnt_namespace(p->mnt_ns);
    --
    1.6.3.3


    \
     
     \ /
      Last update: 2010-09-17 00:17    [W:0.027 / U:0.076 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site