diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 27 |
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 | ||
1847 | static int path_init(int dfd, const char *name, unsigned int flags, | 1848 | static 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) | |||
1954 | static int path_lookupat(int dfd, const char *name, | 1956 | static 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 | ||
2010 | out: | 2011 | out: |
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: | |||
2321 | static int | 2322 | static int |
2322 | path_mountpoint(int dfd, const char *name, struct path *path, unsigned int flags) | 2323 | path_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 | } |
2351 | out: | 2351 | out: |
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: | |||
3205 | static struct file *path_openat(int dfd, struct filename *pathname, | 3205 | static 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, | |||
3255 | out: | 3254 | out: |
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); |