Merge branch 'test.d_iput' into work.misc

This commit is contained in:
Al Viro 2016-07-24 16:36:04 -04:00
commit 17648b871d
1 changed files with 10 additions and 35 deletions

View File

@ -334,44 +334,21 @@ static inline void dentry_rcuwalk_invalidate(struct dentry *dentry)
/* /*
* Release the dentry's inode, using the filesystem * Release the dentry's inode, using the filesystem
* d_iput() operation if defined. Dentry has no refcount * d_iput() operation if defined.
* and is unhashed.
*/
static void dentry_iput(struct dentry * dentry)
__releases(dentry->d_lock)
__releases(dentry->d_inode->i_lock)
{
struct inode *inode = dentry->d_inode;
if (inode) {
__d_clear_type_and_inode(dentry);
hlist_del_init(&dentry->d_u.d_alias);
spin_unlock(&dentry->d_lock);
spin_unlock(&inode->i_lock);
if (!inode->i_nlink)
fsnotify_inoderemove(inode);
if (dentry->d_op && dentry->d_op->d_iput)
dentry->d_op->d_iput(dentry, inode);
else
iput(inode);
} else {
spin_unlock(&dentry->d_lock);
}
}
/*
* Release the dentry's inode, using the filesystem
* d_iput() operation if defined. dentry remains in-use.
*/ */
static void dentry_unlink_inode(struct dentry * dentry) static void dentry_unlink_inode(struct dentry * dentry)
__releases(dentry->d_lock) __releases(dentry->d_lock)
__releases(dentry->d_inode->i_lock) __releases(dentry->d_inode->i_lock)
{ {
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
bool hashed = !d_unhashed(dentry);
raw_write_seqcount_begin(&dentry->d_seq); if (hashed)
raw_write_seqcount_begin(&dentry->d_seq);
__d_clear_type_and_inode(dentry); __d_clear_type_and_inode(dentry);
hlist_del_init(&dentry->d_u.d_alias); hlist_del_init(&dentry->d_u.d_alias);
raw_write_seqcount_end(&dentry->d_seq); if (hashed)
raw_write_seqcount_end(&dentry->d_seq);
spin_unlock(&dentry->d_lock); spin_unlock(&dentry->d_lock);
spin_unlock(&inode->i_lock); spin_unlock(&inode->i_lock);
if (!inode->i_nlink) if (!inode->i_nlink)
@ -572,12 +549,10 @@ static void __dentry_kill(struct dentry *dentry)
dentry_unlist(dentry, parent); dentry_unlist(dentry, parent);
if (parent) if (parent)
spin_unlock(&parent->d_lock); spin_unlock(&parent->d_lock);
dentry_iput(dentry); if (dentry->d_inode)
/* dentry_unlink_inode(dentry);
* dentry_iput drops the locks, at which point nobody (except else
* transient RCU lookups) can reach this dentry. spin_unlock(&dentry->d_lock);
*/
BUG_ON(dentry->d_lockref.count > 0);
this_cpu_dec(nr_dentry); this_cpu_dec(nr_dentry);
if (dentry->d_op && dentry->d_op->d_release) if (dentry->d_op && dentry->d_op->d_release)
dentry->d_op->d_release(dentry); dentry->d_op->d_release(dentry);