diff options
Diffstat (limited to 'fs/dcache.c')
| -rw-r--r-- | fs/dcache.c | 44 | 
1 files changed, 24 insertions, 20 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 40469044088d..8086636bf796 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -218,7 +218,7 @@ static void __d_free(struct rcu_head *head)  {  	struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); -	WARN_ON(!list_empty(&dentry->d_alias)); +	WARN_ON(!hlist_unhashed(&dentry->d_alias));  	if (dname_external(dentry))  		kfree(dentry->d_name.name);  	kmem_cache_free(dentry_cache, dentry);  @@ -267,7 +267,7 @@ static void dentry_iput(struct dentry * dentry)  	struct inode *inode = dentry->d_inode;  	if (inode) {  		dentry->d_inode = NULL; -		list_del_init(&dentry->d_alias); +		hlist_del_init(&dentry->d_alias);  		spin_unlock(&dentry->d_lock);  		spin_unlock(&inode->i_lock);  		if (!inode->i_nlink) @@ -291,7 +291,7 @@ static void dentry_unlink_inode(struct dentry * dentry)  {  	struct inode *inode = dentry->d_inode;  	dentry->d_inode = NULL; -	list_del_init(&dentry->d_alias); +	hlist_del_init(&dentry->d_alias);  	dentry_rcuwalk_barrier(dentry);  	spin_unlock(&dentry->d_lock);  	spin_unlock(&inode->i_lock); @@ -699,10 +699,11 @@ EXPORT_SYMBOL(dget_parent);  static struct dentry *__d_find_alias(struct inode *inode, int want_discon)  {  	struct dentry *alias, *discon_alias; +	struct hlist_node *p;  again:  	discon_alias = NULL; -	list_for_each_entry(alias, &inode->i_dentry, d_alias) { +	hlist_for_each_entry(alias, p, &inode->i_dentry, d_alias) {  		spin_lock(&alias->d_lock);   		if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) {  			if (IS_ROOT(alias) && @@ -737,7 +738,7 @@ struct dentry *d_find_alias(struct inode *inode)  {  	struct dentry *de = NULL; -	if (!list_empty(&inode->i_dentry)) { +	if (!hlist_empty(&inode->i_dentry)) {  		spin_lock(&inode->i_lock);  		de = __d_find_alias(inode, 0);  		spin_unlock(&inode->i_lock); @@ -753,9 +754,10 @@ EXPORT_SYMBOL(d_find_alias);  void d_prune_aliases(struct inode *inode)  {  	struct dentry *dentry; +	struct hlist_node *p;  restart:  	spin_lock(&inode->i_lock); -	list_for_each_entry(dentry, &inode->i_dentry, d_alias) { +	hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) {  		spin_lock(&dentry->d_lock);  		if (!dentry->d_count) {  			__dget_dlock(dentry); @@ -977,7 +979,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)  			inode = dentry->d_inode;  			if (inode) {  				dentry->d_inode = NULL; -				list_del_init(&dentry->d_alias); +				hlist_del_init(&dentry->d_alias);  				if (dentry->d_op && dentry->d_op->d_iput)  					dentry->d_op->d_iput(dentry, inode);  				else @@ -1312,7 +1314,7 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)  	INIT_HLIST_BL_NODE(&dentry->d_hash);  	INIT_LIST_HEAD(&dentry->d_lru);  	INIT_LIST_HEAD(&dentry->d_subdirs); -	INIT_LIST_HEAD(&dentry->d_alias); +	INIT_HLIST_NODE(&dentry->d_alias);  	INIT_LIST_HEAD(&dentry->d_u.d_child);  	d_set_d_op(dentry, dentry->d_sb->s_d_op); @@ -1400,7 +1402,7 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode)  	if (inode) {  		if (unlikely(IS_AUTOMOUNT(inode)))  			dentry->d_flags |= DCACHE_NEED_AUTOMOUNT; -		list_add(&dentry->d_alias, &inode->i_dentry); +		hlist_add_head(&dentry->d_alias, &inode->i_dentry);  	}  	dentry->d_inode = inode;  	dentry_rcuwalk_barrier(dentry); @@ -1425,7 +1427,7 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode)  void d_instantiate(struct dentry *entry, struct inode * inode)  { -	BUG_ON(!list_empty(&entry->d_alias)); +	BUG_ON(!hlist_unhashed(&entry->d_alias));  	if (inode)  		spin_lock(&inode->i_lock);  	__d_instantiate(entry, inode); @@ -1458,13 +1460,14 @@ static struct dentry *__d_instantiate_unique(struct dentry *entry,  	int len = entry->d_name.len;  	const char *name = entry->d_name.name;  	unsigned int hash = entry->d_name.hash; +	struct hlist_node *p;  	if (!inode) {  		__d_instantiate(entry, NULL);  		return NULL;  	} -	list_for_each_entry(alias, &inode->i_dentry, d_alias) { +	hlist_for_each_entry(alias, p, &inode->i_dentry, d_alias) {  		/*  		 * Don't need alias->d_lock here, because aliases with  		 * d_parent == entry->d_parent are not subject to name or @@ -1490,7 +1493,7 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode)  {  	struct dentry *result; -	BUG_ON(!list_empty(&entry->d_alias)); +	BUG_ON(!hlist_unhashed(&entry->d_alias));  	if (inode)  		spin_lock(&inode->i_lock); @@ -1531,9 +1534,9 @@ static struct dentry * __d_find_any_alias(struct inode *inode)  {  	struct dentry *alias; -	if (list_empty(&inode->i_dentry)) +	if (hlist_empty(&inode->i_dentry))  		return NULL; -	alias = list_first_entry(&inode->i_dentry, struct dentry, d_alias); +	alias = hlist_entry(inode->i_dentry.first, struct dentry, d_alias);  	__dget(alias);  	return alias;  } @@ -1607,7 +1610,7 @@ struct dentry *d_obtain_alias(struct inode *inode)  	spin_lock(&tmp->d_lock);  	tmp->d_inode = inode;  	tmp->d_flags |= DCACHE_DISCONNECTED; -	list_add(&tmp->d_alias, &inode->i_dentry); +	hlist_add_head(&tmp->d_alias, &inode->i_dentry);  	hlist_bl_lock(&tmp->d_sb->s_anon);  	hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon);  	hlist_bl_unlock(&tmp->d_sb->s_anon); @@ -2384,14 +2387,13 @@ static struct dentry *__d_unalias(struct inode *inode,  		struct dentry *dentry, struct dentry *alias)  {  	struct mutex *m1 = NULL, *m2 = NULL; -	struct dentry *ret; +	struct dentry *ret = ERR_PTR(-EBUSY);  	/* If alias and dentry share a parent, then no extra locks required */  	if (alias->d_parent == dentry->d_parent)  		goto out_unalias;  	/* See lock_rename() */ -	ret = ERR_PTR(-EBUSY);  	if (!mutex_trylock(&dentry->d_sb->s_vfs_rename_mutex))  		goto out_err;  	m1 = &dentry->d_sb->s_vfs_rename_mutex; @@ -2399,8 +2401,10 @@ static struct dentry *__d_unalias(struct inode *inode,  		goto out_err;  	m2 = &alias->d_parent->d_inode->i_mutex;  out_unalias: -	__d_move(alias, dentry); -	ret = alias; +	if (likely(!d_mountpoint(alias))) { +		__d_move(alias, dentry); +		ret = alias; +	}  out_err:  	spin_unlock(&inode->i_lock);  	if (m2) @@ -2622,7 +2626,7 @@ global_root:  	if (!slash)  		error = prepend(buffer, buflen, "/", 1);  	if (!error) -		error = real_mount(vfsmnt)->mnt_ns ? 1 : 2; +		error = is_mounted(vfsmnt) ? 1 : 2;  	goto out;  }  | 
