aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c27
1 files changed, 13 insertions, 14 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 398a73b522cb..e967f43e56ae 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -496,6 +496,7 @@ struct nameidata {
496 unsigned seq, m_seq; 496 unsigned seq, m_seq;
497 int last_type; 497 int last_type;
498 unsigned depth; 498 unsigned depth;
499 struct file *base;
499 char *saved_names[MAX_NESTED_LINKS + 1]; 500 char *saved_names[MAX_NESTED_LINKS + 1];
500}; 501};
501 502
@@ -1845,13 +1846,14 @@ static int link_path_walk(const char *name, struct nameidata *nd)
1845} 1846}
1846 1847
1847static int path_init(int dfd, const char *name, unsigned int flags, 1848static int path_init(int dfd, const char *name, unsigned int flags,
1848 struct nameidata *nd, struct file **fp) 1849 struct nameidata *nd)
1849{ 1850{
1850 int retval = 0; 1851 int retval = 0;
1851 1852
1852 nd->last_type = LAST_ROOT; /* if there are only slashes... */ 1853 nd->last_type = LAST_ROOT; /* if there are only slashes... */
1853 nd->flags = flags | LOOKUP_JUMPED; 1854 nd->flags = flags | LOOKUP_JUMPED;
1854 nd->depth = 0; 1855 nd->depth = 0;
1856 nd->base = NULL;
1855 if (flags & LOOKUP_ROOT) { 1857 if (flags & LOOKUP_ROOT) {
1856 struct dentry *root = nd->root.dentry; 1858 struct dentry *root = nd->root.dentry;
1857 struct inode *inode = root->d_inode; 1859 struct inode *inode = root->d_inode;
@@ -1921,7 +1923,7 @@ static int path_init(int dfd, const char *name, unsigned int flags,
1921 nd->path = f.file->f_path; 1923 nd->path = f.file->f_path;
1922 if (flags & LOOKUP_RCU) { 1924 if (flags & LOOKUP_RCU) {
1923 if (f.flags & FDPUT_FPUT) 1925 if (f.flags & FDPUT_FPUT)
1924 *fp = f.file; 1926 nd->base = f.file;
1925 nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); 1927 nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
1926 rcu_read_lock(); 1928 rcu_read_lock();
1927 } else { 1929 } else {
@@ -1954,7 +1956,6 @@ static inline int lookup_last(struct nameidata *nd, struct path *path)
1954static int path_lookupat(int dfd, const char *name, 1956static int path_lookupat(int dfd, const char *name,
1955 unsigned int flags, struct nameidata *nd) 1957 unsigned int flags, struct nameidata *nd)
1956{ 1958{
1957 struct file *base = NULL;
1958 struct path path; 1959 struct path path;
1959 int err; 1960 int err;
1960 1961
@@ -1972,7 +1973,7 @@ static int path_lookupat(int dfd, const char *name,
1972 * be handled by restarting a traditional ref-walk (which will always 1973 * be handled by restarting a traditional ref-walk (which will always
1973 * be able to complete). 1974 * be able to complete).
1974 */ 1975 */
1975 err = path_init(dfd, name, flags | LOOKUP_PARENT, nd, &base); 1976 err = path_init(dfd, name, flags | LOOKUP_PARENT, nd);
1976 1977
1977 if (unlikely(err)) 1978 if (unlikely(err))
1978 goto out; 1979 goto out;
@@ -2008,8 +2009,8 @@ static int path_lookupat(int dfd, const char *name,
2008 } 2009 }
2009 2010
2010out: 2011out:
2011 if (base) 2012 if (nd->base)
2012 fput(base); 2013 fput(nd->base);
2013 2014
2014 if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) { 2015 if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) {
2015 path_put(&nd->root); 2016 path_put(&nd->root);
@@ -2321,11 +2322,10 @@ out:
2321static int 2322static int
2322path_mountpoint(int dfd, const char *name, struct path *path, unsigned int flags) 2323path_mountpoint(int dfd, const char *name, struct path *path, unsigned int flags)
2323{ 2324{
2324 struct file *base = NULL;
2325 struct nameidata nd; 2325 struct nameidata nd;
2326 int err; 2326 int err;
2327 2327
2328 err = path_init(dfd, name, flags | LOOKUP_PARENT, &nd, &base); 2328 err = path_init(dfd, name, flags | LOOKUP_PARENT, &nd);
2329 if (unlikely(err)) 2329 if (unlikely(err))
2330 goto out; 2330 goto out;
2331 2331
@@ -2349,8 +2349,8 @@ path_mountpoint(int dfd, const char *name, struct path *path, unsigned int flags
2349 put_link(&nd, &link, cookie); 2349 put_link(&nd, &link, cookie);
2350 } 2350 }
2351out: 2351out:
2352 if (base) 2352 if (nd.base)
2353 fput(base); 2353 fput(nd.base);
2354 2354
2355 if (nd.root.mnt && !(nd.flags & LOOKUP_ROOT)) 2355 if (nd.root.mnt && !(nd.flags & LOOKUP_ROOT))
2356 path_put(&nd.root); 2356 path_put(&nd.root);
@@ -3205,7 +3205,6 @@ out:
3205static struct file *path_openat(int dfd, struct filename *pathname, 3205static struct file *path_openat(int dfd, struct filename *pathname,
3206 struct nameidata *nd, const struct open_flags *op, int flags) 3206 struct nameidata *nd, const struct open_flags *op, int flags)
3207{ 3207{
3208 struct file *base = NULL;
3209 struct file *file; 3208 struct file *file;
3210 struct path path; 3209 struct path path;
3211 int opened = 0; 3210 int opened = 0;
@@ -3222,7 +3221,7 @@ static struct file *path_openat(int dfd, struct filename *pathname,
3222 goto out; 3221 goto out;
3223 } 3222 }
3224 3223
3225 error = path_init(dfd, pathname->name, flags | LOOKUP_PARENT, nd, &base); 3224 error = path_init(dfd, pathname->name, flags | LOOKUP_PARENT, nd);
3226 if (unlikely(error)) 3225 if (unlikely(error))
3227 goto out; 3226 goto out;
3228 3227
@@ -3255,8 +3254,8 @@ static struct file *path_openat(int dfd, struct filename *pathname,
3255out: 3254out:
3256 if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) 3255 if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT))
3257 path_put(&nd->root); 3256 path_put(&nd->root);
3258 if (base) 3257 if (nd->base)
3259 fput(base); 3258 fput(nd->base);
3260 if (!(opened & FILE_OPENED)) { 3259 if (!(opened & FILE_OPENED)) {
3261 BUG_ON(!error); 3260 BUG_ON(!error);
3262 put_filp(file); 3261 put_filp(file);