linux-next: manual merge of the userns tree with Linus' tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Eric,

Today's linux-next merge of the userns tree got a conflict in fs/namei.c
between commits from Linus' tree and commits 3dd905eaa258 ("vfs: Don't
allow overwriting mounts in the current mount namespace") and
f43d102a391d ("vfs: Lazily remove mounts on unlinked files and
directories") from the userns tree.

I fixed it up (I used the conflict resolution that you sent to Linus -
see below) and can carry the fix as necessary (no action is required).

-- 
Cheers,
Stephen Rothwell                    sfr@xxxxxxxxxxxxxxxx

diff --cc fs/namei.c
index 88339f59efb5,384fcc6a5606..000000000000
--- a/fs/namei.c
+++ b/fs/namei.c
@@@ -4082,33 -4045,17 +4085,33 @@@ int vfs_rename(struct inode *old_dir, s
  	if (error)
  		return error;
  
 +	old_name = fsnotify_oldname_init(old_dentry->d_name.name);
  	dget(new_dentry);
 -	lock_two_nondirectories(source, target);
 +	if (!is_dir || (flags & RENAME_EXCHANGE))
 +		lock_two_nondirectories(source, target);
 +	else if (target)
 +		mutex_lock(&target->i_mutex);
  
  	error = -EBUSY;
- 	if (d_mountpoint(old_dentry) || d_mountpoint(new_dentry))
+ 	if (is_local_mountpoint(old_dentry) || is_local_mountpoint(new_dentry))
  		goto out;
  
 -	error = try_break_deleg(source, delegated_inode);
 -	if (error)
 -		goto out;
 -	if (target) {
 +	if (max_links && new_dir != old_dir) {
 +		error = -EMLINK;
 +		if (is_dir && !new_is_dir && new_dir->i_nlink >= max_links)
 +			goto out;
 +		if ((flags & RENAME_EXCHANGE) && !is_dir && new_is_dir &&
 +		    old_dir->i_nlink >= max_links)
 +			goto out;
 +	}
 +	if (is_dir && !(flags & RENAME_EXCHANGE) && target)
 +		shrink_dcache_parent(new_dentry);
 +	if (!is_dir) {
 +		error = try_break_deleg(source, delegated_inode);
 +		if (error)
 +			goto out;
 +	}
 +	if (target && !new_is_dir) {
  		error = try_break_deleg(target, delegated_inode);
  		if (error)
  			goto out;
@@@ -4123,31 -4064,73 +4126,32 @@@
  	if (error)
  		goto out;
  
 -	if (target) {
 +	if (!(flags & RENAME_EXCHANGE) && target) {
 +		if (is_dir)
 +			target->i_flags |= S_DEAD;
  		dont_mount(new_dentry);
+ 		detach_mounts(new_dentry);
  	}
 -	if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
 -		d_move(old_dentry, new_dentry);
 +	if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) {
 +		if (!(flags & RENAME_EXCHANGE))
 +			d_move(old_dentry, new_dentry);
 +		else
 +			d_exchange(old_dentry, new_dentry);
 +	}
  out:
 -	unlock_two_nondirectories(source, target);
 +	if (!is_dir || (flags & RENAME_EXCHANGE))
 +		unlock_two_nondirectories(source, target);
 +	else if (target)
 +		mutex_unlock(&target->i_mutex);
  	dput(new_dentry);
 -	return error;
 -}
 -
 -/**
 - * vfs_rename - rename a filesystem object
 - * @old_dir:	parent of source
 - * @old_dentry:	source
 - * @new_dir:	parent of destination
 - * @new_dentry:	destination
 - * @delegated_inode: returns an inode needing a delegation break
 - *
 - * The caller must hold multiple mutexes--see lock_rename()).
 - *
 - * If vfs_rename discovers a delegation in need of breaking at either
 - * the source or destination, it will return -EWOULDBLOCK and return a
 - * reference to the inode in delegated_inode.  The caller should then
 - * break the delegation and retry.  Because breaking a delegation may
 - * take a long time, the caller should drop all locks before doing
 - * so.
 - *
 - * Alternatively, a caller may pass NULL for delegated_inode.  This may
 - * be appropriate for callers that expect the underlying filesystem not
 - * to be NFS exported.
 - */
 -int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 -	       struct inode *new_dir, struct dentry *new_dentry,
 -	       struct inode **delegated_inode)
 -{
 -	int error;
 -	int is_dir = d_is_directory(old_dentry) || d_is_autodir(old_dentry);
 -	const unsigned char *old_name;
 -
 -	if (old_dentry->d_inode == new_dentry->d_inode)
 - 		return 0;
 - 
 -	error = may_delete(old_dir, old_dentry, is_dir);
 -	if (error)
 -		return error;
 -
 -	if (!new_dentry->d_inode)
 -		error = may_create(new_dir, new_dentry);
 -	else
 -		error = may_delete(new_dir, new_dentry, is_dir);
 -	if (error)
 -		return error;
 -
 -	if (!old_dir->i_op->rename)
 -		return -EPERM;
 -
 -	old_name = fsnotify_oldname_init(old_dentry->d_name.name);
 -
 -	if (is_dir)
 -		error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
 -	else
 -		error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,delegated_inode);
 -	if (!error)
 +	if (!error) {
  		fsnotify_move(old_dir, new_dir, old_name, is_dir,
 -			      new_dentry->d_inode, old_dentry);
 +			      !(flags & RENAME_EXCHANGE) ? target : NULL, old_dentry);
 +		if (flags & RENAME_EXCHANGE) {
 +			fsnotify_move(new_dir, old_dir, old_dentry->d_name.name,
 +				      new_is_dir, NULL, new_dentry);
 +		}
 +	}
  	fsnotify_oldname_free(old_name);
  
  	return error;

Attachment: pgp8GkMn_Mhyl.pgp
Description: PGP signature


[Index of Archives]     [Linux Kernel]     [Linux USB Development]     [Yosemite News]     [Linux SCSI]

  Powered by Linux