Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 37456771 authored by Miklos Szeredi's avatar Miklos Szeredi Committed by Al Viro
Browse files

shmem: support RENAME_EXCHANGE



This is really simple in tmpfs since the VFS already takes care of
shuffling the dentries.  Just adjust nlink on parent directories and touch
c & mtimes.

Signed-off-by: default avatarMiklos Szeredi <mszeredi@suse.cz>
Acked-by: default avatarHugh Dickins <hughd@google.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 3b69ff51
Loading
Loading
Loading
Loading
+26 −1
Original line number Original line Diff line number Diff line
@@ -2048,6 +2048,28 @@ static int shmem_rmdir(struct inode *dir, struct dentry *dentry)
	return shmem_unlink(dir, dentry);
	return shmem_unlink(dir, dentry);
}
}


static int shmem_exchange(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry)
{
	bool old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
	bool new_is_dir = S_ISDIR(new_dentry->d_inode->i_mode);

	if (old_dir != new_dir && old_is_dir != new_is_dir) {
		if (old_is_dir) {
			drop_nlink(old_dir);
			inc_nlink(new_dir);
		} else {
			drop_nlink(new_dir);
			inc_nlink(old_dir);
		}
	}
	old_dir->i_ctime = old_dir->i_mtime =
	new_dir->i_ctime = new_dir->i_mtime =
	old_dentry->d_inode->i_ctime =
	new_dentry->d_inode->i_ctime = CURRENT_TIME;

	return 0;
}

/*
/*
 * The VFS layer already does all the dentry stuff for rename,
 * The VFS layer already does all the dentry stuff for rename,
 * we just have to decrement the usage count for the target if
 * we just have to decrement the usage count for the target if
@@ -2059,9 +2081,12 @@ static int shmem_rename2(struct inode *old_dir, struct dentry *old_dentry, struc
	struct inode *inode = old_dentry->d_inode;
	struct inode *inode = old_dentry->d_inode;
	int they_are_dirs = S_ISDIR(inode->i_mode);
	int they_are_dirs = S_ISDIR(inode->i_mode);


	if (flags & ~(RENAME_NOREPLACE))
	if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
		return -EINVAL;
		return -EINVAL;


	if (flags & RENAME_EXCHANGE)
		return shmem_exchange(old_dir, old_dentry, new_dir, new_dentry);

	if (!simple_empty(new_dentry))
	if (!simple_empty(new_dentry))
		return -ENOTEMPTY;
		return -ENOTEMPTY;