[patch 00/10] Use struct path in struct nameidata - Kernel

This is a discussion on [patch 00/10] Use struct path in struct nameidata - Kernel ; This is a respin for inclusion into -mm of the patch series I send on 27th September. I haven't changed the patches except for letting them apply on 2.6.23-rc8-mm1. Andrew, please add this to -mm. Thanks, Jan -- - To ...

+ Reply to Thread
Results 1 to 10 of 10

Thread: [patch 00/10] Use struct path in struct nameidata

  1. [patch 00/10] Use struct path in struct nameidata

    This is a respin for inclusion into -mm of the patch series I send on 27th
    September. I haven't changed the patches except for letting them apply on
    2.6.23-rc8-mm1.

    Andrew, please add this to -mm.

    Thanks,
    Jan

    --

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  2. [patch 03/10] Remove path_release_on_umount()

    path_release_on_umount() should only be called from sys_umount(). I merged the
    function into sys_umount() instead of having in in namei.c.

    Signed-off-by: Jan Blunck
    Acked-by: Christoph Hellwig
    ---
    fs/namei.c | 10 ----------
    fs/namespace.c | 4 +++-
    include/linux/namei.h | 1 -
    3 files changed, 3 insertions(+), 12 deletions(-)

    Index: b/fs/namei.c
    ================================================== =================
    --- a/fs/namei.c
    +++ b/fs/namei.c
    @@ -368,16 +368,6 @@ void path_release(struct nameidata *nd)
    mntput(nd->mnt);
    }

    -/*
    - * umount() mustn't call path_release()/mntput() as that would clear
    - * mnt_expiry_mark
    - */
    -void path_release_on_umount(struct nameidata *nd)
    -{
    - dput(nd->dentry);
    - mntput_no_expire(nd->mnt);
    -}
    -
    /**
    * release_open_intent - free up open intent resources
    * @nd: pointer to nameidata
    Index: b/fs/namespace.c
    ================================================== =================
    --- a/fs/namespace.c
    +++ b/fs/namespace.c
    @@ -988,7 +988,9 @@ asmlinkage long sys_umount(char __user *

    retval = do_umount(nd.mnt, flags);
    dput_and_out:
    - path_release_on_umount(&nd);
    + /* we mustn't call path_put() as that would clear mnt_expiry_mark */
    + dput(nd.dentry);
    + mntput_no_expire(nd.mnt);
    out:
    return retval;
    }
    Index: b/include/linux/namei.h
    ================================================== =================
    --- a/include/linux/namei.h
    +++ b/include/linux/namei.h
    @@ -73,7 +73,6 @@ extern int FASTCALL(path_lookup(const ch
    extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
    const char *, unsigned int, struct nameidata *);
    extern void path_release(struct nameidata *);
    -extern void path_release_on_umount(struct nameidata *);

    extern int __user_path_lookup_open(const char __user *, unsigned lookup_flags, struct nameidata *nd, int open_flags);
    extern int path_lookup_open(int dfd, const char *name, unsigned lookup_flags, struct nameidata *, int open_flags);

    --

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  3. [patch 08/10] Introduce path_get()

    This introduces the symmetric function to path_put() for getting a reference
    to the dentry and vfsmount of a struct path in the right order.

    Signed-off-by: Jan Blunck
    Signed-off-by: Andreas Gruenbacher
    Acked-by: Christoph Hellwig
    ---
    fs/namei.c | 17 +++++++++++++++--
    include/linux/namei.h | 6 ------
    include/linux/path.h | 1 +
    3 files changed, 16 insertions(+), 8 deletions(-)

    Index: b/fs/namei.c
    ================================================== =================
    --- a/fs/namei.c
    +++ b/fs/namei.c
    @@ -363,6 +363,19 @@ int deny_write_access(struct file * file
    }

    /**
    + * path_get - get a reference to a path
    + * @path: path to get the reference to
    + *
    + * Given a path increment the reference count to the dentry and the vfsmount.
    + */
    +void path_get(struct path *path)
    +{
    + mntget(path->mnt);
    + dget(path->dentry);
    +}
    +EXPORT_SYMBOL(path_get);
    +
    +/**
    * path_put - put a reference to a path
    * @path: path to put the reference to
    *
    @@ -1161,8 +1174,8 @@ static int fastcall do_path_lookup(int d
    if (retval)
    goto fput_fail;

    - nd->path.mnt = mntget(file->f_path.mnt);
    - nd->path.dentry = dget(dentry);
    + nd->path = file->f_path;
    + path_get(&file->f_path);

    fput_light(file, fput_needed);
    }
    Index: b/include/linux/namei.h
    ================================================== =================
    --- a/include/linux/namei.h
    +++ b/include/linux/namei.h
    @@ -94,10 +94,4 @@ static inline char *nd_get_link(struct n
    return nd->saved_names[nd->depth];
    }

    -static inline void pathget(struct path *path)
    -{
    - mntget(path->mnt);
    - dget(path->dentry);
    -}
    -
    #endif /* _LINUX_NAMEI_H */
    Index: b/include/linux/path.h
    ================================================== =================
    --- a/include/linux/path.h
    +++ b/include/linux/path.h
    @@ -9,6 +9,7 @@ struct path {
    struct dentry *dentry;
    };

    +extern void path_get(struct path *);
    extern void path_put(struct path *);

    #endif /* _LINUX_PATH_H */

    --

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  4. [patch 01/10] Dont touch fs_struct in drivers

    The sound drivers and the pnpbios core test for current->root != NULL. This
    test seems to be unnecessary since we always have rootfs mounted before
    initializing the drivers.

    Signed-off-by: Jan Blunck
    Acked-by: Christoph Hellwig
    ---
    drivers/pnp/pnpbios/core.c | 2 --
    sound/core/seq/seq_clientmgr.c | 4 ++--
    sound/core/seq/seq_device.c | 3 ---
    sound/core/sound.c | 4 ----
    sound/core/timer.c | 2 --
    sound/ppc/daca.c | 5 ++---
    sound/ppc/tumbler.c | 5 ++---
    7 files changed, 6 insertions(+), 19 deletions(-)

    Index: b/drivers/pnp/pnpbios/core.c
    ================================================== =================
    --- a/drivers/pnp/pnpbios/core.c
    +++ b/drivers/pnp/pnpbios/core.c
    @@ -105,8 +105,6 @@ static int pnp_dock_event(int dock, stru
    char *argv[3], **envp, *buf, *scratch;
    int i = 0, value;

    - if (!current->fs->root)
    - return -EAGAIN;
    if (!(envp = kcalloc(20, sizeof(char *), GFP_KERNEL)))
    return -ENOMEM;
    if (!(buf = kzalloc(256, GFP_KERNEL))) {
    Index: b/sound/core/seq/seq_clientmgr.c
    ================================================== =================
    --- a/sound/core/seq/seq_clientmgr.c
    +++ b/sound/core/seq/seq_clientmgr.c
    @@ -152,13 +152,13 @@ struct snd_seq_client *snd_seq_client_us
    }
    spin_unlock_irqrestore(&clients_lock, flags);
    #ifdef CONFIG_KMOD
    - if (!in_interrupt() && current->fs->root) {
    + if (!in_interrupt()) {
    static char client_requested[SNDRV_SEQ_GLOBAL_CLIENTS];
    static char card_requested[SNDRV_CARDS];
    if (clientid < SNDRV_SEQ_GLOBAL_CLIENTS) {
    int idx;

    - if (! client_requested[clientid] && current->fs->root) {
    + if (!client_requested[clientid]) {
    client_requested[clientid] = 1;
    for (idx = 0; idx < 15; idx++) {
    if (seq_client_load[idx] < 0)
    Index: b/sound/core/seq/seq_device.c
    ================================================== =================
    --- a/sound/core/seq/seq_device.c
    +++ b/sound/core/seq/seq_device.c
    @@ -150,9 +150,6 @@ void snd_seq_device_load_drivers(void)
    if (snd_seq_in_init)
    return;

    - if (! current->fs->root)
    - return;
    -
    mutex_lock(&ops_mutex);
    list_for_each_entry(ops, &opslist, list) {
    if (! (ops->driver & DRIVER_LOADED) &&
    Index: b/sound/core/sound.c
    ================================================== =================
    --- a/sound/core/sound.c
    +++ b/sound/core/sound.c
    @@ -72,8 +72,6 @@ static DEFINE_MUTEX(sound_mutex);
    */
    void snd_request_card(int card)
    {
    - if (! current->fs->root)
    - return;
    if (snd_card_locked(card))
    return;
    if (card < 0 || card >= cards_limit)
    @@ -87,8 +85,6 @@ static void snd_request_other(int minor)
    {
    char *str;

    - if (! current->fs->root)
    - return;
    switch (minor) {
    case SNDRV_MINOR_SEQUENCER: str = "snd-seq"; break;
    case SNDRV_MINOR_TIMER: str = "snd-timer"; break;
    Index: b/sound/core/timer.c
    ================================================== =================
    --- a/sound/core/timer.c
    +++ b/sound/core/timer.c
    @@ -148,8 +148,6 @@ static struct snd_timer *snd_timer_find(

    static void snd_timer_request(struct snd_timer_id *tid)
    {
    - if (! current->fs->root)
    - return;
    switch (tid->dev_class) {
    case SNDRV_TIMER_CLASS_GLOBAL:
    if (tid->device < timer_limit)
    Index: b/sound/ppc/daca.c
    ================================================== =================
    --- a/sound/ppc/daca.c
    +++ b/sound/ppc/daca.c
    @@ -246,9 +246,8 @@ int __init snd_pmac_daca_init(struct snd
    struct pmac_daca *mix;

    #ifdef CONFIG_KMOD
    - if (current->fs->root)
    - request_module("i2c-powermac");
    -#endif /* CONFIG_KMOD */
    + request_module("i2c-powermac");
    +#endif /* CONFIG_KMOD */

    mix = kzalloc(sizeof(*mix), GFP_KERNEL);
    if (! mix)
    Index: b/sound/ppc/tumbler.c
    ================================================== =================
    --- a/sound/ppc/tumbler.c
    +++ b/sound/ppc/tumbler.c
    @@ -1327,9 +1327,8 @@ int __init snd_pmac_tumbler_init(struct
    char *chipname;

    #ifdef CONFIG_KMOD
    - if (current->fs->root)
    - request_module("i2c-powermac");
    -#endif /* CONFIG_KMOD */
    + request_module("i2c-powermac");
    +#endif /* CONFIG_KMOD */

    mix = kzalloc(sizeof(*mix), GFP_KERNEL);
    if (! mix)

    --

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  5. [patch 04/10] Move struct path into its own header

    Move the definition of struct path into its own header file for further
    patches.

    Signed-off-by: Jan Blunck
    Signed-off-by: Andreas Gruenbacher
    Acked-by: Christoph Hellwig
    ---
    include/linux/namei.h | 6 +-----
    include/linux/path.h | 12 ++++++++++++
    2 files changed, 13 insertions(+), 5 deletions(-)

    Index: b/include/linux/namei.h
    ================================================== =================
    --- a/include/linux/namei.h
    +++ b/include/linux/namei.h
    @@ -4,6 +4,7 @@
    #include
    #include
    #include
    +#include

    struct vfsmount;

    @@ -30,11 +31,6 @@ struct nameidata {
    } intent;
    };

    -struct path {
    - struct vfsmount *mnt;
    - struct dentry *dentry;
    -};
    -
    /*
    * Type of the last component on LOOKUP_PARENT
    */
    Index: b/include/linux/path.h
    ================================================== =================
    --- /dev/null
    +++ b/include/linux/path.h
    @@ -0,0 +1,12 @@
    +#ifndef _LINUX_PATH_H
    +#define _LINUX_PATH_H
    +
    +struct dentry;
    +struct vfsmount;
    +
    +struct path {
    + struct vfsmount *mnt;
    + struct dentry *dentry;
    +};
    +
    +#endif /* _LINUX_PATH_H */

    --

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  6. [patch 02/10] Dont touch fs_struct in usermodehelper

    This test seems to be unnecessary since we always have rootfs mounted before
    calling a usermodehelper.

    Signed-off-by: Andreas Gruenbacher
    Signed-off-by: Jan Blunck
    Acked-by: Christoph Hellwig
    Acked-by: Greg KH
    ---
    kernel/kmod.c | 5 +----
    1 file changed, 1 insertion(+), 4 deletions(-)

    Index: b/kernel/kmod.c
    ================================================== =================
    --- a/kernel/kmod.c
    +++ b/kernel/kmod.c
    @@ -173,10 +173,7 @@ static int ____call_usermodehelper(void
    */
    set_user_nice(current, 0);

    - retval = -EPERM;
    - if (current->fs->root)
    - retval = kernel_execve(sub_info->path,
    - sub_info->argv, sub_info->envp);
    + retval = kernel_execve(sub_info->path, sub_info->argv, sub_info->envp);

    /* Exec failed? */
    sub_info->retval = retval;

    --

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  7. [patch 05/10] Embed a struct path into struct nameidata instead of nd->{dentry,mnt}

    Switch from nd->{dentry,mnt} to nd->path.{dentry,mnt} everywhere.

    Signed-off-by: Jan Blunck
    Signed-off-by: Andreas Gruenbacher
    Acked-by: Christoph Hellwig
    ---
    arch/alpha/kernel/osf_sys.c | 2
    arch/mips/kernel/sysirix.c | 6
    arch/parisc/hpux/sys_hpux.c | 2
    arch/powerpc/platforms/cell/spufs/inode.c | 18 +-
    arch/sparc64/solaris/fs.c | 8
    arch/um/drivers/mconsole_kern.c | 6
    drivers/md/dm-table.c | 2
    drivers/mtd/mtdsuper.c | 10 -
    fs/afs/mntpt.c | 22 +-
    fs/autofs4/root.c | 3
    fs/block_dev.c | 4
    fs/coda/pioctl.c | 2
    fs/compat.c | 4
    fs/configfs/symlink.c | 4
    fs/dquot.c | 7
    fs/ecryptfs/dentry.c | 12 -
    fs/ecryptfs/inode.c | 24 +-
    fs/ecryptfs/main.c | 4
    fs/exec.c | 4
    fs/ext3/super.c | 4
    fs/ext4/super.c | 4
    fs/gfs2/ops_fstype.c | 5
    fs/inotify_user.c | 2
    fs/namei.c | 258 +++++++++++++++---------------
    fs/namespace.c | 195 ++++++++++++----------
    fs/nfs/namespace.c | 27 +--
    fs/nfs/nfs4proc.c | 15 -
    fs/nfsctl.c | 2
    fs/nfsd/export.c | 35 ++--
    fs/nfsd/nfs4recover.c | 36 ++--
    fs/nfsd/nfs4state.c | 2
    fs/open.c | 51 +++--
    fs/proc/base.c | 3
    fs/proc/proc_net.c | 10 -
    fs/proc/proc_sysctl.c | 2
    fs/reiserfs/super.c | 6
    fs/revoke.c | 2
    fs/stat.c | 13 -
    fs/utimes.c | 4
    fs/xattr.c | 24 +-
    fs/xfs/linux-2.6/xfs_ioctl.c | 6
    include/linux/namei.h | 3
    kernel/auditfilter.c | 11 -
    net/sunrpc/rpc_pipe.c | 5
    net/unix/af_unix.c | 30 +--
    security/selinux/hooks.c | 4
    46 files changed, 463 insertions(+), 440 deletions(-)

    Index: b/arch/alpha/kernel/osf_sys.c
    ================================================== =================
    --- a/arch/alpha/kernel/osf_sys.c
    +++ b/arch/alpha/kernel/osf_sys.c
    @@ -260,7 +260,7 @@ osf_statfs(char __user *path, struct osf

    retval = user_path_walk(path, &nd);
    if (!retval) {
    - retval = do_osf_statfs(nd.dentry, buffer, bufsiz);
    + retval = do_osf_statfs(nd.path.dentry, buffer, bufsiz);
    path_release(&nd);
    }
    return retval;
    Index: b/arch/mips/kernel/sysirix.c
    ================================================== =================
    --- a/arch/mips/kernel/sysirix.c
    +++ b/arch/mips/kernel/sysirix.c
    @@ -694,7 +694,7 @@ asmlinkage int irix_statfs(const char __
    if (error)
    goto out;

    - error = vfs_statfs(nd.dentry, &kbuf);
    + error = vfs_statfs(nd.path.dentry, &kbuf);
    if (error)
    goto dput_and_out;

    @@ -1360,7 +1360,7 @@ asmlinkage int irix_statvfs(char __user
    error = user_path_walk(fname, &nd);
    if (error)
    goto out;
    - error = vfs_statfs(nd.dentry, &kbuf);
    + error = vfs_statfs(nd.path.dentry, &kbuf);
    if (error)
    goto dput_and_out;

    @@ -1611,7 +1611,7 @@ asmlinkage int irix_statvfs64(char __use
    error = user_path_walk(fname, &nd);
    if (error)
    goto out;
    - error = vfs_statfs(nd.dentry, &kbuf);
    + error = vfs_statfs(nd.path.dentry, &kbuf);
    if (error)
    goto dput_and_out;

    Index: b/arch/parisc/hpux/sys_hpux.c
    ================================================== =================
    --- a/arch/parisc/hpux/sys_hpux.c
    +++ b/arch/parisc/hpux/sys_hpux.c
    @@ -219,7 +219,7 @@ asmlinkage long hpux_statfs(const char _
    error = user_path_walk(path, &nd);
    if (!error) {
    struct hpux_statfs tmp;
    - error = vfs_statfs_hpux(nd.dentry, &tmp);
    + error = vfs_statfs_hpux(nd.path.dentry, &tmp);
    if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
    error = -EFAULT;
    path_release(&nd);
    Index: b/arch/powerpc/platforms/cell/spufs/inode.c
    ================================================== =================
    --- a/arch/powerpc/platforms/cell/spufs/inode.c
    +++ b/arch/powerpc/platforms/cell/spufs/inode.c
    @@ -1,3 +1,4 @@
    +
    /*
    * SPU file system
    *
    @@ -578,7 +579,7 @@ long spufs_create(struct nameidata *nd,

    ret = -EINVAL;
    /* check if we are on spufs */
    - if (nd->dentry->d_sb->s_type != &spufs_type)
    + if (nd->path.dentry->d_sb->s_type != &spufs_type)
    goto out;

    /* don't accept undefined flags */
    @@ -586,9 +587,9 @@ long spufs_create(struct nameidata *nd,
    goto out;

    /* only threads can be underneath a gang */
    - if (nd->dentry != nd->dentry->d_sb->s_root) {
    + if (nd->path.dentry != nd->path.dentry->d_sb->s_root) {
    if ((flags & SPU_CREATE_GANG) ||
    - !SPUFS_I(nd->dentry->d_inode)->i_gang)
    + !SPUFS_I(nd->path.dentry->d_inode)->i_gang)
    goto out;
    }

    @@ -604,16 +605,17 @@ long spufs_create(struct nameidata *nd,
    mode &= ~current->fs->umask;

    if (flags & SPU_CREATE_GANG)
    - return spufs_create_gang(nd->dentry->d_inode,
    - dentry, nd->mnt, mode);
    + return spufs_create_gang(nd->path.dentry->d_inode,
    + dentry, nd->path.mnt, mode);
    else
    - return spufs_create_context(nd->dentry->d_inode,
    - dentry, nd->mnt, flags, mode, filp);
    + return spufs_create_context(nd->path.dentry->d_inode,
    + dentry, nd->path.mnt, flags, mode,
    + filp);

    out_dput:
    dput(dentry);
    out_dir:
    - mutex_unlock(&nd->dentry->d_inode->i_mutex);
    + mutex_unlock(&nd->path.dentry->d_inode->i_mutex);
    out:
    return ret;
    }
    Index: b/arch/sparc64/solaris/fs.c
    ================================================== =================
    --- a/arch/sparc64/solaris/fs.c
    +++ b/arch/sparc64/solaris/fs.c
    @@ -434,8 +434,8 @@ asmlinkage int solaris_statvfs(u32 path,

    error = user_path_walk(A(path),&nd);
    if (!error) {
    - struct inode * inode = nd.dentry->d_inode;
    - error = report_statvfs(nd.mnt, inode, buf);
    + struct inode *inode = nd.path.dentry->d_inode;
    + error = report_statvfs(nd.path.mnt, inode, buf);
    path_release(&nd);
    }
    return error;
    @@ -464,8 +464,8 @@ asmlinkage int solaris_statvfs64(u32 pat
    lock_kernel();
    error = user_path_walk(A(path), &nd);
    if (!error) {
    - struct inode * inode = nd.dentry->d_inode;
    - error = report_statvfs64(nd.mnt, inode, buf);
    + struct inode *inode = nd.path.dentry->d_inode;
    + error = report_statvfs64(nd.path.mnt, inode, buf);
    path_release(&nd);
    }
    unlock_kernel();
    Index: b/arch/um/drivers/mconsole_kern.c
    ================================================== =================
    --- a/arch/um/drivers/mconsole_kern.c
    +++ b/arch/um/drivers/mconsole_kern.c
    @@ -143,8 +143,8 @@ void mconsole_proc(struct mc_request *re
    }
    up_write(&super->s_umount);

    - nd.dentry = super->s_root;
    - nd.mnt = NULL;
    + nd.path.dentry = super->s_root;
    + nd.path.mnt = NULL;
    nd.flags = O_RDONLY + 1;
    nd.last_type = LAST_ROOT;

    @@ -157,7 +157,7 @@ void mconsole_proc(struct mc_request *re
    goto out_kill;
    }

    - file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
    + file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY);
    if (IS_ERR(file)) {
    mconsole_reply(req, "Failed to open file", 1, 0);
    goto out_kill;
    Index: b/drivers/md/dm-table.c
    ================================================== =================
    --- a/drivers/md/dm-table.c
    +++ b/drivers/md/dm-table.c
    @@ -355,7 +355,7 @@ static int lookup_device(const char *pat
    if ((r = path_lookup(path, LOOKUP_FOLLOW, &nd)))
    return r;

    - inode = nd.dentry->d_inode;
    + inode = nd.path.dentry->d_inode;
    if (!inode) {
    r = -ENOENT;
    goto out;
    Index: b/drivers/mtd/mtdsuper.c
    ================================================== =================
    --- a/drivers/mtd/mtdsuper.c
    +++ b/drivers/mtd/mtdsuper.c
    @@ -184,25 +184,25 @@ int get_sb_mtd(struct file_system_type *
    ret = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);

    DEBUG(1, "MTDSB: path_lookup() returned %d, inode %p\n",
    - ret, nd.dentry ? nd.dentry->d_inode : NULL);
    + ret, nd.path.dentry ? nd.path.dentry->d_inode : NULL);

    if (ret)
    return ret;

    ret = -EINVAL;

    - if (!S_ISBLK(nd.dentry->d_inode->i_mode))
    + if (!S_ISBLK(nd.path.dentry->d_inode->i_mode))
    goto out;

    - if (nd.mnt->mnt_flags & MNT_NODEV) {
    + if (nd.path.mnt->mnt_flags & MNT_NODEV) {
    ret = -EACCES;
    goto out;
    }

    - if (imajor(nd.dentry->d_inode) != MTD_BLOCK_MAJOR)
    + if (imajor(nd.path.dentry->d_inode) != MTD_BLOCK_MAJOR)
    goto not_an_MTD_device;

    - mtdnr = iminor(nd.dentry->d_inode);
    + mtdnr = iminor(nd.path.dentry->d_inode);
    path_release(&nd);

    return get_sb_mtd_nr(fs_type, flags, dev_name, data, mtdnr, fill_super,
    Index: b/fs/afs/mntpt.c
    ================================================== =================
    --- a/fs/afs/mntpt.c
    +++ b/fs/afs/mntpt.c
    @@ -218,14 +218,14 @@ static void *afs_mntpt_follow_link(struc
    _enter("%p{%s},{%s:%p{%s},}",
    dentry,
    dentry->d_name.name,
    - nd->mnt->mnt_devname,
    + nd->path.mnt->mnt_devname,
    dentry,
    - nd->dentry->d_name.name);
    + nd->path.dentry->d_name.name);

    - dput(nd->dentry);
    - nd->dentry = dget(dentry);
    + dput(nd->path.dentry);
    + nd->path.dentry = dget(dentry);

    - newmnt = afs_mntpt_do_automount(nd->dentry);
    + newmnt = afs_mntpt_do_automount(nd->path.dentry);
    if (IS_ERR(newmnt)) {
    path_release(nd);
    return (void *)newmnt;
    @@ -235,17 +235,17 @@ static void *afs_mntpt_follow_link(struc
    err = do_add_mount(newmnt, nd, MNT_SHRINKABLE, &afs_vfsmounts);
    switch (err) {
    case 0:
    - dput(nd->dentry);
    - mntput(nd->mnt);
    - nd->mnt = newmnt;
    - nd->dentry = dget(newmnt->mnt_root);
    + dput(nd->path.dentry);
    + mntput(nd->path.mnt);
    + nd->path.mnt = newmnt;
    + nd->path.dentry = dget(newmnt->mnt_root);
    schedule_delayed_work(&afs_mntpt_expiry_timer,
    afs_mntpt_expiry_timeout * HZ);
    break;
    case -EBUSY:
    /* someone else made a mount here whilst we were busy */
    - while (d_mountpoint(nd->dentry) &&
    - follow_down(&nd->mnt, &nd->dentry))
    + while (d_mountpoint(nd->path.dentry) &&
    + follow_down(&nd->path.mnt, &nd->path.dentry))
    ;
    err = 0;
    default:
    Index: b/fs/autofs4/root.c
    ================================================== =================
    --- a/fs/autofs4/root.c
    +++ b/fs/autofs4/root.c
    @@ -526,7 +526,8 @@ static void *autofs4_follow_link(struct
    * so we don't need to follow the mount.
    */
    if (d_mountpoint(dentry)) {
    - if (!autofs4_follow_mount(&nd->mnt, &nd->dentry)) {
    + if (!autofs4_follow_mount(&nd->path.mnt,
    + &nd->path.dentry)) {
    status = -ENOENT;
    goto out_error;
    }
    Index: b/fs/block_dev.c
    ================================================== =================
    --- a/fs/block_dev.c
    +++ b/fs/block_dev.c
    @@ -1403,12 +1403,12 @@ struct block_device *lookup_bdev(const c
    if (error)
    return ERR_PTR(error);

    - inode = nd.dentry->d_inode;
    + inode = nd.path.dentry->d_inode;
    error = -ENOTBLK;
    if (!S_ISBLK(inode->i_mode))
    goto fail;
    error = -EACCES;
    - if (nd.mnt->mnt_flags & MNT_NODEV)
    + if (nd.path.mnt->mnt_flags & MNT_NODEV)
    goto fail;
    error = -ENOMEM;
    bdev = bd_acquire(inode);
    Index: b/fs/coda/pioctl.c
    ================================================== =================
    --- a/fs/coda/pioctl.c
    +++ b/fs/coda/pioctl.c
    @@ -75,7 +75,7 @@ static int coda_pioctl(struct inode * in
    if ( error ) {
    return error;
    } else {
    - target_inode = nd.dentry->d_inode;
    + target_inode = nd.path.dentry->d_inode;
    }

    /* return if it is not a Coda inode */
    Index: b/fs/compat.c
    ================================================== =================
    --- a/fs/compat.c
    +++ b/fs/compat.c
    @@ -241,7 +241,7 @@ asmlinkage long compat_sys_statfs(const
    error = user_path_walk(path, &nd);
    if (!error) {
    struct kstatfs tmp;
    - error = vfs_statfs(nd.dentry, &tmp);
    + error = vfs_statfs(nd.path.dentry, &tmp);
    if (!error)
    error = put_compat_statfs(buf, &tmp);
    path_release(&nd);
    @@ -309,7 +309,7 @@ asmlinkage long compat_sys_statfs64(cons
    error = user_path_walk(path, &nd);
    if (!error) {
    struct kstatfs tmp;
    - error = vfs_statfs(nd.dentry, &tmp);
    + error = vfs_statfs(nd.path.dentry, &tmp);
    if (!error)
    error = put_compat_statfs64(buf, &tmp);
    path_release(&nd);
    Index: b/fs/configfs/symlink.c
    ================================================== =================
    --- a/fs/configfs/symlink.c
    +++ b/fs/configfs/symlink.c
    @@ -99,8 +99,8 @@ static int get_target(const char *symnam

    ret = path_lookup(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, nd);
    if (!ret) {
    - if (nd->dentry->d_sb == configfs_sb) {
    - *target = configfs_get_config_item(nd->dentry);
    + if (nd->path.dentry->d_sb == configfs_sb) {
    + *target = configfs_get_config_item(nd->path.dentry);
    if (!*target) {
    ret = -ENOENT;
    path_release(nd);
    Index: b/fs/dquot.c
    ================================================== =================
    --- a/fs/dquot.c
    +++ b/fs/dquot.c
    @@ -1620,14 +1620,15 @@ int vfs_quota_on(struct super_block *sb,
    error = path_lookup(path, LOOKUP_FOLLOW, &nd);
    if (error < 0)
    return error;
    - error = security_quota_on(nd.dentry);
    + error = security_quota_on(nd.path.dentry);
    if (error)
    goto out_path;
    /* Quota file not on the same filesystem? */
    - if (nd.mnt->mnt_sb != sb)
    + if (nd.path.mnt->mnt_sb != sb)
    error = -EXDEV;
    else
    - error = vfs_quota_on_inode(nd.dentry->d_inode, type, format_id);
    + error = vfs_quota_on_inode(nd.path.dentry->d_inode, type,
    + format_id);
    out_path:
    path_release(&nd);
    return error;
    Index: b/fs/ecryptfs/dentry.c
    ================================================== =================
    --- a/fs/ecryptfs/dentry.c
    +++ b/fs/ecryptfs/dentry.c
    @@ -51,13 +51,13 @@ static int ecryptfs_d_revalidate(struct

    if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate)
    goto out;
    - dentry_save = nd->dentry;
    - vfsmount_save = nd->mnt;
    - nd->dentry = lower_dentry;
    - nd->mnt = lower_mnt;
    + dentry_save = nd->path.dentry;
    + vfsmount_save = nd->path.mnt;
    + nd->path.dentry = lower_dentry;
    + nd->path.mnt = lower_mnt;
    rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd);
    - nd->dentry = dentry_save;
    - nd->mnt = vfsmount_save;
    + nd->path.dentry = dentry_save;
    + nd->path.mnt = vfsmount_save;
    if (dentry->d_inode) {
    struct inode *lower_inode =
    ecryptfs_inode_to_lower(dentry->d_inode);
    Index: b/fs/ecryptfs/inode.c
    ================================================== =================
    --- a/fs/ecryptfs/inode.c
    +++ b/fs/ecryptfs/inode.c
    @@ -77,13 +77,13 @@ ecryptfs_create_underlying_file(struct i
    struct vfsmount *vfsmount_save;
    int rc;

    - dentry_save = nd->dentry;
    - vfsmount_save = nd->mnt;
    - nd->dentry = lower_dentry;
    - nd->mnt = lower_mnt;
    + dentry_save = nd->path.dentry;
    + vfsmount_save = nd->path.mnt;
    + nd->path.dentry = lower_dentry;
    + nd->path.mnt = lower_mnt;
    rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd);
    - nd->dentry = dentry_save;
    - nd->mnt = vfsmount_save;
    + nd->path.dentry = dentry_save;
    + nd->path.mnt = vfsmount_save;
    return rc;
    }

    @@ -833,14 +833,14 @@ ecryptfs_permission(struct inode *inode,
    int rc;

    if (nd) {
    - struct vfsmount *vfsmnt_save = nd->mnt;
    - struct dentry *dentry_save = nd->dentry;
    + struct vfsmount *vfsmnt_save = nd->path.mnt;
    + struct dentry *dentry_save = nd->path.dentry;

    - nd->mnt = ecryptfs_dentry_to_lower_mnt(nd->dentry);
    - nd->dentry = ecryptfs_dentry_to_lower(nd->dentry);
    + nd->path.mnt = ecryptfs_dentry_to_lower_mnt(nd->path.dentry);
    + nd->path.dentry = ecryptfs_dentry_to_lower(nd->path.dentry);
    rc = permission(ecryptfs_inode_to_lower(inode), mask, nd);
    - nd->mnt = vfsmnt_save;
    - nd->dentry = dentry_save;
    + nd->path.mnt = vfsmnt_save;
    + nd->path.dentry = dentry_save;
    } else
    rc = permission(ecryptfs_inode_to_lower(inode), mask, NULL);
    return rc;
    Index: b/fs/ecryptfs/main.c
    ================================================== =================
    --- a/fs/ecryptfs/main.c
    +++ b/fs/ecryptfs/main.c
    @@ -519,8 +519,8 @@ static int ecryptfs_read_super(struct su
    ecryptfs_printk(KERN_WARNING, "path_lookup() failed\n");
    goto out;
    }
    - lower_root = nd.dentry;
    - lower_mnt = nd.mnt;
    + lower_root = nd.path.dentry;
    + lower_mnt = nd.path.mnt;
    ecryptfs_set_superblock_lower(sb, lower_root->d_sb);
    sb->s_maxbytes = lower_root->d_sb->s_maxbytes;
    ecryptfs_set_dentry_lower(sb->s_root, lower_root);
    Index: b/fs/exec.c
    ================================================== =================
    --- a/fs/exec.c
    +++ b/fs/exec.c
    @@ -112,7 +112,7 @@ asmlinkage long sys_uselib(const char __
    goto out;

    error = -EINVAL;
    - if (!S_ISREG(nd.dentry->d_inode->i_mode))
    + if (!S_ISREG(nd.path.dentry->d_inode->i_mode))
    goto exit;

    error = vfs_permission(&nd, MAY_READ | MAY_EXEC);
    @@ -653,7 +653,7 @@ struct file *open_exec(const char *name)
    file = ERR_PTR(err);

    if (!err) {
    - struct inode *inode = nd.dentry->d_inode;
    + struct inode *inode = nd.path.dentry->d_inode;
    file = ERR_PTR(-EACCES);
    if (S_ISREG(inode->i_mode)) {
    int err = vfs_permission(&nd, MAY_EXEC);
    Index: b/fs/ext3/super.c
    ================================================== =================
    --- a/fs/ext3/super.c
    +++ b/fs/ext3/super.c
    @@ -2731,12 +2731,12 @@ static int ext3_quota_on(struct super_bl
    if (err)
    return err;
    /* Quotafile not on the same filesystem? */
    - if (nd.mnt->mnt_sb != sb) {
    + if (nd.path.mnt->mnt_sb != sb) {
    path_release(&nd);
    return -EXDEV;
    }
    /* Quotafile not of fs root? */
    - if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode)
    + if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode)
    printk(KERN_WARNING
    "EXT3-fs: Quota file not on filesystem root. "
    "Journalled quota will not work.\n");
    Index: b/fs/ext4/super.c
    ================================================== =================
    --- a/fs/ext4/super.c
    +++ b/fs/ext4/super.c
    @@ -2933,12 +2933,12 @@ static int ext4_quota_on(struct super_bl
    if (err)
    return err;
    /* Quotafile not on the same filesystem? */
    - if (nd.mnt->mnt_sb != sb) {
    + if (nd.path.mnt->mnt_sb != sb) {
    path_release(&nd);
    return -EXDEV;
    }
    /* Quotafile not of fs root? */
    - if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode)
    + if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode)
    printk(KERN_WARNING
    "EXT4-fs: Quota file not on filesystem root. "
    "Journalled quota will not work.\n");
    Index: b/fs/gfs2/ops_fstype.c
    ================================================== =================
    --- a/fs/gfs2/ops_fstype.c
    +++ b/fs/gfs2/ops_fstype.c
    @@ -821,12 +821,13 @@ static struct super_block* get_gfs2_sb(c
    dev_name);
    goto out;
    }
    - error = vfs_getattr(nd.mnt, nd.dentry, &stat);
    + error = vfs_getattr(nd.path.mnt, nd.path.dentry, &stat);

    fstype = get_fs_type("gfs2");
    list_for_each_entry(s, &fstype->fs_supers, s_instances) {
    if ((S_ISBLK(stat.mode) && s->s_dev == stat.rdev) ||
    - (S_ISDIR(stat.mode) && s == nd.dentry->d_inode->i_sb)) {
    + (S_ISDIR(stat.mode) &&
    + s == nd.path.dentry->d_inode->i_sb)) {
    sb = s;
    goto free_nd;
    }
    Index: b/fs/inotify_user.c
    ================================================== =================
    --- a/fs/inotify_user.c
    +++ b/fs/inotify_user.c
    @@ -639,7 +639,7 @@ asmlinkage long sys_inotify_add_watch(in
    goto fput_and_out;

    /* inode held in place by reference to nd; dev by fget on fd */
    - inode = nd.dentry->d_inode;
    + inode = nd.path.dentry->d_inode;
    dev = filp->private_data;

    mutex_lock(&dev->up_mutex);
    Index: b/fs/namei.c
    ================================================== =================
    --- a/fs/namei.c
    +++ b/fs/namei.c
    @@ -231,7 +231,7 @@ int permission(struct inode *inode, int
    struct vfsmount *mnt = NULL;

    if (nd)
    - mnt = nd->mnt;
    + mnt = nd->path.mnt;

    if (mask & MAY_WRITE) {
    umode_t mode = inode->i_mode;
    @@ -296,7 +296,7 @@ int permission(struct inode *inode, int
    */
    int vfs_permission(struct nameidata *nd, int mask)
    {
    - return permission(nd->dentry->d_inode, mask, nd);
    + return permission(nd->path.dentry->d_inode, mask, nd);
    }

    /**
    @@ -364,8 +364,8 @@ int deny_write_access(struct file * file

    void path_release(struct nameidata *nd)
    {
    - dput(nd->dentry);
    - mntput(nd->mnt);
    + dput(nd->path.dentry);
    + mntput(nd->path.mnt);
    }

    /**
    @@ -531,15 +531,15 @@ walk_init_root(const char *name, struct

    read_lock(&fs->lock);
    if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
    - nd->mnt = mntget(fs->altrootmnt);
    - nd->dentry = dget(fs->altroot);
    + nd->path.mnt = mntget(fs->altrootmnt);
    + nd->path.dentry = dget(fs->altroot);
    read_unlock(&fs->lock);
    if (__emul_lookup_dentry(name,nd))
    return 0;
    read_lock(&fs->lock);
    }
    - nd->mnt = mntget(fs->rootmnt);
    - nd->dentry = dget(fs->root);
    + nd->path.mnt = mntget(fs->rootmnt);
    + nd->path.dentry = dget(fs->root);
    read_unlock(&fs->lock);
    return 1;
    }
    @@ -582,17 +582,17 @@ fail:
    static inline void dput_path(struct path *path, struct nameidata *nd)
    {
    dput(path->dentry);
    - if (path->mnt != nd->mnt)
    + if (path->mnt != nd->path.mnt)
    mntput(path->mnt);
    }

    static inline void path_to_nameidata(struct path *path, struct nameidata *nd)
    {
    - dput(nd->dentry);
    - if (nd->mnt != path->mnt)
    - mntput(nd->mnt);
    - nd->mnt = path->mnt;
    - nd->dentry = path->dentry;
    + dput(nd->path.dentry);
    + if (nd->path.mnt != path->mnt)
    + mntput(nd->path.mnt);
    + nd->path.mnt = path->mnt;
    + nd->path.dentry = path->dentry;
    }

    static __always_inline int __do_follow_link(struct path *path, struct nameidata *nd)
    @@ -604,7 +604,7 @@ static __always_inline int __do_follow_l
    touch_atime(path->mnt, dentry);
    nd_set_link(nd, NULL);

    - if (path->mnt != nd->mnt) {
    + if (path->mnt != nd->path.mnt) {
    path_to_nameidata(path, nd);
    dget(dentry);
    }
    @@ -734,37 +734,37 @@ static __always_inline void follow_dotdo

    while(1) {
    struct vfsmount *parent;
    - struct dentry *old = nd->dentry;
    + struct dentry *old = nd->path.dentry;

    read_lock(&fs->lock);
    - if (nd->dentry == fs->root &&
    - nd->mnt == fs->rootmnt) {
    + if (nd->path.dentry == fs->root &&
    + nd->path.mnt == fs->rootmnt) {
    read_unlock(&fs->lock);
    break;
    }
    read_unlock(&fs->lock);
    spin_lock(&dcache_lock);
    - if (nd->dentry != nd->mnt->mnt_root) {
    - nd->dentry = dget(nd->dentry->d_parent);
    + if (nd->path.dentry != nd->path.mnt->mnt_root) {
    + nd->path.dentry = dget(nd->path.dentry->d_parent);
    spin_unlock(&dcache_lock);
    dput(old);
    break;
    }
    spin_unlock(&dcache_lock);
    spin_lock(&vfsmount_lock);
    - parent = nd->mnt->mnt_parent;
    - if (parent == nd->mnt) {
    + parent = nd->path.mnt->mnt_parent;
    + if (parent == nd->path.mnt) {
    spin_unlock(&vfsmount_lock);
    break;
    }
    mntget(parent);
    - nd->dentry = dget(nd->mnt->mnt_mountpoint);
    + nd->path.dentry = dget(nd->path.mnt->mnt_mountpoint);
    spin_unlock(&vfsmount_lock);
    dput(old);
    - mntput(nd->mnt);
    - nd->mnt = parent;
    + mntput(nd->path.mnt);
    + nd->path.mnt = parent;
    }
    - follow_mount(&nd->mnt, &nd->dentry);
    + follow_mount(&nd->path.mnt, &nd->path.dentry);
    }

    /*
    @@ -775,8 +775,8 @@ static __always_inline void follow_dotdo
    static int do_lookup(struct nameidata *nd, struct qstr *name,
    struct path *path)
    {
    - struct vfsmount *mnt = nd->mnt;
    - struct dentry *dentry = __d_lookup(nd->dentry, name);
    + struct vfsmount *mnt = nd->path.mnt;
    + struct dentry *dentry = __d_lookup(nd->path.dentry, name);

    if (!dentry)
    goto need_lookup;
    @@ -789,7 +789,7 @@ done:
    return 0;

    need_lookup:
    - dentry = real_lookup(nd->dentry, name, nd);
    + dentry = real_lookup(nd->path.dentry, name, nd);
    if (IS_ERR(dentry))
    goto fail;
    goto done;
    @@ -826,7 +826,7 @@ static fastcall int __link_path_walk(con
    if (!*name)
    goto return_reval;

    - inode = nd->dentry->d_inode;
    + inode = nd->path.dentry->d_inode;
    if (nd->depth)
    lookup_flags = LOOKUP_FOLLOW | (nd->flags & LOOKUP_CONTINUE);

    @@ -874,7 +874,7 @@ static fastcall int __link_path_walk(con
    if (this.name[1] != '.')
    break;
    follow_dotdot(nd);
    - inode = nd->dentry->d_inode;
    + inode = nd->path.dentry->d_inode;
    /* fallthrough */
    case 1:
    continue;
    @@ -883,8 +883,9 @@ static fastcall int __link_path_walk(con
    * See if the low-level filesystem might want
    * to use its own hash..
    */
    - if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {
    - err = nd->dentry->d_op->d_hash(nd->dentry, &this);
    + if (nd->path.dentry->d_op && nd->path.dentry->d_op->d_hash) {
    + err = nd->path.dentry->d_op->d_hash(nd->path.dentry,
    + &this);
    if (err < 0)
    break;
    }
    @@ -906,7 +907,7 @@ static fastcall int __link_path_walk(con
    if (err)
    goto return_err;
    err = -ENOENT;
    - inode = nd->dentry->d_inode;
    + inode = nd->path.dentry->d_inode;
    if (!inode)
    break;
    err = -ENOTDIR;
    @@ -934,13 +935,14 @@ last_component:
    if (this.name[1] != '.')
    break;
    follow_dotdot(nd);
    - inode = nd->dentry->d_inode;
    + inode = nd->path.dentry->d_inode;
    /* fallthrough */
    case 1:
    goto return_reval;
    }
    - if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {
    - err = nd->dentry->d_op->d_hash(nd->dentry, &this);
    + if (nd->path.dentry->d_op && nd->path.dentry->d_op->d_hash) {
    + err = nd->path.dentry->d_op->d_hash(nd->path.dentry,
    + &this);
    if (err < 0)
    break;
    }
    @@ -953,7 +955,7 @@ last_component:
    err = do_follow_link(&next, nd);
    if (err)
    goto return_err;
    - inode = nd->dentry->d_inode;
    + inode = nd->path.dentry->d_inode;
    } else
    path_to_nameidata(&next, nd);
    err = -ENOENT;
    @@ -981,11 +983,12 @@ return_reval:
    * We bypassed the ordinary revalidation routines.
    * We may need to check the cached dentry for staleness.
    */
    - if (nd->dentry && nd->dentry->d_sb &&
    - (nd->dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) {
    + if (nd->path.dentry && nd->path.dentry->d_sb &&
    + (nd->path.dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) {
    err = -ESTALE;
    /* Note: we do not d_invalidate() */
    - if (!nd->dentry->d_op->d_revalidate(nd->dentry, nd))
    + if (!nd->path.dentry->d_op->d_revalidate(
    + nd->path.dentry, nd))
    break;
    }
    return_base:
    @@ -1012,20 +1015,20 @@ static int fastcall link_path_walk(const
    int result;

    /* make sure the stuff we saved doesn't go away */
    - dget(save.dentry);
    - mntget(save.mnt);
    + dget(save.path.dentry);
    + mntget(save.path.mnt);

    result = __link_path_walk(name, nd);
    if (result == -ESTALE) {
    *nd = save;
    - dget(nd->dentry);
    - mntget(nd->mnt);
    + dget(nd->path.dentry);
    + mntget(nd->path.mnt);
    nd->flags |= LOOKUP_REVAL;
    result = __link_path_walk(name, nd);
    }

    - dput(save.dentry);
    - mntput(save.mnt);
    + dput(save.path.dentry);
    + mntput(save.path.mnt);

    return result;
    }
    @@ -1045,9 +1048,10 @@ static int __emul_lookup_dentry(const ch
    if (path_walk(name, nd))
    return 0; /* something went wrong... */

    - if (!nd->dentry->d_inode || S_ISDIR(nd->dentry->d_inode->i_mode)) {
    - struct dentry *old_dentry = nd->dentry;
    - struct vfsmount *old_mnt = nd->mnt;
    + if (!nd->path.dentry->d_inode ||
    + S_ISDIR(nd->path.dentry->d_inode->i_mode)) {
    + struct dentry *old_dentry = nd->path.dentry;
    + struct vfsmount *old_mnt = nd->path.mnt;
    struct qstr last = nd->last;
    int last_type = nd->last_type;
    struct fs_struct *fs = current->fs;
    @@ -1058,19 +1062,19 @@ static int __emul_lookup_dentry(const ch
    */
    nd->last_type = LAST_ROOT;
    read_lock(&fs->lock);
    - nd->mnt = mntget(fs->rootmnt);
    - nd->dentry = dget(fs->root);
    + nd->path.mnt = mntget(fs->rootmnt);
    + nd->path.dentry = dget(fs->root);
    read_unlock(&fs->lock);
    if (path_walk(name, nd) == 0) {
    - if (nd->dentry->d_inode) {
    + if (nd->path.dentry->d_inode) {
    dput(old_dentry);
    mntput(old_mnt);
    return 1;
    }
    path_release(nd);
    }
    - nd->dentry = old_dentry;
    - nd->mnt = old_mnt;
    + nd->path.dentry = old_dentry;
    + nd->path.mnt = old_mnt;
    nd->last = last;
    nd->last_type = last_type;
    }
    @@ -1090,8 +1094,8 @@ void set_fs_altroot(void)
    goto set_it;
    err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd);
    if (!err) {
    - mnt = nd.mnt;
    - dentry = nd.dentry;
    + mnt = nd.path.mnt;
    + dentry = nd.path.dentry;
    }
    set_it:
    write_lock(&fs->lock);
    @@ -1122,20 +1126,20 @@ static int fastcall do_path_lookup(int d
    if (*name=='/') {
    read_lock(&fs->lock);
    if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
    - nd->mnt = mntget(fs->altrootmnt);
    - nd->dentry = dget(fs->altroot);
    + nd->path.mnt = mntget(fs->altrootmnt);
    + nd->path.dentry = dget(fs->altroot);
    read_unlock(&fs->lock);
    if (__emul_lookup_dentry(name,nd))
    goto out; /* found in altroot */
    read_lock(&fs->lock);
    }
    - nd->mnt = mntget(fs->rootmnt);
    - nd->dentry = dget(fs->root);
    + nd->path.mnt = mntget(fs->rootmnt);
    + nd->path.dentry = dget(fs->root);
    read_unlock(&fs->lock);
    } else if (dfd == AT_FDCWD) {
    read_lock(&fs->lock);
    - nd->mnt = mntget(fs->pwdmnt);
    - nd->dentry = dget(fs->pwd);
    + nd->path.mnt = mntget(fs->pwdmnt);
    + nd->path.dentry = dget(fs->pwd);
    read_unlock(&fs->lock);
    } else {
    struct dentry *dentry;
    @@ -1155,17 +1159,17 @@ static int fastcall do_path_lookup(int d
    if (retval)
    goto fput_fail;

    - nd->mnt = mntget(file->f_path.mnt);
    - nd->dentry = dget(dentry);
    + nd->path.mnt = mntget(file->f_path.mnt);
    + nd->path.dentry = dget(dentry);

    fput_light(file, fput_needed);
    }

    retval = path_walk(name, nd);
    out:
    - if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
    - nd->dentry->d_inode))
    - audit_inode(name, nd->dentry);
    + if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
    + nd->path.dentry->d_inode))
    + audit_inode(name, nd->path.dentry);
    out_fail:
    return retval;

    @@ -1199,13 +1203,13 @@ int vfs_path_lookup(struct dentry *dentr
    nd->flags = flags;
    nd->depth = 0;

    - nd->mnt = mntget(mnt);
    - nd->dentry = dget(dentry);
    + nd->path.mnt = mntget(mnt);
    + nd->path.dentry = dget(dentry);

    retval = path_walk(name, nd);
    - if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
    - nd->dentry->d_inode))
    - audit_inode(name, nd->dentry);
    + if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
    + nd->path.dentry->d_inode))
    + audit_inode(name, nd->path.dentry);

    return retval;

    @@ -1324,10 +1328,10 @@ static struct dentry *lookup_hash(struct
    {
    int err;

    - err = permission(nd->dentry->d_inode, MAY_EXEC, nd);
    + err = permission(nd->path.dentry->d_inode, MAY_EXEC, nd);
    if (err)
    return ERR_PTR(err);
    - return __lookup_hash(&nd->last, nd->dentry, nd);
    + return __lookup_hash(&nd->last, nd->path.dentry, nd);
    }

    static int __lookup_one_len(const char *name, struct qstr *this,
    @@ -1586,7 +1590,7 @@ int vfs_create(struct inode *dir, struct

    int may_open(struct nameidata *nd, int acc_mode, int flag)
    {
    - struct dentry *dentry = nd->dentry;
    + struct dentry *dentry = nd->path.dentry;
    struct inode *inode = dentry->d_inode;
    int error;

    @@ -1607,7 +1611,7 @@ int may_open(struct nameidata *nd, int a
    if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
    flag &= ~O_TRUNC;
    } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
    - if (nd->mnt->mnt_flags & MNT_NODEV)
    + if (nd->path.mnt->mnt_flags & MNT_NODEV)
    return -EACCES;

    flag &= ~O_TRUNC;
    @@ -1616,7 +1620,7 @@ int may_open(struct nameidata *nd, int a
    * effectively: !special_file()
    * balanced by __fput()
    */
    - error = mnt_want_write(nd->mnt);
    + error = mnt_want_write(nd->path.mnt);
    if (error)
    return error;
    }
    @@ -1674,14 +1678,14 @@ static int open_namei_create(struct name
    int flag, int mode)
    {
    int error;
    - struct dentry *dir = nd->dentry;
    + struct dentry *dir = nd->path.dentry;

    if (!IS_POSIXACL(dir->d_inode))
    mode &= ~current->fs->umask;
    error = vfs_create(dir->d_inode, path->dentry, mode, nd);
    mutex_unlock(&dir->d_inode->i_mutex);
    - dput(nd->dentry);
    - nd->dentry = path->dentry;
    + dput(nd->path.dentry);
    + nd->path.dentry = path->dentry;
    if (error)
    return error;
    /* Don't check for write permission, don't truncate */
    @@ -1748,11 +1752,11 @@ int open_namei(int dfd, const char *path
    if (nd->last_type != LAST_NORM || nd->last.name[nd->last.len])
    goto exit;

    - dir = nd->dentry;
    + dir = nd->path.dentry;
    nd->flags &= ~LOOKUP_PARENT;
    mutex_lock(&dir->d_inode->i_mutex);
    path.dentry = lookup_hash(nd);
    - path.mnt = nd->mnt;
    + path.mnt = nd->path.mnt;

    do_last:
    error = PTR_ERR(path.dentry);
    @@ -1768,11 +1772,11 @@ do_last:

    /* Negative dentry, just create the file */
    if (!path.dentry->d_inode) {
    - error = mnt_want_write(nd->mnt);
    + error = mnt_want_write(nd->path.mnt);
    if (error)
    goto exit_mutex_unlock;
    error = open_namei_create(nd, &path, flag, mode);
    - mnt_drop_write(nd->mnt);
    + mnt_drop_write(nd->path.mnt);
    if (error)
    goto exit;
    return 0;
    @@ -1862,10 +1866,10 @@ do_link:
    __putname(nd->last.name);
    goto exit;
    }
    - dir = nd->dentry;
    + dir = nd->path.dentry;
    mutex_lock(&dir->d_inode->i_mutex);
    path.dentry = lookup_hash(nd);
    - path.mnt = nd->mnt;
    + path.mnt = nd->path.mnt;
    __putname(nd->last.name);
    goto do_last;
    }
    @@ -1878,13 +1882,13 @@ do_link:
    * Simple function to lookup and return a dentry and create it
    * if it doesn't exist. Is SMP-safe.
    *
    - * Returns with nd->dentry->d_inode->i_mutex locked.
    + * Returns with nd->path.dentry->d_inode->i_mutex locked.
    */
    struct dentry *lookup_create(struct nameidata *nd, int is_dir)
    {
    struct dentry *dentry = ERR_PTR(-EEXIST);

    - mutex_lock_nested(&nd->dentry->d_inode->i_mutex, I_MUTEX_PARENT);
    + mutex_lock_nested(&nd->path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
    /*
    * Yucky last component or no last component at all?
    * (foo/., foo/.., /////)
    @@ -1965,7 +1969,7 @@ asmlinkage long sys_mknodat(int dfd, con
    error = PTR_ERR(dentry);
    goto out_unlock;
    }
    - if (!IS_POSIXACL(nd.dentry->d_inode))
    + if (!IS_POSIXACL(nd.path.dentry->d_inode))
    mode &= ~current->fs->umask;
    if (S_ISDIR(mode)) {
    error = -EPERM;
    @@ -1976,26 +1980,28 @@ asmlinkage long sys_mknodat(int dfd, con
    error = -EINVAL;
    goto out_dput;
    }
    - error = mnt_want_write(nd.mnt);
    + error = mnt_want_write(nd.path.mnt);
    if (error)
    goto out_dput;
    switch (mode & S_IFMT) {
    case 0: case S_IFREG:
    - error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
    + error = vfs_create(nd.path.dentry->d_inode, dentry,
    + mode, &nd);
    break;
    case S_IFCHR: case S_IFBLK:
    - error = vfs_mknod(nd.dentry->d_inode,dentry,mode,
    - new_decode_dev(dev));
    + error = vfs_mknod(nd.path.dentry->d_inode, dentry,
    + mode, new_decode_dev(dev));
    break;
    case S_IFIFO: case S_IFSOCK:
    - error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0);
    + error = vfs_mknod(nd.path.dentry->d_inode, dentry,
    + mode, 0);
    break;
    }
    - mnt_drop_write(nd.mnt);
    + mnt_drop_write(nd.path.mnt);
    out_dput:
    dput(dentry);
    out_unlock:
    - mutex_unlock(&nd.dentry->d_inode->i_mutex);
    + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    path_release(&nd);
    out:
    putname(tmp);
    @@ -2050,17 +2056,17 @@ asmlinkage long sys_mkdirat(int dfd, con
    if (IS_ERR(dentry))
    goto out_unlock;

    - if (!IS_POSIXACL(nd.dentry->d_inode))
    + if (!IS_POSIXACL(nd.path.dentry->d_inode))
    mode &= ~current->fs->umask;
    - error = mnt_want_write(nd.mnt);
    + error = mnt_want_write(nd.path.mnt);
    if (error)
    goto out_dput;
    - error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
    - mnt_drop_write(nd.mnt);
    + error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
    + mnt_drop_write(nd.path.mnt);
    out_dput:
    dput(dentry);
    out_unlock:
    - mutex_unlock(&nd.dentry->d_inode->i_mutex);
    + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    path_release(&nd);
    out:
    putname(tmp);
    @@ -2159,20 +2165,20 @@ static long do_rmdir(int dfd, const char
    error = -EBUSY;
    goto exit1;
    }
    - mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
    + mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
    dentry = lookup_hash(&nd);
    error = PTR_ERR(dentry);
    if (IS_ERR(dentry))
    goto exit2;
    - error = mnt_want_write(nd.mnt);
    + error = mnt_want_write(nd.path.mnt);
    if (error)
    goto exit3;
    - error = vfs_rmdir(nd.dentry->d_inode, dentry);
    - mnt_drop_write(nd.mnt);
    + error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
    + mnt_drop_write(nd.path.mnt);
    exit3:
    dput(dentry);
    exit2:
    - mutex_unlock(&nd.dentry->d_inode->i_mutex);
    + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    exit1:
    path_release(&nd);
    exit:
    @@ -2239,7 +2245,7 @@ static long do_unlinkat(int dfd, const c
    error = -EISDIR;
    if (nd.last_type != LAST_NORM)
    goto exit1;
    - mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
    + mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
    dentry = lookup_hash(&nd);
    error = PTR_ERR(dentry);
    if (!IS_ERR(dentry)) {
    @@ -2249,15 +2255,15 @@ static long do_unlinkat(int dfd, const c
    inode = dentry->d_inode;
    if (inode)
    atomic_inc(&inode->i_count);
    - error = mnt_want_write(nd.mnt);
    + error = mnt_want_write(nd.path.mnt);
    if (error)
    goto exit2;
    - error = vfs_unlink(nd.dentry->d_inode, dentry);
    - mnt_drop_write(nd.mnt);
    + error = vfs_unlink(nd.path.dentry->d_inode, dentry);
    + mnt_drop_write(nd.path.mnt);
    exit2:
    dput(dentry);
    }
    - mutex_unlock(&nd.dentry->d_inode->i_mutex);
    + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    if (inode)
    iput(inode); /* truncate the inode here */
    exit1:
    @@ -2334,15 +2340,15 @@ asmlinkage long sys_symlinkat(const char
    if (IS_ERR(dentry))
    goto out_unlock;

    - error = mnt_want_write(nd.mnt);
    + error = mnt_want_write(nd.path.mnt);
    if (error)
    goto out_dput;
    - error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
    - mnt_drop_write(nd.mnt);
    + error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO);
    + mnt_drop_write(nd.path.mnt);
    out_dput:
    dput(dentry);
    out_unlock:
    - mutex_unlock(&nd.dentry->d_inode->i_mutex);
    + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    path_release(&nd);
    out:
    putname(to);
    @@ -2428,21 +2434,21 @@ asmlinkage long sys_linkat(int olddfd, c
    if (error)
    goto out;
    error = -EXDEV;
    - if (old_nd.mnt != nd.mnt)
    + if (old_nd.path.mnt != nd.path.mnt)
    goto out_release;
    new_dentry = lookup_create(&nd, 0);
    error = PTR_ERR(new_dentry);
    if (IS_ERR(new_dentry))
    goto out_unlock;
    - error = mnt_want_write(nd.mnt);
    + error = mnt_want_write(nd.path.mnt);
    if (error)
    goto out_dput;
    - error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
    - mnt_drop_write(nd.mnt);
    + error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry);
    + mnt_drop_write(nd.path.mnt);
    out_dput:
    dput(new_dentry);
    out_unlock:
    - mutex_unlock(&nd.dentry->d_inode->i_mutex);
    + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    out_release:
    path_release(&nd);
    out:
    @@ -2622,15 +2628,15 @@ static int do_rename(int olddfd, const c
    goto exit1;

    error = -EXDEV;
    - if (oldnd.mnt != newnd.mnt)
    + if (oldnd.path.mnt != newnd.path.mnt)
    goto exit2;

    - old_dir = oldnd.dentry;
    + old_dir = oldnd.path.dentry;
    error = -EBUSY;
    if (oldnd.last_type != LAST_NORM)
    goto exit2;

    - new_dir = newnd.dentry;
    + new_dir = newnd.path.dentry;
    if (newnd.last_type != LAST_NORM)
    goto exit2;

    @@ -2665,12 +2671,12 @@ static int do_rename(int olddfd, const c
    if (new_dentry == trap)
    goto exit5;

    - error = mnt_want_write(oldnd.mnt);
    + error = mnt_want_write(oldnd.path.mnt);
    if (error)
    goto exit5;
    error = vfs_rename(old_dir->d_inode, old_dentry,
    new_dir->d_inode, new_dentry);
    - mnt_drop_write(oldnd.mnt);
    + mnt_drop_write(oldnd.path.mnt);
    exit5:
    dput(new_dentry);
    exit4:
    Index: b/fs/namespace.c
    ================================================== =================
    --- a/fs/namespace.c
    +++ b/fs/namespace.c
    @@ -389,13 +389,13 @@ static void __touch_mnt_namespace(struct

    static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
    {
    - old_nd->dentry = mnt->mnt_mountpoint;
    - old_nd->mnt = mnt->mnt_parent;
    + old_nd->path.dentry = mnt->mnt_mountpoint;
    + old_nd->path.mnt = mnt->mnt_parent;
    mnt->mnt_parent = mnt;
    mnt->mnt_mountpoint = mnt->mnt_root;
    list_del_init(&mnt->mnt_child);
    list_del_init(&mnt->mnt_hash);
    - old_nd->dentry->d_mounted--;
    + old_nd->path.dentry->d_mounted--;
    }

    void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
    @@ -408,10 +408,10 @@ void mnt_set_mountpoint(struct vfsmount

    static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd)
    {
    - mnt_set_mountpoint(nd->mnt, nd->dentry, mnt);
    + mnt_set_mountpoint(nd->path.mnt, nd->path.dentry, mnt);
    list_add_tail(&mnt->mnt_hash, mount_hashtable +
    - hash(nd->mnt, nd->dentry));
    - list_add_tail(&mnt->mnt_child, &nd->mnt->mnt_mounts);
    + hash(nd->path.mnt, nd->path.dentry));
    + list_add_tail(&mnt->mnt_child, &nd->path.mnt->mnt_mounts);
    }

    /*
    @@ -977,20 +977,20 @@ asmlinkage long sys_umount(char __user *
    if (retval)
    goto out;
    retval = -EINVAL;
    - if (nd.dentry != nd.mnt->mnt_root)
    + if (nd.path.dentry != nd.path.mnt->mnt_root)
    goto dput_and_out;
    - if (!check_mnt(nd.mnt))
    + if (!check_mnt(nd.path.mnt))
    goto dput_and_out;

    retval = -EPERM;
    - if (!permit_umount(nd.mnt, flags))
    + if (!permit_umount(nd.path.mnt, flags))
    goto dput_and_out;

    - retval = do_umount(nd.mnt, flags);
    + retval = do_umount(nd.path.mnt, flags);
    dput_and_out:
    /* we mustn't call path_put() as that would clear mnt_expiry_mark */
    - dput(nd.dentry);
    - mntput_no_expire(nd.mnt);
    + dput(nd.path.dentry);
    + mntput_no_expire(nd.path.mnt);
    out:
    return retval;
    }
    @@ -1015,7 +1015,7 @@ asmlinkage long sys_oldumount(char __use
    static bool permit_mount(struct nameidata *nd, struct file_system_type *type,
    int *flags)
    {
    - struct inode *inode = nd->dentry->d_inode;
    + struct inode *inode = nd->path.dentry->d_inode;

    if (capable(CAP_SYS_ADMIN))
    return true;
    @@ -1026,10 +1026,10 @@ static bool permit_mount(struct nameidat
    if (S_ISLNK(inode->i_mode))
    return false;

    - if (nd->mnt->mnt_flags & MNT_NOMNT)
    + if (nd->path.mnt->mnt_flags & MNT_NOMNT)
    return false;

    - if (!is_mount_owner(nd->mnt, current->fsuid))
    + if (!is_mount_owner(nd->path.mnt, current->fsuid))
    return false;

    *flags |= MS_SETUSER;
    @@ -1076,8 +1076,8 @@ struct vfsmount *copy_tree(struct vfsmou
    q = q->mnt_parent;
    }
    p = s;
    - nd.mnt = q;
    - nd.dentry = p->mnt_mountpoint;
    + nd.path.mnt = q;
    + nd.path.dentry = p->mnt_mountpoint;
    q = clone_mnt(p, p->mnt_root, flag, owner);
    if (IS_ERR(q))
    goto error;
    @@ -1186,8 +1186,8 @@ static int attach_recursive_mnt(struct v
    struct nameidata *nd, struct nameidata *parent_nd)
    {
    LIST_HEAD(tree_list);
    - struct vfsmount *dest_mnt = nd->mnt;
    - struct dentry *dest_dentry = nd->dentry;
    + struct vfsmount *dest_mnt = nd->path.mnt;
    + struct dentry *dest_dentry = nd->path.dentry;
    struct vfsmount *child, *p;

    if (propagate_mnt(dest_mnt, dest_dentry, source_mnt, &tree_list))
    @@ -1222,13 +1222,13 @@ static int graft_tree(struct vfsmount *m
    if (mnt->mnt_sb->s_flags & MS_NOUSER)
    return -EINVAL;

    - if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
    + if (S_ISDIR(nd->path.dentry->d_inode->i_mode) !=
    S_ISDIR(mnt->mnt_root->d_inode->i_mode))
    return -ENOTDIR;

    err = -ENOENT;
    - mutex_lock(&nd->dentry->d_inode->i_mutex);
    - if (IS_DEADDIR(nd->dentry->d_inode))
    + mutex_lock(&nd->path.dentry->d_inode->i_mutex);
    + if (IS_DEADDIR(nd->path.dentry->d_inode))
    goto out_unlock;

    err = security_sb_check_sb(mnt, nd);
    @@ -1236,10 +1236,10 @@ static int graft_tree(struct vfsmount *m
    goto out_unlock;

    err = -ENOENT;
    - if (IS_ROOT(nd->dentry) || !d_unhashed(nd->dentry))
    + if (IS_ROOT(nd->path.dentry) || !d_unhashed(nd->path.dentry))
    err = attach_recursive_mnt(mnt, nd, NULL);
    out_unlock:
    - mutex_unlock(&nd->dentry->d_inode->i_mutex);
    + mutex_unlock(&nd->path.dentry->d_inode->i_mutex);
    if (!err)
    security_sb_post_addmount(mnt, nd);
    return err;
    @@ -1250,14 +1250,14 @@ out_unlock:
    */
    static int do_change_type(struct nameidata *nd, int flag)
    {
    - struct vfsmount *m, *mnt = nd->mnt;
    + struct vfsmount *m, *mnt = nd->path.mnt;
    int recurse = flag & MS_REC;
    int type = flag & ~MS_REC;

    if (!capable(CAP_SYS_ADMIN))
    return -EPERM;

    - if (nd->dentry != nd->mnt->mnt_root)
    + if (nd->path.dentry != nd->path.mnt->mnt_root)
    return -EINVAL;

    down_write(&namespace_sem);
    @@ -1290,10 +1290,10 @@ static int do_loopback(struct nameidata

    down_write(&namespace_sem);
    err = -EINVAL;
    - if (IS_MNT_UNBINDABLE(old_nd.mnt))
    - goto out;
    + if (IS_MNT_UNBINDABLE(old_nd.path.mnt))
    + goto out;

    - if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt))
    + if (!check_mnt(nd->path.mnt) || !check_mnt(old_nd.path.mnt))
    goto out;

    if (flags & MS_SETUSER) {
    @@ -1302,9 +1302,11 @@ static int do_loopback(struct nameidata
    }

    if (flags & MS_REC)
    - mnt = copy_tree(old_nd.mnt, old_nd.dentry, clone_flags, owner);
    + mnt = copy_tree(old_nd.path.mnt, old_nd.path.dentry,
    + clone_flags, owner);
    else
    - mnt = clone_mnt(old_nd.mnt, old_nd.dentry, clone_flags, owner);
    + mnt = clone_mnt(old_nd.path.mnt, old_nd.path.dentry,
    + clone_flags, owner);

    err = PTR_ERR(mnt);
    if (IS_ERR(mnt))
    @@ -1351,31 +1353,31 @@ static int do_remount(struct nameidata *
    void *data)
    {
    int err;
    - struct super_block *sb = nd->mnt->mnt_sb;
    + struct super_block *sb = nd->path.mnt->mnt_sb;

    if (!capable(CAP_SYS_ADMIN))
    return -EPERM;

    - if (!check_mnt(nd->mnt))
    + if (!check_mnt(nd->path.mnt))
    return -EINVAL;

    - if (nd->dentry != nd->mnt->mnt_root)
    + if (nd->path.dentry != nd->path.mnt->mnt_root)
    return -EINVAL;

    down_write(&sb->s_umount);
    if (flags & MS_BIND)
    - err = change_mount_flags(nd->mnt, flags);
    + err = change_mount_flags(nd->path.mnt, flags);
    else
    err = do_remount_sb(sb, flags, data, 0);
    if (!err) {
    - clear_mnt_user(nd->mnt);
    - nd->mnt->mnt_flags = mnt_flags;
    + clear_mnt_user(nd->path.mnt);
    + nd->path.mnt->mnt_flags = mnt_flags;
    if (flags & MS_SETUSER)
    - set_mnt_user(nd->mnt);
    + set_mnt_user(nd->path.mnt);
    }
    up_write(&sb->s_umount);
    if (!err)
    - security_sb_post_remount(nd->mnt, flags, data);
    + security_sb_post_remount(nd->path.mnt, flags, data);
    return err;
    }

    @@ -1403,56 +1405,60 @@ static int do_move_mount(struct nameidat
    return err;

    down_write(&namespace_sem);
    - while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
    + while (d_mountpoint(nd->path.dentry) &&
    + follow_down(&nd->path.mnt, &nd->path.dentry))
    ;
    err = -EINVAL;
    - if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt))
    + if (!check_mnt(nd->path.mnt) || !check_mnt(old_nd.path.mnt))
    goto out;

    err = -ENOENT;
    - mutex_lock(&nd->dentry->d_inode->i_mutex);
    - if (IS_DEADDIR(nd->dentry->d_inode))
    + mutex_lock(&nd->path.dentry->d_inode->i_mutex);
    + if (IS_DEADDIR(nd->path.dentry->d_inode))
    goto out1;

    - if (!IS_ROOT(nd->dentry) && d_unhashed(nd->dentry))
    + if (!IS_ROOT(nd->path.dentry) && d_unhashed(nd->path.dentry))
    goto out1;

    err = -EINVAL;
    - if (old_nd.dentry != old_nd.mnt->mnt_root)
    + if (old_nd.path.dentry != old_nd.path.mnt->mnt_root)
    goto out1;

    - if (old_nd.mnt == old_nd.mnt->mnt_parent)
    + if (old_nd.path.mnt == old_nd.path.mnt->mnt_parent)
    goto out1;

    - if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
    - S_ISDIR(old_nd.dentry->d_inode->i_mode))
    + if (S_ISDIR(nd->path.dentry->d_inode->i_mode) !=
    + S_ISDIR(old_nd.path.dentry->d_inode->i_mode))
    goto out1;
    /*
    * Don't move a mount residing in a shared parent.
    */
    - if (old_nd.mnt->mnt_parent && IS_MNT_SHARED(old_nd.mnt->mnt_parent))
    + if (old_nd.path.mnt->mnt_parent &&
    + IS_MNT_SHARED(old_nd.path.mnt->mnt_parent))
    goto out1;
    /*
    * Don't move a mount tree containing unbindable mounts to a destination
    * mount which is shared.
    */
    - if (IS_MNT_SHARED(nd->mnt) && tree_contains_unbindable(old_nd.mnt))
    + if (IS_MNT_SHARED(nd->path.mnt) &&
    + tree_contains_unbindable(old_nd.path.mnt))
    goto out1;
    err = -ELOOP;
    - for (p = nd->mnt; p->mnt_parent != p; p = p->mnt_parent)
    - if (p == old_nd.mnt)
    + for (p = nd->path.mnt; p->mnt_parent != p; p = p->mnt_parent)
    + if (p == old_nd.path.mnt)
    goto out1;

    - if ((err = attach_recursive_mnt(old_nd.mnt, nd, &parent_nd)))
    + err = attach_recursive_mnt(old_nd.path.mnt, nd, &parent_nd);
    + if (err)
    goto out1;

    spin_lock(&vfsmount_lock);
    /* if the mount is moved, it should no longer be expire
    * automatically */
    - list_del_init(&old_nd.mnt->mnt_expire);
    + list_del_init(&old_nd.path.mnt->mnt_expire);
    spin_unlock(&vfsmount_lock);
    out1:
    - mutex_unlock(&nd->dentry->d_inode->i_mutex);
    + mutex_unlock(&nd->path.dentry->d_inode->i_mutex);
    out:
    up_write(&namespace_sem);
    if (!err)
    @@ -1544,16 +1550,17 @@ int do_add_mount(struct vfsmount *newmnt

    down_write(&namespace_sem);
    /* Something was mounted here while we slept */
    - while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
    + while (d_mountpoint(nd->path.dentry) &&
    + follow_down(&nd->path.mnt, &nd->path.dentry))
    ;
    err = -EINVAL;
    - if (!check_mnt(nd->mnt))
    + if (!check_mnt(nd->path.mnt))
    goto unlock;

    /* Refuse the same filesystem on the same mount point */
    err = -EBUSY;
    - if (nd->mnt->mnt_sb == newmnt->mnt_sb &&
    - nd->mnt->mnt_root == nd->dentry)
    + if (nd->path.mnt->mnt_sb == newmnt->mnt_sb &&
    + nd->path.mnt->mnt_root == nd->path.dentry)
    goto unlock;

    err = -EINVAL;
    @@ -2085,12 +2092,14 @@ static void chroot_fs_refs(struct nameid
    if (fs) {
    atomic_inc(&fs->count);
    task_unlock(p);
    - if (fs->root == old_nd->dentry
    - && fs->rootmnt == old_nd->mnt)
    - set_fs_root(fs, new_nd->mnt, new_nd->dentry);
    - if (fs->pwd == old_nd->dentry
    - && fs->pwdmnt == old_nd->mnt)
    - set_fs_pwd(fs, new_nd->mnt, new_nd->dentry);
    + if (fs->root == old_nd->path.dentry
    + && fs->rootmnt == old_nd->path.mnt)
    + set_fs_root(fs, new_nd->path.mnt,
    + new_nd->path.dentry);
    + if (fs->pwd == old_nd->path.dentry
    + && fs->pwdmnt == old_nd->path.mnt)
    + set_fs_pwd(fs, new_nd->path.mnt,
    + new_nd->path.dentry);
    put_fs_struct(fs);
    } else
    task_unlock(p);
    @@ -2140,7 +2149,7 @@ asmlinkage long sys_pivot_root(const cha
    if (error)
    goto out0;
    error = -EINVAL;
    - if (!check_mnt(new_nd.mnt))
    + if (!check_mnt(new_nd.path.mnt))
    goto out1;

    error = __user_walk(put_old, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &old_nd);
    @@ -2154,55 +2163,59 @@ asmlinkage long sys_pivot_root(const cha
    }

    read_lock(&current->fs->lock);
    - user_nd.mnt = mntget(current->fs->rootmnt);
    - user_nd.dentry = dget(current->fs->root);
    + user_nd.path.mnt = mntget(current->fs->rootmnt);
    + user_nd.path.dentry = dget(current->fs->root);
    read_unlock(&current->fs->lock);
    down_write(&namespace_sem);
    - mutex_lock(&old_nd.dentry->d_inode->i_mutex);
    + mutex_lock(&old_nd.path.dentry->d_inode->i_mutex);
    error = -EINVAL;
    - if (IS_MNT_SHARED(old_nd.mnt) ||
    - IS_MNT_SHARED(new_nd.mnt->mnt_parent) ||
    - IS_MNT_SHARED(user_nd.mnt->mnt_parent))
    + if (IS_MNT_SHARED(old_nd.path.mnt) ||
    + IS_MNT_SHARED(new_nd.path.mnt->mnt_parent) ||
    + IS_MNT_SHARED(user_nd.path.mnt->mnt_parent))
    goto out2;
    - if (!check_mnt(user_nd.mnt))
    + if (!check_mnt(user_nd.path.mnt))
    goto out2;
    error = -ENOENT;
    - if (IS_DEADDIR(new_nd.dentry->d_inode))
    + if (IS_DEADDIR(new_nd.path.dentry->d_inode))
    goto out2;
    - if (d_unhashed(new_nd.dentry) && !IS_ROOT(new_nd.dentry))
    + if (d_unhashed(new_nd.path.dentry) && !IS_ROOT(new_nd.path.dentry))
    goto out2;
    - if (d_unhashed(old_nd.dentry) && !IS_ROOT(old_nd.dentry))
    + if (d_unhashed(old_nd.path.dentry) && !IS_ROOT(old_nd.path.dentry))
    goto out2;
    error = -EBUSY;
    - if (new_nd.mnt == user_nd.mnt || old_nd.mnt == user_nd.mnt)
    + if (new_nd.path.mnt == user_nd.path.mnt ||
    + old_nd.path.mnt == user_nd.path.mnt)
    goto out2; /* loop, on the same file system */
    error = -EINVAL;
    - if (user_nd.mnt->mnt_root != user_nd.dentry)
    + if (user_nd.path.mnt->mnt_root != user_nd.path.dentry)
    goto out2; /* not a mountpoint */
    - if (user_nd.mnt->mnt_parent == user_nd.mnt)
    + if (user_nd.path.mnt->mnt_parent == user_nd.path.mnt)
    goto out2; /* not attached */
    - if (new_nd.mnt->mnt_root != new_nd.dentry)
    + if (new_nd.path.mnt->mnt_root != new_nd.path.dentry)
    goto out2; /* not a mountpoint */
    - if (new_nd.mnt->mnt_parent == new_nd.mnt)
    + if (new_nd.path.mnt->mnt_parent == new_nd.path.mnt)
    goto out2; /* not attached */
    - tmp = old_nd.mnt; /* make sure we can reach put_old from new_root */
    + /* make sure we can reach put_old from new_root */
    + tmp = old_nd.path.mnt;
    spin_lock(&vfsmount_lock);
    - if (tmp != new_nd.mnt) {
    + if (tmp != new_nd.path.mnt) {
    for (; {
    if (tmp->mnt_parent == tmp)
    goto out3; /* already mounted on put_old */
    - if (tmp->mnt_parent == new_nd.mnt)
    + if (tmp->mnt_parent == new_nd.path.mnt)
    break;
    tmp = tmp->mnt_parent;
    }
    - if (!is_subdir(tmp->mnt_mountpoint, new_nd.dentry))
    + if (!is_subdir(tmp->mnt_mountpoint, new_nd.path.dentry))
    goto out3;
    - } else if (!is_subdir(old_nd.dentry, new_nd.dentry))
    + } else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry))
    goto out3;
    - detach_mnt(new_nd.mnt, &parent_nd);
    - detach_mnt(user_nd.mnt, &root_parent);
    - attach_mnt(user_nd.mnt, &old_nd); /* mount old root on put_old */
    - attach_mnt(new_nd.mnt, &root_parent); /* mount new_root on / */
    + detach_mnt(new_nd.path.mnt, &parent_nd);
    + detach_mnt(user_nd.path.mnt, &root_parent);
    + /* mount old root on put_old */
    + attach_mnt(user_nd.path.mnt, &old_nd);
    + /* mount new_root on / */
    + attach_mnt(new_nd.path.mnt, &root_parent);
    touch_mnt_namespace(current->nsproxy->mnt_ns);
    spin_unlock(&vfsmount_lock);
    chroot_fs_refs(&user_nd, &new_nd);
    @@ -2211,7 +2224,7 @@ asmlinkage long sys_pivot_root(const cha
    path_release(&root_parent);
    path_release(&parent_nd);
    out2:
    - mutex_unlock(&old_nd.dentry->d_inode->i_mutex);
    + mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex);
    up_write(&namespace_sem);
    path_release(&user_nd);
    path_release(&old_nd);
    Index: b/fs/nfs/namespace.c
    ================================================== =================
    --- a/fs/nfs/namespace.c
    +++ b/fs/nfs/namespace.c
    @@ -107,38 +107,40 @@ static void * nfs_follow_mountpoint(stru

    BUG_ON(IS_ROOT(dentry));
    dprintk("%s: enter\n", __FUNCTION__);
    - dput(nd->dentry);
    - nd->dentry = dget(dentry);
    + dput(nd->path.dentry);
    + nd->path.dentry = dget(dentry);

    /* Look it up again */
    - parent = dget_parent(nd->dentry);
    + parent = dget_parent(nd->path.dentry);
    err = server->nfs_client->rpc_ops->lookup(parent->d_inode,
    - &nd->dentry->d_name,
    + &nd->path.dentry->d_name,
    &fh, &fattr);
    dput(parent);
    if (err != 0)
    goto out_err;

    if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL)
    - mnt = nfs_do_refmount(nd->mnt, nd->dentry);
    + mnt = nfs_do_refmount(nd->path.mnt, nd->path.dentry);
    else
    - mnt = nfs_do_submount(nd->mnt, nd->dentry, &fh, &fattr);
    + mnt = nfs_do_submount(nd->path.mnt, nd->path.dentry, &fh,
    + &fattr);
    err = PTR_ERR(mnt);
    if (IS_ERR(mnt))
    goto out_err;

    mntget(mnt);
    - err = do_add_mount(mnt, nd, nd->mnt->mnt_flags|MNT_SHRINKABLE, &nfs_automount_list);
    + err = do_add_mount(mnt, nd, nd->path.mnt->mnt_flags|MNT_SHRINKABLE,
    + &nfs_automount_list);
    if (err < 0) {
    mntput(mnt);
    if (err == -EBUSY)
    goto out_follow;
    goto out_err;
    }
    - mntput(nd->mnt);
    - dput(nd->dentry);
    - nd->mnt = mnt;
    - nd->dentry = dget(mnt->mnt_root);
    + mntput(nd->path.mnt);
    + dput(nd->path.dentry);
    + nd->path.mnt = mnt;
    + nd->path.dentry = dget(mnt->mnt_root);
    schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout);
    out:
    dprintk("%s: done, returned %d\n", __FUNCTION__, err);
    @@ -149,7 +151,8 @@ out_err:
    path_release(nd);
    goto out;
    out_follow:
    - while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
    + while (d_mountpoint(nd->path.dentry) &&
    + follow_down(&nd->path.mnt, &nd->path.dentry))
    ;
    err = 0;
    goto out;
    Index: b/fs/nfs/nfs4proc.c
    ================================================== =================
    --- a/fs/nfs/nfs4proc.c
    +++ b/fs/nfs/nfs4proc.c
    @@ -1371,10 +1371,7 @@ out_close:
    struct dentry *
    nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
    {
    - struct path path = {
    - .mnt = nd->mnt,
    - .dentry = dentry,
    - };
    + struct path path = nd->path;
    struct iattr attr;
    struct rpc_cred *cred;
    struct nfs4_state *state;
    @@ -1410,10 +1407,7 @@ nfs4_atomic_open(struct inode *dir, stru
    int
    nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata *nd)
    {
    - struct path path = {
    - .mnt = nd->mnt,
    - .dentry = dentry,
    - };
    + struct path path = nd->path;
    struct rpc_cred *cred;
    struct nfs4_state *state;

    @@ -1861,10 +1855,7 @@ static int
    nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
    int flags, struct nameidata *nd)
    {
    - struct path path = {
    - .mnt = nd->mnt,
    - .dentry = dentry,
    - };
    + struct path path = nd->path;
    struct nfs4_state *state;
    struct rpc_cred *cred;
    int status = 0;
    Index: b/fs/nfsctl.c
    ================================================== =================
    --- a/fs/nfsctl.c
    +++ b/fs/nfsctl.c
    @@ -41,7 +41,7 @@ static struct file *do_open(char *name,
    error = may_open(&nd, MAY_WRITE, FMODE_WRITE);

    if (!error)
    - return dentry_open(nd.dentry, nd.mnt, flags);
    + return dentry_open(nd.path.dentry, nd.path.mnt, flags);

    path_release(&nd);
    return ERR_PTR(error);
    Index: b/fs/nfsd/export.c
    ================================================== =================
    --- a/fs/nfsd/export.c
    +++ b/fs/nfsd/export.c
    @@ -169,8 +169,8 @@ static int expkey_parse(struct cache_det
    goto out;

    dprintk("Found the path %s\n", buf);
    - key.ek_mnt = nd.mnt;
    - key.ek_dentry = nd.dentry;
    + key.ek_mnt = nd.path.mnt;
    + key.ek_dentry = nd.path.dentry;

    ek = svc_expkey_update(&key, ek);
    if (ek)
    @@ -507,7 +507,7 @@ static int svc_export_parse(struct cache
    struct svc_export exp, *expp;
    int an_int;

    - nd.dentry = NULL;
    + nd.path.dentry = NULL;
    exp.ex_path = NULL;

    /* fs locations */
    @@ -547,8 +547,8 @@ static int svc_export_parse(struct cache

    exp.h.flags = 0;
    exp.ex_client = dom;
    - exp.ex_mnt = nd.mnt;
    - exp.ex_dentry = nd.dentry;
    + exp.ex_mnt = nd.path.mnt;
    + exp.ex_dentry = nd.path.dentry;
    exp.ex_path = kstrdup(buf, GFP_KERNEL);
    err = -ENOMEM;
    if (!exp.ex_path)
    @@ -610,7 +610,7 @@ static int svc_export_parse(struct cache
    goto out;
    }

    - err = check_export(nd.dentry->d_inode, exp.ex_flags,
    + err = check_export(nd.path.dentry->d_inode, exp.ex_flags,
    exp.ex_uuid);
    if (err) goto out;
    }
    @@ -629,7 +629,7 @@ static int svc_export_parse(struct cache
    nfsd4_fslocs_free(&exp.ex_fslocs);
    kfree(exp.ex_uuid);
    kfree(exp.ex_path);
    - if (nd.dentry)
    + if (nd.path.dentry)
    path_release(&nd);
    out_no_path:
    if (dom)
    @@ -1030,7 +1030,7 @@ exp_export(struct nfsctl_export *nxp)
    goto out_unlock;
    err = -EINVAL;

    - exp = exp_get_by_name(clp, nd.mnt, nd.dentry, NULL);
    + exp = exp_get_by_name(clp, nd.path.mnt, nd.path.dentry, NULL);

    memset(&new, 0, sizeof(new));

    @@ -1038,7 +1038,8 @@ exp_export(struct nfsctl_export *nxp)
    if ((nxp->ex_flags & NFSEXP_FSID) &&
    (!IS_ERR(fsid_key = exp_get_fsid_key(clp, nxp->ex_dev))) &&
    fsid_key->ek_mnt &&
    - (fsid_key->ek_mnt != nd.mnt || fsid_key->ek_dentry != nd.dentry) )
    + (fsid_key->ek_mnt != nd.path.mnt ||
    + fsid_key->ek_dentry != nd.path.dentry))
    goto finish;

    if (!IS_ERR(exp)) {
    @@ -1054,7 +1055,7 @@ exp_export(struct nfsctl_export *nxp)
    goto finish;
    }

    - err = check_export(nd.dentry->d_inode, nxp->ex_flags, NULL);
    + err = check_export(nd.path.dentry->d_inode, nxp->ex_flags, NULL);
    if (err) goto finish;

    err = -ENOMEM;
    @@ -1067,8 +1068,8 @@ exp_export(struct nfsctl_export *nxp)
    if (!new.ex_path)
    goto finish;
    new.ex_client = clp;
    - new.ex_mnt = nd.mnt;
    - new.ex_dentry = nd.dentry;
    + new.ex_mnt = nd.path.mnt;
    + new.ex_dentry = nd.path.dentry;
    new.ex_flags = nxp->ex_flags;
    new.ex_anon_uid = nxp->ex_anon_uid;
    new.ex_anon_gid = nxp->ex_anon_gid;
    @@ -1148,7 +1149,7 @@ exp_unexport(struct nfsctl_export *nxp)
    goto out_domain;

    err = -EINVAL;
    - exp = exp_get_by_name(dom, nd.mnt, nd.dentry, NULL);
    + exp = exp_get_by_name(dom, nd.path.mnt, nd.path.dentry, NULL);
    path_release(&nd);
    if (IS_ERR(exp))
    goto out_domain;
    @@ -1185,12 +1186,12 @@ exp_rootfh(svc_client *clp, char *path,
    printk("nfsd: exp_rootfh path not found %s", path);
    return err;
    }
    - inode = nd.dentry->d_inode;
    + inode = nd.path.dentry->d_inode;

    dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n",
    - path, nd.dentry, clp->name,
    + path, nd.path.dentry, clp->name,
    inode->i_sb->s_id, inode->i_ino);
    - exp = exp_parent(clp, nd.mnt, nd.dentry, NULL);
    + exp = exp_parent(clp, nd.path.mnt, nd.path.dentry, NULL);
    if (IS_ERR(exp)) {
    err = PTR_ERR(exp);
    goto out;
    @@ -1200,7 +1201,7 @@ exp_rootfh(svc_client *clp, char *path,
    * fh must be initialized before calling fh_compose
    */
    fh_init(&fh, maxsize);
    - if (fh_compose(&fh, exp, nd.dentry, NULL))
    + if (fh_compose(&fh, exp, nd.path.dentry, NULL))
    err = -EINVAL;
    else
    err = 0;
    Index: b/fs/nfsd/nfs4recover.c
    ================================================== =================
    --- a/fs/nfsd/nfs4recover.c
    +++ b/fs/nfsd/nfs4recover.c
    @@ -122,9 +122,9 @@ out_no_tfm:
    static void
    nfsd4_sync_rec_dir(void)
    {
    - mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
    - nfsd_sync_dir(rec_dir.dentry);
    - mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
    + mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex);
    + nfsd_sync_dir(rec_dir.path.dentry);
    + mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex);
    }

    int
    @@ -144,9 +144,9 @@ nfsd4_create_clid_dir(struct nfs4_client
    nfs4_save_user(&uid, &gid);

    /* lock the parent */
    - mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
    + mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex);

    - dentry = lookup_one_len(dname, rec_dir.dentry, HEXDIR_LEN-1);
    + dentry = lookup_one_len(dname, rec_dir.path.dentry, HEXDIR_LEN-1);
    if (IS_ERR(dentry)) {
    status = PTR_ERR(dentry);
    goto out_unlock;
    @@ -156,15 +156,15 @@ nfsd4_create_clid_dir(struct nfs4_client
    dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
    goto out_put;
    }
    - status = mnt_want_write(rec_dir.mnt);
    + status = mnt_want_write(rec_dir.path.mnt);
    if (status)
    goto out_put;
    - status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU);
    - mnt_drop_write(rec_dir.mnt);
    + status = vfs_mkdir(rec_dir.path.dentry->d_inode, dentry, S_IRWXU);
    + mnt_drop_write(rec_dir.path.mnt);
    out_put:
    dput(dentry);
    out_unlock:
    - mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
    + mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex);
    if (status == 0) {
    clp->cl_firststate = 1;
    nfsd4_sync_rec_dir();
    @@ -227,7 +227,7 @@ nfsd4_list_rec_dir(struct dentry *dir, r

    nfs4_save_user(&uid, &gid);

    - filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY);
    + filp = dentry_open(dget(dir), mntget(rec_dir.path.mnt), O_RDONLY);
    status = PTR_ERR(filp);
    if (IS_ERR(filp))
    goto out;
    @@ -292,9 +292,9 @@ nfsd4_unlink_clid_dir(char *name, int na

    dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);

    - mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
    - dentry = lookup_one_len(name, rec_dir.dentry, namlen);
    - mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
    + mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex);
    + dentry = lookup_one_len(name, rec_dir.path.dentry, namlen);
    + mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex);
    if (IS_ERR(dentry)) {
    status = PTR_ERR(dentry);
    return status;
    @@ -303,7 +303,7 @@ nfsd4_unlink_clid_dir(char *name, int na
    if (!dentry->d_inode)
    goto out;

    - status = nfsd4_clear_clid_dir(rec_dir.dentry, dentry);
    + status = nfsd4_clear_clid_dir(rec_dir.path.dentry, dentry);
    out:
    dput(dentry);
    return status;
    @@ -353,12 +353,12 @@ nfsd4_recdir_purge_old(void) {

    if (!rec_dir_init)
    return;
    - status = nfsd4_list_rec_dir(rec_dir.dentry, purge_old);
    + status = nfsd4_list_rec_dir(rec_dir.path.dentry, purge_old);
    if (status == 0)
    nfsd4_sync_rec_dir();
    if (status)
    printk("nfsd4: failed to purge old clients from recovery"
    - " directory %s\n", rec_dir.dentry->d_name.name);
    + " directory %s\n", rec_dir.path.dentry->d_name.name);
    return;
    }

    @@ -379,10 +379,10 @@ int
    nfsd4_recdir_load(void) {
    int status;

    - status = nfsd4_list_rec_dir(rec_dir.dentry, load_recdir);
    + status = nfsd4_list_rec_dir(rec_dir.path.dentry, load_recdir);
    if (status)
    printk("nfsd4: failed loading clients from recovery"
    - " directory %s\n", rec_dir.dentry->d_name.name);
    + " directory %s\n", rec_dir.path.dentry->d_name.name);
    return status;
    }

    Index: b/fs/nfsd/nfs4state.c
    ================================================== =================
    --- a/fs/nfsd/nfs4state.c
    +++ b/fs/nfsd/nfs4state.c
    @@ -3321,7 +3321,7 @@ nfs4_reset_recoverydir(char *recdir)
    if (status)
    return status;
    status = -ENOTDIR;
    - if (S_ISDIR(nd.dentry->d_inode->i_mode)) {
    + if (S_ISDIR(nd.path.dentry->d_inode->i_mode)) {
    nfs4_set_recdir(recdir);
    status = 0;
    }
    Index: b/fs/open.c
    ================================================== =================
    --- a/fs/open.c
    +++ b/fs/open.c
    @@ -127,7 +127,7 @@ asmlinkage long sys_statfs(const char __
    error = user_path_walk(path, &nd);
    if (!error) {
    struct statfs tmp;
    - error = vfs_statfs_native(nd.dentry, &tmp);
    + error = vfs_statfs_native(nd.path.dentry, &tmp);
    if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
    error = -EFAULT;
    path_release(&nd);
    @@ -146,7 +146,7 @@ asmlinkage long sys_statfs64(const char
    error = user_path_walk(path, &nd);
    if (!error) {
    struct statfs64 tmp;
    - error = vfs_statfs64(nd.dentry, &tmp);
    + error = vfs_statfs64(nd.path.dentry, &tmp);
    if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
    error = -EFAULT;
    path_release(&nd);
    @@ -233,7 +233,7 @@ static long do_sys_truncate(const char _
    error = user_path_walk(path, &nd);
    if (error)
    goto out;
    - inode = nd.dentry->d_inode;
    + inode = nd.path.dentry->d_inode;

    /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
    error = -EISDIR;
    @@ -244,7 +244,7 @@ static long do_sys_truncate(const char _
    if (!S_ISREG(inode->i_mode))
    goto dput_and_out;

    - error = mnt_want_write(nd.mnt);
    + error = mnt_want_write(nd.path.mnt);
    if (error)
    goto dput_and_out;

    @@ -271,13 +271,13 @@ static long do_sys_truncate(const char _
    error = locks_verify_truncate(inode, NULL, length);
    if (!error) {
    DQUOT_INIT(inode);
    - error = do_truncate(nd.dentry, length, 0, NULL);
    + error = do_truncate(nd.path.dentry, length, 0, NULL);
    }

    put_write_and_out:
    put_write_access(inode);
    mnt_drop_write_and_out:
    - mnt_drop_write(nd.mnt);
    + mnt_drop_write(nd.path.mnt);
    dput_and_out:
    path_release(&nd);
    out:
    @@ -457,7 +457,7 @@ asmlinkage long sys_faccessat(int dfd, c
    res = vfs_permission(&nd, mode);
    /* SuS v2 requires we report a read only fs too */
    if(res || !(mode & S_IWOTH) ||
    - special_file(nd.dentry->d_inode->i_mode))
    + special_file(nd.path.dentry->d_inode->i_mode))
    goto out_path_release;
    /*
    * This is a rare case where using __mnt_is_readonly()
    @@ -469,7 +469,7 @@ asmlinkage long sys_faccessat(int dfd, c
    * inherently racy and know that the fs may change
    * state before we even see this result.
    */
    - if (__mnt_is_readonly(nd.mnt))
    + if (__mnt_is_readonly(nd.path.mnt))
    res = -EROFS;

    out_path_release:
    @@ -501,7 +501,7 @@ asmlinkage long sys_chdir(const char __u
    if (error)
    goto dput_and_out;

    - set_fs_pwd(current->fs, nd.mnt, nd.dentry);
    + set_fs_pwd(current->fs, nd.path.mnt, nd.path.dentry);

    dput_and_out:
    path_release(&nd);
    @@ -556,7 +556,7 @@ asmlinkage long sys_chroot(const char __
    if (!capable(CAP_SYS_CHROOT))
    goto dput_and_out;

    - set_fs_root(current->fs, nd.mnt, nd.dentry);
    + set_fs_root(current->fs, nd.path.mnt, nd.path.dentry);
    set_fs_altroot();
    error = 0;
    dput_and_out:
    @@ -615,9 +615,9 @@ asmlinkage long sys_fchmodat(int dfd, co
    error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd);
    if (error)
    goto out;
    - inode = nd.dentry->d_inode;
    + inode = nd.path.dentry->d_inode;

    - error = mnt_want_write(nd.mnt);
    + error = mnt_want_write(nd.path.mnt);
    if (error)
    goto dput_and_out;

    @@ -630,11 +630,11 @@ asmlinkage long sys_fchmodat(int dfd, co
    mode = inode->i_mode;
    newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
    newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
    - error = notify_change(nd.dentry, &newattrs);
    + error = notify_change(nd.path.dentry, &newattrs);
    mutex_unlock(&inode->i_mutex);

    out_drop_write:
    - mnt_drop_write(nd.mnt);
    + mnt_drop_write(nd.path.mnt);
    dput_and_out:
    path_release(&nd);
    out:
    @@ -687,11 +687,11 @@ asmlinkage long sys_chown(const char __u
    error = user_path_walk(filename, &nd);
    if (error)
    goto out;
    - error = mnt_want_write(nd.mnt);
    + error = mnt_want_write(nd.path.mnt);
    if (error)
    goto out_release;
    - error = chown_common(nd.dentry, user, group);
    - mnt_drop_write(nd.mnt);
    + error = chown_common(nd.path.dentry, user, group);
    + mnt_drop_write(nd.path.mnt);
    out_release:
    path_release(&nd);
    out:
    @@ -712,11 +712,11 @@ asmlinkage long sys_fchownat(int dfd, co
    error = __user_walk_fd(dfd, filename, follow, &nd);
    if (error)
    goto out;
    - error = mnt_want_write(nd.mnt);
    + error = mnt_want_write(nd.path.mnt);
    if (error)
    goto out_release;
    - error = chown_common(nd.dentry, user, group);
    - mnt_drop_write(nd.mnt);
    + error = chown_common(nd.path.dentry, user, group);
    + mnt_drop_write(nd.path.mnt);
    out_release:
    path_release(&nd);
    out:
    @@ -731,11 +731,11 @@ asmlinkage long sys_lchown(const char __
    error = user_path_walk_link(filename, &nd);
    if (error)
    goto out;
    - error = mnt_want_write(nd.mnt);
    + error = mnt_want_write(nd.path.mnt);
    if (error)
    goto out_release;
    - error = chown_common(nd.dentry, user, group);
    - mnt_drop_write(nd.mnt);
    + error = chown_common(nd.path.dentry, user, group);
    + mnt_drop_write(nd.path.mnt);
    out_release:
    path_release(&nd);
    out:
    @@ -895,7 +895,7 @@ struct file *lookup_instantiate_filp(str
    goto out;
    if (IS_ERR(dentry))
    goto out_err;
    - nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->mnt),
    + nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt),
    nd->intent.open.flags - 1,
    nd->intent.open.file,
    open);
    @@ -923,7 +923,8 @@ struct file *nameidata_to_filp(struct na
    filp = nd->intent.open.file;
    /* Has the filesystem initialised the file for us? */
    if (filp->f_path.dentry == NULL)
    - filp = __dentry_open(nd->dentry, nd->mnt, flags, filp, NULL);
    + filp = __dentry_open(nd->path.dentry, nd->path.mnt, flags, filp,
    + NULL);
    else
    path_release(nd);
    return filp;
    Index: b/fs/proc/base.c
    ================================================== =================
    --- a/fs/proc/base.c
    +++ b/fs/proc/base.c
    @@ -990,7 +990,8 @@ static void *proc_pid_follow_link(struct
    if (!proc_fd_access_allowed(inode))
    goto out;

    - error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt);
    + error = PROC_I(inode)->op.proc_get_link(inode, &nd->path.dentry,
    + &nd->path.mnt);
    nd->last_type = LAST_BIND;
    out:
    return ERR_PTR(error);
    Index: b/fs/proc/proc_net.c
    ================================================== =================
    --- a/fs/proc/proc_net.c
    +++ b/fs/proc/proc_net.c
    @@ -92,11 +92,11 @@ static void *proc_net_follow_link(struct
    if (!shadow)
    return ERR_PTR(-ENOENT);

    - dput(nd->dentry);
    + dput(nd->path.dentry);
    /* My dentry count is 1 and that should be enough as the
    * shadow dentry is thrown away immediately.
    */
    - nd->dentry = shadow;
    + nd->path.dentry = shadow;
    return NULL;
    }

    @@ -106,12 +106,12 @@ static struct dentry *proc_net_lookup(st
    struct net *net = current->nsproxy->net_ns;
    struct dentry *shadow;

    - shadow = proc_net_shadow_dentry(nd->dentry, net->proc_net);
    + shadow = proc_net_shadow_dentry(nd->path.dentry, net->proc_net);
    if (!shadow)
    return ERR_PTR(-ENOENT);

    - dput(nd->dentry);
    - nd->dentry = shadow;
    + dput(nd->path.dentry);
    + nd->path.dentry = shadow;

    return shadow->d_inode->i_op->lookup(shadow->d_inode, dentry, nd);
    }
    Index: b/fs/proc/proc_sysctl.c
    ================================================== =================
    --- a/fs/proc/proc_sysctl.c
    +++ b/fs/proc/proc_sysctl.c
    @@ -405,7 +405,7 @@ static int proc_sys_permission(struct in
    if (!nd || !depth)
    goto out;

    - dentry = nd->dentry;
    + dentry = nd->path.dentry;
    table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);

    /* If the entry does not exist deny permission */
    Index: b/fs/reiserfs/super.c
    ================================================== =================
    --- a/fs/reiserfs/super.c
    +++ b/fs/reiserfs/super.c
    @@ -1997,12 +1997,12 @@ static int reiserfs_quota_on(struct supe
    if (err)
    return err;
    /* Quotafile not on the same filesystem? */
    - if (nd.mnt->mnt_sb != sb) {
    + if (nd.path.mnt->mnt_sb != sb) {
    path_release(&nd);
    return -EXDEV;
    }
    /* We must not pack tails for quota files on reiserfs for quota IO to work */
    - if (!REISERFS_I(nd.dentry->d_inode)->i_flags & i_nopack_mask) {
    + if (!REISERFS_I(nd.path.dentry->d_inode)->i_flags & i_nopack_mask) {
    reiserfs_warning(sb,
    "reiserfs: Quota file must have tail packing disabled.");
    path_release(&nd);
    @@ -2015,7 +2015,7 @@ static int reiserfs_quota_on(struct supe
    return vfs_quota_on(sb, type, format_id, path);
    }
    /* Quotafile not of fs root? */
    - if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode)
    + if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode)
    reiserfs_warning(sb,
    "reiserfs: Quota file not on filesystem root. "
    "Journalled quota will not work.");
    Index: b/fs/revoke.c
    ================================================== =================
    --- a/fs/revoke.c
    +++ b/fs/revoke.c
    @@ -649,7 +649,7 @@ asmlinkage long sys_revokeat(int dfd, co

    err = __user_walk_fd(dfd, filename, 0, &nd);
    if (!err) {
    - err = do_revoke(nd.dentry->d_inode, NULL);
    + err = do_revoke(nd.path.dentry->d_inode, NULL);
    path_release(&nd);
    }
    return err;
    Index: b/fs/stat.c
    ================================================== =================
    --- a/fs/stat.c
    +++ b/fs/stat.c
    @@ -62,7 +62,7 @@ int vfs_stat_fd(int dfd, char __user *na

    error = __user_walk_fd(dfd, name, LOOKUP_FOLLOW, &nd);
    if (!error) {
    - error = vfs_getattr(nd.mnt, nd.dentry, stat);
    + error = vfs_getattr(nd.path.mnt, nd.path.dentry, stat);
    path_release(&nd);
    }
    return error;
    @@ -82,7 +82,7 @@ int vfs_lstat_fd(int dfd, char __user *n

    error = __user_walk_fd(dfd, name, 0, &nd);
    if (!error) {
    - error = vfs_getattr(nd.mnt, nd.dentry, stat);
    + error = vfs_getattr(nd.path.mnt, nd.path.dentry, stat);
    path_release(&nd);
    }
    return error;
    @@ -302,14 +302,15 @@ asmlinkage long sys_readlinkat(int dfd,

    error = __user_walk_fd(dfd, path, 0, &nd);
    if (!error) {
    - struct inode * inode = nd.dentry->d_inode;
    + struct inode *inode = nd.path.dentry->d_inode;

    error = -EINVAL;
    if (inode->i_op && inode->i_op->readlink) {
    - error = security_inode_readlink(nd.dentry);
    + error = security_inode_readlink(nd.path.dentry);
    if (!error) {
    - touch_atime(nd.mnt, nd.dentry);
    - error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
    + touch_atime(nd.path.mnt, nd.path.dentry);
    + error = inode->i_op->readlink(nd.path.dentry,
    + buf, bufsiz);
    }
    }
    path_release(&nd);
    Index: b/fs/utimes.c
    ================================================== =================
    --- a/fs/utimes.c
    +++ b/fs/utimes.c
    @@ -86,8 +86,8 @@ long do_utimes(int dfd, char __user *fil
    if (error)
    goto out;

    - dentry = nd.dentry;
    - mnt = nd.mnt;
    + dentry = nd.path.dentry;
    + mnt = nd.path.mnt;
    }

    inode = dentry->d_inode;
    Index: b/fs/xattr.c
    ================================================== =================
    --- a/fs/xattr.c
    +++ b/fs/xattr.c
    @@ -234,11 +234,11 @@ sys_setxattr(char __user *path, char __u
    error = user_path_walk(path, &nd);
    if (error)
    return error;
    - error = mnt_want_write(nd.mnt);
    + error = mnt_want_write(nd.path.mnt);
    if (error)
    return error;
    - error = setxattr(nd.dentry, name, value, size, flags);
    - mnt_drop_write(nd.mnt);
    + error = setxattr(nd.path.dentry, name, value, size, flags);
    + mnt_drop_write(nd.path.mnt);
    path_release(&nd);
    return error;
    }
    @@ -253,11 +253,11 @@ sys_lsetxattr(char __user *path, char __
    error = user_path_walk_link(path, &nd);
    if (error)
    return error;
    - error = mnt_want_write(nd.mnt);
    + error = mnt_want_write(nd.path.mnt);
    if (error)
    return error;
    - error = setxattr(nd.dentry, name, value, size, flags);
    - mnt_drop_write(nd.mnt);
    + error = setxattr(nd.path.dentry, name, value, size, flags);
    + mnt_drop_write(nd.path.mnt);
    path_release(&nd);
    return error;
    }
    @@ -332,7 +332,7 @@ sys_getxattr(char __user *path, char __u
    error = user_path_walk(path, &nd);
    if (error)
    return error;
    - error = getxattr(nd.dentry, name, value, size);
    + error = getxattr(nd.path.dentry, name, value, size);
    path_release(&nd);
    return error;
    }
    @@ -347,7 +347,7 @@ sys_lgetxattr(char __user *path, char __
    error = user_path_walk_link(path, &nd);
    if (error)
    return error;
    - error = getxattr(nd.dentry, name, value, size);
    + error = getxattr(nd.path.dentry, name, value, size);
    path_release(&nd);
    return error;
    }
    @@ -406,7 +406,7 @@ sys_listxattr(char __user *path, char __
    error = user_path_walk(path, &nd);
    if (error)
    return error;
    - error = listxattr(nd.dentry, list, size);
    + error = listxattr(nd.path.dentry, list, size);
    path_release(&nd);
    return error;
    }
    @@ -420,7 +420,7 @@ sys_llistxattr(char __user *path, char _
    error = user_path_walk_link(path, &nd);
    if (error)
    return error;
    - error = listxattr(nd.dentry, list, size);
    + error = listxattr(nd.path.dentry, list, size);
    path_release(&nd);
    return error;
    }
    @@ -467,7 +467,7 @@ sys_removexattr(char __user *path, char
    error = user_path_walk(path, &nd);
    if (error)
    return error;
    - error = removexattr(nd.dentry, name);
    + error = removexattr(nd.path.dentry, name);
    path_release(&nd);
    return error;
    }
    @@ -481,7 +481,7 @@ sys_lremovexattr(char __user *path, char
    error = user_path_walk_link(path, &nd);
    if (error)
    return error;
    - error = removexattr(nd.dentry, name);
    + error = removexattr(nd.path.dentry, name);
    path_release(&nd);
    return error;
    }
    Index: b/fs/xfs/linux-2.6/xfs_ioctl.c
    ================================================== =================
    --- a/fs/xfs/linux-2.6/xfs_ioctl.c
    +++ b/fs/xfs/linux-2.6/xfs_ioctl.c
    @@ -92,9 +92,9 @@ xfs_find_handle(
    if (error)
    return error;

    - ASSERT(nd.dentry);
    - ASSERT(nd.dentry->d_inode);
    - inode = igrab(nd.dentry->d_inode);
    + ASSERT(nd.path.dentry);
    + ASSERT(nd.path.dentry->d_inode);
    + inode = igrab(nd.path.dentry->d_inode);
    path_release(&nd);
    break;
    }
    Index: b/include/linux/namei.h
    ================================================== =================
    --- a/include/linux/namei.h
    +++ b/include/linux/namei.h
    @@ -17,8 +17,7 @@ struct open_intent {
    enum { MAX_NESTED_LINKS = 8 };

    struct nameidata {
    - struct dentry *dentry;
    - struct vfsmount *mnt;
    + struct path path;
    struct qstr last;
    unsigned int flags;
    int last_type;
    Index: b/kernel/auditfilter.c
    ================================================== =================
    --- a/kernel/auditfilter.c
    +++ b/kernel/auditfilter.c
    @@ -167,8 +167,8 @@ static struct audit_parent *audit_init_p
    inotify_init_watch(&parent->wdata);
    /* grab a ref so inotify watch hangs around until we take audit_filter_mutex */
    get_inotify_watch(&parent->wdata);
    - wd = inotify_add_watch(audit_ih, &parent->wdata, ndp->dentry->d_inode,
    - AUDIT_IN_WATCH);
    + wd = inotify_add_watch(audit_ih, &parent->wdata,
    + ndp->path.dentry->d_inode, AUDIT_IN_WATCH);
    if (wd < 0) {
    audit_free_parent(&parent->wdata);
    return ERR_PTR(wd);
    @@ -1205,8 +1205,8 @@ static int audit_add_watch(struct audit_

    /* update watch filter fields */
    if (ndw) {
    - watch->dev = ndw->dentry->d_inode->i_sb->s_dev;
    - watch->ino = ndw->dentry->d_inode->i_ino;
    + watch->dev = ndw->path.dentry->d_inode->i_sb->s_dev;
    + watch->ino = ndw->path.dentry->d_inode->i_ino;
    }

    /* The audit_filter_mutex must not be held during inotify calls because
    @@ -1216,7 +1216,8 @@ static int audit_add_watch(struct audit_
    */
    mutex_unlock(&audit_filter_mutex);

    - if (inotify_find_watch(audit_ih, ndp->dentry->d_inode, &i_watch) < 0) {
    + if (inotify_find_watch(audit_ih, ndp->path.dentry->d_inode,
    + &i_watch) < 0) {
    parent = audit_init_parent(ndp);
    if (IS_ERR(parent)) {
    /* caller expects mutex locked */
    Index: b/net/sunrpc/rpc_pipe.c
    ================================================== =================
    --- a/net/sunrpc/rpc_pipe.c
    +++ b/net/sunrpc/rpc_pipe.c
    @@ -656,7 +656,8 @@ rpc_lookup_negative(char *path, struct n

    if ((error = rpc_lookup_parent(path, nd)) != 0)
    return ERR_PTR(error);
    - dentry = rpc_lookup_create(nd->dentry, nd->last.name, nd->last.len, 1);
    + dentry = rpc_lookup_create(nd->path.dentry, nd->last.name, nd->last.len,
    + 1);
    if (IS_ERR(dentry))
    rpc_release_path(nd);
    return dentry;
    @@ -674,7 +675,7 @@ rpc_mkdir(char *path, struct rpc_clnt *r
    dentry = rpc_lookup_negative(path, &nd);
    if (IS_ERR(dentry))
    return dentry;
    - dir = nd.dentry->d_inode;
    + dir = nd.path.dentry->d_inode;
    if ((error = __rpc_mkdir(dir, dentry)) != 0)
    goto err_dput;
    RPC_I(dentry->d_inode)->private = rpc_client;
    Index: b/net/unix/af_unix.c
    ================================================== =================
    --- a/net/unix/af_unix.c
    +++ b/net/unix/af_unix.c
    @@ -734,7 +734,7 @@ static struct sock *unix_find_other(stru
    if (err)
    goto fail;

    - err = mnt_want_write(nd.mnt);
    + err = mnt_want_write(nd.path.mnt);
    if (err)
    goto put_path_fail;

    @@ -743,17 +743,17 @@ static struct sock *unix_find_other(stru
    goto mnt_drop_write_fail;

    err = -ECONNREFUSED;
    - if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
    + if (!S_ISSOCK(nd.path.dentry->d_inode->i_mode))
    goto mnt_drop_write_fail;
    - u=unix_find_socket_byinode(nd.dentry->d_inode);
    + u=unix_find_socket_byinode(nd.path.dentry->d_inode);
    if (!u)
    goto mnt_drop_write_fail;

    if (u->sk_type == type)
    - touch_atime(nd.mnt, nd.dentry);
    + touch_atime(nd.path.mnt, nd.path.dentry);

    path_release(&nd);
    - mnt_drop_write(nd.mnt);
    + mnt_drop_write(nd.path.mnt);

    err=-EPROTOTYPE;
    if (u->sk_type != type) {
    @@ -774,7 +774,7 @@ static struct sock *unix_find_other(stru
    return u;

    mnt_drop_write_fail:
    - mnt_drop_write(nd.mnt);
    + mnt_drop_write(nd.path.mnt);
    put_path_fail:
    path_release(&nd);
    fail:
    @@ -846,16 +846,16 @@ static int unix_bind(struct socket *sock
    */
    mode = S_IFSOCK |
    (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
    - err = mnt_want_write(nd.mnt);
    + err = mnt_want_write(nd.path.mnt);
    if (err)
    goto out_mknod_dput;
    - err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
    - mnt_drop_write(nd.mnt);
    + err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0);
    + mnt_drop_write(nd.path.mnt);
    if (err)
    goto out_mknod_dput;
    - mutex_unlock(&nd.dentry->d_inode->i_mutex);
    - dput(nd.dentry);
    - nd.dentry = dentry;
    + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    + dput(nd.path.dentry);
    + nd.path.dentry = dentry;

    addr->hash = UNIX_HASH_SIZE;
    }
    @@ -873,8 +873,8 @@ static int unix_bind(struct socket *sock
    list = &unix_socket_table[addr->hash];
    } else {
    list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
    - u->dentry = nd.dentry;
    - u->mnt = nd.mnt;
    + u->dentry = nd.path.dentry;
    + u->mnt = nd.path.mnt;
    }

    err = 0;
    @@ -892,7 +892,7 @@ out:
    out_mknod_dput:
    dput(dentry);
    out_mknod_unlock:
    - mutex_unlock(&nd.dentry->d_inode->i_mutex);
    + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    path_release(&nd);
    out_mknod_parent:
    if (err==-EEXIST)
    Index: b/security/selinux/hooks.c
    ================================================== =================
    --- a/security/selinux/hooks.c
    +++ b/security/selinux/hooks.c
    @@ -2091,10 +2091,10 @@ static int selinux_mount(char * dev_name
    return rc;

    if (flags & MS_REMOUNT)
    - return superblock_has_perm(current, nd->mnt->mnt_sb,
    + return superblock_has_perm(current, nd->path.mnt->mnt_sb,
    FILESYSTEM__REMOUNT, NULL);
    else
    - return dentry_has_perm(current, nd->mnt, nd->dentry,
    + return dentry_has_perm(current, nd->path.mnt, nd->path.dentry,
    FILE__MOUNTON);
    }


    --

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  8. [patch 06/10] Introduce path_put()

    * Add path_put() functions for releasing a reference to the dentry and
    vfsmount of a struct path in the right order

    * Switch from path_release(nd) to path_put(&nd->path)

    * Rename dput_path() to path_put_conditional()

    Signed-off-by: Jan Blunck
    Signed-off-by: Andreas Gruenbacher
    Acked-by: Christoph Hellwig
    ---
    arch/alpha/kernel/osf_sys.c | 2
    arch/mips/kernel/sysirix.c | 6 +-
    arch/parisc/hpux/sys_hpux.c | 2
    arch/powerpc/platforms/cell/spufs/syscalls.c | 2
    arch/sparc64/solaris/fs.c | 4 -
    drivers/md/dm-table.c | 2
    drivers/mtd/mtdsuper.c | 4 -
    fs/afs/mntpt.c | 2
    fs/autofs4/root.c | 2
    fs/block_dev.c | 2
    fs/coda/pioctl.c | 4 -
    fs/compat.c | 4 -
    fs/configfs/symlink.c | 4 -
    fs/dquot.c | 2
    fs/ecryptfs/main.c | 2
    fs/exec.c | 4 -
    fs/ext3/super.c | 4 -
    fs/ext4/super.c | 4 -
    fs/gfs2/ops_fstype.c | 2
    fs/inotify_user.c | 4 -
    fs/namei.c | 56 ++++++++++++++-------------
    fs/namespace.c | 20 ++++-----
    fs/nfs/namespace.c | 2
    fs/nfsctl.c | 2
    fs/nfsd/export.c | 10 ++--
    fs/nfsd/nfs4recover.c | 2
    fs/nfsd/nfs4state.c | 2
    fs/open.c | 22 +++++-----
    fs/proc/base.c | 2
    fs/reiserfs/super.c | 8 +--
    fs/revoke.c | 2
    fs/stat.c | 6 +-
    fs/utimes.c | 2
    fs/xattr.c | 16 +++----
    fs/xfs/linux-2.6/xfs_ioctl.c | 2
    include/linux/namei.h | 7 ---
    include/linux/path.h | 2
    kernel/auditfilter.c | 4 -
    net/sunrpc/rpc_pipe.c | 2
    net/unix/af_unix.c | 6 +-
    40 files changed, 119 insertions(+), 118 deletions(-)

    Index: b/arch/alpha/kernel/osf_sys.c
    ================================================== =================
    --- a/arch/alpha/kernel/osf_sys.c
    +++ b/arch/alpha/kernel/osf_sys.c
    @@ -261,7 +261,7 @@ osf_statfs(char __user *path, struct osf
    retval = user_path_walk(path, &nd);
    if (!retval) {
    retval = do_osf_statfs(nd.path.dentry, buffer, bufsiz);
    - path_release(&nd);
    + path_put(&nd.path);
    }
    return retval;
    }
    Index: b/arch/mips/kernel/sysirix.c
    ================================================== =================
    --- a/arch/mips/kernel/sysirix.c
    +++ b/arch/mips/kernel/sysirix.c
    @@ -711,7 +711,7 @@ asmlinkage int irix_statfs(const char __
    }

    dput_and_out:
    - path_release(&nd);
    + path_put(&nd.path);
    out:
    return error;
    }
    @@ -1385,7 +1385,7 @@ asmlinkage int irix_statvfs(char __user
    error |= __put_user(0, &buf->f_fstr[i]);

    dput_and_out:
    - path_release(&nd);
    + path_put(&nd.path);
    out:
    return error;
    }
    @@ -1636,7 +1636,7 @@ asmlinkage int irix_statvfs64(char __use
    error |= __put_user(0, &buf->f_fstr[i]);

    dput_and_out:
    - path_release(&nd);
    + path_put(&nd.path);
    out:
    return error;
    }
    Index: b/arch/parisc/hpux/sys_hpux.c
    ================================================== =================
    --- a/arch/parisc/hpux/sys_hpux.c
    +++ b/arch/parisc/hpux/sys_hpux.c
    @@ -222,7 +222,7 @@ asmlinkage long hpux_statfs(const char _
    error = vfs_statfs_hpux(nd.path.dentry, &tmp);
    if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
    error = -EFAULT;
    - path_release(&nd);
    + path_put(&nd.path);
    }
    return error;
    }
    Index: b/arch/powerpc/platforms/cell/spufs/syscalls.c
    ================================================== =================
    --- a/arch/powerpc/platforms/cell/spufs/syscalls.c
    +++ b/arch/powerpc/platforms/cell/spufs/syscalls.c
    @@ -73,7 +73,7 @@ static long do_spu_create(const char __u
    LOOKUP_OPEN|LOOKUP_CREATE, &nd);
    if (!ret) {
    ret = spufs_create(&nd, flags, mode, neighbor);
    - path_release(&nd);
    + path_put(&nd.path);
    }
    putname(tmp);
    }
    Index: b/arch/sparc64/solaris/fs.c
    ================================================== =================
    --- a/arch/sparc64/solaris/fs.c
    +++ b/arch/sparc64/solaris/fs.c
    @@ -436,7 +436,7 @@ asmlinkage int solaris_statvfs(u32 path,
    if (!error) {
    struct inode *inode = nd.path.dentry->d_inode;
    error = report_statvfs(nd.path.mnt, inode, buf);
    - path_release(&nd);
    + path_put(&nd.path);
    }
    return error;
    }
    @@ -466,7 +466,7 @@ asmlinkage int solaris_statvfs64(u32 pat
    if (!error) {
    struct inode *inode = nd.path.dentry->d_inode;
    error = report_statvfs64(nd.path.mnt, inode, buf);
    - path_release(&nd);
    + path_put(&nd.path);
    }
    unlock_kernel();
    return error;
    Index: b/drivers/md/dm-table.c
    ================================================== =================
    --- a/drivers/md/dm-table.c
    +++ b/drivers/md/dm-table.c
    @@ -369,7 +369,7 @@ static int lookup_device(const char *pat
    *dev = inode->i_rdev;

    out:
    - path_release(&nd);
    + path_put(&nd.path);
    return r;
    }

    Index: b/drivers/mtd/mtdsuper.c
    ================================================== =================
    --- a/drivers/mtd/mtdsuper.c
    +++ b/drivers/mtd/mtdsuper.c
    @@ -203,7 +203,7 @@ int get_sb_mtd(struct file_system_type *
    goto not_an_MTD_device;

    mtdnr = iminor(nd.path.dentry->d_inode);
    - path_release(&nd);
    + path_put(&nd.path);

    return get_sb_mtd_nr(fs_type, flags, dev_name, data, mtdnr, fill_super,
    mnt);
    @@ -214,7 +214,7 @@ not_an_MTD_device:
    "MTD: Attempt to mount non-MTD device \"%s\"\n",
    dev_name);
    out:
    - path_release(&nd);
    + path_put(&nd.path);
    return ret;

    }
    Index: b/fs/afs/mntpt.c
    ================================================== =================
    --- a/fs/afs/mntpt.c
    +++ b/fs/afs/mntpt.c
    @@ -227,7 +227,7 @@ static void *afs_mntpt_follow_link(struc

    newmnt = afs_mntpt_do_automount(nd->path.dentry);
    if (IS_ERR(newmnt)) {
    - path_release(nd);
    + path_put(&nd->path);
    return (void *)newmnt;
    }

    Index: b/fs/autofs4/root.c
    ================================================== =================
    --- a/fs/autofs4/root.c
    +++ b/fs/autofs4/root.c
    @@ -541,7 +541,7 @@ done:
    return NULL;

    out_error:
    - path_release(nd);
    + path_put(&nd->path);
    return ERR_PTR(status);
    }

    Index: b/fs/block_dev.c
    ================================================== =================
    --- a/fs/block_dev.c
    +++ b/fs/block_dev.c
    @@ -1415,7 +1415,7 @@ struct block_device *lookup_bdev(const c
    if (!bdev)
    goto fail;
    out:
    - path_release(&nd);
    + path_put(&nd.path);
    return bdev;
    fail:
    bdev = ERR_PTR(error);
    Index: b/fs/coda/pioctl.c
    ================================================== =================
    --- a/fs/coda/pioctl.c
    +++ b/fs/coda/pioctl.c
    @@ -80,7 +80,7 @@ static int coda_pioctl(struct inode * in

    /* return if it is not a Coda inode */
    if ( target_inode->i_sb != inode->i_sb ) {
    - path_release(&nd);
    + path_put(&nd.path);
    return -EINVAL;
    }

    @@ -89,7 +89,7 @@ static int coda_pioctl(struct inode * in

    error = venus_pioctl(inode->i_sb, &(cnp->c_fid), cmd, &data);

    - path_release(&nd);
    + path_put(&nd.path);
    return error;
    }

    Index: b/fs/compat.c
    ================================================== =================
    --- a/fs/compat.c
    +++ b/fs/compat.c
    @@ -244,7 +244,7 @@ asmlinkage long compat_sys_statfs(const
    error = vfs_statfs(nd.path.dentry, &tmp);
    if (!error)
    error = put_compat_statfs(buf, &tmp);
    - path_release(&nd);
    + path_put(&nd.path);
    }
    return error;
    }
    @@ -312,7 +312,7 @@ asmlinkage long compat_sys_statfs64(cons
    error = vfs_statfs(nd.path.dentry, &tmp);
    if (!error)
    error = put_compat_statfs64(buf, &tmp);
    - path_release(&nd);
    + path_put(&nd.path);
    }
    return error;
    }
    Index: b/fs/configfs/symlink.c
    ================================================== =================
    --- a/fs/configfs/symlink.c
    +++ b/fs/configfs/symlink.c
    @@ -103,7 +103,7 @@ static int get_target(const char *symnam
    *target = configfs_get_config_item(nd->path.dentry);
    if (!*target) {
    ret = -ENOENT;
    - path_release(nd);
    + path_put(&nd->path);
    }
    } else
    ret = -EPERM;
    @@ -141,7 +141,7 @@ int configfs_symlink(struct inode *dir,
    ret = create_link(parent_item, target_item, dentry);

    config_item_put(target_item);
    - path_release(&nd);
    + path_put(&nd.path);

    out_put:
    config_item_put(parent_item);
    Index: b/fs/dquot.c
    ================================================== =================
    --- a/fs/dquot.c
    +++ b/fs/dquot.c
    @@ -1630,7 +1630,7 @@ int vfs_quota_on(struct super_block *sb,
    error = vfs_quota_on_inode(nd.path.dentry->d_inode, type,
    format_id);
    out_path:
    - path_release(&nd);
    + path_put(&nd.path);
    return error;
    }

    Index: b/fs/ecryptfs/main.c
    ================================================== =================
    --- a/fs/ecryptfs/main.c
    +++ b/fs/ecryptfs/main.c
    @@ -531,7 +531,7 @@ static int ecryptfs_read_super(struct su
    rc = 0;
    goto out;
    out_free:
    - path_release(&nd);
    + path_put(&nd.path);
    out:
    return rc;
    }
    Index: b/fs/exec.c
    ================================================== =================
    --- a/fs/exec.c
    +++ b/fs/exec.c
    @@ -148,7 +148,7 @@ out:
    return error;
    exit:
    release_open_intent(&nd);
    - path_release(&nd);
    + path_put(&nd.path);
    goto out;
    }

    @@ -672,7 +672,7 @@ out:
    }
    }
    release_open_intent(&nd);
    - path_release(&nd);
    + path_put(&nd.path);
    }
    goto out;
    }
    Index: b/fs/ext3/super.c
    ================================================== =================
    --- a/fs/ext3/super.c
    +++ b/fs/ext3/super.c
    @@ -2732,7 +2732,7 @@ static int ext3_quota_on(struct super_bl
    return err;
    /* Quotafile not on the same filesystem? */
    if (nd.path.mnt->mnt_sb != sb) {
    - path_release(&nd);
    + path_put(&nd.path);
    return -EXDEV;
    }
    /* Quotafile not of fs root? */
    @@ -2740,7 +2740,7 @@ static int ext3_quota_on(struct super_bl
    printk(KERN_WARNING
    "EXT3-fs: Quota file not on filesystem root. "
    "Journalled quota will not work.\n");
    - path_release(&nd);
    + path_put(&nd.path);
    return vfs_quota_on(sb, type, format_id, path);
    }

    Index: b/fs/ext4/super.c
    ================================================== =================
    --- a/fs/ext4/super.c
    +++ b/fs/ext4/super.c
    @@ -2934,7 +2934,7 @@ static int ext4_quota_on(struct super_bl
    return err;
    /* Quotafile not on the same filesystem? */
    if (nd.path.mnt->mnt_sb != sb) {
    - path_release(&nd);
    + path_put(&nd.path);
    return -EXDEV;
    }
    /* Quotafile not of fs root? */
    @@ -2942,7 +2942,7 @@ static int ext4_quota_on(struct super_bl
    printk(KERN_WARNING
    "EXT4-fs: Quota file not on filesystem root. "
    "Journalled quota will not work.\n");
    - path_release(&nd);
    + path_put(&nd.path);
    return vfs_quota_on(sb, type, format_id, path);
    }

    Index: b/fs/gfs2/ops_fstype.c
    ================================================== =================
    --- a/fs/gfs2/ops_fstype.c
    +++ b/fs/gfs2/ops_fstype.c
    @@ -837,7 +837,7 @@ static struct super_block* get_gfs2_sb(c
    "mount point %s\n", dev_name);

    free_nd:
    - path_release(&nd);
    + path_put(&nd.path);
    out:
    return sb;
    }
    Index: b/fs/inotify_user.c
    ================================================== =================
    --- a/fs/inotify_user.c
    +++ b/fs/inotify_user.c
    @@ -351,7 +351,7 @@ static int find_inode(const char __user
    /* you can only watch an inode if you have read permissions on it */
    error = vfs_permission(nd, MAY_READ);
    if (error)
    - path_release(nd);
    + path_put(&nd->path);
    return error;
    }

    @@ -648,7 +648,7 @@ asmlinkage long sys_inotify_add_watch(in
    ret = create_watch(dev, inode, mask);
    mutex_unlock(&dev->up_mutex);

    - path_release(&nd);
    + path_put(&nd.path);
    fput_and_out:
    fput_light(filp, fput_needed);
    return ret;
    Index: b/fs/namei.c
    ================================================== =================
    --- a/fs/namei.c
    +++ b/fs/namei.c
    @@ -362,11 +362,18 @@ int deny_write_access(struct file * file
    return 0;
    }

    -void path_release(struct nameidata *nd)
    +/**
    + * path_put - put a reference to a path
    + * @path: path to put the reference to
    + *
    + * Given a path decrement the reference count to the dentry and the vfsmount.
    + */
    +void path_put(struct path *path)
    {
    - dput(nd->path.dentry);
    - mntput(nd->path.mnt);
    + dput(path->dentry);
    + mntput(path->mnt);
    }
    +EXPORT_SYMBOL(path_put);

    /**
    * release_open_intent - free up open intent resources
    @@ -552,7 +559,7 @@ static __always_inline int __vfs_follow_
    goto fail;

    if (*link == '/') {
    - path_release(nd);
    + path_put(&nd->path);
    if (!walk_init_root(link, nd))
    /* weird __emul_prefix() stuff did it */
    goto out;
    @@ -568,18 +575,18 @@ out:
    */
    name = __getname();
    if (unlikely(!name)) {
    - path_release(nd);
    + path_put(&nd->path);
    return -ENOMEM;
    }
    strcpy(name, nd->last.name);
    nd->last.name = name;
    return 0;
    fail:
    - path_release(nd);
    + path_put(&nd->path);
    return PTR_ERR(link);
    }

    -static inline void dput_path(struct path *path, struct nameidata *nd)
    +static void path_put_conditional(struct path *path, struct nameidata *nd)
    {
    dput(path->dentry);
    if (path->mnt != nd->path.mnt)
    @@ -652,8 +659,8 @@ static inline int do_follow_link(struct
    nd->depth--;
    return err;
    loop:
    - dput_path(path, nd);
    - path_release(nd);
    + path_put_conditional(path, nd);
    + path_put(&nd->path);
    return err;
    }

    @@ -994,10 +1001,10 @@ return_reval:
    return_base:
    return 0;
    out_dput:
    - dput_path(&next, nd);
    + path_put_conditional(&next, nd);
    break;
    }
    - path_release(nd);
    + path_put(&nd->path);
    return_err:
    return err;
    }
    @@ -1071,7 +1078,7 @@ static int __emul_lookup_dentry(const ch
    mntput(old_mnt);
    return 1;
    }
    - path_release(nd);
    + path_put(&nd->path);
    }
    nd->path.dentry = old_dentry;
    nd->path.mnt = old_mnt;
    @@ -1231,7 +1238,7 @@ static int __path_lookup_intent_open(int
    if (IS_ERR(nd->intent.open.file)) {
    if (err == 0) {
    err = PTR_ERR(nd->intent.open.file);
    - path_release(nd);
    + path_put(&nd->path);
    }
    } else if (err != 0)
    release_open_intent(nd);
    @@ -1817,11 +1824,11 @@ ok:
    exit_mutex_unlock:
    mutex_unlock(&dir->d_inode->i_mutex);
    exit_dput:
    - dput_path(&path, nd);
    + path_put_conditional(&path, nd);
    exit:
    if (!IS_ERR(nd->intent.open.file))
    release_open_intent(nd);
    - path_release(nd);
    + path_put(&nd->path);
    return error;

    do_link:
    @@ -2002,7 +2009,7 @@ out_dput:
    dput(dentry);
    out_unlock:
    mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    - path_release(&nd);
    + path_put(&nd.path);
    out:
    putname(tmp);

    @@ -2067,7 +2074,7 @@ out_dput:
    dput(dentry);
    out_unlock:
    mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    - path_release(&nd);
    + path_put(&nd.path);
    out:
    putname(tmp);
    out_err:
    @@ -2180,7 +2187,7 @@ exit3:
    exit2:
    mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    exit1:
    - path_release(&nd);
    + path_put(&nd.path);
    exit:
    putname(name);
    return error;
    @@ -2267,7 +2274,7 @@ static long do_unlinkat(int dfd, const c
    if (inode)
    iput(inode); /* truncate the inode here */
    exit1:
    - path_release(&nd);
    + path_put(&nd.path);
    exit:
    putname(name);
    return error;
    @@ -2349,7 +2356,7 @@ out_dput:
    dput(dentry);
    out_unlock:
    mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    - path_release(&nd);
    + path_put(&nd.path);
    out:
    putname(to);
    out_putname:
    @@ -2450,9 +2457,9 @@ out_dput:
    out_unlock:
    mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    out_release:
    - path_release(&nd);
    + path_put(&nd.path);
    out:
    - path_release(&old_nd);
    + path_put(&old_nd.path);
    exit:
    putname(to);

    @@ -2684,9 +2691,9 @@ exit4:
    exit3:
    unlock_rename(new_dir, old_dir);
    exit2:
    - path_release(&newnd);
    + path_put(&newnd.path);
    exit1:
    - path_release(&oldnd);
    + path_put(&oldnd.path);
    exit:
    return error;
    }
    @@ -2860,7 +2867,6 @@ EXPORT_SYMBOL(page_symlink);
    EXPORT_SYMBOL(page_symlink_inode_operations);
    EXPORT_SYMBOL(path_lookup);
    EXPORT_SYMBOL(vfs_path_lookup);
    -EXPORT_SYMBOL(path_release);
    EXPORT_SYMBOL(permission);
    EXPORT_SYMBOL(vfs_permission);
    EXPORT_SYMBOL(file_permission);
    Index: b/fs/namespace.c
    ================================================== =================
    --- a/fs/namespace.c
    +++ b/fs/namespace.c
    @@ -1323,7 +1323,7 @@ static int do_loopback(struct nameidata

    out:
    up_write(&namespace_sem);
    - path_release(&old_nd);
    + path_put(&old_nd.path);
    return err;
    }

    @@ -1462,8 +1462,8 @@ out1:
    out:
    up_write(&namespace_sem);
    if (!err)
    - path_release(&parent_nd);
    - path_release(&old_nd);
    + path_put(&parent_nd.path);
    + path_put(&old_nd.path);
    return err;
    }

    @@ -1902,7 +1902,7 @@ long do_mount(char *dev_name, char *dir_
    retval = do_new_mount(&nd, type_page, flags, mnt_flags,
    dev_name, data_page);
    dput_out:
    - path_release(&nd);
    + path_put(&nd.path);
    return retval;
    }

    @@ -2158,7 +2158,7 @@ asmlinkage long sys_pivot_root(const cha

    error = security_sb_pivotroot(&old_nd, &new_nd);
    if (error) {
    - path_release(&old_nd);
    + path_put(&old_nd.path);
    goto out1;
    }

    @@ -2221,15 +2221,15 @@ asmlinkage long sys_pivot_root(const cha
    chroot_fs_refs(&user_nd, &new_nd);
    security_sb_post_pivotroot(&user_nd, &new_nd);
    error = 0;
    - path_release(&root_parent);
    - path_release(&parent_nd);
    + path_put(&root_parent.path);
    + path_put(&parent_nd.path);
    out2:
    mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex);
    up_write(&namespace_sem);
    - path_release(&user_nd);
    - path_release(&old_nd);
    + path_put(&user_nd.path);
    + path_put(&old_nd.path);
    out1:
    - path_release(&new_nd);
    + path_put(&new_nd.path);
    out0:
    unlock_kernel();
    return error;
    Index: b/fs/nfs/namespace.c
    ================================================== =================
    --- a/fs/nfs/namespace.c
    +++ b/fs/nfs/namespace.c
    @@ -148,7 +148,7 @@ out:
    dprintk("<-- nfs_follow_mountpoint() = %d\n", err);
    return ERR_PTR(err);
    out_err:
    - path_release(nd);
    + path_put(&nd->path);
    goto out;
    out_follow:
    while (d_mountpoint(nd->path.dentry) &&
    Index: b/fs/nfsctl.c
    ================================================== =================
    --- a/fs/nfsctl.c
    +++ b/fs/nfsctl.c
    @@ -43,7 +43,7 @@ static struct file *do_open(char *name,
    if (!error)
    return dentry_open(nd.path.dentry, nd.path.mnt, flags);

    - path_release(&nd);
    + path_put(&nd.path);
    return ERR_PTR(error);
    }

    Index: b/fs/nfsd/export.c
    ================================================== =================
    --- a/fs/nfsd/export.c
    +++ b/fs/nfsd/export.c
    @@ -177,7 +177,7 @@ static int expkey_parse(struct cache_det
    cache_put(&ek->h, &svc_expkey_cache);
    else
    err = -ENOMEM;
    - path_release(&nd);
    + path_put(&nd.path);
    }
    cache_flush();
    out:
    @@ -630,7 +630,7 @@ static int svc_export_parse(struct cache
    kfree(exp.ex_uuid);
    kfree(exp.ex_path);
    if (nd.path.dentry)
    - path_release(&nd);
    + path_put(&nd.path);
    out_no_path:
    if (dom)
    auth_domain_put(dom);
    @@ -1098,7 +1098,7 @@ finish:
    cache_put(&fsid_key->h, &svc_expkey_cache);
    if (clp)
    auth_domain_put(clp);
    - path_release(&nd);
    + path_put(&nd.path);
    out_unlock:
    exp_writeunlock();
    out:
    @@ -1150,7 +1150,7 @@ exp_unexport(struct nfsctl_export *nxp)

    err = -EINVAL;
    exp = exp_get_by_name(dom, nd.path.mnt, nd.path.dentry, NULL);
    - path_release(&nd);
    + path_put(&nd.path);
    if (IS_ERR(exp))
    goto out_domain;

    @@ -1209,7 +1209,7 @@ exp_rootfh(svc_client *clp, char *path,
    fh_put(&fh);
    exp_put(exp);
    out:
    - path_release(&nd);
    + path_put(&nd.path);
    return err;
    }

    Index: b/fs/nfsd/nfs4recover.c
    ================================================== =================
    --- a/fs/nfsd/nfs4recover.c
    +++ b/fs/nfsd/nfs4recover.c
    @@ -421,5 +421,5 @@ nfsd4_shutdown_recdir(void)
    if (!rec_dir_init)
    return;
    rec_dir_init = 0;
    - path_release(&rec_dir);
    + path_put(&rec_dir.path);
    }
    Index: b/fs/nfsd/nfs4state.c
    ================================================== =================
    --- a/fs/nfsd/nfs4state.c
    +++ b/fs/nfsd/nfs4state.c
    @@ -3325,7 +3325,7 @@ nfs4_reset_recoverydir(char *recdir)
    nfs4_set_recdir(recdir);
    status = 0;
    }
    - path_release(&nd);
    + path_put(&nd.path);
    return status;
    }

    Index: b/fs/open.c
    ================================================== =================
    --- a/fs/open.c
    +++ b/fs/open.c
    @@ -130,7 +130,7 @@ asmlinkage long sys_statfs(const char __
    error = vfs_statfs_native(nd.path.dentry, &tmp);
    if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
    error = -EFAULT;
    - path_release(&nd);
    + path_put(&nd.path);
    }
    return error;
    }
    @@ -149,7 +149,7 @@ asmlinkage long sys_statfs64(const char
    error = vfs_statfs64(nd.path.dentry, &tmp);
    if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
    error = -EFAULT;
    - path_release(&nd);
    + path_put(&nd.path);
    }
    return error;
    }
    @@ -279,7 +279,7 @@ put_write_and_out:
    mnt_drop_write_and_out:
    mnt_drop_write(nd.path.mnt);
    dput_and_out:
    - path_release(&nd);
    + path_put(&nd.path);
    out:
    return error;
    }
    @@ -473,7 +473,7 @@ asmlinkage long sys_faccessat(int dfd, c
    res = -EROFS;

    out_path_release:
    - path_release(&nd);
    + path_put(&nd.path);
    out:
    current->fsuid = old_fsuid;
    current->fsgid = old_fsgid;
    @@ -504,7 +504,7 @@ asmlinkage long sys_chdir(const char __u
    set_fs_pwd(current->fs, nd.path.mnt, nd.path.dentry);

    dput_and_out:
    - path_release(&nd);
    + path_put(&nd.path);
    out:
    return error;
    }
    @@ -560,7 +560,7 @@ asmlinkage long sys_chroot(const char __
    set_fs_altroot();
    error = 0;
    dput_and_out:
    - path_release(&nd);
    + path_put(&nd.path);
    out:
    return error;
    }
    @@ -636,7 +636,7 @@ asmlinkage long sys_fchmodat(int dfd, co
    out_drop_write:
    mnt_drop_write(nd.path.mnt);
    dput_and_out:
    - path_release(&nd);
    + path_put(&nd.path);
    out:
    return error;
    }
    @@ -693,7 +693,7 @@ asmlinkage long sys_chown(const char __u
    error = chown_common(nd.path.dentry, user, group);
    mnt_drop_write(nd.path.mnt);
    out_release:
    - path_release(&nd);
    + path_put(&nd.path);
    out:
    return error;
    }
    @@ -718,7 +718,7 @@ asmlinkage long sys_fchownat(int dfd, co
    error = chown_common(nd.path.dentry, user, group);
    mnt_drop_write(nd.path.mnt);
    out_release:
    - path_release(&nd);
    + path_put(&nd.path);
    out:
    return error;
    }
    @@ -737,7 +737,7 @@ asmlinkage long sys_lchown(const char __
    error = chown_common(nd.path.dentry, user, group);
    mnt_drop_write(nd.path.mnt);
    out_release:
    - path_release(&nd);
    + path_put(&nd.path);
    out:
    return error;
    }
    @@ -926,7 +926,7 @@ struct file *nameidata_to_filp(struct na
    filp = __dentry_open(nd->path.dentry, nd->path.mnt, flags, filp,
    NULL);
    else
    - path_release(nd);
    + path_put(&nd->path);
    return filp;
    }

    Index: b/fs/proc/base.c
    ================================================== =================
    --- a/fs/proc/base.c
    +++ b/fs/proc/base.c
    @@ -984,7 +984,7 @@ static void *proc_pid_follow_link(struct
    int error = -EACCES;

    /* We don't need a base pointer in the /proc filesystem */
    - path_release(nd);
    + path_put(&nd->path);

    /* Are we allowed to snoop on the tasks file descriptors? */
    if (!proc_fd_access_allowed(inode))
    Index: b/fs/reiserfs/super.c
    ================================================== =================
    --- a/fs/reiserfs/super.c
    +++ b/fs/reiserfs/super.c
    @@ -1998,20 +1998,20 @@ static int reiserfs_quota_on(struct supe
    return err;
    /* Quotafile not on the same filesystem? */
    if (nd.path.mnt->mnt_sb != sb) {
    - path_release(&nd);
    + path_put(&nd.path);
    return -EXDEV;
    }
    /* We must not pack tails for quota files on reiserfs for quota IO to work */
    if (!REISERFS_I(nd.path.dentry->d_inode)->i_flags & i_nopack_mask) {
    reiserfs_warning(sb,
    "reiserfs: Quota file must have tail packing disabled.");
    - path_release(&nd);
    + path_put(&nd.path);
    return -EINVAL;
    }
    /* Not journalling quota? No more tests needed... */
    if (!REISERFS_SB(sb)->s_qf_names[USRQUOTA] &&
    !REISERFS_SB(sb)->s_qf_names[GRPQUOTA]) {
    - path_release(&nd);
    + path_put(&nd.path);
    return vfs_quota_on(sb, type, format_id, path);
    }
    /* Quotafile not of fs root? */
    @@ -2019,7 +2019,7 @@ static int reiserfs_quota_on(struct supe
    reiserfs_warning(sb,
    "reiserfs: Quota file not on filesystem root. "
    "Journalled quota will not work.");
    - path_release(&nd);
    + path_put(&nd.path);
    return vfs_quota_on(sb, type, format_id, path);
    }

    Index: b/fs/revoke.c
    ================================================== =================
    --- a/fs/revoke.c
    +++ b/fs/revoke.c
    @@ -650,7 +650,7 @@ asmlinkage long sys_revokeat(int dfd, co
    err = __user_walk_fd(dfd, filename, 0, &nd);
    if (!err) {
    err = do_revoke(nd.path.dentry->d_inode, NULL);
    - path_release(&nd);
    + path_put(&nd.path);
    }
    return err;
    }
    Index: b/fs/stat.c
    ================================================== =================
    --- a/fs/stat.c
    +++ b/fs/stat.c
    @@ -63,7 +63,7 @@ int vfs_stat_fd(int dfd, char __user *na
    error = __user_walk_fd(dfd, name, LOOKUP_FOLLOW, &nd);
    if (!error) {
    error = vfs_getattr(nd.path.mnt, nd.path.dentry, stat);
    - path_release(&nd);
    + path_put(&nd.path);
    }
    return error;
    }
    @@ -83,7 +83,7 @@ int vfs_lstat_fd(int dfd, char __user *n
    error = __user_walk_fd(dfd, name, 0, &nd);
    if (!error) {
    error = vfs_getattr(nd.path.mnt, nd.path.dentry, stat);
    - path_release(&nd);
    + path_put(&nd.path);
    }
    return error;
    }
    @@ -313,7 +313,7 @@ asmlinkage long sys_readlinkat(int dfd,
    buf, bufsiz);
    }
    }
    - path_release(&nd);
    + path_put(&nd.path);
    }
    return error;
    }
    Index: b/fs/utimes.c
    ================================================== =================
    --- a/fs/utimes.c
    +++ b/fs/utimes.c
    @@ -143,7 +143,7 @@ dput_and_out:
    if (f)
    fput(f);
    else
    - path_release(&nd);
    + path_put(&nd.path);
    out:
    return error;
    }
    Index: b/fs/xattr.c
    ================================================== =================
    --- a/fs/xattr.c
    +++ b/fs/xattr.c
    @@ -239,7 +239,7 @@ sys_setxattr(char __user *path, char __u
    return error;
    error = setxattr(nd.path.dentry, name, value, size, flags);
    mnt_drop_write(nd.path.mnt);
    - path_release(&nd);
    + path_put(&nd.path);
    return error;
    }

    @@ -258,7 +258,7 @@ sys_lsetxattr(char __user *path, char __
    return error;
    error = setxattr(nd.path.dentry, name, value, size, flags);
    mnt_drop_write(nd.path.mnt);
    - path_release(&nd);
    + path_put(&nd.path);
    return error;
    }

    @@ -333,7 +333,7 @@ sys_getxattr(char __user *path, char __u
    if (error)
    return error;
    error = getxattr(nd.path.dentry, name, value, size);
    - path_release(&nd);
    + path_put(&nd.path);
    return error;
    }

    @@ -348,7 +348,7 @@ sys_lgetxattr(char __user *path, char __
    if (error)
    return error;
    error = getxattr(nd.path.dentry, name, value, size);
    - path_release(&nd);
    + path_put(&nd.path);
    return error;
    }

    @@ -407,7 +407,7 @@ sys_listxattr(char __user *path, char __
    if (error)
    return error;
    error = listxattr(nd.path.dentry, list, size);
    - path_release(&nd);
    + path_put(&nd.path);
    return error;
    }

    @@ -421,7 +421,7 @@ sys_llistxattr(char __user *path, char _
    if (error)
    return error;
    error = listxattr(nd.path.dentry, list, size);
    - path_release(&nd);
    + path_put(&nd.path);
    return error;
    }

    @@ -468,7 +468,7 @@ sys_removexattr(char __user *path, char
    if (error)
    return error;
    error = removexattr(nd.path.dentry, name);
    - path_release(&nd);
    + path_put(&nd.path);
    return error;
    }

    @@ -482,7 +482,7 @@ sys_lremovexattr(char __user *path, char
    if (error)
    return error;
    error = removexattr(nd.path.dentry, name);
    - path_release(&nd);
    + path_put(&nd.path);
    return error;
    }

    Index: b/fs/xfs/linux-2.6/xfs_ioctl.c
    ================================================== =================
    --- a/fs/xfs/linux-2.6/xfs_ioctl.c
    +++ b/fs/xfs/linux-2.6/xfs_ioctl.c
    @@ -95,7 +95,7 @@ xfs_find_handle(
    ASSERT(nd.path.dentry);
    ASSERT(nd.path.dentry->d_inode);
    inode = igrab(nd.path.dentry->d_inode);
    - path_release(&nd);
    + path_put(&nd.path);
    break;
    }

    Index: b/include/linux/namei.h
    ================================================== =================
    --- a/include/linux/namei.h
    +++ b/include/linux/namei.h
    @@ -67,7 +67,6 @@ extern int FASTCALL(__user_walk_fd(int d
    extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
    extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
    const char *, unsigned int, struct nameidata *);
    -extern void path_release(struct nameidata *);

    extern int __user_path_lookup_open(const char __user *, unsigned lookup_flags, struct nameidata *nd, int open_flags);
    extern int path_lookup_open(int dfd, const char *name, unsigned lookup_flags, struct nameidata *, int open_flags);
    @@ -101,10 +100,4 @@ static inline void pathget(struct path *
    dget(path->dentry);
    }

    -static inline void pathput(struct path *path)
    -{
    - dput(path->dentry);
    - mntput(path->mnt);
    -}
    -
    #endif /* _LINUX_NAMEI_H */
    Index: b/include/linux/path.h
    ================================================== =================
    --- a/include/linux/path.h
    +++ b/include/linux/path.h
    @@ -9,4 +9,6 @@ struct path {
    struct dentry *dentry;
    };

    +extern void path_put(struct path *);
    +
    #endif /* _LINUX_PATH_H */
    Index: b/kernel/auditfilter.c
    ================================================== =================
    --- a/kernel/auditfilter.c
    +++ b/kernel/auditfilter.c
    @@ -1152,11 +1152,11 @@ static int audit_get_nd(char *path, stru
    static void audit_put_nd(struct nameidata *ndp, struct nameidata *ndw)
    {
    if (ndp) {
    - path_release(ndp);
    + path_put(&ndp->path);
    kfree(ndp);
    }
    if (ndw) {
    - path_release(ndw);
    + path_put(&ndw->path);
    kfree(ndw);
    }
    }
    Index: b/net/sunrpc/rpc_pipe.c
    ================================================== =================
    --- a/net/sunrpc/rpc_pipe.c
    +++ b/net/sunrpc/rpc_pipe.c
    @@ -483,7 +483,7 @@ rpc_lookup_parent(char *path, struct nam
    static void
    rpc_release_path(struct nameidata *nd)
    {
    - path_release(nd);
    + path_put(&nd->path);
    rpc_put_mount();
    }

    Index: b/net/unix/af_unix.c
    ================================================== =================
    --- a/net/unix/af_unix.c
    +++ b/net/unix/af_unix.c
    @@ -752,7 +752,7 @@ static struct sock *unix_find_other(stru
    if (u->sk_type == type)
    touch_atime(nd.path.mnt, nd.path.dentry);

    - path_release(&nd);
    + path_put(&nd.path);
    mnt_drop_write(nd.path.mnt);

    err=-EPROTOTYPE;
    @@ -776,7 +776,7 @@ static struct sock *unix_find_other(stru
    mnt_drop_write_fail:
    mnt_drop_write(nd.path.mnt);
    put_path_fail:
    - path_release(&nd);
    + path_put(&nd.path);
    fail:
    *error=err;
    return NULL;
    @@ -893,7 +893,7 @@ out_mknod_dput:
    dput(dentry);
    out_mknod_unlock:
    mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    - path_release(&nd);
    + path_put(&nd.path);
    out_mknod_parent:
    if (err==-EEXIST)
    err=-EADDRINUSE;

    --

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  9. [patch 10/10] Make set_fs_{root,pwd} take a struct path

    In nearly all cases the set_fs_{root,pwd}() calls work on a struct
    path. Change the function to reflect this and use path_get() here.

    Signed-off-by: Jan Blunck
    Signed-off-by: Andreas Gruenbacher
    Acked-by: Christoph Hellwig
    ---
    fs/namespace.c | 28 ++++++++++++++--------------
    fs/open.c | 12 ++++--------
    include/linux/fs_struct.h | 4 ++--
    3 files changed, 20 insertions(+), 24 deletions(-)

    Index: b/fs/namespace.c
    ================================================== =================
    --- a/fs/namespace.c
    +++ b/fs/namespace.c
    @@ -2040,15 +2040,14 @@ out1:
    * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values.
    * It can block. Requires the big lock held.
    */
    -void set_fs_root(struct fs_struct *fs, struct vfsmount *mnt,
    - struct dentry *dentry)
    +void set_fs_root(struct fs_struct *fs, struct path *path)
    {
    struct path old_root;

    write_lock(&fs->lock);
    old_root = fs->root;
    - fs->root.mnt = mntget(mnt);
    - fs->root.dentry = dget(dentry);
    + fs->root = *path;
    + path_get(path);
    write_unlock(&fs->lock);
    if (old_root.dentry)
    path_put(&old_root);
    @@ -2058,15 +2057,14 @@ void set_fs_root(struct fs_struct *fs, s
    * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values.
    * It can block. Requires the big lock held.
    */
    -void set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt,
    - struct dentry *dentry)
    +void set_fs_pwd(struct fs_struct *fs, struct path *path)
    {
    struct path old_pwd;

    write_lock(&fs->lock);
    old_pwd = fs->pwd;
    - fs->pwd.mnt = mntget(mnt);
    - fs->pwd.dentry = dget(dentry);
    + fs->pwd = *path;
    + path_get(path);
    write_unlock(&fs->lock);

    if (old_pwd.dentry)
    @@ -2087,12 +2085,10 @@ static void chroot_fs_refs(struct nameid
    task_unlock(p);
    if (fs->root.dentry == old_nd->path.dentry
    && fs->root.mnt == old_nd->path.mnt)
    - set_fs_root(fs, new_nd->path.mnt,
    - new_nd->path.dentry);
    + set_fs_root(fs, &new_nd->path);
    if (fs->pwd.dentry == old_nd->path.dentry
    && fs->pwd.mnt == old_nd->path.mnt)
    - set_fs_pwd(fs, new_nd->path.mnt,
    - new_nd->path.dentry);
    + set_fs_pwd(fs, &new_nd->path);
    put_fs_struct(fs);
    } else
    task_unlock(p);
    @@ -2235,6 +2231,7 @@ static void __init init_mount_tree(void)
    {
    struct vfsmount *mnt;
    struct mnt_namespace *ns;
    + struct path root;

    mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
    if (IS_ERR(mnt))
    @@ -2253,8 +2250,11 @@ static void __init init_mount_tree(void)
    init_task.nsproxy->mnt_ns = ns;
    get_mnt_ns(ns);

    - set_fs_pwd(current->fs, ns->root, ns->root->mnt_root);
    - set_fs_root(current->fs, ns->root, ns->root->mnt_root);
    + root.mnt = ns->root;
    + root.dentry = ns->root->mnt_root;
    +
    + set_fs_pwd(current->fs, &root);
    + set_fs_root(current->fs, &root);
    }

    void __init mnt_init(void)
    Index: b/fs/open.c
    ================================================== =================
    --- a/fs/open.c
    +++ b/fs/open.c
    @@ -501,7 +501,7 @@ asmlinkage long sys_chdir(const char __u
    if (error)
    goto dput_and_out;

    - set_fs_pwd(current->fs, nd.path.mnt, nd.path.dentry);
    + set_fs_pwd(current->fs, &nd.path);

    dput_and_out:
    path_put(&nd.path);
    @@ -512,9 +512,7 @@ out:
    asmlinkage long sys_fchdir(unsigned int fd)
    {
    struct file *file;
    - struct dentry *dentry;
    struct inode *inode;
    - struct vfsmount *mnt;
    int error;

    error = -EBADF;
    @@ -522,9 +520,7 @@ asmlinkage long sys_fchdir(unsigned int
    if (!file)
    goto out;

    - dentry = file->f_path.dentry;
    - mnt = file->f_path.mnt;
    - inode = dentry->d_inode;
    + inode = file->f_path.dentry->d_inode;

    error = -ENOTDIR;
    if (!S_ISDIR(inode->i_mode))
    @@ -532,7 +528,7 @@ asmlinkage long sys_fchdir(unsigned int

    error = file_permission(file, MAY_EXEC);
    if (!error)
    - set_fs_pwd(current->fs, mnt, dentry);
    + set_fs_pwd(current->fs, &file->f_path);
    out_putf:
    fput(file);
    out:
    @@ -556,7 +552,7 @@ asmlinkage long sys_chroot(const char __
    if (!capable(CAP_SYS_CHROOT))
    goto dput_and_out;

    - set_fs_root(current->fs, nd.path.mnt, nd.path.dentry);
    + set_fs_root(current->fs, &nd.path);
    set_fs_altroot();
    error = 0;
    dput_and_out:
    Index: b/include/linux/fs_struct.h
    ================================================== =================
    --- a/include/linux/fs_struct.h
    +++ b/include/linux/fs_struct.h
    @@ -20,8 +20,8 @@ extern struct kmem_cache *fs_cachep;

    extern void exit_fs(struct task_struct *);
    extern void set_fs_altroot(void);
    -extern void set_fs_root(struct fs_struct *, struct vfsmount *, struct dentry *);
    -extern void set_fs_pwd(struct fs_struct *, struct vfsmount *, struct dentry *);
    +extern void set_fs_root(struct fs_struct *, struct path *);
    +extern void set_fs_pwd(struct fs_struct *, struct path *);
    extern struct fs_struct *copy_fs_struct(struct fs_struct *);
    extern void put_fs_struct(struct fs_struct *);


    --

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  10. [patch 09/10] Use struct path in fs_struct

    * Use struct path in fs_struct.

    Signed-off-by: Andreas Gruenbacher
    Signed-off-by: Jan Blunck
    Acked-by: Christoph Hellwig
    ---
    fs/dcache.c | 34 ++++++++++++---------------
    fs/namei.c | 53 ++++++++++++++++++------------------------
    fs/namespace.c | 57 ++++++++++++++++++++--------------------------
    fs/proc/base.c | 8 +++---
    include/linux/fs_struct.h | 6 +---
    init/do_mounts.c | 6 ++--
    kernel/auditsc.c | 4 +--
    kernel/exit.c | 12 +++------
    kernel/fork.c | 18 +++++++-------
    9 files changed, 87 insertions(+), 111 deletions(-)

    Index: b/fs/dcache.c
    ================================================== =================
    --- a/fs/dcache.c
    +++ b/fs/dcache.c
    @@ -1851,8 +1851,7 @@ char * d_path(struct dentry *dentry, str
    char *buf, int buflen)
    {
    char *res;
    - struct vfsmount *rootmnt;
    - struct dentry *root;
    + struct path root;

    /*
    * We have various synthetic filesystems that never get mounted. On
    @@ -1865,14 +1864,13 @@ char * d_path(struct dentry *dentry, str
    return dentry->d_op->d_dname(dentry, buf, buflen);

    read_lock(&current->fs->lock);
    - rootmnt = mntget(current->fs->rootmnt);
    - root = dget(current->fs->root);
    + root = current->fs->root;
    + path_get(&current->fs->root);
    read_unlock(&current->fs->lock);
    spin_lock(&dcache_lock);
    - res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
    + res = __d_path(dentry, vfsmnt, root.dentry, root.mnt, buf, buflen);
    spin_unlock(&dcache_lock);
    - dput(root);
    - mntput(rootmnt);
    + path_put(&root);
    return res;
    }

    @@ -1918,28 +1916,28 @@ char *dynamic_dname(struct dentry *dentr
    asmlinkage long sys_getcwd(char __user *buf, unsigned long size)
    {
    int error;
    - struct vfsmount *pwdmnt, *rootmnt;
    - struct dentry *pwd, *root;
    + struct path pwd, root;
    char *page = (char *) __get_free_page(GFP_USER);

    if (!page)
    return -ENOMEM;

    read_lock(&current->fs->lock);
    - pwdmnt = mntget(current->fs->pwdmnt);
    - pwd = dget(current->fs->pwd);
    - rootmnt = mntget(current->fs->rootmnt);
    - root = dget(current->fs->root);
    + pwd = current->fs->pwd;
    + path_get(&current->fs->pwd);
    + root = current->fs->root;
    + path_get(&current->fs->root);
    read_unlock(&current->fs->lock);

    error = -ENOENT;
    /* Has the current directory has been unlinked? */
    spin_lock(&dcache_lock);
    - if (pwd->d_parent == pwd || !d_unhashed(pwd)) {
    + if (pwd.dentry->d_parent == pwd.dentry || !d_unhashed(pwd.dentry)) {
    unsigned long len;
    char * cwd;

    - cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE);
    + cwd = __d_path(pwd.dentry, pwd.mnt, root.dentry, root.mnt,
    + page, PAGE_SIZE);
    spin_unlock(&dcache_lock);

    error = PTR_ERR(cwd);
    @@ -1957,10 +1955,8 @@ asmlinkage long sys_getcwd(char __user *
    spin_unlock(&dcache_lock);

    out:
    - dput(pwd);
    - mntput(pwdmnt);
    - dput(root);
    - mntput(rootmnt);
    + path_put(&pwd);
    + path_put(&root);
    free_page((unsigned long) page);
    return error;
    }
    Index: b/fs/namei.c
    ================================================== =================
    --- a/fs/namei.c
    +++ b/fs/namei.c
    @@ -550,16 +550,16 @@ walk_init_root(const char *name, struct
    struct fs_struct *fs = current->fs;

    read_lock(&fs->lock);
    - if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
    - nd->path.mnt = mntget(fs->altrootmnt);
    - nd->path.dentry = dget(fs->altroot);
    + if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) {
    + nd->path = fs->altroot;
    + path_get(&fs->altroot);
    read_unlock(&fs->lock);
    if (__emul_lookup_dentry(name,nd))
    return 0;
    read_lock(&fs->lock);
    }
    - nd->path.mnt = mntget(fs->rootmnt);
    - nd->path.dentry = dget(fs->root);
    + nd->path = fs->root;
    + path_get(&fs->root);
    read_unlock(&fs->lock);
    return 1;
    }
    @@ -756,8 +756,8 @@ static __always_inline void follow_dotdo
    struct dentry *old = nd->path.dentry;

    read_lock(&fs->lock);
    - if (nd->path.dentry == fs->root &&
    - nd->path.mnt == fs->rootmnt) {
    + if (nd->path.dentry == fs->root.dentry &&
    + nd->path.mnt == fs->root.mnt) {
    read_unlock(&fs->lock);
    break;
    }
    @@ -1079,8 +1079,8 @@ static int __emul_lookup_dentry(const ch
    */
    nd->last_type = LAST_ROOT;
    read_lock(&fs->lock);
    - nd->path.mnt = mntget(fs->rootmnt);
    - nd->path.dentry = dget(fs->root);
    + nd->path = fs->root;
    + path_get(&fs->root);
    read_unlock(&fs->lock);
    if (path_walk(name, nd) == 0) {
    if (nd->path.dentry->d_inode) {
    @@ -1100,29 +1100,22 @@ void set_fs_altroot(void)
    {
    char *emul = __emul_prefix();
    struct nameidata nd;
    - struct vfsmount *mnt = NULL, *oldmnt;
    - struct dentry *dentry = NULL, *olddentry;
    + struct path path = {}, old_path;
    int err;
    struct fs_struct *fs = current->fs;

    if (!emul)
    goto set_it;
    err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd);
    - if (!err) {
    - mnt = nd.path.mnt;
    - dentry = nd.path.dentry;
    - }
    + if (!err)
    + path = nd.path;
    set_it:
    write_lock(&fs->lock);
    - oldmnt = fs->altrootmnt;
    - olddentry = fs->altroot;
    - fs->altrootmnt = mnt;
    - fs->altroot = dentry;
    + old_path = fs->altroot;
    + fs->altroot = path;
    write_unlock(&fs->lock);
    - if (olddentry) {
    - dput(olddentry);
    - mntput(oldmnt);
    - }
    + if (old_path.dentry)
    + path_put(&old_path);
    }

    /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
    @@ -1140,21 +1133,21 @@ static int fastcall do_path_lookup(int d

    if (*name=='/') {
    read_lock(&fs->lock);
    - if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
    - nd->path.mnt = mntget(fs->altrootmnt);
    - nd->path.dentry = dget(fs->altroot);
    + if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) {
    + nd->path = fs->altroot;
    + path_get(&fs->altroot);
    read_unlock(&fs->lock);
    if (__emul_lookup_dentry(name,nd))
    goto out; /* found in altroot */
    read_lock(&fs->lock);
    }
    - nd->path.mnt = mntget(fs->rootmnt);
    - nd->path.dentry = dget(fs->root);
    + nd->path = fs->root;
    + path_get(&fs->root);
    read_unlock(&fs->lock);
    } else if (dfd == AT_FDCWD) {
    read_lock(&fs->lock);
    - nd->path.mnt = mntget(fs->pwdmnt);
    - nd->path.dentry = dget(fs->pwd);
    + nd->path = fs->pwd;
    + path_get(&fs->pwd);
    read_unlock(&fs->lock);
    } else {
    struct dentry *dentry;
    Index: b/fs/namespace.c
    ================================================== =================
    --- a/fs/namespace.c
    +++ b/fs/namespace.c
    @@ -868,7 +868,7 @@ static int do_umount(struct vfsmount *mn
    * (2) the usage count == 1 [parent vfsmount] + 1 [sys_umount]
    */
    if (flags & MNT_EXPIRE) {
    - if (mnt == current->fs->rootmnt ||
    + if (mnt == current->fs->root.mnt ||
    flags & (MNT_FORCE | MNT_DETACH))
    return -EINVAL;

    @@ -903,7 +903,7 @@ static int do_umount(struct vfsmount *mn
    * /reboot - static binary that would close all descriptors and
    * call reboot(9). Then init(8) could umount root and exec /reboot.
    */
    - if (mnt == current->fs->rootmnt && !(flags & MNT_DETACH)) {
    + if (mnt == current->fs->root.mnt && !(flags & MNT_DETACH)) {
    /*
    * Special case for "unmounting" root ...
    * we just try to remount it readonly.
    @@ -1949,17 +1949,17 @@ static struct mnt_namespace *dup_mnt_ns(
    while (p) {
    q->mnt_ns = new_ns;
    if (fs) {
    - if (p == fs->rootmnt) {
    + if (p == fs->root.mnt) {
    rootmnt = p;
    - fs->rootmnt = mntget(q);
    + fs->root.mnt = mntget(q);
    }
    - if (p == fs->pwdmnt) {
    + if (p == fs->pwd.mnt) {
    pwdmnt = p;
    - fs->pwdmnt = mntget(q);
    + fs->pwd.mnt = mntget(q);
    }
    - if (p == fs->altrootmnt) {
    + if (p == fs->altroot.mnt) {
    altrootmnt = p;
    - fs->altrootmnt = mntget(q);
    + fs->altroot.mnt = mntget(q);
    }
    }
    p = next_mnt(p, mnt_ns->root);
    @@ -2043,18 +2043,15 @@ out1:
    void set_fs_root(struct fs_struct *fs, struct vfsmount *mnt,
    struct dentry *dentry)
    {
    - struct dentry *old_root;
    - struct vfsmount *old_rootmnt;
    + struct path old_root;
    +
    write_lock(&fs->lock);
    old_root = fs->root;
    - old_rootmnt = fs->rootmnt;
    - fs->rootmnt = mntget(mnt);
    - fs->root = dget(dentry);
    + fs->root.mnt = mntget(mnt);
    + fs->root.dentry = dget(dentry);
    write_unlock(&fs->lock);
    - if (old_root) {
    - dput(old_root);
    - mntput(old_rootmnt);
    - }
    + if (old_root.dentry)
    + path_put(&old_root);
    }

    /*
    @@ -2064,20 +2061,16 @@ void set_fs_root(struct fs_struct *fs, s
    void set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt,
    struct dentry *dentry)
    {
    - struct dentry *old_pwd;
    - struct vfsmount *old_pwdmnt;
    + struct path old_pwd;

    write_lock(&fs->lock);
    old_pwd = fs->pwd;
    - old_pwdmnt = fs->pwdmnt;
    - fs->pwdmnt = mntget(mnt);
    - fs->pwd = dget(dentry);
    + fs->pwd.mnt = mntget(mnt);
    + fs->pwd.dentry = dget(dentry);
    write_unlock(&fs->lock);

    - if (old_pwd) {
    - dput(old_pwd);
    - mntput(old_pwdmnt);
    - }
    + if (old_pwd.dentry)
    + path_put(&old_pwd);
    }

    static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
    @@ -2092,12 +2085,12 @@ static void chroot_fs_refs(struct nameid
    if (fs) {
    atomic_inc(&fs->count);
    task_unlock(p);
    - if (fs->root == old_nd->path.dentry
    - && fs->rootmnt == old_nd->path.mnt)
    + if (fs->root.dentry == old_nd->path.dentry
    + && fs->root.mnt == old_nd->path.mnt)
    set_fs_root(fs, new_nd->path.mnt,
    new_nd->path.dentry);
    - if (fs->pwd == old_nd->path.dentry
    - && fs->pwdmnt == old_nd->path.mnt)
    + if (fs->pwd.dentry == old_nd->path.dentry
    + && fs->pwd.mnt == old_nd->path.mnt)
    set_fs_pwd(fs, new_nd->path.mnt,
    new_nd->path.dentry);
    put_fs_struct(fs);
    @@ -2163,8 +2156,8 @@ asmlinkage long sys_pivot_root(const cha
    }

    read_lock(&current->fs->lock);
    - user_nd.path.mnt = mntget(current->fs->rootmnt);
    - user_nd.path.dentry = dget(current->fs->root);
    + user_nd.path = current->fs->root;
    + path_get(&current->fs->root);
    read_unlock(&current->fs->lock);
    down_write(&namespace_sem);
    mutex_lock(&old_nd.path.dentry->d_inode->i_mutex);
    Index: b/fs/proc/base.c
    ================================================== =================
    --- a/fs/proc/base.c
    +++ b/fs/proc/base.c
    @@ -165,8 +165,8 @@ static int proc_cwd_link(struct inode *i
    }
    if (fs) {
    read_lock(&fs->lock);
    - *mnt = mntget(fs->pwdmnt);
    - *dentry = dget(fs->pwd);
    + *mnt = mntget(fs->pwd.mnt);
    + *dentry = dget(fs->pwd.dentry);
    read_unlock(&fs->lock);
    result = 0;
    put_fs_struct(fs);
    @@ -186,8 +186,8 @@ static int proc_root_link(struct inode *
    }
    if (fs) {
    read_lock(&fs->lock);
    - *mnt = mntget(fs->rootmnt);
    - *dentry = dget(fs->root);
    + *mnt = mntget(fs->root.mnt);
    + *dentry = dget(fs->root.dentry);
    read_unlock(&fs->lock);
    result = 0;
    put_fs_struct(fs);
    Index: b/include/linux/fs_struct.h
    ================================================== =================
    --- a/include/linux/fs_struct.h
    +++ b/include/linux/fs_struct.h
    @@ -1,15 +1,13 @@
    #ifndef _LINUX_FS_STRUCT_H
    #define _LINUX_FS_STRUCT_H

    -struct dentry;
    -struct vfsmount;
    +#include

    struct fs_struct {
    atomic_t count;
    rwlock_t lock;
    int umask;
    - struct dentry * root, * pwd, * altroot;
    - struct vfsmount * rootmnt, * pwdmnt, * altrootmnt;
    + struct path root, pwd, altroot;
    };

    #define INIT_FS { \
    Index: b/init/do_mounts.c
    ================================================== =================
    --- a/init/do_mounts.c
    +++ b/init/do_mounts.c
    @@ -286,10 +286,10 @@ static int __init do_mount_root(char *na
    return err;

    sys_chdir("/root");
    - ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
    + ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;
    printk("VFS: Mounted root (%s filesystem)%s.\n",
    - current->fs->pwdmnt->mnt_sb->s_type->name,
    - current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY ?
    + current->fs->pwd.mnt->mnt_sb->s_type->name,
    + current->fs->pwd.mnt->mnt_sb->s_flags & MS_RDONLY ?
    " readonly" : "");
    return 0;
    }
    Index: b/kernel/auditsc.c
    ================================================== =================
    --- a/kernel/auditsc.c
    +++ b/kernel/auditsc.c
    @@ -1528,8 +1528,8 @@ void __audit_getname(const char *name)
    ++context->name_count;
    if (!context->pwd) {
    read_lock(&current->fs->lock);
    - context->pwd = dget(current->fs->pwd);
    - context->pwdmnt = mntget(current->fs->pwdmnt);
    + context->pwd = dget(current->fs->pwd.dentry);
    + context->pwdmnt = mntget(current->fs->pwd.mnt);
    read_unlock(&current->fs->lock);
    }

    Index: b/kernel/exit.c
    ================================================== =================
    --- a/kernel/exit.c
    +++ b/kernel/exit.c
    @@ -513,14 +513,10 @@ static inline void __put_fs_struct(struc
    {
    /* No need to hold fs->lock if we are killing it */
    if (atomic_dec_and_test(&fs->count)) {
    - dput(fs->root);
    - mntput(fs->rootmnt);
    - dput(fs->pwd);
    - mntput(fs->pwdmnt);
    - if (fs->altroot) {
    - dput(fs->altroot);
    - mntput(fs->altrootmnt);
    - }
    + path_put(&fs->root);
    + path_put(&fs->pwd);
    + if (fs->altroot.dentry)
    + path_put(&fs->altroot);
    kmem_cache_free(fs_cachep, fs);
    }
    }
    Index: b/kernel/fork.c
    ================================================== =================
    --- a/kernel/fork.c
    +++ b/kernel/fork.c
    @@ -598,16 +598,16 @@ static inline struct fs_struct *__copy_f
    rwlock_init(&fs->lock);
    fs->umask = old->umask;
    read_lock(&old->lock);
    - fs->rootmnt = mntget(old->rootmnt);
    - fs->root = dget(old->root);
    - fs->pwdmnt = mntget(old->pwdmnt);
    - fs->pwd = dget(old->pwd);
    - if (old->altroot) {
    - fs->altrootmnt = mntget(old->altrootmnt);
    - fs->altroot = dget(old->altroot);
    + fs->root = old->root;
    + path_get(&old->root);
    + fs->pwd = old->pwd;
    + path_get(&old->pwd);
    + if (old->altroot.dentry) {
    + fs->altroot = old->altroot;
    + path_get(&old->altroot);
    } else {
    - fs->altrootmnt = NULL;
    - fs->altroot = NULL;
    + fs->altroot.mnt = NULL;
    + fs->altroot.dentry = NULL;
    }
    read_unlock(&old->lock);
    }

    --

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

+ Reply to Thread