diff options
Diffstat (limited to 'fs/dcache.c')
| -rw-r--r-- | fs/dcache.c | 24 | 
1 files changed, 13 insertions, 11 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index aac41adf4743..c663c602f9ef 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -344,7 +344,7 @@ static void dentry_free(struct dentry *dentry)  		}  	}  	/* if dentry was never visible to RCU, immediate free is OK */ -	if (!(dentry->d_flags & DCACHE_RCUACCESS)) +	if (dentry->d_flags & DCACHE_NORCU)  		__d_free(&dentry->d_u.d_rcu);  	else  		call_rcu(&dentry->d_u.d_rcu, __d_free); @@ -1701,7 +1701,6 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)  	struct dentry *dentry = __d_alloc(parent->d_sb, name);  	if (!dentry)  		return NULL; -	dentry->d_flags |= DCACHE_RCUACCESS;  	spin_lock(&parent->d_lock);  	/*  	 * don't need child lock because it is not subject @@ -1726,7 +1725,7 @@ struct dentry *d_alloc_cursor(struct dentry * parent)  {  	struct dentry *dentry = d_alloc_anon(parent->d_sb);  	if (dentry) { -		dentry->d_flags |= DCACHE_RCUACCESS | DCACHE_DENTRY_CURSOR; +		dentry->d_flags |= DCACHE_DENTRY_CURSOR;  		dentry->d_parent = dget(parent);  	}  	return dentry; @@ -1739,10 +1738,17 @@ struct dentry *d_alloc_cursor(struct dentry * parent)   *   * For a filesystem that just pins its dentries in memory and never   * performs lookups at all, return an unhashed IS_ROOT dentry. + * This is used for pipes, sockets et.al. - the stuff that should + * never be anyone's children or parents.  Unlike all other + * dentries, these will not have RCU delay between dropping the + * last reference and freeing them.   */  struct dentry *d_alloc_pseudo(struct super_block *sb, const struct qstr *name)  { -	return __d_alloc(sb, name); +	struct dentry *dentry = __d_alloc(sb, name); +	if (likely(dentry)) +		dentry->d_flags |= DCACHE_NORCU; +	return dentry;  }  EXPORT_SYMBOL(d_alloc_pseudo); @@ -1911,12 +1917,10 @@ struct dentry *d_make_root(struct inode *root_inode)  	if (root_inode) {  		res = d_alloc_anon(root_inode->i_sb); -		if (res) { -			res->d_flags |= DCACHE_RCUACCESS; +		if (res)  			d_instantiate(res, root_inode); -		} else { +		else  			iput(root_inode); -		}  	}  	return res;  } @@ -2781,9 +2785,7 @@ static void __d_move(struct dentry *dentry, struct dentry *target,  		copy_name(dentry, target);  		target->d_hash.pprev = NULL;  		dentry->d_parent->d_lockref.count++; -		if (dentry == old_parent) -			dentry->d_flags |= DCACHE_RCUACCESS; -		else +		if (dentry != old_parent) /* wasn't IS_ROOT */  			WARN_ON(!--old_parent->d_lockref.count);  	} else {  		target->d_parent = old_parent;  | 
