aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2014-07-23 09:15:34 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2014-08-07 14:40:09 -0400
commit37456771c58be10dd813fb4510035d0d67a969aa (patch)
tree4532039773a41c234ed5f4029b7c22a3c4c7a6e0 /mm
parent3b69ff51d087d265aa4af3a532fc4f20bf33e718 (diff)
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: Miklos Szeredi <mszeredi@suse.cz> Acked-by: Hugh Dickins <hughd@google.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'mm')
-rw-r--r--mm/shmem.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/mm/shmem.c b/mm/shmem.c
index fe959181f995..0f018002dd64 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2048,6 +2048,28 @@ static int shmem_rmdir(struct inode *dir, struct dentry *dentry)
2048 return shmem_unlink(dir, dentry); 2048 return shmem_unlink(dir, dentry);
2049} 2049}
2050 2050
2051static int shmem_exchange(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry)
2052{
2053 bool old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
2054 bool new_is_dir = S_ISDIR(new_dentry->d_inode->i_mode);
2055
2056 if (old_dir != new_dir && old_is_dir != new_is_dir) {
2057 if (old_is_dir) {
2058 drop_nlink(old_dir);
2059 inc_nlink(new_dir);
2060 } else {
2061 drop_nlink(new_dir);
2062 inc_nlink(old_dir);
2063 }
2064 }
2065 old_dir->i_ctime = old_dir->i_mtime =
2066 new_dir->i_ctime = new_dir->i_mtime =
2067 old_dentry->d_inode->i_ctime =
2068 new_dentry->d_inode->i_ctime = CURRENT_TIME;
2069
2070 return 0;
2071}
2072
2051/* 2073/*
2052 * The VFS layer already does all the dentry stuff for rename, 2074 * The VFS layer already does all the dentry stuff for rename,
2053 * we just have to decrement the usage count for the target if 2075 * 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
2059 struct inode *inode = old_dentry->d_inode; 2081 struct inode *inode = old_dentry->d_inode;
2060 int they_are_dirs = S_ISDIR(inode->i_mode); 2082 int they_are_dirs = S_ISDIR(inode->i_mode);
2061 2083
2062 if (flags & ~(RENAME_NOREPLACE)) 2084 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
2063 return -EINVAL; 2085 return -EINVAL;
2064 2086
2087 if (flags & RENAME_EXCHANGE)
2088 return shmem_exchange(old_dir, old_dentry, new_dir, new_dentry);
2089
2065 if (!simple_empty(new_dentry)) 2090 if (!simple_empty(new_dentry))
2066 return -ENOTEMPTY; 2091 return -ENOTEMPTY;
2067 2092