Commit c83727a6 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 7fbb58a0 75a6f82a
...@@ -540,8 +540,7 @@ static struct inode *v9fs_qid_iget(struct super_block *sb, ...@@ -540,8 +540,7 @@ static struct inode *v9fs_qid_iget(struct super_block *sb,
unlock_new_inode(inode); unlock_new_inode(inode);
return inode; return inode;
error: error:
unlock_new_inode(inode); iget_failed(inode);
iput(inode);
return ERR_PTR(retval); return ERR_PTR(retval);
} }
......
...@@ -149,8 +149,7 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb, ...@@ -149,8 +149,7 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
unlock_new_inode(inode); unlock_new_inode(inode);
return inode; return inode;
error: error:
unlock_new_inode(inode); iget_failed(inode);
iput(inode);
return ERR_PTR(retval); return ERR_PTR(retval);
} }
......
...@@ -642,7 +642,7 @@ static inline bool fast_dput(struct dentry *dentry) ...@@ -642,7 +642,7 @@ static inline bool fast_dput(struct dentry *dentry)
/* /*
* If we have a d_op->d_delete() operation, we sould not * If we have a d_op->d_delete() operation, we sould not
* let the dentry count go to zero, so use "put__or_lock". * let the dentry count go to zero, so use "put_or_lock".
*/ */
if (unlikely(dentry->d_flags & DCACHE_OP_DELETE)) if (unlikely(dentry->d_flags & DCACHE_OP_DELETE))
return lockref_put_or_lock(&dentry->d_lockref); return lockref_put_or_lock(&dentry->d_lockref);
...@@ -697,7 +697,7 @@ static inline bool fast_dput(struct dentry *dentry) ...@@ -697,7 +697,7 @@ static inline bool fast_dput(struct dentry *dentry)
*/ */
smp_rmb(); smp_rmb();
d_flags = ACCESS_ONCE(dentry->d_flags); d_flags = ACCESS_ONCE(dentry->d_flags);
d_flags &= DCACHE_REFERENCED | DCACHE_LRU_LIST; d_flags &= DCACHE_REFERENCED | DCACHE_LRU_LIST | DCACHE_DISCONNECTED;
/* Nothing to do? Dropping the reference was all we needed? */ /* Nothing to do? Dropping the reference was all we needed? */
if (d_flags == (DCACHE_REFERENCED | DCACHE_LRU_LIST) && !d_unhashed(dentry)) if (d_flags == (DCACHE_REFERENCED | DCACHE_LRU_LIST) && !d_unhashed(dentry))
...@@ -776,6 +776,9 @@ void dput(struct dentry *dentry) ...@@ -776,6 +776,9 @@ void dput(struct dentry *dentry)
if (unlikely(d_unhashed(dentry))) if (unlikely(d_unhashed(dentry)))
goto kill_it; goto kill_it;
if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED))
goto kill_it;
if (unlikely(dentry->d_flags & DCACHE_OP_DELETE)) { if (unlikely(dentry->d_flags & DCACHE_OP_DELETE)) {
if (dentry->d_op->d_delete(dentry)) if (dentry->d_op->d_delete(dentry))
goto kill_it; goto kill_it;
......
...@@ -343,6 +343,9 @@ struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags) ...@@ -343,6 +343,9 @@ struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags)
struct path realpath; struct path realpath;
enum ovl_path_type type; enum ovl_path_type type;
if (d_is_dir(dentry))
return d_backing_inode(dentry);
type = ovl_path_real(dentry, &realpath); type = ovl_path_real(dentry, &realpath);
if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) { if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) {
err = ovl_want_write(dentry); err = ovl_want_write(dentry);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment