[PATCH 06/24] VFS: remove nameidata args from ->follow_link

Al Viro
2015-04-20T18:17:50Z

From: NeilBrown <neilb@suse.de>

Now that current->nameidata is available, nd_set_link() can
use that directly, so 'nd' doesn't need to be passed through
->follow_link.

As a result of this change, 'nameidata' is almost entirely
local to namei.c. It is only exposed externally as an opaque struct
pointed to by current->nameidata.

Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
Documentation/filesystems/Locking | 2 +-
Documentation/filesystems/porting | 5 +++++
Documentation/filesystems/vfs.txt | 2 +-
drivers/staging/lustre/lustre/llite/symlink.c | 4 ++--
fs/9p/vfs_inode.c | 5 ++---
fs/9p/vfs_inode_dotl.c | 5 ++---
fs/autofs4/symlink.c | 4 ++--
fs/befs/linuxvfs.c | 12 ++++++------
fs/ceph/inode.c | 4 ++--
fs/cifs/cifsfs.h | 2 +-
fs/cifs/link.c | 4 ++--
fs/configfs/symlink.c | 6 +++---
fs/debugfs/file.c | 4 ++--
fs/ecryptfs/inode.c | 6 ++----
fs/exofs/symlink.c | 4 ++--
fs/ext2/symlink.c | 4 ++--
fs/ext3/symlink.c | 4 ++--
fs/ext4/symlink.c | 4 ++--
fs/freevxfs/vxfs_immed.c | 7 +++----
fs/fuse/dir.c | 4 ++--
fs/gfs2/inode.c | 7 +++----
fs/hostfs/hostfs_kern.c | 4 ++--
fs/hppfs/hppfs.c | 4 ++--
fs/jffs2/symlink.c | 6 +++---
fs/jfs/symlink.c | 4 ++--
fs/kernfs/symlink.c | 4 ++--
fs/namei.c | 18 +++++++++++-------
fs/nfs/symlink.c | 6 +++---
fs/ntfs/namei.c | 1 -
fs/overlayfs/inode.c | 4 ++--
fs/proc/base.c | 4 ++--
fs/proc/inode.c | 4 ++--
fs/proc/namespaces.c | 4 ++--
fs/proc/self.c | 4 ++--
fs/proc/thread_self.c | 4 ++--
fs/sysv/symlink.c | 4 ++--
fs/ubifs/file.c | 4 ++--
fs/ufs/symlink.c | 4 ++--
fs/xfs/xfs_iops.c | 7 +++----
include/linux/fs.h | 5 ++---
include/linux/namei.h | 5 ++---
include/linux/sched.h | 1 +
mm/shmem.c | 8 ++++----
43 files changed, 104 insertions(+), 104 deletions(-)

diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 3fc99e0..e4a0c36 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -50,7 +50,7 @@ prototypes:
int (*rename2) (struct inode *, struct dentry *,
struct inode *, struct dentry *, unsigned int);
int (*readlink) (struct dentry *, char __user *,int);
- void * (*follow_link) (struct dentry *, struct nameidata *);
+ void * (*follow_link) (struct dentry *);
void (*put_link) (struct dentry *, char *, void *);
void (*truncate) (struct inode *);
int (*permission) (struct inode *, int, unsigned int);
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting
index c1ee367..08f8a27 100644
--- a/Documentation/filesystems/porting
+++ b/Documentation/filesystems/porting
@@ -488,3 +488,8 @@ in your dentry operations instead.
->put_link now takes a 'char *' rather than a 'struct nameidata*'.
Instead of calling nd_get_link() on the later, just use the former
directly.
+--
+[mandatory]
+ ->follow_link() no longer receives 'struct nameidata *'.
+ The nd is now attached to 'current' and nd_set_link()
+ accesses it directly.
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 7bba952..807bd4b 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -350,7 +350,7 @@ struct inode_operations {
int (*rename2) (struct inode *, struct dentry *,
struct inode *, struct dentry *, unsigned int);
int (*readlink) (struct dentry *, char __user *,int);
- void * (*follow_link) (struct dentry *, struct nameidata *);
+ void * (*follow_link) (struct dentry *);
void (*put_link) (struct dentry *, char *, void *);
int (*permission) (struct inode *, int);
int (*get_acl)(struct inode *, int);
diff --git a/drivers/staging/lustre/lustre/llite/symlink.c b/drivers/staging/lustre/lustre/llite/symlink.c
index a0bebc3..d71c2a9 100644
--- a/drivers/staging/lustre/lustre/llite/symlink.c
+++ b/drivers/staging/lustre/lustre/llite/symlink.c
@@ -118,7 +118,7 @@ failed:
return rc;
}

-static void *ll_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *ll_follow_link(struct dentry *dentry)
{
struct inode *inode = d_inode(dentry);
struct ptlrpc_request *request = NULL;
@@ -135,7 +135,7 @@ static void *ll_follow_link(struct dentry *dentry, struct nameidata *nd)
symname = ERR_PTR(rc);
}

- nd_set_link(nd, symname);
+ nd_set_link(symname);
/* symname may contain a pointer to the request message buffer,
* we delay request releasing until ll_put_link then.
*/
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 0ba1171..2895295 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -1226,11 +1226,10 @@ ino_t v9fs_qid2ino(struct p9_qid *qid)
/**
* v9fs_vfs_follow_link - follow a symlink path
* @dentry: dentry for symlink
- * @nd: nameidata
*
*/

-static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *v9fs_vfs_follow_link(struct dentry *dentry)
{
struct v9fs_session_info *v9ses = v9fs_dentry2v9ses(dentry);
struct p9_fid *fid = v9fs_fid_lookup(dentry);
@@ -1256,7 +1255,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
if (strlen(st->extension) >= PATH_MAX)
st->extension[PATH_MAX - 1] = '\0';

- nd_set_link(nd, st->extension);
+ nd_set_link(st->extension);
st->extension = NULL;
p9stat_free(st);
kfree(st);
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
index bc2a91f..577af9b 100644
--- a/fs/9p/vfs_inode_dotl.c
+++ b/fs/9p/vfs_inode_dotl.c
@@ -905,12 +905,11 @@ error:
/**
* v9fs_vfs_follow_link_dotl - follow a symlink path
* @dentry: dentry for symlink
- * @nd: nameidata
*
*/

static void *
-v9fs_vfs_follow_link_dotl(struct dentry *dentry, struct nameidata *nd)
+v9fs_vfs_follow_link_dotl(struct dentry *dentry)
{
struct p9_fid *fid = v9fs_fid_lookup(dentry);
char *target;
@@ -923,7 +922,7 @@ v9fs_vfs_follow_link_dotl(struct dentry *dentry, struct nameidata *nd)
retval = p9_client_readlink(fid, &target);
if (retval)
return ERR_PTR(retval);
- nd_set_link(nd, target);
+ nd_set_link(target);
return NULL;
}

diff --git a/fs/autofs4/symlink.c b/fs/autofs4/symlink.c
index de58cc7..d6dd4c5 100644
--- a/fs/autofs4/symlink.c
+++ b/fs/autofs4/symlink.c
@@ -12,13 +12,13 @@

#include "autofs_i.h"

-static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *autofs4_follow_link(struct dentry *dentry)
{
struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
struct autofs_info *ino = autofs4_dentry_ino(dentry);
if (ino && !autofs4_oz_mode(sbi))
ino->last_used = jiffies;
- nd_set_link(nd, d_inode(dentry)->i_private);
+ nd_set_link(d_inode(dentry)->i_private);
return NULL;
}

diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index d3cb877..0714644 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -42,8 +42,8 @@ static struct inode *befs_iget(struct super_block *, unsigned long);
static struct inode *befs_alloc_inode(struct super_block *sb);
static void befs_destroy_inode(struct inode *inode);
static void befs_destroy_inodecache(void);
-static void *befs_follow_link(struct dentry *, struct nameidata *);
-static void *befs_fast_follow_link(struct dentry *, struct nameidata *);
+static void *befs_follow_link(struct dentry *);
+static void *befs_fast_follow_link(struct dentry *);
static int befs_utf2nls(struct super_block *sb, const char *in, int in_len,
char **out, int *out_len);
static int befs_nls2utf(struct super_block *sb, const char *in, int in_len,
@@ -469,7 +469,7 @@ befs_destroy_inodecache(void)
* flag is set.
*/
static void *
-befs_follow_link(struct dentry *dentry, struct nameidata *nd)
+befs_follow_link(struct dentry *dentry)
{
struct super_block *sb = dentry->d_sb;
befs_inode_info *befs_ino = BEFS_I(d_inode(dentry));
@@ -494,16 +494,16 @@ befs_follow_link(struct dentry *dentry, struct nameidata *nd)
link[len - 1] = '\0';
}
}
- nd_set_link(nd, link);
+ nd_set_link(link);
return NULL;
}

static void *
-befs_fast_follow_link(struct dentry *dentry, struct nameidata *nd)
+befs_fast_follow_link(struct dentry *dentry)
{
befs_inode_info *befs_ino = BEFS_I(d_inode(dentry));
- nd_set_link(nd, befs_ino->i_data.symlink);
+ nd_set_link(befs_ino->i_data.symlink);
return NULL;
}

diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index e876e19..7dd8f1c 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -1691,10 +1691,10 @@ retry:
/*
* symlinks
*/
-static void *ceph_sym_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *ceph_sym_follow_link(struct dentry *dentry)
{
struct ceph_inode_info *ci = ceph_inode(d_inode(dentry));
- nd_set_link(nd, ci->i_symlink);
+ nd_set_link(ci->i_symlink);
return NULL;
}

diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 252f5c1..e3a6ef5 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -120,7 +120,7 @@ extern struct vfsmount *cifs_dfs_d_automount(struct path *path);
#endif

/* Functions related to symlinks */
-extern void *cifs_follow_link(struct dentry *direntry, struct nameidata *nd);
+extern void *cifs_follow_link(struct dentry *direntry);
extern int cifs_readlink(struct dentry *direntry, char __user *buffer,
int buflen);
extern int cifs_symlink(struct inode *inode, struct dentry *direntry,
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 252e672..470666c 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -627,7 +627,7 @@ cifs_hl_exit:
}

void *
-cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
+cifs_follow_link(struct dentry *direntry)
{
struct inode *inode = d_inode(direntry);
int rc = -ENOMEM;
@@ -679,7 +679,7 @@ out:
free_xid(xid);
if (tlink)
cifs_put_tlink(tlink);
- nd_set_link(nd, target_path);
+ nd_set_link(target_path);
return NULL;
}

diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c
index e860ddb..ff41712 100644
--- a/fs/configfs/symlink.c
+++ b/fs/configfs/symlink.c
@@ -279,7 +279,7 @@ static int configfs_getlink(struct dentry *dentry, char * path)

}

-static void *configfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *configfs_follow_link(struct dentry *dentry)
{
int error = -ENOMEM;
unsigned long page = get_zeroed_page(GFP_KERNEL);
@@ -287,12 +287,12 @@ static void *configfs_follow_link(struct dentry *dentry, struct nameidata *nd)
if (page) {
error = configfs_getlink(dentry, (char *)page);
if (!error) {
- nd_set_link(nd, (char *)page);
+ nd_set_link((char *)page);
return (void *)page;
}
}

- nd_set_link(nd, ERR_PTR(error));
+ nd_set_link(ERR_PTR(error));
return NULL;
}

diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index 830a7e7..4a612f1 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -43,9 +43,9 @@ const struct file_operations debugfs_file_operations = {
.llseek = noop_llseek,
};

-static void *debugfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *debugfs_follow_link(struct dentry *dentry)
{
- nd_set_link(nd, d_inode(dentry)->i_private);
+ nd_set_link(d_inode(dentry)->i_private);
return NULL;
}

diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index fc850b5..8f46945 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -170,7 +170,6 @@ out_unlock:
* @directory_inode: inode of the new file's dentry's parent in ecryptfs
* @ecryptfs_dentry: New file's dentry in ecryptfs
* @mode: The mode of the new file
- * @nd: nameidata of ecryptfs' parent's dentry & vfsmount
*
* Creates the underlying file and the eCryptfs inode which will link to
* it. It will also update the eCryptfs directory inode to mimic the
@@ -384,7 +383,6 @@ static int ecryptfs_lookup_interpose(struct dentry *dentry,
* ecryptfs_lookup
* @ecryptfs_dir_inode: The eCryptfs directory inode
* @ecryptfs_dentry: The eCryptfs dentry that we are looking up
- * @ecryptfs_nd: nameidata; may be NULL
*
* Find a file on disk. If the file does not exist, then we'll add it to the
* dentry cache and continue on to read it from the disk.
@@ -675,7 +673,7 @@ out:
return rc ? ERR_PTR(rc) : buf;
}

-static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *ecryptfs_follow_link(struct dentry *dentry)
{
size_t len;
char *buf = ecryptfs_readlink_lower(dentry, &len);
@@ -685,7 +683,7 @@ static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd)
d_inode(ecryptfs_dentry_to_lower(dentry)));
buf[len] = '\0';
out:
- nd_set_link(nd, buf);
+ nd_set_link(buf);
return NULL;
}

diff --git a/fs/exofs/symlink.c b/fs/exofs/symlink.c
index 6f6f3a4..c4e3db4 100644
--- a/fs/exofs/symlink.c
+++ b/fs/exofs/symlink.c
@@ -35,11 +35,11 @@

#include "exofs.h"

-static void *exofs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *exofs_follow_link(struct dentry *dentry)
{
struct exofs_i_info *oi = exofs_i(d_inode(dentry));

- nd_set_link(nd, (char *)oi->i_data);
+ nd_set_link((char *)oi->i_data);
return NULL;
}

diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c
index 20608f1..a6b1642 100644
--- a/fs/ext2/symlink.c
+++ b/fs/ext2/symlink.c
@@ -21,10 +21,10 @@
#include "xattr.h"
#include <linux/namei.h>

-static void *ext2_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *ext2_follow_link(struct dentry *dentry)
{
struct ext2_inode_info *ei = EXT2_I(d_inode(dentry));
- nd_set_link(nd, (char *)ei->i_data);
+ nd_set_link((char *)ei->i_data);
return NULL;
}

diff --git a/fs/ext3/symlink.c b/fs/ext3/symlink.c
index ea96df3..dd9763f 100644
--- a/fs/ext3/symlink.c
+++ b/fs/ext3/symlink.c
@@ -21,10 +21,10 @@
#include "ext3.h"
#include "xattr.h"

-static void * ext3_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void * ext3_follow_link(struct dentry *dentry)
{
struct ext3_inode_info *ei = EXT3_I(d_inode(dentry));
- nd_set_link(nd, (char*)ei->i_data);
+ nd_set_link((char*)ei->i_data);
return NULL;
}

diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c
index 57f5009..af7dc39 100644
--- a/fs/ext4/symlink.c
+++ b/fs/ext4/symlink.c
@@ -23,10 +23,10 @@
#include "ext4.h"
#include "xattr.h"

-static void *ext4_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *ext4_follow_link(struct dentry *dentry)
{
struct ext4_inode_info *ei = EXT4_I(d_inode(dentry));
- nd_set_link(nd, (char *) ei->i_data);
+ nd_set_link((char *) ei->i_data);
return NULL;
}

diff --git a/fs/freevxfs/vxfs_immed.c b/fs/freevxfs/vxfs_immed.c
index 8b9229e..f906f31 100644
--- a/fs/freevxfs/vxfs_immed.c
+++ b/fs/freevxfs/vxfs_immed.c
@@ -39,7 +39,7 @@
#include "vxfs_inode.h"

-static void * vxfs_immed_follow_link(struct dentry *, struct nameidata *);
+static void * vxfs_immed_follow_link(struct dentry *);

static int vxfs_immed_readpage(struct file *, struct page *);

@@ -64,7 +64,6 @@ const struct address_space_operations vxfs_immed_aops = {
/**
* vxfs_immed_follow_link - follow immed symlink
* @dp: dentry for the link
- * @np: pathname lookup data for the current path walk
*
* Description:
* vxfs_immed_follow_link restarts the pathname lookup with
@@ -74,10 +73,10 @@ const struct address_space_operations vxfs_immed_aops = {
* Zero on success, else a negative error code.
*/
static void *
-vxfs_immed_follow_link(struct dentry *dp, struct nameidata *np)
+vxfs_immed_follow_link(struct dentry *dp)
{
struct vxfs_inode_info *vip = VXFS_INO(d_inode(dp));
- nd_set_link(np, vip->vii_immed.vi_immed);
+ nd_set_link(vip->vii_immed.vi_immed);
return NULL;
}

diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 1453c6f..99230de 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1400,9 +1400,9 @@ static void free_link(char *link)
free_page((unsigned long) link);
}

-static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *fuse_follow_link(struct dentry *dentry)
{
- nd_set_link(nd, read_link(dentry));
+ nd_set_link(read_link(dentry));
return NULL;
}

diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index e301850..b89fa98 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -1541,14 +1541,13 @@ out:
/**
* gfs2_follow_link - Follow a symbolic link
* @dentry: The dentry of the link
- * @nd: Data that we pass to vfs_follow_link()
*
* This can handle symlinks of any size.
*
* Returns: 0 on success or error code
*/

