diff options
author | Miklos Szeredi <mszeredi@redhat.com> | 2016-05-10 19:16:37 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-05-10 23:56:28 -0400 |
commit | 3c9fe8cdff1b889a059a30d22f130372f2b3885f (patch) | |
tree | 29f9b50b15ebbea097686abd2b0a71dedfcc128d | |
parent | 9409e22acdfc9153f88d9b1ed2bd2a5b34d2d3ca (diff) |
vfs: add lookup_hash() helper
Overlayfs needs lookup without inode_permission() and already has the name
hash (in form of dentry->d_name on overlayfs dentry). It also doesn't
support filesystems with d_op->d_hash() so basically it only needs
the actual hashed lookup from lookup_one_len_unlocked()
So add a new helper that does unlocked lookup of a hashed name.
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
-rw-r--r-- | fs/namei.c | 33 | ||||
-rw-r--r-- | include/linux/namei.h | 2 |
2 files changed, 30 insertions, 5 deletions
diff --git a/fs/namei.c b/fs/namei.c index 3ef87d673bbe..1a1ea79a7ba0 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2267,6 +2267,33 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt, | |||
2267 | EXPORT_SYMBOL(vfs_path_lookup); | 2267 | EXPORT_SYMBOL(vfs_path_lookup); |
2268 | 2268 | ||
2269 | /** | 2269 | /** |
2270 | * lookup_hash - lookup single pathname component on already hashed name | ||
2271 | * @name: name and hash to lookup | ||
2272 | * @base: base directory to lookup from | ||
2273 | * | ||
2274 | * The name must have been verified and hashed (see lookup_one_len()). Using | ||
2275 | * this after just full_name_hash() is unsafe. | ||
2276 | * | ||
2277 | * This function also doesn't check for search permission on base directory. | ||
2278 | * | ||
2279 | * Use lookup_one_len_unlocked() instead, unless you really know what you are | ||
2280 | * doing. | ||
2281 | * | ||
2282 | * Do not hold i_mutex; this helper takes i_mutex if necessary. | ||
2283 | */ | ||
2284 | struct dentry *lookup_hash(const struct qstr *name, struct dentry *base) | ||
2285 | { | ||
2286 | struct dentry *ret; | ||
2287 | |||
2288 | ret = lookup_dcache(name, base, 0); | ||
2289 | if (!ret) | ||
2290 | ret = lookup_slow(name, base, 0); | ||
2291 | |||
2292 | return ret; | ||
2293 | } | ||
2294 | EXPORT_SYMBOL(lookup_hash); | ||
2295 | |||
2296 | /** | ||
2270 | * lookup_one_len - filesystem helper to lookup single pathname component | 2297 | * lookup_one_len - filesystem helper to lookup single pathname component |
2271 | * @name: pathname component to lookup | 2298 | * @name: pathname component to lookup |
2272 | * @base: base directory to lookup from | 2299 | * @base: base directory to lookup from |
@@ -2337,7 +2364,6 @@ struct dentry *lookup_one_len_unlocked(const char *name, | |||
2337 | struct qstr this; | 2364 | struct qstr this; |
2338 | unsigned int c; | 2365 | unsigned int c; |
2339 | int err; | 2366 | int err; |
2340 | struct dentry *ret; | ||
2341 | 2367 | ||
2342 | this.name = name; | 2368 | this.name = name; |
2343 | this.len = len; | 2369 | this.len = len; |
@@ -2369,10 +2395,7 @@ struct dentry *lookup_one_len_unlocked(const char *name, | |||
2369 | if (err) | 2395 | if (err) |
2370 | return ERR_PTR(err); | 2396 | return ERR_PTR(err); |
2371 | 2397 | ||
2372 | ret = lookup_dcache(&this, base, 0); | 2398 | return lookup_hash(&this, base); |
2373 | if (!ret) | ||
2374 | ret = lookup_slow(&this, base, 0); | ||
2375 | return ret; | ||
2376 | } | 2399 | } |
2377 | EXPORT_SYMBOL(lookup_one_len_unlocked); | 2400 | EXPORT_SYMBOL(lookup_one_len_unlocked); |
2378 | 2401 | ||
diff --git a/include/linux/namei.h b/include/linux/namei.h index 77d01700daf7..ec5ec2818a28 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h | |||
@@ -79,6 +79,8 @@ extern int kern_path_mountpoint(int, const char *, struct path *, unsigned int); | |||
79 | 79 | ||
80 | extern struct dentry *lookup_one_len(const char *, struct dentry *, int); | 80 | extern struct dentry *lookup_one_len(const char *, struct dentry *, int); |
81 | extern struct dentry *lookup_one_len_unlocked(const char *, struct dentry *, int); | 81 | extern struct dentry *lookup_one_len_unlocked(const char *, struct dentry *, int); |
82 | struct qstr; | ||
83 | extern struct dentry *lookup_hash(const struct qstr *, struct dentry *); | ||
82 | 84 | ||
83 | extern int follow_down_one(struct path *); | 85 | extern int follow_down_one(struct path *); |
84 | extern int follow_down(struct path *); | 86 | extern int follow_down(struct path *); |