lkml.org 
[lkml]   [2009]   [May]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 4/5] union-directory: Make lookup continue in overlayed directories
    From: Jan Blunck <jblunck@suse.de>

    This patch lets adds support for union-directory lookup to lookups from dentry
    cache and real lookups. On union-directories a lookup must continue on
    overlayed directories of the union. The lookup continues until the first
    no-negative dentry is found. Otherwise the topmost negative dentry is
    returned.

    Signed-off-by: Jan Blunck <jblunck@suse.de>
    Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
    ---
    fs/namei.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
    1 file changed, 49 insertions(+)

    Index: linux-2.6/fs/namei.c
    ===================================================================
    --- linux-2.6.orig/fs/namei.c 2009-05-20 15:05:15.000000000 +0200
    +++ linux-2.6/fs/namei.c 2009-05-20 15:10:09.000000000 +0200
    @@ -34,6 +34,7 @@
    #include <linux/device_cgroup.h>
    #include <linux/fs_struct.h>
    #include <asm/uaccess.h>
    +#include "union.h"

    #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])

    @@ -778,6 +779,49 @@ static __always_inline void follow_dotdo
    follow_mount(&nd->path.mnt, &nd->path.dentry);
    }

    +static int do_lookup_union(struct nameidata *nd, struct qstr *name,
    + struct path *path)
    +{
    + int err;
    + struct path save;
    +
    + save = nd->path;
    + path_get(&save);
    + while (follow_union_up(&nd->path)) {
    + struct dentry *dentry;
    +
    + dentry = d_hash_and_lookup(nd->path.dentry, name);
    + if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
    + dentry = do_revalidate(dentry, nd);
    + err = PTR_ERR(dentry);
    + if (IS_ERR(dentry))
    + goto out;
    + }
    + if (!dentry) {
    + dentry = real_lookup(nd->path.dentry, name, nd);
    + err = PTR_ERR(dentry);
    + if (IS_ERR(dentry))
    + goto out;
    + }
    + if (dentry->d_inode) {
    + dput(path->dentry);
    + path->dentry = dentry;
    + path->mnt = mntget(nd->path.mnt);
    + follow_mount(&path->mnt, &path->dentry);
    + err = 0;
    + goto out;
    + }
    + dput(dentry);
    + }
    + __follow_mount(path);
    + err = 0;
    +out:
    + path_put(&nd->path);
    + nd->path = save;
    +
    + return err;
    +}
    +
    /*
    * It's more convoluted than I'd like it to be, but... it's still fairly
    * small and for now I'd prefer to have fast path as straight as possible.
    @@ -796,6 +840,11 @@ static int do_lookup(struct nameidata *n
    done:
    path->mnt = mnt;
    path->dentry = dentry;
    + if (IS_MNT_UNION(mnt) && !dentry->d_inode &&
    + nd->path.dentry == nd->path.mnt->mnt_root) {
    + return do_lookup_union(nd, name, path);
    + }
    +
    __follow_mount(path);
    return 0;

    --


    \
     
     \ /
      Last update: 2009-05-21 11:27    [W:0.022 / U:0.332 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site