-static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *gfs2_follow_link(struct dentry *dentry)
{
struct gfs2_inode *ip = GFS2_I(d_inode(dentry));
struct gfs2_holder i_gh;
@@ -1561,7 +1560,7 @@ static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd)
error = gfs2_glock_nq(&i_gh);
if (error) {
gfs2_holder_uninit(&i_gh);
- nd_set_link(nd, ERR_PTR(error));
+ nd_set_link(ERR_PTR(error));
return NULL;
}

@@ -1586,7 +1585,7 @@ static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd)
brelse(dibh);
out:
gfs2_glock_dq_uninit(&i_gh);
- nd_set_link(nd, buf);
+ nd_set_link(buf);
return NULL;
}

diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 5f40dfa..f80292b 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -880,7 +880,7 @@ static const struct inode_operations hostfs_dir_iops = {
.setattr = hostfs_setattr,
};

-static void *hostfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *hostfs_follow_link(struct dentry *dentry)
{
char *link = __getname();
if (link) {
@@ -900,7 +900,7 @@ static void *hostfs_follow_link(struct dentry *dentry, struct nameidata *nd)
link = ERR_PTR(-ENOMEM);
}

- nd_set_link(nd, link);
+ nd_set_link(link);
return NULL;
}

diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c
index 237907e..2620030 100644
--- a/fs/hppfs/hppfs.c
+++ b/fs/hppfs/hppfs.c
@@ -642,11 +642,11 @@ static int hppfs_readlink(struct dentry *dentry, char __user *buffer,
buflen);
}

-static void *hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *hppfs_follow_link(struct dentry *dentry)
{
struct dentry *proc_dentry = HPPFS_I(d_inode(dentry))->proc_dentry;

- return d_inode(proc_dentry)->i_op->follow_link(proc_dentry, nd);
+ return d_inode(proc_dentry)->i_op->follow_link(proc_dentry);
}

static void hppfs_put_link(struct dentry *dentry, char *link, void *cookie)
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c
index 1fefa25..ec28871 100644
--- a/fs/jffs2/symlink.c
+++ b/fs/jffs2/symlink.c
@@ -16,7 +16,7 @@
#include <linux/namei.h>
#include "nodelist.h"

-static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd);
+static void *jffs2_follow_link(struct dentry *dentry);

const struct inode_operations jffs2_symlink_inode_operations =
{
@@ -29,7 +29,7 @@ const struct inode_operations jffs2_symlink_inode_operations =
.removexattr = jffs2_removexattr
};

-static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *jffs2_follow_link(struct dentry *dentry)
{
struct jffs2_inode_info *f = JFFS2_INODE_INFO(d_inode(dentry));
char *p = (char *)f->target;
@@ -54,7 +54,7 @@ static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd)
jffs2_dbg(1, "%s(): target path is '%s'\n",
__func__, (char *)f->target);

- nd_set_link(nd, p);
+ nd_set_link(p);

/*
* We will unlock the f->sem mutex but VFS will use the f->target string. This is safe
diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c
index 80f42bc..4299a3c 100644
--- a/fs/jfs/symlink.c
+++ b/fs/jfs/symlink.c
@@ -22,10 +22,10 @@
#include "jfs_inode.h"
#include "jfs_xattr.h"

-static void *jfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *jfs_follow_link(struct dentry *dentry)
{
char *s = JFS_IP(d_inode(dentry))->i_inline;
- nd_set_link(nd, s);
+ nd_set_link(s);
return NULL;
}

diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c
index 2aa55cb..63d08ec 100644
--- a/fs/kernfs/symlink.c
+++ b/fs/kernfs/symlink.c
@@ -112,7 +112,7 @@ static int kernfs_getlink(struct dentry *dentry, char *path)
return error;
}

-static void *kernfs_iop_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *kernfs_iop_follow_link(struct dentry *dentry)
{
int error = -ENOMEM;
unsigned long page = get_zeroed_page(GFP_KERNEL);
@@ -121,7 +121,7 @@ static void *kernfs_iop_follow_link(struct dentry *dentry, struct nameidata *nd)
if (error < 0)
free_page((unsigned long)page);
}
- nd_set_link(nd, error ? ERR_PTR(error) : (char *)page);
+ nd_set_link(error ? ERR_PTR(error) : (char *)page);
return NULL;
}

diff --git a/fs/namei.c b/fs/namei.c
index 981080c..4c6ce01f 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -723,8 +723,10 @@ static inline void path_to_nameidata(const struct path *path,
* Helper to directly jump to a known parsed path from ->follow_link,
* caller must have taken a reference to path beforehand.
*/
-void nd_jump_link(struct nameidata *nd, struct path *path)
+void nd_jump_link(struct path *path)
{
+ struct nameidata *nd = current->nameidata;
+
path_put(&nd->path);

nd->path = *path;
@@ -732,8 +734,10 @@ void nd_jump_link(struct nameidata *nd, struct path *path)
nd->flags |= LOOKUP_JUMPED;
}

