summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2016-09-27 05:03:57 -0400
committerMiklos Szeredi <mszeredi@redhat.com>2016-09-27 05:03:57 -0400
commitf03b8ad8d38634d13e802165cc15917481b47835 (patch)
tree4dc9c060684f242d1e6c07d28d1ff625db63fd6c
parent9a232de4999666b2e8ea6775b2b0e3e4feb09b7a (diff)
fs: support RENAME_NOREPLACE for local filesystems
This is trivial to do: - add flags argument to foo_rename() - check if flags doesn't have any other than RENAME_NOREPLACE - assign foo_rename() to .rename2 instead of .rename Filesystems converted: affs, bfs, exofs, ext2, hfs, hfsplus, jffs2, jfs, logfs, minix, msdos, nilfs2, omfs, reiserfs, sysvfs, ubifs, udf, ufs, vfat. Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Acked-by: Boaz Harrosh <ooo@electrozaur.com> Acked-by: Richard Weinberger <richard@nod.at> Acked-by: Bob Copeland <me@bobcopeland.com> Acked-by: Jan Kara <jack@suse.cz> Cc: Theodore Ts'o <tytso@mit.edu> Cc: Jaegeuk Kim <jaegeuk@kernel.org> Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> Cc: Mikulas Patocka <mpatocka@redhat.com> Cc: David Woodhouse <dwmw2@infradead.org> Cc: Dave Kleikamp <shaggy@kernel.org> Cc: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> Cc: Christoph Hellwig <hch@infradead.org>
-rw-r--r--fs/affs/affs.h3
-rw-r--r--fs/affs/dir.c2
-rw-r--r--fs/affs/namei.c6
-rw-r--r--fs/bfs/dir.c8
-rw-r--r--fs/exofs/namei.c8
-rw-r--r--fs/ext2/namei.c8
-rw-r--r--fs/fat/namei_msdos.c8
-rw-r--r--fs/fat/namei_vfat.c8
-rw-r--r--fs/hfs/dir.c8
-rw-r--r--fs/hfsplus/dir.c8
-rw-r--r--fs/hpfs/namei.c8
-rw-r--r--fs/jffs2/dir.c11
-rw-r--r--fs/jfs/namei.c7
-rw-r--r--fs/logfs/dir.c8
-rw-r--r--fs/minix/namei.c8
-rw-r--r--fs/nilfs2/namei.c8
-rw-r--r--fs/omfs/dir.c8
-rw-r--r--fs/reiserfs/namei.c8
-rw-r--r--fs/sysv/namei.c8
-rw-r--r--fs/ubifs/dir.c8
-rw-r--r--fs/udf/namei.c8
-rw-r--r--fs/ufs/namei.c8
22 files changed, 123 insertions, 42 deletions
diff --git a/fs/affs/affs.h b/fs/affs/affs.h
index cc2b2efc9211..2f088773f1c0 100644
--- a/fs/affs/affs.h
+++ b/fs/affs/affs.h
@@ -173,7 +173,8 @@ extern int affs_link(struct dentry *olddentry, struct inode *dir,
173extern int affs_symlink(struct inode *dir, struct dentry *dentry, 173extern int affs_symlink(struct inode *dir, struct dentry *dentry,
174 const char *symname); 174 const char *symname);
175extern int affs_rename(struct inode *old_dir, struct dentry *old_dentry, 175extern int affs_rename(struct inode *old_dir, struct dentry *old_dentry,
176 struct inode *new_dir, struct dentry *new_dentry); 176 struct inode *new_dir, struct dentry *new_dentry,
177 unsigned int flags);
177 178
178/* inode.c */ 179/* inode.c */
179 180
diff --git a/fs/affs/dir.c b/fs/affs/dir.c
index f1e7294381c5..8f127c239472 100644
--- a/fs/affs/dir.c
+++ b/fs/affs/dir.c
@@ -35,7 +35,7 @@ const struct inode_operations affs_dir_inode_operations = {
35 .symlink = affs_symlink, 35 .symlink = affs_symlink,
36 .mkdir = affs_mkdir, 36 .mkdir = affs_mkdir,
37 .rmdir = affs_rmdir, 37 .rmdir = affs_rmdir,
38 .rename = affs_rename, 38 .rename2 = affs_rename,
39 .setattr = affs_notify_change, 39 .setattr = affs_notify_change,
40}; 40};
41 41
diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index a2d68f828d53..29186d29a3b6 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -414,12 +414,16 @@ affs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
414 414
415int 415int
416affs_rename(struct inode *old_dir, struct dentry *old_dentry, 416affs_rename(struct inode *old_dir, struct dentry *old_dentry,
417 struct inode *new_dir, struct dentry *new_dentry) 417 struct inode *new_dir, struct dentry *new_dentry,
418 unsigned int flags)
418{ 419{
419 struct super_block *sb = old_dir->i_sb; 420 struct super_block *sb = old_dir->i_sb;
420 struct buffer_head *bh = NULL; 421 struct buffer_head *bh = NULL;
421 int retval; 422 int retval;
422 423
424 if (flags & ~RENAME_NOREPLACE)
425 return -EINVAL;
426
423 pr_debug("%s(old=%lu,\"%pd\" to new=%lu,\"%pd\")\n", __func__, 427 pr_debug("%s(old=%lu,\"%pd\" to new=%lu,\"%pd\")\n", __func__,
424 old_dir->i_ino, old_dentry, new_dir->i_ino, new_dentry); 428 old_dir->i_ino, old_dentry, new_dir->i_ino, new_dentry);
425 429
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c
index 34a5bc2f1290..9d5f875e85d0 100644
--- a/fs/bfs/dir.c
+++ b/fs/bfs/dir.c
@@ -207,7 +207,8 @@ out_brelse:
207} 207}
208 208
209static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry, 209static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry,
210 struct inode *new_dir, struct dentry *new_dentry) 210 struct inode *new_dir, struct dentry *new_dentry,
211 unsigned int flags)
211{ 212{
212 struct inode *old_inode, *new_inode; 213 struct inode *old_inode, *new_inode;
213 struct buffer_head *old_bh, *new_bh; 214 struct buffer_head *old_bh, *new_bh;
@@ -215,6 +216,9 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry,
215 struct bfs_sb_info *info; 216 struct bfs_sb_info *info;
216 int error = -ENOENT; 217 int error = -ENOENT;
217 218
219 if (flags & ~RENAME_NOREPLACE)
220 return -EINVAL;
221
218 old_bh = new_bh = NULL; 222 old_bh = new_bh = NULL;
219 old_inode = d_inode(old_dentry); 223 old_inode = d_inode(old_dentry);
220 if (S_ISDIR(old_inode->i_mode)) 224 if (S_ISDIR(old_inode->i_mode))
@@ -270,7 +274,7 @@ const struct inode_operations bfs_dir_inops = {
270 .lookup = bfs_lookup, 274 .lookup = bfs_lookup,
271 .link = bfs_link, 275 .link = bfs_link,
272 .unlink = bfs_unlink, 276 .unlink = bfs_unlink,
273 .rename = bfs_rename, 277 .rename2 = bfs_rename,
274}; 278};
275 279
276static int bfs_add_entry(struct inode *dir, const unsigned char *name, 280static int bfs_add_entry(struct inode *dir, const unsigned char *name,
diff --git a/fs/exofs/namei.c b/fs/exofs/namei.c
index 622a686bb08b..ddf343259f13 100644
--- a/fs/exofs/namei.c
+++ b/fs/exofs/namei.c
@@ -227,7 +227,8 @@ static int exofs_rmdir(struct inode *dir, struct dentry *dentry)
227} 227}
228 228
229static int exofs_rename(struct inode *old_dir, struct dentry *old_dentry, 229static int exofs_rename(struct inode *old_dir, struct dentry *old_dentry,
230 struct inode *new_dir, struct dentry *new_dentry) 230 struct inode *new_dir, struct dentry *new_dentry,
231 unsigned int flags)
231{ 232{
232 struct inode *old_inode = d_inode(old_dentry); 233 struct inode *old_inode = d_inode(old_dentry);
233 struct inode *new_inode = d_inode(new_dentry); 234 struct inode *new_inode = d_inode(new_dentry);
@@ -237,6 +238,9 @@ static int exofs_rename(struct inode *old_dir, struct dentry *old_dentry,
237 struct exofs_dir_entry *old_de; 238 struct exofs_dir_entry *old_de;
238 int err = -ENOENT; 239 int err = -ENOENT;
239 240
241 if (flags & ~RENAME_NOREPLACE)
242 return -EINVAL;
243
240 old_de = exofs_find_entry(old_dir, old_dentry, &old_page); 244 old_de = exofs_find_entry(old_dir, old_dentry, &old_page);
241 if (!old_de) 245 if (!old_de)
242 goto out; 246 goto out;
@@ -310,7 +314,7 @@ const struct inode_operations exofs_dir_inode_operations = {
310 .mkdir = exofs_mkdir, 314 .mkdir = exofs_mkdir,
311 .rmdir = exofs_rmdir, 315 .rmdir = exofs_rmdir,
312 .mknod = exofs_mknod, 316 .mknod = exofs_mknod,
313 .rename = exofs_rename, 317 .rename2 = exofs_rename,
314 .setattr = exofs_setattr, 318 .setattr = exofs_setattr,
315}; 319};
316 320
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index d446203127fc..38fac85ff786 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -328,7 +328,8 @@ static int ext2_rmdir (struct inode * dir, struct dentry *dentry)
328} 328}
329 329
330static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry, 330static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
331 struct inode * new_dir, struct dentry * new_dentry ) 331 struct inode * new_dir, struct dentry * new_dentry,
332 unsigned int flags)
332{ 333{
333 struct inode * old_inode = d_inode(old_dentry); 334 struct inode * old_inode = d_inode(old_dentry);
334 struct inode * new_inode = d_inode(new_dentry); 335 struct inode * new_inode = d_inode(new_dentry);
@@ -338,6 +339,9 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
338 struct ext2_dir_entry_2 * old_de; 339 struct ext2_dir_entry_2 * old_de;
339 int err; 340 int err;
340 341
342 if (flags & ~RENAME_NOREPLACE)
343 return -EINVAL;
344
341 err = dquot_initialize(old_dir); 345 err = dquot_initialize(old_dir);
342 if (err) 346 if (err)
343 goto out; 347 goto out;
@@ -426,7 +430,7 @@ const struct inode_operations ext2_dir_inode_operations = {
426 .mkdir = ext2_mkdir, 430 .mkdir = ext2_mkdir,
427 .rmdir = ext2_rmdir, 431 .rmdir = ext2_rmdir,
428 .mknod = ext2_mknod, 432 .mknod = ext2_mknod,
429 .rename = ext2_rename, 433 .rename2 = ext2_rename,
430#ifdef CONFIG_EXT2_FS_XATTR 434#ifdef CONFIG_EXT2_FS_XATTR
431 .setxattr = generic_setxattr, 435 .setxattr = generic_setxattr,
432 .getxattr = generic_getxattr, 436 .getxattr = generic_getxattr,
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
index 664655b2c55f..6c814699d5d5 100644
--- a/fs/fat/namei_msdos.c
+++ b/fs/fat/namei_msdos.c
@@ -596,12 +596,16 @@ error_inode:
596 596
597/***** Rename, a wrapper for rename_same_dir & rename_diff_dir */ 597/***** Rename, a wrapper for rename_same_dir & rename_diff_dir */
598static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry, 598static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry,
599 struct inode *new_dir, struct dentry *new_dentry) 599 struct inode *new_dir, struct dentry *new_dentry,
600 unsigned int flags)
600{ 601{
601 struct super_block *sb = old_dir->i_sb; 602 struct super_block *sb = old_dir->i_sb;
602 unsigned char old_msdos_name[MSDOS_NAME], new_msdos_name[MSDOS_NAME]; 603 unsigned char old_msdos_name[MSDOS_NAME], new_msdos_name[MSDOS_NAME];
603 int err, is_hid; 604 int err, is_hid;
604 605
606 if (flags & ~RENAME_NOREPLACE)
607 return -EINVAL;
608
605 mutex_lock(&MSDOS_SB(sb)->s_lock); 609 mutex_lock(&MSDOS_SB(sb)->s_lock);
606 610
607 err = msdos_format_name(old_dentry->d_name.name, 611 err = msdos_format_name(old_dentry->d_name.name,
@@ -633,7 +637,7 @@ static const struct inode_operations msdos_dir_inode_operations = {
633 .unlink = msdos_unlink, 637 .unlink = msdos_unlink,
634 .mkdir = msdos_mkdir, 638 .mkdir = msdos_mkdir,
635 .rmdir = msdos_rmdir, 639 .rmdir = msdos_rmdir,
636 .rename = msdos_rename, 640 .rename2 = msdos_rename,
637 .setattr = fat_setattr, 641 .setattr = fat_setattr,
638 .getattr = fat_getattr, 642 .getattr = fat_getattr,
639}; 643};
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index 92b7363dafa9..ce8986f3918a 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -903,7 +903,8 @@ out:
903} 903}
904 904
905static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, 905static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
906 struct inode *new_dir, struct dentry *new_dentry) 906 struct inode *new_dir, struct dentry *new_dentry,
907 unsigned int flags)
907{ 908{
908 struct buffer_head *dotdot_bh; 909 struct buffer_head *dotdot_bh;
909 struct msdos_dir_entry *dotdot_de; 910 struct msdos_dir_entry *dotdot_de;
@@ -914,6 +915,9 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
914 int err, is_dir, update_dotdot, corrupt = 0; 915 int err, is_dir, update_dotdot, corrupt = 0;
915 struct super_block *sb = old_dir->i_sb; 916 struct super_block *sb = old_dir->i_sb;
916 917
918 if (flags & ~RENAME_NOREPLACE)
919 return -EINVAL;
920
917 old_sinfo.bh = sinfo.bh = dotdot_bh = NULL; 921 old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
918 old_inode = d_inode(old_dentry); 922 old_inode = d_inode(old_dentry);
919 new_inode = d_inode(new_dentry); 923 new_inode = d_inode(new_dentry);
@@ -1036,7 +1040,7 @@ static const struct inode_operations vfat_dir_inode_operations = {
1036 .unlink = vfat_unlink, 1040 .unlink = vfat_unlink,
1037 .mkdir = vfat_mkdir, 1041 .mkdir = vfat_mkdir,
1038 .rmdir = vfat_rmdir, 1042 .rmdir = vfat_rmdir,
1039 .rename = vfat_rename, 1043 .rename2 = vfat_rename,
1040 .setattr = fat_setattr, 1044 .setattr = fat_setattr,
1041 .getattr = fat_getattr, 1045 .getattr = fat_getattr,
1042}; 1046};
diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c
index 163190ecc0d2..d5ce9fcad10f 100644
--- a/fs/hfs/dir.c
+++ b/fs/hfs/dir.c
@@ -286,10 +286,14 @@ static int hfs_remove(struct inode *dir, struct dentry *dentry)
286 * XXX: how do you handle must_be dir? 286 * XXX: how do you handle must_be dir?
287 */ 287 */
288static int hfs_rename(struct inode *old_dir, struct dentry *old_dentry, 288static int hfs_rename(struct inode *old_dir, struct dentry *old_dentry,
289 struct inode *new_dir, struct dentry *new_dentry) 289 struct inode *new_dir, struct dentry *new_dentry,
290 unsigned int flags)
290{ 291{
291 int res; 292 int res;
292 293
294 if (flags & ~RENAME_NOREPLACE)
295 return -EINVAL;
296
293 /* Unlink destination if it already exists */ 297 /* Unlink destination if it already exists */
294 if (d_really_is_positive(new_dentry)) { 298 if (d_really_is_positive(new_dentry)) {
295 res = hfs_remove(new_dir, new_dentry); 299 res = hfs_remove(new_dir, new_dentry);
@@ -320,6 +324,6 @@ const struct inode_operations hfs_dir_inode_operations = {
320 .unlink = hfs_remove, 324 .unlink = hfs_remove,
321 .mkdir = hfs_mkdir, 325 .mkdir = hfs_mkdir,
322 .rmdir = hfs_remove, 326 .rmdir = hfs_remove,
323 .rename = hfs_rename, 327 .rename2 = hfs_rename,
324 .setattr = hfs_inode_setattr, 328 .setattr = hfs_inode_setattr,
325}; 329};
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 42e128661dc1..ca64a75f12b3 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -530,10 +530,14 @@ static int hfsplus_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
530} 530}
531 531
532static int hfsplus_rename(struct inode *old_dir, struct dentry *old_dentry, 532static int hfsplus_rename(struct inode *old_dir, struct dentry *old_dentry,
533 struct inode *new_dir, struct dentry *new_dentry) 533 struct inode *new_dir, struct dentry *new_dentry,
534 unsigned int flags)
534{ 535{
535 int res; 536 int res;
536 537
538 if (flags & ~RENAME_NOREPLACE)
539 return -EINVAL;
540
537 /* Unlink destination if it already exists */ 541 /* Unlink destination if it already exists */
538 if (d_really_is_positive(new_dentry)) { 542 if (d_really_is_positive(new_dentry)) {
539 if (d_is_dir(new_dentry)) 543 if (d_is_dir(new_dentry))
@@ -561,7 +565,7 @@ const struct inode_operations hfsplus_dir_inode_operations = {
561 .rmdir = hfsplus_rmdir, 565 .rmdir = hfsplus_rmdir,
562 .symlink = hfsplus_symlink, 566 .symlink = hfsplus_symlink,
563 .mknod = hfsplus_mknod, 567 .mknod = hfsplus_mknod,
564 .rename = hfsplus_rename, 568 .rename2 = hfsplus_rename,
565 .setxattr = generic_setxattr, 569 .setxattr = generic_setxattr,
566 .getxattr = generic_getxattr, 570 .getxattr = generic_getxattr,
567 .listxattr = hfsplus_listxattr, 571 .listxattr = hfsplus_listxattr,
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c
index bb8d67e2740a..3c5c1a75569d 100644
--- a/fs/hpfs/namei.c
+++ b/fs/hpfs/namei.c
@@ -507,7 +507,8 @@ const struct address_space_operations hpfs_symlink_aops = {
507}; 507};
508 508
509static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, 509static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
510 struct inode *new_dir, struct dentry *new_dentry) 510 struct inode *new_dir, struct dentry *new_dentry,
511 unsigned int flags)
511{ 512{
512 const unsigned char *old_name = old_dentry->d_name.name; 513 const unsigned char *old_name = old_dentry->d_name.name;
513 unsigned old_len = old_dentry->d_name.len; 514 unsigned old_len = old_dentry->d_name.len;
@@ -524,6 +525,9 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
524 struct fnode *fnode; 525 struct fnode *fnode;
525 int err; 526 int err;
526 527
528 if (flags & ~RENAME_NOREPLACE)
529 return -EINVAL;
530
527 if ((err = hpfs_chk_name(new_name, &new_len))) return err; 531 if ((err = hpfs_chk_name(new_name, &new_len))) return err;
528 err = 0; 532 err = 0;
529 hpfs_adjust_length(old_name, &old_len); 533 hpfs_adjust_length(old_name, &old_len);
@@ -618,6 +622,6 @@ const struct inode_operations hpfs_dir_iops =
618 .mkdir = hpfs_mkdir, 622 .mkdir = hpfs_mkdir,
619 .rmdir = hpfs_rmdir, 623 .rmdir = hpfs_rmdir,
620 .mknod = hpfs_mknod, 624 .mknod = hpfs_mknod,
621 .rename = hpfs_rename, 625 .rename2 = hpfs_rename,
622 .setattr = hpfs_setattr, 626 .setattr = hpfs_setattr,
623}; 627};
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 30eb33ff8189..11e711b12ccf 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -35,7 +35,8 @@ static int jffs2_mkdir (struct inode *,struct dentry *,umode_t);
35static int jffs2_rmdir (struct inode *,struct dentry *); 35static int jffs2_rmdir (struct inode *,struct dentry *);
36static int jffs2_mknod (struct inode *,struct dentry *,umode_t,dev_t); 36static int jffs2_mknod (struct inode *,struct dentry *,umode_t,dev_t);
37static int jffs2_rename (struct inode *, struct dentry *, 37static int jffs2_rename (struct inode *, struct dentry *,
38 struct inode *, struct dentry *); 38 struct inode *, struct dentry *,
39 unsigned int);
39 40
40const struct file_operations jffs2_dir_operations = 41const struct file_operations jffs2_dir_operations =
41{ 42{
@@ -57,7 +58,7 @@ const struct inode_operations jffs2_dir_inode_operations =
57 .mkdir = jffs2_mkdir, 58 .mkdir = jffs2_mkdir,
58 .rmdir = jffs2_rmdir, 59 .rmdir = jffs2_rmdir,
59 .mknod = jffs2_mknod, 60 .mknod = jffs2_mknod,
60 .rename = jffs2_rename, 61 .rename2 = jffs2_rename,
61 .get_acl = jffs2_get_acl, 62 .get_acl = jffs2_get_acl,
62 .set_acl = jffs2_set_acl, 63 .set_acl = jffs2_set_acl,
63 .setattr = jffs2_setattr, 64 .setattr = jffs2_setattr,
@@ -759,7 +760,8 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, umode_t mode
759} 760}
760 761
761static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, 762static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
762 struct inode *new_dir_i, struct dentry *new_dentry) 763 struct inode *new_dir_i, struct dentry *new_dentry,
764 unsigned int flags)
763{ 765{
764 int ret; 766 int ret;
765 struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb); 767 struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb);
@@ -767,6 +769,9 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
767 uint8_t type; 769 uint8_t type;
768 uint32_t now; 770 uint32_t now;
769 771
772 if (flags & ~RENAME_NOREPLACE)
773 return -EINVAL;
774
770 /* The VFS will check for us and prevent trying to rename a 775 /* The VFS will check for us and prevent trying to rename a
771 * file over a directory and vice versa, but if it's a directory, 776 * file over a directory and vice versa, but if it's a directory,
772 * the VFS can't check whether the victim is empty. The filesystem 777 * the VFS can't check whether the victim is empty. The filesystem
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 814b0c58016c..ee1aa32f7c24 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -1078,7 +1078,8 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
1078 * FUNCTION: rename a file or directory 1078 * FUNCTION: rename a file or directory
1079 */ 1079 */
1080static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, 1080static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1081 struct inode *new_dir, struct dentry *new_dentry) 1081 struct inode *new_dir, struct dentry *new_dentry,
1082 unsigned int flags)
1082{ 1083{
1083 struct btstack btstack; 1084 struct btstack btstack;
1084 ino_t ino; 1085 ino_t ino;
@@ -1097,6 +1098,8 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1097 s64 new_size = 0; 1098 s64 new_size = 0;
1098 int commit_flag; 1099 int commit_flag;
1099 1100
1101 if (flags & ~RENAME_NOREPLACE)
1102 return -EINVAL;
1100 1103
1101 jfs_info("jfs_rename: %pd %pd", old_dentry, new_dentry); 1104 jfs_info("jfs_rename: %pd %pd", old_dentry, new_dentry);
1102 1105
@@ -1536,7 +1539,7 @@ const struct inode_operations jfs_dir_inode_operations = {
1536 .mkdir = jfs_mkdir, 1539 .mkdir = jfs_mkdir,
1537 .rmdir = jfs_rmdir, 1540 .rmdir = jfs_rmdir,
1538 .mknod = jfs_mknod, 1541 .mknod = jfs_mknod,
1539 .rename = jfs_rename, 1542 .rename2 = jfs_rename,
1540 .setxattr = generic_setxattr, 1543 .setxattr = generic_setxattr,
1541 .getxattr = generic_getxattr, 1544 .getxattr = generic_getxattr,
1542 .listxattr = jfs_listxattr, 1545 .listxattr = jfs_listxattr,
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c
index 9568064ecadf..57f2da17a905 100644
--- a/fs/logfs/dir.c
+++ b/fs/logfs/dir.c
@@ -718,8 +718,12 @@ out:
718} 718}
719 719
720static int logfs_rename(struct inode *old_dir, struct dentry *old_dentry, 720static int logfs_rename(struct inode *old_dir, struct dentry *old_dentry,
721 struct inode *new_dir, struct dentry *new_dentry) 721 struct inode *new_dir, struct dentry *new_dentry,
722 unsigned int flags)
722{ 723{
724 if (flags & ~RENAME_NOREPLACE)
725 return -EINVAL;
726
723 if (d_really_is_positive(new_dentry)) 727 if (d_really_is_positive(new_dentry))
724 return logfs_rename_target(old_dir, old_dentry, 728 return logfs_rename_target(old_dir, old_dentry,
725 new_dir, new_dentry); 729 new_dir, new_dentry);
@@ -783,7 +787,7 @@ const struct inode_operations logfs_dir_iops = {
783 .lookup = logfs_lookup, 787 .lookup = logfs_lookup,
784 .mkdir = logfs_mkdir, 788 .mkdir = logfs_mkdir,
785 .mknod = logfs_mknod, 789 .mknod = logfs_mknod,
786 .rename = logfs_rename, 790 .rename2 = logfs_rename,
787 .rmdir = logfs_rmdir, 791 .rmdir = logfs_rmdir,
788 .symlink = logfs_symlink, 792 .symlink = logfs_symlink,
789 .unlink = logfs_unlink, 793 .unlink = logfs_unlink,
diff --git a/fs/minix/namei.c b/fs/minix/namei.c
index 2887d1d95ce2..6dc210c0e3ce 100644
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -185,7 +185,8 @@ static int minix_rmdir(struct inode * dir, struct dentry *dentry)
185} 185}
186 186
187static int minix_rename(struct inode * old_dir, struct dentry *old_dentry, 187static int minix_rename(struct inode * old_dir, struct dentry *old_dentry,
188 struct inode * new_dir, struct dentry *new_dentry) 188 struct inode * new_dir, struct dentry *new_dentry,
189 unsigned int flags)
189{ 190{
190 struct inode * old_inode = d_inode(old_dentry); 191 struct inode * old_inode = d_inode(old_dentry);
191 struct inode * new_inode = d_inode(new_dentry); 192 struct inode * new_inode = d_inode(new_dentry);
@@ -195,6 +196,9 @@ static int minix_rename(struct inode * old_dir, struct dentry *old_dentry,
195 struct minix_dir_entry * old_de; 196 struct minix_dir_entry * old_de;
196 int err = -ENOENT; 197 int err = -ENOENT;
197 198
199 if (flags & ~RENAME_NOREPLACE)
200 return -EINVAL;
201
198 old_de = minix_find_entry(old_dentry, &old_page); 202 old_de = minix_find_entry(old_dentry, &old_page);
199 if (!old_de) 203 if (!old_de)
200 goto out; 204 goto out;
@@ -264,7 +268,7 @@ const struct inode_operations minix_dir_inode_operations = {
264 .mkdir = minix_mkdir, 268 .mkdir = minix_mkdir,
265 .rmdir = minix_rmdir, 269 .rmdir = minix_rmdir,
266 .mknod = minix_mknod, 270 .mknod = minix_mknod,
267 .rename = minix_rename, 271 .rename2 = minix_rename,
268 .getattr = minix_getattr, 272 .getattr = minix_getattr,
269 .tmpfile = minix_tmpfile, 273 .tmpfile = minix_tmpfile,
270}; 274};
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
index dbcf1dc93a51..8540c13ef374 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -350,7 +350,8 @@ static int nilfs_rmdir(struct inode *dir, struct dentry *dentry)
350} 350}
351 351
352static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry, 352static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry,
353 struct inode *new_dir, struct dentry *new_dentry) 353 struct inode *new_dir, struct dentry *new_dentry,
354 unsigned int flags)
354{ 355{
355 struct inode *old_inode = d_inode(old_dentry); 356 struct inode *old_inode = d_inode(old_dentry);
356 struct inode *new_inode = d_inode(new_dentry); 357 struct inode *new_inode = d_inode(new_dentry);
@@ -361,6 +362,9 @@ static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry,
361 struct nilfs_transaction_info ti; 362 struct nilfs_transaction_info ti;
362 int err; 363 int err;
363 364
365 if (flags & ~RENAME_NOREPLACE)
366 return -EINVAL;
367
364 err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1); 368 err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1);
365 if (unlikely(err)) 369 if (unlikely(err))
366 return err; 370 return err;
@@ -552,7 +556,7 @@ const struct inode_operations nilfs_dir_inode_operations = {
552 .mkdir = nilfs_mkdir, 556 .mkdir = nilfs_mkdir,
553 .rmdir = nilfs_rmdir, 557 .rmdir = nilfs_rmdir,
554 .mknod = nilfs_mknod, 558 .mknod = nilfs_mknod,
555 .rename = nilfs_rename, 559 .rename2 = nilfs_rename,
556 .setattr = nilfs_setattr, 560 .setattr = nilfs_setattr,
557 .permission = nilfs_permission, 561 .permission = nilfs_permission,
558 .fiemap = nilfs_fiemap, 562 .fiemap = nilfs_fiemap,
diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c
index c8cbf3b60645..417511bbe362 100644
--- a/fs/omfs/dir.c
+++ b/fs/omfs/dir.c
@@ -371,12 +371,16 @@ static bool omfs_fill_chain(struct inode *dir, struct dir_context *ctx,
371} 371}
372 372
373static int omfs_rename(struct inode *old_dir, struct dentry *old_dentry, 373static int omfs_rename(struct inode *old_dir, struct dentry *old_dentry,
374 struct inode *new_dir, struct dentry *new_dentry) 374 struct inode *new_dir, struct dentry *new_dentry,
375 unsigned int flags)
375{ 376{
376 struct inode *new_inode = d_inode(new_dentry); 377 struct inode *new_inode = d_inode(new_dentry);
377 struct inode *old_inode = d_inode(old_dentry); 378 struct inode *old_inode = d_inode(old_dentry);
378 int err; 379 int err;
379 380
381 if (flags & ~RENAME_NOREPLACE)
382 return -EINVAL;
383
380 if (new_inode) { 384 if (new_inode) {
381 /* overwriting existing file/dir */ 385 /* overwriting existing file/dir */
382 err = omfs_remove(new_dir, new_dentry); 386 err = omfs_remove(new_dir, new_dentry);
@@ -444,7 +448,7 @@ static int omfs_readdir(struct file *file, struct dir_context *ctx)
444const struct inode_operations omfs_dir_inops = { 448const struct inode_operations omfs_dir_inops = {
445 .lookup = omfs_lookup, 449 .lookup = omfs_lookup,
446 .mkdir = omfs_mkdir, 450 .mkdir = omfs_mkdir,
447 .rename = omfs_rename, 451 .rename2 = omfs_rename,
448 .create = omfs_create, 452 .create = omfs_create,
449 .unlink = omfs_remove, 453 .unlink = omfs_remove,
450 .rmdir = omfs_remove, 454 .rmdir = omfs_remove,
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 8a36696d6df9..21b4b7138985 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -1306,7 +1306,8 @@ static void set_ino_in_dir_entry(struct reiserfs_dir_entry *de,
1306 * get_empty_nodes or its clones 1306 * get_empty_nodes or its clones
1307 */ 1307 */
1308static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry, 1308static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1309 struct inode *new_dir, struct dentry *new_dentry) 1309 struct inode *new_dir, struct dentry *new_dentry,
1310 unsigned int flags)
1310{ 1311{
1311 int retval; 1312 int retval;
1312 INITIALIZE_PATH(old_entry_path); 1313 INITIALIZE_PATH(old_entry_path);
@@ -1321,6 +1322,9 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1321 unsigned long savelink = 1; 1322 unsigned long savelink = 1;
1322 struct timespec ctime; 1323 struct timespec ctime;
1323 1324
1325 if (flags & ~RENAME_NOREPLACE)
1326 return -EINVAL;
1327
1324 /* 1328 /*
1325 * three balancings: (1) old name removal, (2) new name insertion 1329 * three balancings: (1) old name removal, (2) new name insertion
1326 * and (3) maybe "save" link insertion 1330 * and (3) maybe "save" link insertion
@@ -1648,7 +1652,7 @@ const struct inode_operations reiserfs_dir_inode_operations = {
1648 .mkdir = reiserfs_mkdir, 1652 .mkdir = reiserfs_mkdir,
1649 .rmdir = reiserfs_rmdir, 1653 .rmdir = reiserfs_rmdir,
1650 .mknod = reiserfs_mknod, 1654 .mknod = reiserfs_mknod,
1651 .rename = reiserfs_rename, 1655 .rename2 = reiserfs_rename,
1652 .setattr = reiserfs_setattr, 1656 .setattr = reiserfs_setattr,
1653 .setxattr = generic_setxattr, 1657 .setxattr = generic_setxattr,
1654 .getxattr = generic_getxattr, 1658 .getxattr = generic_getxattr,
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c
index a42de45ce40d..765d79de1217 100644
--- a/fs/sysv/namei.c
+++ b/fs/sysv/namei.c
@@ -206,7 +206,8 @@ static int sysv_rmdir(struct inode * dir, struct dentry * dentry)
206 * higher-level routines. 206 * higher-level routines.
207 */ 207 */
208static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry, 208static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry,
209 struct inode * new_dir, struct dentry * new_dentry) 209 struct inode * new_dir, struct dentry * new_dentry,
210 unsigned int flags)
210{ 211{
211 struct inode * old_inode = d_inode(old_dentry); 212 struct inode * old_inode = d_inode(old_dentry);
212 struct inode * new_inode = d_inode(new_dentry); 213 struct inode * new_inode = d_inode(new_dentry);
@@ -216,6 +217,9 @@ static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry,
216 struct sysv_dir_entry * old_de; 217 struct sysv_dir_entry * old_de;
217 int err = -ENOENT; 218 int err = -ENOENT;
218 219
220 if (flags & ~RENAME_NOREPLACE)
221 return -EINVAL;
222
219 old_de = sysv_find_entry(old_dentry, &old_page); 223 old_de = sysv_find_entry(old_dentry, &old_page);
220 if (!old_de) 224 if (!old_de)
221 goto out; 225 goto out;
@@ -285,6 +289,6 @@ const struct inode_operations sysv_dir_inode_operations = {
285 .mkdir = sysv_mkdir, 289 .mkdir = sysv_mkdir,
286 .rmdir = sysv_rmdir, 290 .rmdir = sysv_rmdir,
287 .mknod = sysv_mknod, 291 .mknod = sysv_mknod,
288 .rename = sysv_rename, 292 .rename2 = sysv_rename,
289 .getattr = sysv_getattr, 293 .getattr = sysv_getattr,
290}; 294};
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 4b86d3a738e1..23d1ebabc688 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -966,7 +966,8 @@ static void unlock_3_inodes(struct inode *inode1, struct inode *inode2,
966} 966}
967 967
968static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry, 968static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
969 struct inode *new_dir, struct dentry *new_dentry) 969 struct inode *new_dir, struct dentry *new_dentry,
970 unsigned int flags)
970{ 971{
971 struct ubifs_info *c = old_dir->i_sb->s_fs_info; 972 struct ubifs_info *c = old_dir->i_sb->s_fs_info;
972 struct inode *old_inode = d_inode(old_dentry); 973 struct inode *old_inode = d_inode(old_dentry);
@@ -984,6 +985,9 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
984 struct timespec time; 985 struct timespec time;
985 unsigned int uninitialized_var(saved_nlink); 986 unsigned int uninitialized_var(saved_nlink);
986 987
988 if (flags & ~RENAME_NOREPLACE)
989 return -EINVAL;
990
987 /* 991 /*
988 * Budget request settings: deletion direntry, new direntry, removing 992 * Budget request settings: deletion direntry, new direntry, removing
989 * the old inode, and changing old and new parent directory inodes. 993 * the old inode, and changing old and new parent directory inodes.
@@ -1179,7 +1183,7 @@ const struct inode_operations ubifs_dir_inode_operations = {
1179 .mkdir = ubifs_mkdir, 1183 .mkdir = ubifs_mkdir,
1180 .rmdir = ubifs_rmdir, 1184 .rmdir = ubifs_rmdir,
1181 .mknod = ubifs_mknod, 1185 .mknod = ubifs_mknod,
1182 .rename = ubifs_rename, 1186 .rename2 = ubifs_rename,
1183 .setattr = ubifs_setattr, 1187 .setattr = ubifs_setattr,
1184 .getattr = ubifs_getattr, 1188 .getattr = ubifs_getattr,
1185 .setxattr = generic_setxattr, 1189 .setxattr = generic_setxattr,
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index c3e5c9679371..ca2ec0061802 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -1093,7 +1093,8 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir,
1093 * higher-level routines. 1093 * higher-level routines.
1094 */ 1094 */
1095static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, 1095static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
1096 struct inode *new_dir, struct dentry *new_dentry) 1096 struct inode *new_dir, struct dentry *new_dentry,
1097 unsigned int flags)
1097{ 1098{
1098 struct inode *old_inode = d_inode(old_dentry); 1099 struct inode *old_inode = d_inode(old_dentry);
1099 struct inode *new_inode = d_inode(new_dentry); 1100 struct inode *new_inode = d_inode(new_dentry);
@@ -1105,6 +1106,9 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
1105 struct kernel_lb_addr tloc; 1106 struct kernel_lb_addr tloc;
1106 struct udf_inode_info *old_iinfo = UDF_I(old_inode); 1107 struct udf_inode_info *old_iinfo = UDF_I(old_inode);
1107 1108
1109 if (flags & ~RENAME_NOREPLACE)
1110 return -EINVAL;
1111
1108 ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); 1112 ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi);
1109 if (IS_ERR(ofi)) { 1113 if (IS_ERR(ofi)) {
1110 retval = PTR_ERR(ofi); 1114 retval = PTR_ERR(ofi);
@@ -1353,6 +1357,6 @@ const struct inode_operations udf_dir_inode_operations = {
1353 .mkdir = udf_mkdir, 1357 .mkdir = udf_mkdir,
1354 .rmdir = udf_rmdir, 1358 .rmdir = udf_rmdir,
1355 .mknod = udf_mknod, 1359 .mknod = udf_mknod,
1356 .rename = udf_rename, 1360 .rename2 = udf_rename,
1357 .tmpfile = udf_tmpfile, 1361 .tmpfile = udf_tmpfile,
1358}; 1362};
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index a1559f762805..719c9c9b83d8 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -245,7 +245,8 @@ static int ufs_rmdir (struct inode * dir, struct dentry *dentry)
245} 245}
246 246
247static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, 247static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry,
248 struct inode *new_dir, struct dentry *new_dentry) 248 struct inode *new_dir, struct dentry *new_dentry,
249 unsigned int flags)
249{ 250{
250 struct inode *old_inode = d_inode(old_dentry); 251 struct inode *old_inode = d_inode(old_dentry);
251 struct inode *new_inode = d_inode(new_dentry); 252 struct inode *new_inode = d_inode(new_dentry);
@@ -255,6 +256,9 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry,
255 struct ufs_dir_entry *old_de; 256 struct ufs_dir_entry *old_de;
256 int err = -ENOENT; 257 int err = -ENOENT;
257 258
259 if (flags & ~RENAME_NOREPLACE)
260 return -EINVAL;
261
258 old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page); 262 old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page);
259 if (!old_de) 263 if (!old_de)
260 goto out; 264 goto out;
@@ -333,5 +337,5 @@ const struct inode_operations ufs_dir_inode_operations = {
333 .mkdir = ufs_mkdir, 337 .mkdir = ufs_mkdir,
334 .rmdir = ufs_rmdir, 338 .rmdir = ufs_rmdir,
335 .mknod = ufs_mknod, 339 .mknod = ufs_mknod,
336 .rename = ufs_rename, 340 .rename2 = ufs_rename,
337}; 341};