diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2014-07-23 09:15:34 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-08-07 14:40:09 -0400 |
commit | 37456771c58be10dd813fb4510035d0d67a969aa (patch) | |
tree | 4532039773a41c234ed5f4029b7c22a3c4c7a6e0 /mm | |
parent | 3b69ff51d087d265aa4af3a532fc4f20bf33e718 (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.c | 27 |
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 | ||
2051 | static 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 | ||