-void nd_set_link(struct nameidata *nd, char *path)
+void nd_set_link(char *path)
{
+ struct nameidata *nd = current->nameidata;
+
nd->saved_names[nd->depth] = path;
}
EXPORT_SYMBOL(nd_set_link);
@@ -887,14 +891,14 @@ follow_link(struct path *link, struct nameidata *nd, void **p)
nd->total_link_count++;

touch_atime(link);
- nd_set_link(nd, NULL);
+ nd_set_link(NULL);

error = security_inode_follow_link(link->dentry);
if (error)
goto out_put_nd_path;

nd->last_type = LAST_BIND;
- *p = dentry->d_inode->i_op->follow_link(dentry, nd);
+ *p = dentry->d_inode->i_op->follow_link(dentry);
error = PTR_ERR(*p);
if (IS_ERR(*p))
goto out_put_nd_path;
@@ -4458,7 +4462,7 @@ int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen)
int res;

nd.depth = 0;
- cookie = dentry->d_inode->i_op->follow_link(dentry, &nd);
+ cookie = dentry->d_inode->i_op->follow_link(dentry);
if (IS_ERR(cookie))
res = PTR_ERR(cookie);
else {
@@ -4500,10 +4504,10 @@ int page_readlink(struct dentry *dentry, char __user *buffer, int buflen)
}
EXPORT_SYMBOL(page_readlink);

-void *page_follow_link_light(struct dentry *dentry, struct nameidata *nd)
+void *page_follow_link_light(struct dentry *dentry)
{
struct page *page = NULL;
- nd_set_link(nd, page_getlink(dentry, &page));
+ nd_set_link(page_getlink(dentry, &page));
return page;
}
EXPORT_SYMBOL(page_follow_link_light);
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c
index 2d56200..1394f87 100644
--- a/fs/nfs/symlink.c
+++ b/fs/nfs/symlink.c
@@ -43,7 +43,7 @@ error:
return -EIO;
}

-static void *nfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *nfs_follow_link(struct dentry *dentry)
{
struct inode *inode = d_inode(dentry);
struct page *page;
@@ -58,11 +58,11 @@ static void *nfs_follow_link(struct dentry *dentry, struct nameidata *nd)
err = page;
goto read_failed;
}
- nd_set_link(nd, kmap(page));
+ nd_set_link(kmap(page));
return page;

read_failed:
- nd_set_link(nd, err);
+ nd_set_link(err);
return NULL;
}

diff --git a/fs/ntfs/namei.c b/fs/ntfs/namei.c
index 0f35b80..dcb5490 100644
--- a/fs/ntfs/namei.c
+++ b/fs/ntfs/namei.c
@@ -35,7 +35,6 @@
* ntfs_lookup - find the inode represented by a dentry in a directory inode
* @dir_ino: directory inode in which to look for the inode
* @dent: dentry representing the inode to look for
- * @nd: lookup nameidata
*
* In short, ntfs_lookup() looks for the inode represented by the dentry @dent
* in the directory inode @dir_ino and if found attaches the inode to the
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index f1abb51..0de7b87 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -140,7 +140,7 @@ struct ovl_link_data {
void *cookie;
};

-static void *ovl_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *ovl_follow_link(struct dentry *dentry)
{
void *ret;
struct dentry *realdentry;
@@ -160,7 +160,7 @@ static void *ovl_follow_link(struct dentry *dentry, struct nameidata *nd)
data->realdentry = realdentry;
}

- ret = realinode->i_op->follow_link(realdentry, nd);
+ ret = realinode->i_op->follow_link(realdentry);
if (IS_ERR(ret)) {
kfree(data);
return ret;
diff --git a/fs/proc/base.c b/fs/proc/base.c
index a3d6b55..a511738 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1371,7 +1371,7 @@ static int proc_exe_link(struct dentry *dentry, struct path *exe_path)
return -ENOENT;
}

-static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *proc_pid_follow_link(struct dentry *dentry)
{
struct inode *inode = d_inode(dentry);
struct path path;
@@ -1385,7 +1385,7 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
if (error)
goto out;

- nd_jump_link(nd, &path);
+ nd_jump_link(&path);
return NULL;
out:
return ERR_PTR(error);
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 27fd86d..68934dd 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -394,12 +394,12 @@ static const struct file_operations proc_reg_file_ops_no_compat = {
};
#endif

-static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *proc_follow_link(struct dentry *dentry)
{
struct proc_dir_entry *pde = PDE(d_inode(dentry));
if (unlikely(!use_pde(pde)))
return ERR_PTR(-EINVAL);
- nd_set_link(nd, pde->data);
+ nd_set_link(pde->data);
return pde;
}

diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c
index e512642..15852e1 100644
--- a/fs/proc/namespaces.c
+++ b/fs/proc/namespaces.c
@@ -30,7 +30,7 @@ static const struct proc_ns_operations *ns_entries[] = {
&mntns_operations,
};

-static void *proc_ns_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *proc_ns_follow_link(struct dentry *dentry)
{
struct inode *inode = d_inode(dentry);
const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops;
@@ -45,7 +45,7 @@ static void *proc_ns_follow_link(struct dentry *dentry, struct nameidata *nd)
if (ptrace_may_access(task, PTRACE_MODE_READ)) {
error = ns_get_path(&ns_path, task, ns_ops);
if (!error)
- nd_jump_link(nd, &ns_path);
+ nd_jump_link(&ns_path);
}
put_task_struct(task);
return error;
diff --git a/fs/proc/self.c b/fs/proc/self.c
index 6195b4a..51ed086 100644
--- a/fs/proc/self.c
+++ b/fs/proc/self.c
@@ -19,7 +19,7 @@ static int proc_self_readlink(struct dentry *dentry, char __user *buffer,
return readlink_copy(buffer, buflen, tmp);
}

-static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *proc_self_follow_link(struct dentry *dentry)
{
struct pid_namespace *ns = dentry->d_sb->s_fs_info;
pid_t tgid = task_tgid_nr_ns(current, ns);
@@ -32,7 +32,7 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
else
sprintf(name, "%d", tgid);
}
- nd_set_link(nd, name);
+ nd_set_link(name);
return NULL;
}

diff --git a/fs/proc/thread_self.c b/fs/proc/thread_self.c
index a837199..60457f6 100644
--- a/fs/proc/thread_self.c
+++ b/fs/proc/thread_self.c
@@ -20,7 +20,7 @@ static int proc_thread_self_readlink(struct dentry *dentry, char __user *buffer,
return readlink_copy(buffer, buflen, tmp);
}

-static void *proc_thread_self_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *proc_thread_self_follow_link(struct dentry *dentry)
{
struct pid_namespace *ns = dentry->d_sb->s_fs_info;
pid_t tgid = task_tgid_nr_ns(current, ns);
@@ -33,7 +33,7 @@ static void *proc_thread_self_follow_link(struct dentry *dentry, struct nameidat
else
sprintf(name, "%d/task/%d", tgid, pid);
}
- nd_set_link(nd, name);
+ nd_set_link(name);
return NULL;
}

diff --git a/fs/sysv/symlink.c b/fs/sysv/symlink.c
index d3fa0d7..6af76f1 100644
--- a/fs/sysv/symlink.c
+++ b/fs/sysv/symlink.c
@@ -8,9 +8,9 @@
#include "sysv.h"
#include <linux/namei.h>

-static void *sysv_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *sysv_follow_link(struct dentry *dentry)
{
- nd_set_link(nd, (char *)SYSV_I(d_inode(dentry))->i_data);
+ nd_set_link((char *)SYSV_I(d_inode(dentry))->i_data);
return NULL;
}

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index b5c6941..c8ea213 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1299,11 +1299,11 @@ static void ubifs_invalidatepage(struct page *page, unsigned int offset,
ClearPageChecked(page);
}

-static void *ubifs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *ubifs_follow_link(struct dentry *dentry)
{
struct ubifs_inode *ui = ubifs_inode(d_inode(dentry));

- nd_set_link(nd, ui->data);
+ nd_set_link(ui->data);
return NULL;
}

diff --git a/fs/ufs/symlink.c b/fs/ufs/symlink.c
index 5b537e2..dd34c35 100644
--- a/fs/ufs/symlink.c
+++ b/fs/ufs/symlink.c
@@ -32,10 +32,10 @@
#include "ufs.h"

-static void *ufs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *ufs_follow_link(struct dentry *dentry)
{
struct ufs_inode_info *p = UFS_I(d_inode(dentry));
- nd_set_link(nd, (char*)p->i_u1.i_symlink);
+ nd_set_link((char*)p->i_u1.i_symlink);
return NULL;
}

diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 54b9523..1c3df6b 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -411,8 +411,7 @@ xfs_vn_rename(
*/
STATIC void *
xfs_vn_follow_link(
- struct dentry *dentry,
- struct nameidata *nd)
+ struct dentry *dentry)
{
char *link;
int error = -ENOMEM;
@@ -425,13 +424,13 @@ xfs_vn_follow_link(
if (unlikely(error))
goto out_kfree;

- nd_set_link(nd, link);
+ nd_set_link(link);
return NULL;

out_kfree:
kfree(link);
out_err:
- nd_set_link(nd, ERR_PTR(error));
+ nd_set_link(ERR_PTR(error));
return NULL;
}

diff --git a/include/linux/fs.h b/include/linux/fs.h
index d407d59..a892fb7 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -38,7 +38,6 @@ struct backing_dev_info;
struct export_operations;
struct hd_geometry;
struct iovec;
-struct nameidata;
struct kiocb;
struct kobject;
struct pipe_inode_info;
@@ -1599,7 +1598,7 @@ struct file_operations {

struct inode_operations {
struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
- void * (*follow_link) (struct dentry *, struct nameidata *);
+ void * (*follow_link) (struct dentry *);
int (*permission) (struct inode *, int);
struct posix_acl * (*get_acl)(struct inode *, int);

@@ -2695,7 +2694,7 @@ extern const struct file_operations generic_ro_fops;

extern int readlink_copy(char __user *, int, const char *);
extern int page_readlink(struct dentry *, char __user *, int);
-extern void *page_follow_link_light(struct dentry *, struct nameidata *);
+extern void *page_follow_link_light(struct dentry *);
extern void page_put_link(struct dentry *, char *, void *);
extern int __page_symlink(struct inode *inode, const char *symname, int len,
int nofs);
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 2ec27f2..cc8b51a 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -7,7 +7,6 @@
#include <linux/path.h>

struct vfsmount;
-struct nameidata;

enum { MAX_NESTED_LINKS = 8 };

@@ -70,8 +69,8 @@ extern int follow_up(struct path *);
extern struct dentry *lock_rename(struct dentry *, struct dentry *);
extern void unlock_rename(struct dentry *, struct dentry *);

-extern void nd_jump_link(struct nameidata *nd, struct path *path);
-extern void nd_set_link(struct nameidata *nd, char *path);
+extern void nd_jump_link(struct path *path);
+extern void nd_set_link(char *path);

static inline void nd_terminate_link(void *name, size_t len, size_t maxlen)
{
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 4402c91..d3886e5 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1267,6 +1267,7 @@ union rcu_special {
short s;
};
struct rcu_node;
+struct nameidata;

enum perf_event_task_context {
perf_invalid_context = -1,
diff --git a/mm/shmem.c b/mm/shmem.c
index 00707f8..daad5af 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2474,17 +2474,17 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
return 0;
}

-static void *shmem_follow_short_symlink(struct dentry *dentry, struct nameidata *nd)
+static void *shmem_follow_short_symlink(struct dentry *dentry)
{
- nd_set_link(nd, SHMEM_I(d_inode(dentry))->symlink);
+ nd_set_link(SHMEM_I(d_inode(dentry))->symlink);
return NULL;
}

-static void *shmem_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *shmem_follow_link(struct dentry *dentry)
{
struct page *page = NULL;
int error = shmem_getpage(d_inode(dentry), 0, &page, SGP_READ, NULL);
- nd_set_link(nd, error ? ERR_PTR(error) : kmap(page));
+ nd_set_link(error ? ERR_PTR(error) : kmap(page));
if (page)
unlock_page(page);
return page;
--
2.1.4