Skip to content

Commit c83727a

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull VFS fixes from Al Viro: "Fixes for this cycle regression in overlayfs and a couple of long-standing (== all the way back to 2.6.12, at least) bugs" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: freeing unlinked file indefinitely delayed fix a braino in ovl_d_select_inode() 9p: don't leave a half-initialized inode sitting around
2 parents 7fbb58a + 75a6f82 commit c83727a

File tree

4 files changed

+10
-6
lines changed

4 files changed

+10
-6
lines changed

fs/9p/vfs_inode.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -540,8 +540,7 @@ static struct inode *v9fs_qid_iget(struct super_block *sb,
540540
unlock_new_inode(inode);
541541
return inode;
542542
error:
543-
unlock_new_inode(inode);
544-
iput(inode);
543+
iget_failed(inode);
545544
return ERR_PTR(retval);
546545

547546
}

fs/9p/vfs_inode_dotl.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,7 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
149149
unlock_new_inode(inode);
150150
return inode;
151151
error:
152-
unlock_new_inode(inode);
153-
iput(inode);
152+
iget_failed(inode);
154153
return ERR_PTR(retval);
155154

156155
}

fs/dcache.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@ static inline bool fast_dput(struct dentry *dentry)
642642

643643
/*
644644
* 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".
646646
*/
647647
if (unlikely(dentry->d_flags & DCACHE_OP_DELETE))
648648
return lockref_put_or_lock(&dentry->d_lockref);
@@ -697,7 +697,7 @@ static inline bool fast_dput(struct dentry *dentry)
697697
*/
698698
smp_rmb();
699699
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;
701701

702702
/* Nothing to do? Dropping the reference was all we needed? */
703703
if (d_flags == (DCACHE_REFERENCED | DCACHE_LRU_LIST) && !d_unhashed(dentry))
@@ -776,6 +776,9 @@ void dput(struct dentry *dentry)
776776
if (unlikely(d_unhashed(dentry)))
777777
goto kill_it;
778778

779+
if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED))
780+
goto kill_it;
781+
779782
if (unlikely(dentry->d_flags & DCACHE_OP_DELETE)) {
780783
if (dentry->d_op->d_delete(dentry))
781784
goto kill_it;

fs/overlayfs/inode.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,9 @@ struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags)
343343
struct path realpath;
344344
enum ovl_path_type type;
345345

346+
if (d_is_dir(dentry))
347+
return d_backing_inode(dentry);
348+
346349
type = ovl_path_real(dentry, &realpath);
347350
if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) {
348351
err = ovl_want_write(dentry);

0 commit comments

Comments
 (0)