mirror of https://gitee.com/openkylin/linux.git
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
This commit is contained in:
commit
c83727a656
|
@ -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,
|
||||||
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)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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)
|
||||||
*/
|
*/
|
||||||
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)
|
||||||
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)
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue