diff options
| -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); |
