diff options
Diffstat (limited to 'fs/pnode.c')
| -rw-r--r-- | fs/pnode.c | 26 | 
1 files changed, 15 insertions, 11 deletions
diff --git a/fs/pnode.c b/fs/pnode.c index c7221bb19801..88396df725b4 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -220,14 +220,14 @@ static struct mount *get_source(struct mount *dest,   * @tree_list : list of heads of trees to be attached.   */  int propagate_mnt(struct mount *dest_mnt, struct mountpoint *dest_mp, -		    struct mount *source_mnt, struct list_head *tree_list) +		    struct mount *source_mnt, struct hlist_head *tree_list)  {  	struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns;  	struct mount *m, *child;  	int ret = 0;  	struct mount *prev_dest_mnt = dest_mnt;  	struct mount *prev_src_mnt  = source_mnt; -	LIST_HEAD(tmp_list); +	HLIST_HEAD(tmp_list);  	for (m = propagation_next(dest_mnt, dest_mnt); m;  			m = propagation_next(m, dest_mnt)) { @@ -246,27 +246,29 @@ int propagate_mnt(struct mount *dest_mnt, struct mountpoint *dest_mp,  		child = copy_tree(source, source->mnt.mnt_root, type);  		if (IS_ERR(child)) {  			ret = PTR_ERR(child); -			list_splice(tree_list, tmp_list.prev); +			tmp_list = *tree_list; +			tmp_list.first->pprev = &tmp_list.first; +			INIT_HLIST_HEAD(tree_list);  			goto out;  		}  		if (is_subdir(dest_mp->m_dentry, m->mnt.mnt_root)) {  			mnt_set_mountpoint(m, dest_mp, child); -			list_add_tail(&child->mnt_hash, tree_list); +			hlist_add_head(&child->mnt_hash, tree_list);  		} else {  			/*  			 * This can happen if the parent mount was bind mounted  			 * on some subdirectory of a shared/slave mount.  			 */ -			list_add_tail(&child->mnt_hash, &tmp_list); +			hlist_add_head(&child->mnt_hash, &tmp_list);  		}  		prev_dest_mnt = m;  		prev_src_mnt  = child;  	}  out:  	lock_mount_hash(); -	while (!list_empty(&tmp_list)) { -		child = list_first_entry(&tmp_list, struct mount, mnt_hash); +	while (!hlist_empty(&tmp_list)) { +		child = hlist_entry(tmp_list.first, struct mount, mnt_hash);  		umount_tree(child, 0);  	}  	unlock_mount_hash(); @@ -338,8 +340,10 @@ static void __propagate_umount(struct mount *mnt)  		 * umount the child only if the child has no  		 * other children  		 */ -		if (child && list_empty(&child->mnt_mounts)) -			list_move_tail(&child->mnt_hash, &mnt->mnt_hash); +		if (child && list_empty(&child->mnt_mounts)) { +			hlist_del_init_rcu(&child->mnt_hash); +			hlist_add_before_rcu(&child->mnt_hash, &mnt->mnt_hash); +		}  	}  } @@ -350,11 +354,11 @@ static void __propagate_umount(struct mount *mnt)   *   * vfsmount lock must be held for write   */ -int propagate_umount(struct list_head *list) +int propagate_umount(struct hlist_head *list)  {  	struct mount *mnt; -	list_for_each_entry(mnt, list, mnt_hash) +	hlist_for_each_entry(mnt, list, mnt_hash)  		__propagate_umount(mnt);  	return 0;  }  |