aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/9p/vfs_inode.c3
-rw-r--r--fs/9p/vfs_inode_dotl.c3
-rw-r--r--fs/dcache.c7
-rw-r--r--fs/overlayfs/inode.c3
4 files changed, 10 insertions, 6 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 510040b04c96..b1dc51888048 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -540,8 +540,7 @@ static struct inode *v9fs_qid_iget(struct super_block *sb,
540 unlock_new_inode(inode); 540 unlock_new_inode(inode);
541 return inode; 541 return inode;
542error: 542error:
543 unlock_new_inode(inode); 543 iget_failed(inode);
544 iput(inode);
545 return ERR_PTR(retval); 544 return ERR_PTR(retval);
546 545
547} 546}
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
index 09e4433717b8..e8aa57dc8d6d 100644
--- a/fs/9p/vfs_inode_dotl.c
+++ b/fs/9p/vfs_inode_dotl.c
@@ -149,8 +149,7 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
149 unlock_new_inode(inode); 149 unlock_new_inode(inode);
150 return inode; 150 return inode;
151error: 151error:
152 unlock_new_inode(inode); 152 iget_failed(inode);
153 iput(inode);
154 return ERR_PTR(retval); 153 return ERR_PTR(retval);
155 154
156} 155}
diff --git a/fs/dcache.c b/fs/dcache.c
index 7a3f3e5f9cea..5c8ea15e73a5 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -642,7 +642,7 @@ static inline bool fast_dput(struct dentry *dentry)
642 642
643 /* 643 /*
644 * If we have a d_op->d_delete() operation, we sould not 644 * If we have a d_op->d_delete() operation, we sould not
645 * let the dentry count go to zero, so use "put__or_lock". 645 * let the dentry count go to zero, so use "put_or_lock".
646 */ 646 */
647 if (unlikely(dentry->d_flags & DCACHE_OP_DELETE)) 647 if (unlikely(dentry->d_flags & DCACHE_OP_DELETE))
648 return lockref_put_or_lock(&dentry->d_lockref); 648 return lockref_put_or_lock(&dentry->d_lockref);
@@ -697,7 +697,7 @@ static inline bool fast_dput(struct dentry *dentry)
697 */ 697 */
698 smp_rmb(); 698 smp_rmb();
699 d_flags = ACCESS_ONCE(dentry->d_flags); 699 d_flags = ACCESS_ONCE(dentry->d_flags);
700 d_flags &= DCACHE_REFERENCED | DCACHE_LRU_LIST; 700 d_flags &= DCACHE_REFERENCED | DCACHE_LRU_LIST | DCACHE_DISCONNECTED;
701 701
702 /* Nothing to do? Dropping the reference was all we needed? */ 702 /* Nothing to do? Dropping the reference was all we needed? */
703 if (d_flags == (DCACHE_REFERENCED | DCACHE_LRU_LIST) && !d_unhashed(dentry)) 703 if (d_flags == (DCACHE_REFERENCED | DCACHE_LRU_LIST) && !d_unhashed(dentry))
@@ -776,6 +776,9 @@ repeat:
776 if (unlikely(d_unhashed(dentry))) 776 if (unlikely(d_unhashed(dentry)))
777 goto kill_it; 777 goto kill_it;
778 778
779 if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED))
780 goto kill_it;
781
779 if (unlikely(dentry->d_flags & DCACHE_OP_DELETE)) { 782 if (unlikely(dentry->d_flags & DCACHE_OP_DELETE)) {
780 if (dentry->d_op->d_delete(dentry)) 783 if (dentry->d_op->d_delete(dentry))
781 goto kill_it; 784 goto kill_it;
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index f140e3dbfb7b..d9da5a4e9382 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -343,6 +343,9 @@ struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags)
343 struct path realpath; 343 struct path realpath;
344 enum ovl_path_type type; 344 enum ovl_path_type type;
345 345
346 if (d_is_dir(dentry))
347 return d_backing_inode(dentry);
348
346 type = ovl_path_real(dentry, &realpath); 349 type = ovl_path_real(dentry, &realpath);
347 if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) { 350 if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) {
348 err = ovl_want_write(dentry); 351 err = ovl_want_write(dentry);