aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cachefiles/namei.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2018-05-10 22:59:45 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2018-05-21 14:30:10 -0400
commit9c3e9025a3f7ed25c99a0add8af65431c8043800 (patch)
treed8f892f5750d1aea00dcef9d9f7ea1719f11a6ce /fs/cachefiles/namei.c
parent7b745a4e4051e1bbce40e0b1c2cf636c70583aa4 (diff)
cachefiles: vfs_mkdir() might succeed leaving dentry negative unhashed
That can (and does, on some filesystems) happen - ->mkdir() (and thus vfs_mkdir()) can legitimately leave its argument negative and just unhash it, counting upon the lookup to pick the object we'd created next time we try to look at that name. Some vfs_mkdir() callers forget about that possibility... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/cachefiles/namei.c')
-rw-r--r--fs/cachefiles/namei.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
index 0daa1e3fe0df..ab0bbe93b398 100644
--- a/fs/cachefiles/namei.c
+++ b/fs/cachefiles/namei.c
@@ -572,6 +572,11 @@ lookup_again:
572 if (ret < 0) 572 if (ret < 0)
573 goto create_error; 573 goto create_error;
574 574
575 if (unlikely(d_unhashed(next))) {
576 dput(next);
577 inode_unlock(d_inode(dir));
578 goto lookup_again;
579 }
575 ASSERT(d_backing_inode(next)); 580 ASSERT(d_backing_inode(next));
576 581
577 _debug("mkdir -> %p{%p{ino=%lu}}", 582 _debug("mkdir -> %p{%p{ino=%lu}}",
@@ -764,6 +769,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
764 /* search the current directory for the element name */ 769 /* search the current directory for the element name */
765 inode_lock(d_inode(dir)); 770 inode_lock(d_inode(dir));
766 771
772retry:
767 start = jiffies; 773 start = jiffies;
768 subdir = lookup_one_len(dirname, dir, strlen(dirname)); 774 subdir = lookup_one_len(dirname, dir, strlen(dirname));
769 cachefiles_hist(cachefiles_lookup_histogram, start); 775 cachefiles_hist(cachefiles_lookup_histogram, start);
@@ -793,6 +799,10 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
793 if (ret < 0) 799 if (ret < 0)
794 goto mkdir_error; 800 goto mkdir_error;
795 801
802 if (unlikely(d_unhashed(subdir))) {
803 dput(subdir);
804 goto retry;
805 }
796 ASSERT(d_backing_inode(subdir)); 806 ASSERT(d_backing_inode(subdir));
797 807
798 _debug("mkdir -> %p{%p{ino=%lu}}", 808 _debug("mkdir -> %p{%p{ino=%lu}}",