Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge patch series "Create and use APIs to centralise locking for directory ops."

NeilBrown <neilb@ownmail.net> says:

This series is the next part of my effort to change directory-op
locking to allow multiple concurrent ops in a directory. Ultimately we
will (in my plan) lock the target dentry(s) rather than the whole
parent directory.

To help with changing the locking protocol, this series centralises
locking and lookup in some helpers. The various helpers are introduced
and then used in the same patch - roughly one patch per helper though
with various exceptions.

I haven't introduced these helpers into the various filesystems that
Al's tree-in-dcache series is changing. That series introduces and
uses similar helpers tuned to the specific needs of that set of
filesystems. Ultimately all the helpers will use the same backends
which can then be adjusted when it is time to change the locking
protocol.

One change that deserves highlighting is in patch 13 where vfs_mkdir()
is changed to unlock the parent on failure, as well as the current
behaviour of dput()ing the dentry on failure. Once this change is in
place, the final step of both create and an remove sequences only
requires the target dentry, not the parent. So e.g. end_creating() is
only given the dentry (which may be IS_ERR() after vfs_mkdir()). This
helps establish the pattern that it is the dentry that is being locked
and unlocked (the lock is currently held on dentry->d_parent->d_inode,
but that can change).

* patches from https://patch.msgid.link/20251113002050.676694-1-neilb@ownmail.net:
VFS: introduce end_creating_keep()
VFS: change vfs_mkdir() to unlock on failure.
ecryptfs: use new start_creating/start_removing APIs
Add start_renaming_two_dentries()
VFS/ovl/smb: introduce start_renaming_dentry()
VFS/nfsd/ovl: introduce start_renaming() and end_renaming()
VFS: add start_creating_killable() and start_removing_killable()
VFS: introduce start_removing_dentry()
smb/server: use end_removing_noperm for for target of smb2_create_link()
VFS: introduce start_creating_noperm() and start_removing_noperm()
VFS/nfsd/cachefiles/ovl: introduce start_removing() and end_removing()
VFS/nfsd/cachefiles/ovl: add start_creating() and end_creating()
VFS: tidy up do_unlinkat()
VFS: introduce start_dirop() and end_dirop()
debugfs: rename end_creating() to debugfs_end_creating()

Link: https://patch.msgid.link/20251113002050.676694-1-neilb@ownmail.net
Signed-off-by: Christian Brauner <brauner@kernel.org>

+1300 -837
+13
Documentation/filesystems/porting.rst
··· 1309 1309 vfs_parse_fs_qstr(fc, key, &QSTR_LEN(value, len)) 1310 1310 1311 1311 instead. 1312 + 1313 + --- 1314 + 1315 + **mandatory** 1316 + 1317 + vfs_mkdir() now returns a dentry - the one returned by ->mkdir(). If 1318 + that dentry is different from the dentry passed in, including if it is 1319 + an IS_ERR() dentry pointer, the original dentry is dput(). 1320 + 1321 + When vfs_mkdir() returns an error, and so both dputs() the original 1322 + dentry and doesn't provide a replacement, it also unlocks the parent. 1323 + Consequently the return value from vfs_mkdir() can be passed to 1324 + end_creating() and the parent will be unlocked precisely when necessary.
+12 -29
fs/btrfs/ioctl.c
··· 904 904 struct fscrypt_str name_str = FSTR_INIT((char *)qname->name, qname->len); 905 905 int ret; 906 906 907 - ret = down_write_killable_nested(&dir->i_rwsem, I_MUTEX_PARENT); 908 - if (ret == -EINTR) 909 - return ret; 910 - 911 - dentry = lookup_one(idmap, qname, parent); 912 - ret = PTR_ERR(dentry); 907 + dentry = start_creating_killable(idmap, parent, qname); 913 908 if (IS_ERR(dentry)) 914 - goto out_unlock; 909 + return PTR_ERR(dentry); 915 910 916 911 ret = btrfs_may_create(idmap, dir, dentry); 917 912 if (ret) ··· 935 940 out_up_read: 936 941 up_read(&fs_info->subvol_sem); 937 942 out_dput: 938 - dput(dentry); 939 - out_unlock: 940 - btrfs_inode_unlock(BTRFS_I(dir), 0); 943 + end_creating(dentry); 941 944 return ret; 942 945 } 943 946 ··· 2410 2417 goto free_subvol_name; 2411 2418 } 2412 2419 2413 - ret = down_write_killable_nested(&dir->i_rwsem, I_MUTEX_PARENT); 2414 - if (ret == -EINTR) 2415 - goto free_subvol_name; 2416 - dentry = lookup_one(idmap, &QSTR(subvol_name), parent); 2420 + dentry = start_removing_killable(idmap, parent, &QSTR(subvol_name)); 2417 2421 if (IS_ERR(dentry)) { 2418 2422 ret = PTR_ERR(dentry); 2419 - goto out_unlock_dir; 2420 - } 2421 - 2422 - if (d_really_is_negative(dentry)) { 2423 - ret = -ENOENT; 2424 - goto out_dput; 2423 + goto out_end_removing; 2425 2424 } 2426 2425 2427 2426 inode = d_inode(dentry); ··· 2434 2449 */ 2435 2450 ret = -EPERM; 2436 2451 if (!btrfs_test_opt(fs_info, USER_SUBVOL_RM_ALLOWED)) 2437 - goto out_dput; 2452 + goto out_end_removing; 2438 2453 2439 2454 /* 2440 2455 * Do not allow deletion if the parent dir is the same ··· 2445 2460 */ 2446 2461 ret = -EINVAL; 2447 2462 if (root == dest) 2448 - goto out_dput; 2463 + goto out_end_removing; 2449 2464 2450 2465 ret = inode_permission(idmap, inode, MAY_WRITE | MAY_EXEC); 2451 2466 if (ret) 2452 - goto out_dput; 2467 + goto out_end_removing; 2453 2468 } 2454 2469 2455 2470 /* check if subvolume may be deleted by a user */ 2456 2471 ret = btrfs_may_delete(idmap, dir, dentry, 1); 2457 2472 if (ret) 2458 - goto out_dput; 2473 + goto out_end_removing; 2459 2474 2460 2475 if (btrfs_ino(BTRFS_I(inode)) != BTRFS_FIRST_FREE_OBJECTID) { 2461 2476 ret = -EINVAL; 2462 - goto out_dput; 2477 + goto out_end_removing; 2463 2478 } 2464 2479 2465 2480 btrfs_inode_lock(BTRFS_I(inode), 0); ··· 2468 2483 if (!ret) 2469 2484 d_delete_notify(dir, dentry); 2470 2485 2471 - out_dput: 2472 - dput(dentry); 2473 - out_unlock_dir: 2474 - btrfs_inode_unlock(BTRFS_I(dir), 0); 2486 + out_end_removing: 2487 + end_removing(dentry); 2475 2488 free_subvol_name: 2476 2489 kfree(subvol_name_ptr); 2477 2490 free_parent:
+7 -4
fs/cachefiles/interface.c
··· 9 9 #include <linux/mount.h> 10 10 #include <linux/xattr.h> 11 11 #include <linux/file.h> 12 + #include <linux/namei.h> 12 13 #include <linux/falloc.h> 13 14 #include <trace/events/fscache.h> 14 15 #include "internal.h" ··· 429 428 if (!old_tmpfile) { 430 429 struct cachefiles_volume *volume = object->volume; 431 430 struct dentry *fan = volume->fanout[(u8)cookie->key_hash]; 431 + struct dentry *obj; 432 432 433 - inode_lock_nested(d_inode(fan), I_MUTEX_PARENT); 434 - cachefiles_bury_object(volume->cache, object, fan, 435 - old_file->f_path.dentry, 436 - FSCACHE_OBJECT_INVALIDATED); 433 + obj = start_removing_dentry(fan, old_file->f_path.dentry); 434 + if (!IS_ERR(obj)) 435 + cachefiles_bury_object(volume->cache, object, 436 + fan, obj, 437 + FSCACHE_OBJECT_INVALIDATED); 437 438 } 438 439 fput(old_file); 439 440 }
+46 -50
fs/cachefiles/namei.c
··· 93 93 _enter(",,%s", dirname); 94 94 95 95 /* search the current directory for the element name */ 96 - inode_lock_nested(d_inode(dir), I_MUTEX_PARENT); 97 96 98 97 retry: 99 98 ret = cachefiles_inject_read_error(); 100 99 if (ret == 0) 101 - subdir = lookup_one(&nop_mnt_idmap, &QSTR(dirname), dir); 100 + subdir = start_creating(&nop_mnt_idmap, dir, &QSTR(dirname)); 102 101 else 103 102 subdir = ERR_PTR(ret); 104 103 trace_cachefiles_lookup(NULL, dir, subdir); ··· 128 129 if (ret < 0) 129 130 goto mkdir_error; 130 131 ret = cachefiles_inject_write_error(); 131 - if (ret == 0) 132 + if (ret == 0) { 132 133 subdir = vfs_mkdir(&nop_mnt_idmap, d_inode(dir), subdir, 0700); 133 - else 134 + } else { 135 + end_creating(subdir); 134 136 subdir = ERR_PTR(ret); 137 + } 135 138 if (IS_ERR(subdir)) { 136 139 trace_cachefiles_vfs_error(NULL, d_inode(dir), ret, 137 140 cachefiles_trace_mkdir_error); ··· 142 141 trace_cachefiles_mkdir(dir, subdir); 143 142 144 143 if (unlikely(d_unhashed(subdir) || d_is_negative(subdir))) { 145 - dput(subdir); 144 + end_creating(subdir); 146 145 goto retry; 147 146 } 148 147 ASSERT(d_backing_inode(subdir)); ··· 155 154 156 155 /* Tell rmdir() it's not allowed to delete the subdir */ 157 156 inode_lock(d_inode(subdir)); 158 - inode_unlock(d_inode(dir)); 157 + end_creating_keep(subdir); 159 158 160 159 if (!__cachefiles_mark_inode_in_use(NULL, d_inode(subdir))) { 161 160 pr_notice("cachefiles: Inode already in use: %pd (B=%lx)\n", ··· 197 196 return ERR_PTR(-EBUSY); 198 197 199 198 mkdir_error: 200 - inode_unlock(d_inode(dir)); 201 - if (!IS_ERR(subdir)) 202 - dput(subdir); 199 + end_creating(subdir); 203 200 pr_err("mkdir %s failed with error %d\n", dirname, ret); 204 201 return ERR_PTR(ret); 205 202 206 203 lookup_error: 207 - inode_unlock(d_inode(dir)); 208 204 ret = PTR_ERR(subdir); 209 205 pr_err("Lookup %s failed with error %d\n", dirname, ret); 210 206 return ERR_PTR(ret); ··· 261 263 * - File backed objects are unlinked 262 264 * - Directory backed objects are stuffed into the graveyard for userspace to 263 265 * delete 266 + * On entry dir must be locked. It will be unlocked on exit. 267 + * On entry there must be at least 2 refs on rep, one will be dropped on exit. 264 268 */ 265 269 int cachefiles_bury_object(struct cachefiles_cache *cache, 266 270 struct cachefiles_object *object, ··· 278 278 _enter(",'%pd','%pd'", dir, rep); 279 279 280 280 if (rep->d_parent != dir) { 281 - inode_unlock(d_inode(dir)); 281 + end_removing(rep); 282 282 _leave(" = -ESTALE"); 283 283 return -ESTALE; 284 284 } 285 285 286 286 /* non-directories can just be unlinked */ 287 287 if (!d_is_dir(rep)) { 288 - dget(rep); /* Stop the dentry being negated if it's only pinned 289 - * by a file struct. 290 - */ 291 288 ret = cachefiles_unlink(cache, object, dir, rep, why); 292 - dput(rep); 289 + end_removing(rep); 293 290 294 - inode_unlock(d_inode(dir)); 295 291 _leave(" = %d", ret); 296 292 return ret; 297 293 } 298 294 299 295 /* directories have to be moved to the graveyard */ 300 296 _debug("move stale object to graveyard"); 301 - inode_unlock(d_inode(dir)); 297 + end_removing(rep); 302 298 303 299 try_again: 304 300 /* first step is to make up a grave dentry in the graveyard */ ··· 421 425 422 426 _enter(",OBJ%x{%pD}", object->debug_id, object->file); 423 427 424 - /* Stop the dentry being negated if it's only pinned by a file struct. */ 425 - dget(dentry); 426 - 427 - inode_lock_nested(d_backing_inode(fan), I_MUTEX_PARENT); 428 - ret = cachefiles_unlink(volume->cache, object, fan, dentry, why); 429 - inode_unlock(d_backing_inode(fan)); 430 - dput(dentry); 428 + dentry = start_removing_dentry(fan, dentry); 429 + if (IS_ERR(dentry)) 430 + ret = PTR_ERR(dentry); 431 + else 432 + ret = cachefiles_unlink(volume->cache, object, fan, dentry, why); 433 + end_removing(dentry); 431 434 return ret; 432 435 } 433 436 ··· 639 644 640 645 if (!d_is_reg(dentry)) { 641 646 pr_err("%pd is not a file\n", dentry); 642 - inode_lock_nested(d_inode(fan), I_MUTEX_PARENT); 643 - ret = cachefiles_bury_object(volume->cache, object, fan, dentry, 644 - FSCACHE_OBJECT_IS_WEIRD); 647 + struct dentry *de = start_removing_dentry(fan, dentry); 648 + if (IS_ERR(de)) 649 + ret = PTR_ERR(de); 650 + else 651 + ret = cachefiles_bury_object(volume->cache, object, 652 + fan, de, 653 + FSCACHE_OBJECT_IS_WEIRD); 645 654 dput(dentry); 646 655 if (ret < 0) 647 656 return false; ··· 678 679 679 680 _enter(",%pD", object->file); 680 681 681 - inode_lock_nested(d_inode(fan), I_MUTEX_PARENT); 682 682 ret = cachefiles_inject_read_error(); 683 683 if (ret == 0) 684 - dentry = lookup_one(&nop_mnt_idmap, &QSTR(object->d_name), fan); 684 + dentry = start_creating(&nop_mnt_idmap, fan, &QSTR(object->d_name)); 685 685 else 686 686 dentry = ERR_PTR(ret); 687 687 if (IS_ERR(dentry)) { 688 688 trace_cachefiles_vfs_error(object, d_inode(fan), PTR_ERR(dentry), 689 689 cachefiles_trace_lookup_error); 690 690 _debug("lookup fail %ld", PTR_ERR(dentry)); 691 - goto out_unlock; 691 + goto out; 692 692 } 693 693 694 - if (!d_is_negative(dentry)) { 694 + /* 695 + * This loop will only execute more than once if some other thread 696 + * races to create the object we are trying to create. 697 + */ 698 + while (!d_is_negative(dentry)) { 695 699 ret = cachefiles_unlink(volume->cache, object, fan, dentry, 696 700 FSCACHE_OBJECT_IS_STALE); 697 701 if (ret < 0) 698 - goto out_dput; 702 + goto out_end; 699 703 700 - dput(dentry); 704 + end_creating(dentry); 705 + 701 706 ret = cachefiles_inject_read_error(); 702 707 if (ret == 0) 703 - dentry = lookup_one(&nop_mnt_idmap, &QSTR(object->d_name), fan); 708 + dentry = start_creating(&nop_mnt_idmap, fan, 709 + &QSTR(object->d_name)); 704 710 else 705 711 dentry = ERR_PTR(ret); 706 712 if (IS_ERR(dentry)) { 707 713 trace_cachefiles_vfs_error(object, d_inode(fan), PTR_ERR(dentry), 708 714 cachefiles_trace_lookup_error); 709 715 _debug("lookup fail %ld", PTR_ERR(dentry)); 710 - goto out_unlock; 716 + goto out; 711 717 } 712 718 } 713 719 ··· 733 729 success = true; 734 730 } 735 731 736 - out_dput: 737 - dput(dentry); 738 - out_unlock: 739 - inode_unlock(d_inode(fan)); 732 + out_end: 733 + end_creating(dentry); 734 + out: 740 735 _leave(" = %u", success); 741 736 return success; 742 737 } ··· 751 748 struct dentry *victim; 752 749 int ret = -ENOENT; 753 750 754 - inode_lock_nested(d_inode(dir), I_MUTEX_PARENT); 751 + victim = start_removing(&nop_mnt_idmap, dir, &QSTR(filename)); 755 752 756 - victim = lookup_one(&nop_mnt_idmap, &QSTR(filename), dir); 757 753 if (IS_ERR(victim)) 758 754 goto lookup_error; 759 - if (d_is_negative(victim)) 760 - goto lookup_put; 761 755 if (d_inode(victim)->i_flags & S_KERNEL_FILE) 762 756 goto lookup_busy; 763 757 return victim; 764 758 765 759 lookup_busy: 766 760 ret = -EBUSY; 767 - lookup_put: 768 - inode_unlock(d_inode(dir)); 769 - dput(victim); 761 + end_removing(victim); 770 762 return ERR_PTR(ret); 771 763 772 764 lookup_error: 773 - inode_unlock(d_inode(dir)); 774 765 ret = PTR_ERR(victim); 775 766 if (ret == -ENOENT) 776 767 return ERR_PTR(-ESTALE); /* Probably got retired by the netfs */ ··· 812 815 813 816 ret = cachefiles_bury_object(cache, NULL, dir, victim, 814 817 FSCACHE_OBJECT_WAS_CULLED); 818 + dput(victim); 815 819 if (ret < 0) 816 820 goto error; 817 821 818 822 fscache_count_culled(); 819 - dput(victim); 820 823 _leave(" = 0"); 821 824 return 0; 822 825 823 826 error_unlock: 824 - inode_unlock(d_inode(dir)); 827 + end_removing(victim); 825 828 error: 826 - dput(victim); 827 829 if (ret == -ENOENT) 828 830 return -ESTALE; /* Probably got retired by the netfs */ 829 831
+6 -3
fs/cachefiles/volume.c
··· 7 7 8 8 #include <linux/fs.h> 9 9 #include <linux/slab.h> 10 + #include <linux/namei.h> 10 11 #include "internal.h" 11 12 #include <trace/events/fscache.h> 12 13 ··· 59 58 if (ret < 0) { 60 59 if (ret != -ESTALE) 61 60 goto error_dir; 62 - inode_lock_nested(d_inode(cache->store), I_MUTEX_PARENT); 63 - cachefiles_bury_object(cache, NULL, cache->store, vdentry, 64 - FSCACHE_VOLUME_IS_WEIRD); 61 + vdentry = start_removing_dentry(cache->store, vdentry); 62 + if (!IS_ERR(vdentry)) 63 + cachefiles_bury_object(cache, NULL, cache->store, 64 + vdentry, 65 + FSCACHE_VOLUME_IS_WEIRD); 65 66 cachefiles_put_directory(volume->dentry); 66 67 cond_resched(); 67 68 goto retry;
+36 -40
fs/debugfs/inode.c
··· 403 403 return dentry; 404 404 } 405 405 406 - static struct dentry *failed_creating(struct dentry *dentry) 406 + static struct dentry *debugfs_failed_creating(struct dentry *dentry) 407 407 { 408 408 inode_unlock(d_inode(dentry->d_parent)); 409 409 dput(dentry); ··· 411 411 return ERR_PTR(-ENOMEM); 412 412 } 413 413 414 - static struct dentry *end_creating(struct dentry *dentry) 414 + static struct dentry *debugfs_end_creating(struct dentry *dentry) 415 415 { 416 416 inode_unlock(d_inode(dentry->d_parent)); 417 417 return dentry; ··· 435 435 return dentry; 436 436 437 437 if (!(debugfs_allow & DEBUGFS_ALLOW_API)) { 438 - failed_creating(dentry); 438 + debugfs_failed_creating(dentry); 439 439 return ERR_PTR(-EPERM); 440 440 } 441 441 ··· 443 443 if (unlikely(!inode)) { 444 444 pr_err("out of free dentries, can not create file '%s'\n", 445 445 name); 446 - return failed_creating(dentry); 446 + return debugfs_failed_creating(dentry); 447 447 } 448 448 449 449 inode->i_mode = mode; ··· 458 458 459 459 d_instantiate(dentry, inode); 460 460 fsnotify_create(d_inode(dentry->d_parent), dentry); 461 - return end_creating(dentry); 461 + return debugfs_end_creating(dentry); 462 462 } 463 463 464 464 struct dentry *debugfs_create_file_full(const char *name, umode_t mode, ··· 585 585 return dentry; 586 586 587 587 if (!(debugfs_allow & DEBUGFS_ALLOW_API)) { 588 - failed_creating(dentry); 588 + debugfs_failed_creating(dentry); 589 589 return ERR_PTR(-EPERM); 590 590 } 591 591 ··· 593 593 if (unlikely(!inode)) { 594 594 pr_err("out of free dentries, can not create directory '%s'\n", 595 595 name); 596 - return failed_creating(dentry); 596 + return debugfs_failed_creating(dentry); 597 597 } 598 598 599 599 inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; ··· 605 605 d_instantiate(dentry, inode); 606 606 inc_nlink(d_inode(dentry->d_parent)); 607 607 fsnotify_mkdir(d_inode(dentry->d_parent), dentry); 608 - return end_creating(dentry); 608 + return debugfs_end_creating(dentry); 609 609 } 610 610 EXPORT_SYMBOL_GPL(debugfs_create_dir); 611 611 ··· 632 632 return dentry; 633 633 634 634 if (!(debugfs_allow & DEBUGFS_ALLOW_API)) { 635 - failed_creating(dentry); 635 + debugfs_failed_creating(dentry); 636 636 return ERR_PTR(-EPERM); 637 637 } 638 638 ··· 640 640 if (unlikely(!inode)) { 641 641 pr_err("out of free dentries, can not create automount '%s'\n", 642 642 name); 643 - return failed_creating(dentry); 643 + return debugfs_failed_creating(dentry); 644 644 } 645 645 646 646 make_empty_dir_inode(inode); ··· 652 652 d_instantiate(dentry, inode); 653 653 inc_nlink(d_inode(dentry->d_parent)); 654 654 fsnotify_mkdir(d_inode(dentry->d_parent), dentry); 655 - return end_creating(dentry); 655 + return debugfs_end_creating(dentry); 656 656 } 657 657 EXPORT_SYMBOL(debugfs_create_automount); 658 658 ··· 699 699 pr_err("out of free dentries, can not create symlink '%s'\n", 700 700 name); 701 701 kfree(link); 702 - return failed_creating(dentry); 702 + return debugfs_failed_creating(dentry); 703 703 } 704 704 inode->i_mode = S_IFLNK | S_IRWXUGO; 705 705 inode->i_op = &debugfs_symlink_inode_operations; 706 706 inode->i_link = link; 707 707 d_instantiate(dentry, inode); 708 - return end_creating(dentry); 708 + return debugfs_end_creating(dentry); 709 709 } 710 710 EXPORT_SYMBOL_GPL(debugfs_create_symlink); 711 711 ··· 842 842 int error = 0; 843 843 const char *new_name; 844 844 struct name_snapshot old_name; 845 - struct dentry *parent, *target; 845 + struct dentry *target; 846 + struct renamedata rd = {}; 846 847 struct inode *dir; 847 848 va_list ap; 848 849 ··· 856 855 if (!new_name) 857 856 return -ENOMEM; 858 857 859 - parent = dget_parent(dentry); 860 - dir = d_inode(parent); 861 - inode_lock(dir); 858 + rd.old_parent = dget_parent(dentry); 859 + rd.new_parent = rd.old_parent; 860 + rd.flags = RENAME_NOREPLACE; 861 + target = lookup_noperm_unlocked(&QSTR(new_name), rd.new_parent); 862 + if (IS_ERR(target)) 863 + return PTR_ERR(target); 862 864 865 + error = start_renaming_two_dentries(&rd, dentry, target); 866 + if (error) { 867 + if (error == -EEXIST && target == dentry) 868 + /* it isn't an error to rename a thing to itself */ 869 + error = 0; 870 + goto out; 871 + } 872 + 873 + dir = d_inode(rd.old_parent); 863 874 take_dentry_name_snapshot(&old_name, dentry); 864 - 865 - if (WARN_ON_ONCE(dentry->d_parent != parent)) { 866 - error = -EINVAL; 867 - goto out; 868 - } 869 - if (strcmp(old_name.name.name, new_name) == 0) 870 - goto out; 871 - target = lookup_noperm(&QSTR(new_name), parent); 872 - if (IS_ERR(target)) { 873 - error = PTR_ERR(target); 874 - goto out; 875 - } 876 - if (d_really_is_positive(target)) { 877 - dput(target); 878 - error = -EINVAL; 879 - goto out; 880 - } 881 - simple_rename_timestamp(dir, dentry, dir, target); 882 - d_move(dentry, target); 883 - dput(target); 875 + simple_rename_timestamp(dir, dentry, dir, rd.new_dentry); 876 + d_move(dentry, rd.new_dentry); 884 877 fsnotify_move(dir, dir, &old_name.name, d_is_dir(dentry), NULL, dentry); 885 - out: 886 878 release_dentry_name_snapshot(&old_name); 887 - inode_unlock(dir); 888 - dput(parent); 879 + end_renaming(&rd); 880 + out: 881 + dput(rd.old_parent); 882 + dput(target); 889 883 kfree_const(new_name); 890 884 return error; 891 885 }
+72 -81
fs/ecryptfs/inode.c
··· 24 24 #include <linux/unaligned.h> 25 25 #include "ecryptfs_kernel.h" 26 26 27 - static int lock_parent(struct dentry *dentry, 28 - struct dentry **lower_dentry, 29 - struct inode **lower_dir) 27 + static struct dentry *ecryptfs_start_creating_dentry(struct dentry *dentry) 30 28 { 31 - struct dentry *lower_dir_dentry; 29 + struct dentry *parent = dget_parent(dentry); 30 + struct dentry *ret; 32 31 33 - lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent); 34 - *lower_dir = d_inode(lower_dir_dentry); 35 - *lower_dentry = ecryptfs_dentry_to_lower(dentry); 32 + ret = start_creating_dentry(ecryptfs_dentry_to_lower(parent), 33 + ecryptfs_dentry_to_lower(dentry)); 34 + dput(parent); 35 + return ret; 36 + } 36 37 37 - inode_lock_nested(*lower_dir, I_MUTEX_PARENT); 38 - return (*lower_dentry)->d_parent == lower_dir_dentry ? 0 : -EINVAL; 38 + static struct dentry *ecryptfs_start_removing_dentry(struct dentry *dentry) 39 + { 40 + struct dentry *parent = dget_parent(dentry); 41 + struct dentry *ret; 42 + 43 + ret = start_removing_dentry(ecryptfs_dentry_to_lower(parent), 44 + ecryptfs_dentry_to_lower(dentry)); 45 + dput(parent); 46 + return ret; 39 47 } 40 48 41 49 static int ecryptfs_inode_test(struct inode *inode, void *lower_inode) ··· 149 141 struct inode *lower_dir; 150 142 int rc; 151 143 152 - rc = lock_parent(dentry, &lower_dentry, &lower_dir); 153 - dget(lower_dentry); // don't even try to make the lower negative 154 - if (!rc) { 155 - if (d_unhashed(lower_dentry)) 156 - rc = -EINVAL; 157 - else 158 - rc = vfs_unlink(&nop_mnt_idmap, lower_dir, lower_dentry, 159 - NULL); 160 - } 144 + lower_dentry = ecryptfs_start_removing_dentry(dentry); 145 + if (IS_ERR(lower_dentry)) 146 + return PTR_ERR(lower_dentry); 147 + 148 + lower_dir = lower_dentry->d_parent->d_inode; 149 + rc = vfs_unlink(&nop_mnt_idmap, lower_dir, lower_dentry, NULL); 161 150 if (rc) { 162 151 printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); 163 152 goto out_unlock; ··· 163 158 set_nlink(inode, ecryptfs_inode_to_lower(inode)->i_nlink); 164 159 inode_set_ctime_to_ts(inode, inode_get_ctime(dir)); 165 160 out_unlock: 166 - dput(lower_dentry); 167 - inode_unlock(lower_dir); 161 + end_removing(lower_dentry); 168 162 if (!rc) 169 163 d_drop(dentry); 170 164 return rc; ··· 190 186 struct inode *lower_dir; 191 187 struct inode *inode; 192 188 193 - rc = lock_parent(ecryptfs_dentry, &lower_dentry, &lower_dir); 194 - if (!rc) 195 - rc = vfs_create(&nop_mnt_idmap, lower_dir, 196 - lower_dentry, mode, true); 189 + lower_dentry = ecryptfs_start_creating_dentry(ecryptfs_dentry); 190 + if (IS_ERR(lower_dentry)) 191 + return ERR_CAST(lower_dentry); 192 + lower_dir = lower_dentry->d_parent->d_inode; 193 + rc = vfs_create(&nop_mnt_idmap, lower_dir, 194 + lower_dentry, mode, true); 197 195 if (rc) { 198 196 printk(KERN_ERR "%s: Failure to create dentry in lower fs; " 199 197 "rc = [%d]\n", __func__, rc); ··· 211 205 fsstack_copy_attr_times(directory_inode, lower_dir); 212 206 fsstack_copy_inode_size(directory_inode, lower_dir); 213 207 out_lock: 214 - inode_unlock(lower_dir); 208 + end_creating(lower_dentry); 215 209 return inode; 216 210 } 217 211 ··· 439 433 440 434 file_size_save = i_size_read(d_inode(old_dentry)); 441 435 lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); 442 - rc = lock_parent(new_dentry, &lower_new_dentry, &lower_dir); 443 - if (!rc) 444 - rc = vfs_link(lower_old_dentry, &nop_mnt_idmap, lower_dir, 445 - lower_new_dentry, NULL); 436 + lower_new_dentry = ecryptfs_start_creating_dentry(new_dentry); 437 + if (IS_ERR(lower_new_dentry)) 438 + return PTR_ERR(lower_new_dentry); 439 + lower_dir = lower_new_dentry->d_parent->d_inode; 440 + rc = vfs_link(lower_old_dentry, &nop_mnt_idmap, lower_dir, 441 + lower_new_dentry, NULL); 446 442 if (rc || d_really_is_negative(lower_new_dentry)) 447 443 goto out_lock; 448 444 rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb); ··· 456 448 ecryptfs_inode_to_lower(d_inode(old_dentry))->i_nlink); 457 449 i_size_write(d_inode(new_dentry), file_size_save); 458 450 out_lock: 459 - inode_unlock(lower_dir); 451 + end_creating(lower_new_dentry); 460 452 return rc; 461 453 } 462 454 ··· 476 468 size_t encoded_symlen; 477 469 struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; 478 470 479 - rc = lock_parent(dentry, &lower_dentry, &lower_dir); 480 - if (rc) 481 - goto out_lock; 471 + lower_dentry = ecryptfs_start_creating_dentry(dentry); 472 + if (IS_ERR(lower_dentry)) 473 + return PTR_ERR(lower_dentry); 474 + lower_dir = lower_dentry->d_parent->d_inode; 475 + 482 476 mount_crypt_stat = &ecryptfs_superblock_to_private( 483 477 dir->i_sb)->mount_crypt_stat; 484 478 rc = ecryptfs_encrypt_and_encode_filename(&encoded_symname, ··· 500 490 fsstack_copy_attr_times(dir, lower_dir); 501 491 fsstack_copy_inode_size(dir, lower_dir); 502 492 out_lock: 503 - inode_unlock(lower_dir); 493 + end_creating(lower_dentry); 504 494 if (d_really_is_negative(dentry)) 505 495 d_drop(dentry); 506 496 return rc; ··· 511 501 { 512 502 int rc; 513 503 struct dentry *lower_dentry; 504 + struct dentry *lower_dir_dentry; 514 505 struct inode *lower_dir; 515 506 516 - rc = lock_parent(dentry, &lower_dentry, &lower_dir); 517 - if (rc) 518 - goto out; 519 - 507 + lower_dentry = ecryptfs_start_creating_dentry(dentry); 508 + if (IS_ERR(lower_dentry)) 509 + return lower_dentry; 510 + lower_dir_dentry = dget(lower_dentry->d_parent); 511 + lower_dir = lower_dir_dentry->d_inode; 520 512 lower_dentry = vfs_mkdir(&nop_mnt_idmap, lower_dir, 521 513 lower_dentry, mode); 522 514 rc = PTR_ERR(lower_dentry); ··· 534 522 fsstack_copy_inode_size(dir, lower_dir); 535 523 set_nlink(dir, lower_dir->i_nlink); 536 524 out: 537 - inode_unlock(lower_dir); 525 + end_creating(lower_dentry); 538 526 if (d_really_is_negative(dentry)) 539 527 d_drop(dentry); 540 528 return ERR_PTR(rc); ··· 546 534 struct inode *lower_dir; 547 535 int rc; 548 536 549 - rc = lock_parent(dentry, &lower_dentry, &lower_dir); 550 - dget(lower_dentry); // don't even try to make the lower negative 551 - if (!rc) { 552 - if (d_unhashed(lower_dentry)) 553 - rc = -EINVAL; 554 - else 555 - rc = vfs_rmdir(&nop_mnt_idmap, lower_dir, lower_dentry); 556 - } 537 + lower_dentry = ecryptfs_start_removing_dentry(dentry); 538 + if (IS_ERR(lower_dentry)) 539 + return PTR_ERR(lower_dentry); 540 + lower_dir = lower_dentry->d_parent->d_inode; 541 + 542 + rc = vfs_rmdir(&nop_mnt_idmap, lower_dir, lower_dentry); 557 543 if (!rc) { 558 544 clear_nlink(d_inode(dentry)); 559 545 fsstack_copy_attr_times(dir, lower_dir); 560 546 set_nlink(dir, lower_dir->i_nlink); 561 547 } 562 - dput(lower_dentry); 563 - inode_unlock(lower_dir); 548 + end_removing(lower_dentry); 564 549 if (!rc) 565 550 d_drop(dentry); 566 551 return rc; ··· 571 562 struct dentry *lower_dentry; 572 563 struct inode *lower_dir; 573 564 574 - rc = lock_parent(dentry, &lower_dentry, &lower_dir); 575 - if (!rc) 576 - rc = vfs_mknod(&nop_mnt_idmap, lower_dir, 577 - lower_dentry, mode, dev); 565 + lower_dentry = ecryptfs_start_creating_dentry(dentry); 566 + if (IS_ERR(lower_dentry)) 567 + return PTR_ERR(lower_dentry); 568 + lower_dir = lower_dentry->d_parent->d_inode; 569 + 570 + rc = vfs_mknod(&nop_mnt_idmap, lower_dir, lower_dentry, mode, dev); 578 571 if (rc || d_really_is_negative(lower_dentry)) 579 572 goto out; 580 573 rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); ··· 585 574 fsstack_copy_attr_times(dir, lower_dir); 586 575 fsstack_copy_inode_size(dir, lower_dir); 587 576 out: 588 - inode_unlock(lower_dir); 577 + end_removing(lower_dentry); 589 578 if (d_really_is_negative(dentry)) 590 579 d_drop(dentry); 591 580 return rc; ··· 601 590 struct dentry *lower_new_dentry; 602 591 struct dentry *lower_old_dir_dentry; 603 592 struct dentry *lower_new_dir_dentry; 604 - struct dentry *trap; 605 593 struct inode *target_inode; 606 594 struct renamedata rd = {}; 607 595 ··· 615 605 616 606 target_inode = d_inode(new_dentry); 617 607 618 - trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); 619 - if (IS_ERR(trap)) 620 - return PTR_ERR(trap); 621 - dget(lower_new_dentry); 622 - rc = -EINVAL; 623 - if (lower_old_dentry->d_parent != lower_old_dir_dentry) 624 - goto out_lock; 625 - if (lower_new_dentry->d_parent != lower_new_dir_dentry) 626 - goto out_lock; 627 - if (d_unhashed(lower_old_dentry) || d_unhashed(lower_new_dentry)) 628 - goto out_lock; 629 - /* source should not be ancestor of target */ 630 - if (trap == lower_old_dentry) 631 - goto out_lock; 632 - /* target should not be ancestor of source */ 633 - if (trap == lower_new_dentry) { 634 - rc = -ENOTEMPTY; 635 - goto out_lock; 636 - } 608 + rd.mnt_idmap = &nop_mnt_idmap; 609 + rd.old_parent = lower_old_dir_dentry; 610 + rd.new_parent = lower_new_dir_dentry; 611 + rc = start_renaming_two_dentries(&rd, lower_old_dentry, lower_new_dentry); 612 + if (rc) 613 + return rc; 637 614 638 - rd.mnt_idmap = &nop_mnt_idmap; 639 - rd.old_parent = lower_old_dir_dentry; 640 - rd.old_dentry = lower_old_dentry; 641 - rd.new_parent = lower_new_dir_dentry; 642 - rd.new_dentry = lower_new_dentry; 643 615 rc = vfs_rename(&rd); 644 616 if (rc) 645 617 goto out_lock; ··· 632 640 if (new_dir != old_dir) 633 641 fsstack_copy_attr_all(old_dir, d_inode(lower_old_dir_dentry)); 634 642 out_lock: 635 - dput(lower_new_dentry); 636 - unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); 643 + end_renaming(&rd); 637 644 return rc; 638 645 } 639 646
+8 -11
fs/fuse/dir.c
··· 1397 1397 if (!parent) 1398 1398 return -ENOENT; 1399 1399 1400 - inode_lock_nested(parent, I_MUTEX_PARENT); 1401 1400 if (!S_ISDIR(parent->i_mode)) 1402 - goto unlock; 1401 + goto put_parent; 1403 1402 1404 1403 err = -ENOENT; 1405 1404 dir = d_find_alias(parent); 1406 1405 if (!dir) 1407 - goto unlock; 1406 + goto put_parent; 1408 1407 1409 - name->hash = full_name_hash(dir, name->name, name->len); 1410 - entry = d_lookup(dir, name); 1408 + entry = start_removing_noperm(dir, name); 1411 1409 dput(dir); 1412 - if (!entry) 1413 - goto unlock; 1410 + if (IS_ERR(entry)) 1411 + goto put_parent; 1414 1412 1415 1413 fuse_dir_changed(parent); 1416 1414 if (!(flags & FUSE_EXPIRE_ONLY)) 1417 1415 d_invalidate(entry); 1418 1416 fuse_invalidate_entry_cache(entry); 1419 1417 1420 - if (child_nodeid != 0 && d_really_is_positive(entry)) { 1418 + if (child_nodeid != 0) { 1421 1419 inode_lock(d_inode(entry)); 1422 1420 if (get_node_id(d_inode(entry)) != child_nodeid) { 1423 1421 err = -ENOENT; ··· 1443 1445 } else { 1444 1446 err = 0; 1445 1447 } 1446 - dput(entry); 1447 1448 1448 - unlock: 1449 - inode_unlock(parent); 1449 + end_removing(entry); 1450 + put_parent: 1450 1451 iput(parent); 1451 1452 return err; 1452 1453 }
+3
fs/internal.h
··· 67 67 const struct path *parentpath, 68 68 struct file *file, umode_t mode); 69 69 struct dentry *d_hash_and_lookup(struct dentry *, struct qstr *); 70 + struct dentry *start_dirop(struct dentry *parent, struct qstr *name, 71 + unsigned int lookup_flags); 72 + int lookup_noperm_common(struct qstr *qname, struct dentry *base); 70 73 71 74 /* 72 75 * namespace.c
+17 -19
fs/libfs.c
··· 2289 2289 cmpxchg(stashed, dentry, NULL); 2290 2290 } 2291 2291 2292 - /* parent must be held exclusive */ 2292 + /** 2293 + * simple_start_creating - prepare to create a given name 2294 + * @parent: directory in which to prepare to create the name 2295 + * @name: the name to be created 2296 + * 2297 + * Required lock is taken and a lookup in performed prior to creating an 2298 + * object in a directory. No permission checking is performed. 2299 + * 2300 + * Returns: a negative dentry on which vfs_create() or similar may 2301 + * be attempted, or an error. 2302 + */ 2293 2303 struct dentry *simple_start_creating(struct dentry *parent, const char *name) 2294 2304 { 2295 - struct dentry *dentry; 2296 - struct inode *dir = d_inode(parent); 2305 + struct qstr qname = QSTR(name); 2306 + int err; 2297 2307 2298 - inode_lock(dir); 2299 - if (unlikely(IS_DEADDIR(dir))) { 2300 - inode_unlock(dir); 2301 - return ERR_PTR(-ENOENT); 2302 - } 2303 - dentry = lookup_noperm(&QSTR(name), parent); 2304 - if (IS_ERR(dentry)) { 2305 - inode_unlock(dir); 2306 - return dentry; 2307 - } 2308 - if (dentry->d_inode) { 2309 - dput(dentry); 2310 - inode_unlock(dir); 2311 - return ERR_PTR(-EEXIST); 2312 - } 2313 - return dentry; 2308 + err = lookup_noperm_common(&qname, parent); 2309 + if (err) 2310 + return ERR_PTR(err); 2311 + return start_dirop(parent, &qname, LOOKUP_CREATE | LOOKUP_EXCL); 2314 2312 } 2315 2313 EXPORT_SYMBOL(simple_start_creating);
+640 -109
fs/namei.c
··· 2765 2765 return __filename_parentat(dfd, name, flags, parent, last, type, NULL); 2766 2766 } 2767 2767 2768 + /** 2769 + * start_dirop - begin a create or remove dirop, performing locking and lookup 2770 + * @parent: the dentry of the parent in which the operation will occur 2771 + * @name: a qstr holding the name within that parent 2772 + * @lookup_flags: intent and other lookup flags. 2773 + * 2774 + * The lookup is performed and necessary locks are taken so that, on success, 2775 + * the returned dentry can be operated on safely. 2776 + * The qstr must already have the hash value calculated. 2777 + * 2778 + * Returns: a locked dentry, or an error. 2779 + * 2780 + */ 2781 + static struct dentry *__start_dirop(struct dentry *parent, struct qstr *name, 2782 + unsigned int lookup_flags, 2783 + unsigned int state) 2784 + { 2785 + struct dentry *dentry; 2786 + struct inode *dir = d_inode(parent); 2787 + 2788 + if (state == TASK_KILLABLE) { 2789 + int ret = down_write_killable_nested(&dir->i_rwsem, 2790 + I_MUTEX_PARENT); 2791 + if (ret) 2792 + return ERR_PTR(ret); 2793 + } else { 2794 + inode_lock_nested(dir, I_MUTEX_PARENT); 2795 + } 2796 + dentry = lookup_one_qstr_excl(name, parent, lookup_flags); 2797 + if (IS_ERR(dentry)) 2798 + inode_unlock(dir); 2799 + return dentry; 2800 + } 2801 + 2802 + struct dentry *start_dirop(struct dentry *parent, struct qstr *name, 2803 + unsigned int lookup_flags) 2804 + { 2805 + return __start_dirop(parent, name, lookup_flags, TASK_NORMAL); 2806 + } 2807 + 2808 + /** 2809 + * end_dirop - signal completion of a dirop 2810 + * @de: the dentry which was returned by start_dirop or similar. 2811 + * 2812 + * If the de is an error, nothing happens. Otherwise any lock taken to 2813 + * protect the dentry is dropped and the dentry itself is release (dput()). 2814 + */ 2815 + void end_dirop(struct dentry *de) 2816 + { 2817 + if (!IS_ERR(de)) { 2818 + inode_unlock(de->d_parent->d_inode); 2819 + dput(de); 2820 + } 2821 + } 2822 + EXPORT_SYMBOL(end_dirop); 2823 + 2768 2824 /* does lookup, returns the object with parent locked */ 2769 2825 static struct dentry *__start_removing_path(int dfd, struct filename *name, 2770 2826 struct path *path) ··· 2837 2781 return ERR_PTR(-EINVAL); 2838 2782 /* don't fail immediately if it's r/o, at least try to report other errors */ 2839 2783 error = mnt_want_write(parent_path.mnt); 2840 - inode_lock_nested(parent_path.dentry->d_inode, I_MUTEX_PARENT); 2841 - d = lookup_one_qstr_excl(&last, parent_path.dentry, 0); 2784 + d = start_dirop(parent_path.dentry, &last, 0); 2842 2785 if (IS_ERR(d)) 2843 - goto unlock; 2786 + goto drop; 2844 2787 if (error) 2845 2788 goto fail; 2846 2789 path->dentry = no_free_ptr(parent_path.dentry); ··· 2847 2792 return d; 2848 2793 2849 2794 fail: 2850 - dput(d); 2795 + end_dirop(d); 2851 2796 d = ERR_PTR(error); 2852 - unlock: 2853 - inode_unlock(parent_path.dentry->d_inode); 2797 + drop: 2854 2798 if (!error) 2855 2799 mnt_drop_write(parent_path.mnt); 2856 2800 return d; ··· 2964 2910 } 2965 2911 EXPORT_SYMBOL(vfs_path_lookup); 2966 2912 2967 - static int lookup_noperm_common(struct qstr *qname, struct dentry *base) 2913 + int lookup_noperm_common(struct qstr *qname, struct dentry *base) 2968 2914 { 2969 2915 const char *name = qname->name; 2970 2916 u32 len = qname->len; ··· 3235 3181 } 3236 3182 EXPORT_SYMBOL(lookup_noperm_positive_unlocked); 3237 3183 3184 + /** 3185 + * start_creating - prepare to create a given name with permission checking 3186 + * @idmap: idmap of the mount 3187 + * @parent: directory in which to prepare to create the name 3188 + * @name: the name to be created 3189 + * 3190 + * Locks are taken and a lookup is performed prior to creating 3191 + * an object in a directory. Permission checking (MAY_EXEC) is performed 3192 + * against @idmap. 3193 + * 3194 + * If the name already exists, a positive dentry is returned, so 3195 + * behaviour is similar to O_CREAT without O_EXCL, which doesn't fail 3196 + * with -EEXIST. 3197 + * 3198 + * Returns: a negative or positive dentry, or an error. 3199 + */ 3200 + struct dentry *start_creating(struct mnt_idmap *idmap, struct dentry *parent, 3201 + struct qstr *name) 3202 + { 3203 + int err = lookup_one_common(idmap, name, parent); 3204 + 3205 + if (err) 3206 + return ERR_PTR(err); 3207 + return start_dirop(parent, name, LOOKUP_CREATE); 3208 + } 3209 + EXPORT_SYMBOL(start_creating); 3210 + 3211 + /** 3212 + * start_removing - prepare to remove a given name with permission checking 3213 + * @idmap: idmap of the mount 3214 + * @parent: directory in which to find the name 3215 + * @name: the name to be removed 3216 + * 3217 + * Locks are taken and a lookup in performed prior to removing 3218 + * an object from a directory. Permission checking (MAY_EXEC) is performed 3219 + * against @idmap. 3220 + * 3221 + * If the name doesn't exist, an error is returned. 3222 + * 3223 + * end_removing() should be called when removal is complete, or aborted. 3224 + * 3225 + * Returns: a positive dentry, or an error. 3226 + */ 3227 + struct dentry *start_removing(struct mnt_idmap *idmap, struct dentry *parent, 3228 + struct qstr *name) 3229 + { 3230 + int err = lookup_one_common(idmap, name, parent); 3231 + 3232 + if (err) 3233 + return ERR_PTR(err); 3234 + return start_dirop(parent, name, 0); 3235 + } 3236 + EXPORT_SYMBOL(start_removing); 3237 + 3238 + /** 3239 + * start_creating_killable - prepare to create a given name with permission checking 3240 + * @idmap: idmap of the mount 3241 + * @parent: directory in which to prepare to create the name 3242 + * @name: the name to be created 3243 + * 3244 + * Locks are taken and a lookup in performed prior to creating 3245 + * an object in a directory. Permission checking (MAY_EXEC) is performed 3246 + * against @idmap. 3247 + * 3248 + * If the name already exists, a positive dentry is returned. 3249 + * 3250 + * If a signal is received or was already pending, the function aborts 3251 + * with -EINTR; 3252 + * 3253 + * Returns: a negative or positive dentry, or an error. 3254 + */ 3255 + struct dentry *start_creating_killable(struct mnt_idmap *idmap, 3256 + struct dentry *parent, 3257 + struct qstr *name) 3258 + { 3259 + int err = lookup_one_common(idmap, name, parent); 3260 + 3261 + if (err) 3262 + return ERR_PTR(err); 3263 + return __start_dirop(parent, name, LOOKUP_CREATE, TASK_KILLABLE); 3264 + } 3265 + EXPORT_SYMBOL(start_creating_killable); 3266 + 3267 + /** 3268 + * start_removing_killable - prepare to remove a given name with permission checking 3269 + * @idmap: idmap of the mount 3270 + * @parent: directory in which to find the name 3271 + * @name: the name to be removed 3272 + * 3273 + * Locks are taken and a lookup in performed prior to removing 3274 + * an object from a directory. Permission checking (MAY_EXEC) is performed 3275 + * against @idmap. 3276 + * 3277 + * If the name doesn't exist, an error is returned. 3278 + * 3279 + * end_removing() should be called when removal is complete, or aborted. 3280 + * 3281 + * If a signal is received or was already pending, the function aborts 3282 + * with -EINTR; 3283 + * 3284 + * Returns: a positive dentry, or an error. 3285 + */ 3286 + struct dentry *start_removing_killable(struct mnt_idmap *idmap, 3287 + struct dentry *parent, 3288 + struct qstr *name) 3289 + { 3290 + int err = lookup_one_common(idmap, name, parent); 3291 + 3292 + if (err) 3293 + return ERR_PTR(err); 3294 + return __start_dirop(parent, name, 0, TASK_KILLABLE); 3295 + } 3296 + EXPORT_SYMBOL(start_removing_killable); 3297 + 3298 + /** 3299 + * start_creating_noperm - prepare to create a given name without permission checking 3300 + * @parent: directory in which to prepare to create the name 3301 + * @name: the name to be created 3302 + * 3303 + * Locks are taken and a lookup in performed prior to creating 3304 + * an object in a directory. 3305 + * 3306 + * If the name already exists, a positive dentry is returned. 3307 + * 3308 + * Returns: a negative or positive dentry, or an error. 3309 + */ 3310 + struct dentry *start_creating_noperm(struct dentry *parent, 3311 + struct qstr *name) 3312 + { 3313 + int err = lookup_noperm_common(name, parent); 3314 + 3315 + if (err) 3316 + return ERR_PTR(err); 3317 + return start_dirop(parent, name, LOOKUP_CREATE); 3318 + } 3319 + EXPORT_SYMBOL(start_creating_noperm); 3320 + 3321 + /** 3322 + * start_removing_noperm - prepare to remove a given name without permission checking 3323 + * @parent: directory in which to find the name 3324 + * @name: the name to be removed 3325 + * 3326 + * Locks are taken and a lookup in performed prior to removing 3327 + * an object from a directory. 3328 + * 3329 + * If the name doesn't exist, an error is returned. 3330 + * 3331 + * end_removing() should be called when removal is complete, or aborted. 3332 + * 3333 + * Returns: a positive dentry, or an error. 3334 + */ 3335 + struct dentry *start_removing_noperm(struct dentry *parent, 3336 + struct qstr *name) 3337 + { 3338 + int err = lookup_noperm_common(name, parent); 3339 + 3340 + if (err) 3341 + return ERR_PTR(err); 3342 + return start_dirop(parent, name, 0); 3343 + } 3344 + EXPORT_SYMBOL(start_removing_noperm); 3345 + 3346 + /** 3347 + * start_creating_dentry - prepare to create a given dentry 3348 + * @parent: directory from which dentry should be removed 3349 + * @child: the dentry to be removed 3350 + * 3351 + * A lock is taken to protect the dentry again other dirops and 3352 + * the validity of the dentry is checked: correct parent and still hashed. 3353 + * 3354 + * If the dentry is valid and negative a reference is taken and 3355 + * returned. If not an error is returned. 3356 + * 3357 + * end_creating() should be called when creation is complete, or aborted. 3358 + * 3359 + * Returns: the valid dentry, or an error. 3360 + */ 3361 + struct dentry *start_creating_dentry(struct dentry *parent, 3362 + struct dentry *child) 3363 + { 3364 + inode_lock_nested(parent->d_inode, I_MUTEX_PARENT); 3365 + if (unlikely(IS_DEADDIR(parent->d_inode) || 3366 + child->d_parent != parent || 3367 + d_unhashed(child))) { 3368 + inode_unlock(parent->d_inode); 3369 + return ERR_PTR(-EINVAL); 3370 + } 3371 + if (d_is_positive(child)) { 3372 + inode_unlock(parent->d_inode); 3373 + return ERR_PTR(-EEXIST); 3374 + } 3375 + return dget(child); 3376 + } 3377 + EXPORT_SYMBOL(start_creating_dentry); 3378 + 3379 + /** 3380 + * start_removing_dentry - prepare to remove a given dentry 3381 + * @parent: directory from which dentry should be removed 3382 + * @child: the dentry to be removed 3383 + * 3384 + * A lock is taken to protect the dentry again other dirops and 3385 + * the validity of the dentry is checked: correct parent and still hashed. 3386 + * 3387 + * If the dentry is valid and positive, a reference is taken and 3388 + * returned. If not an error is returned. 3389 + * 3390 + * end_removing() should be called when removal is complete, or aborted. 3391 + * 3392 + * Returns: the valid dentry, or an error. 3393 + */ 3394 + struct dentry *start_removing_dentry(struct dentry *parent, 3395 + struct dentry *child) 3396 + { 3397 + inode_lock_nested(parent->d_inode, I_MUTEX_PARENT); 3398 + if (unlikely(IS_DEADDIR(parent->d_inode) || 3399 + child->d_parent != parent || 3400 + d_unhashed(child))) { 3401 + inode_unlock(parent->d_inode); 3402 + return ERR_PTR(-EINVAL); 3403 + } 3404 + if (d_is_negative(child)) { 3405 + inode_unlock(parent->d_inode); 3406 + return ERR_PTR(-ENOENT); 3407 + } 3408 + return dget(child); 3409 + } 3410 + EXPORT_SYMBOL(start_removing_dentry); 3411 + 3238 3412 #ifdef CONFIG_UNIX98_PTYS 3239 3413 int path_pts(struct path *path) 3240 3414 { ··· 3699 3417 } 3700 3418 } 3701 3419 EXPORT_SYMBOL(unlock_rename); 3420 + 3421 + /** 3422 + * __start_renaming - lookup and lock names for rename 3423 + * @rd: rename data containing parents and flags, and 3424 + * for receiving found dentries 3425 + * @lookup_flags: extra flags to pass to ->lookup (e.g. LOOKUP_REVAL, 3426 + * LOOKUP_NO_SYMLINKS etc). 3427 + * @old_last: name of object in @rd.old_parent 3428 + * @new_last: name of object in @rd.new_parent 3429 + * 3430 + * Look up two names and ensure locks are in place for 3431 + * rename. 3432 + * 3433 + * On success the found dentries are stored in @rd.old_dentry, 3434 + * @rd.new_dentry and an extra ref is taken on @rd.old_parent. 3435 + * These references and the lock are dropped by end_renaming(). 3436 + * 3437 + * The passed in qstrs must have the hash calculated, and no permission 3438 + * checking is performed. 3439 + * 3440 + * Returns: zero or an error. 3441 + */ 3442 + static int 3443 + __start_renaming(struct renamedata *rd, int lookup_flags, 3444 + struct qstr *old_last, struct qstr *new_last) 3445 + { 3446 + struct dentry *trap; 3447 + struct dentry *d1, *d2; 3448 + int target_flags = LOOKUP_RENAME_TARGET | LOOKUP_CREATE; 3449 + int err; 3450 + 3451 + if (rd->flags & RENAME_EXCHANGE) 3452 + target_flags = 0; 3453 + if (rd->flags & RENAME_NOREPLACE) 3454 + target_flags |= LOOKUP_EXCL; 3455 + 3456 + trap = lock_rename(rd->old_parent, rd->new_parent); 3457 + if (IS_ERR(trap)) 3458 + return PTR_ERR(trap); 3459 + 3460 + d1 = lookup_one_qstr_excl(old_last, rd->old_parent, 3461 + lookup_flags); 3462 + err = PTR_ERR(d1); 3463 + if (IS_ERR(d1)) 3464 + goto out_unlock; 3465 + 3466 + d2 = lookup_one_qstr_excl(new_last, rd->new_parent, 3467 + lookup_flags | target_flags); 3468 + err = PTR_ERR(d2); 3469 + if (IS_ERR(d2)) 3470 + goto out_dput_d1; 3471 + 3472 + if (d1 == trap) { 3473 + /* source is an ancestor of target */ 3474 + err = -EINVAL; 3475 + goto out_dput_d2; 3476 + } 3477 + 3478 + if (d2 == trap) { 3479 + /* target is an ancestor of source */ 3480 + if (rd->flags & RENAME_EXCHANGE) 3481 + err = -EINVAL; 3482 + else 3483 + err = -ENOTEMPTY; 3484 + goto out_dput_d2; 3485 + } 3486 + 3487 + rd->old_dentry = d1; 3488 + rd->new_dentry = d2; 3489 + dget(rd->old_parent); 3490 + return 0; 3491 + 3492 + out_dput_d2: 3493 + dput(d2); 3494 + out_dput_d1: 3495 + dput(d1); 3496 + out_unlock: 3497 + unlock_rename(rd->old_parent, rd->new_parent); 3498 + return err; 3499 + } 3500 + 3501 + /** 3502 + * start_renaming - lookup and lock names for rename with permission checking 3503 + * @rd: rename data containing parents and flags, and 3504 + * for receiving found dentries 3505 + * @lookup_flags: extra flags to pass to ->lookup (e.g. LOOKUP_REVAL, 3506 + * LOOKUP_NO_SYMLINKS etc). 3507 + * @old_last: name of object in @rd.old_parent 3508 + * @new_last: name of object in @rd.new_parent 3509 + * 3510 + * Look up two names and ensure locks are in place for 3511 + * rename. 3512 + * 3513 + * On success the found dentries are stored in @rd.old_dentry, 3514 + * @rd.new_dentry. Also the refcount on @rd->old_parent is increased. 3515 + * These references and the lock are dropped by end_renaming(). 3516 + * 3517 + * The passed in qstrs need not have the hash calculated, and basic 3518 + * eXecute permission checking is performed against @rd.mnt_idmap. 3519 + * 3520 + * Returns: zero or an error. 3521 + */ 3522 + int start_renaming(struct renamedata *rd, int lookup_flags, 3523 + struct qstr *old_last, struct qstr *new_last) 3524 + { 3525 + int err; 3526 + 3527 + err = lookup_one_common(rd->mnt_idmap, old_last, rd->old_parent); 3528 + if (err) 3529 + return err; 3530 + err = lookup_one_common(rd->mnt_idmap, new_last, rd->new_parent); 3531 + if (err) 3532 + return err; 3533 + return __start_renaming(rd, lookup_flags, old_last, new_last); 3534 + } 3535 + EXPORT_SYMBOL(start_renaming); 3536 + 3537 + static int 3538 + __start_renaming_dentry(struct renamedata *rd, int lookup_flags, 3539 + struct dentry *old_dentry, struct qstr *new_last) 3540 + { 3541 + struct dentry *trap; 3542 + struct dentry *d2; 3543 + int target_flags = LOOKUP_RENAME_TARGET | LOOKUP_CREATE; 3544 + int err; 3545 + 3546 + if (rd->flags & RENAME_EXCHANGE) 3547 + target_flags = 0; 3548 + if (rd->flags & RENAME_NOREPLACE) 3549 + target_flags |= LOOKUP_EXCL; 3550 + 3551 + /* Already have the dentry - need to be sure to lock the correct parent */ 3552 + trap = lock_rename_child(old_dentry, rd->new_parent); 3553 + if (IS_ERR(trap)) 3554 + return PTR_ERR(trap); 3555 + if (d_unhashed(old_dentry) || 3556 + (rd->old_parent && rd->old_parent != old_dentry->d_parent)) { 3557 + /* dentry was removed, or moved and explicit parent requested */ 3558 + err = -EINVAL; 3559 + goto out_unlock; 3560 + } 3561 + 3562 + d2 = lookup_one_qstr_excl(new_last, rd->new_parent, 3563 + lookup_flags | target_flags); 3564 + err = PTR_ERR(d2); 3565 + if (IS_ERR(d2)) 3566 + goto out_unlock; 3567 + 3568 + if (old_dentry == trap) { 3569 + /* source is an ancestor of target */ 3570 + err = -EINVAL; 3571 + goto out_dput_d2; 3572 + } 3573 + 3574 + if (d2 == trap) { 3575 + /* target is an ancestor of source */ 3576 + if (rd->flags & RENAME_EXCHANGE) 3577 + err = -EINVAL; 3578 + else 3579 + err = -ENOTEMPTY; 3580 + goto out_dput_d2; 3581 + } 3582 + 3583 + rd->old_dentry = dget(old_dentry); 3584 + rd->new_dentry = d2; 3585 + rd->old_parent = dget(old_dentry->d_parent); 3586 + return 0; 3587 + 3588 + out_dput_d2: 3589 + dput(d2); 3590 + out_unlock: 3591 + unlock_rename(old_dentry->d_parent, rd->new_parent); 3592 + return err; 3593 + } 3594 + 3595 + /** 3596 + * start_renaming_dentry - lookup and lock name for rename with permission checking 3597 + * @rd: rename data containing parents and flags, and 3598 + * for receiving found dentries 3599 + * @lookup_flags: extra flags to pass to ->lookup (e.g. LOOKUP_REVAL, 3600 + * LOOKUP_NO_SYMLINKS etc). 3601 + * @old_dentry: dentry of name to move 3602 + * @new_last: name of target in @rd.new_parent 3603 + * 3604 + * Look up target name and ensure locks are in place for 3605 + * rename. 3606 + * 3607 + * On success the found dentry is stored in @rd.new_dentry and 3608 + * @rd.old_parent is confirmed to be the parent of @old_dentry. If it 3609 + * was originally %NULL, it is set. In either case a reference is taken 3610 + * so that end_renaming() can have a stable reference to unlock. 3611 + * 3612 + * References and the lock can be dropped with end_renaming() 3613 + * 3614 + * The passed in qstr need not have the hash calculated, and basic 3615 + * eXecute permission checking is performed against @rd.mnt_idmap. 3616 + * 3617 + * Returns: zero or an error. 3618 + */ 3619 + int start_renaming_dentry(struct renamedata *rd, int lookup_flags, 3620 + struct dentry *old_dentry, struct qstr *new_last) 3621 + { 3622 + int err; 3623 + 3624 + err = lookup_one_common(rd->mnt_idmap, new_last, rd->new_parent); 3625 + if (err) 3626 + return err; 3627 + return __start_renaming_dentry(rd, lookup_flags, old_dentry, new_last); 3628 + } 3629 + EXPORT_SYMBOL(start_renaming_dentry); 3630 + 3631 + /** 3632 + * start_renaming_two_dentries - Lock to dentries in given parents for rename 3633 + * @rd: rename data containing parent 3634 + * @old_dentry: dentry of name to move 3635 + * @new_dentry: dentry to move to 3636 + * 3637 + * Ensure locks are in place for rename and check parentage is still correct. 3638 + * 3639 + * On success the two dentries are stored in @rd.old_dentry and 3640 + * @rd.new_dentry and @rd.old_parent and @rd.new_parent are confirmed to 3641 + * be the parents of the dentries. 3642 + * 3643 + * References and the lock can be dropped with end_renaming() 3644 + * 3645 + * Returns: zero or an error. 3646 + */ 3647 + int 3648 + start_renaming_two_dentries(struct renamedata *rd, 3649 + struct dentry *old_dentry, struct dentry *new_dentry) 3650 + { 3651 + struct dentry *trap; 3652 + int err; 3653 + 3654 + /* Already have the dentry - need to be sure to lock the correct parent */ 3655 + trap = lock_rename_child(old_dentry, rd->new_parent); 3656 + if (IS_ERR(trap)) 3657 + return PTR_ERR(trap); 3658 + err = -EINVAL; 3659 + if (d_unhashed(old_dentry) || 3660 + (rd->old_parent && rd->old_parent != old_dentry->d_parent)) 3661 + /* old_dentry was removed, or moved and explicit parent requested */ 3662 + goto out_unlock; 3663 + if (d_unhashed(new_dentry) || 3664 + rd->new_parent != new_dentry->d_parent) 3665 + /* new_dentry was removed or moved */ 3666 + goto out_unlock; 3667 + 3668 + if (old_dentry == trap) 3669 + /* source is an ancestor of target */ 3670 + goto out_unlock; 3671 + 3672 + if (new_dentry == trap) { 3673 + /* target is an ancestor of source */ 3674 + if (rd->flags & RENAME_EXCHANGE) 3675 + err = -EINVAL; 3676 + else 3677 + err = -ENOTEMPTY; 3678 + goto out_unlock; 3679 + } 3680 + 3681 + err = -EEXIST; 3682 + if (d_is_positive(new_dentry) && (rd->flags & RENAME_NOREPLACE)) 3683 + goto out_unlock; 3684 + 3685 + rd->old_dentry = dget(old_dentry); 3686 + rd->new_dentry = dget(new_dentry); 3687 + rd->old_parent = dget(old_dentry->d_parent); 3688 + return 0; 3689 + 3690 + out_unlock: 3691 + unlock_rename(old_dentry->d_parent, rd->new_parent); 3692 + return err; 3693 + } 3694 + EXPORT_SYMBOL(start_renaming_two_dentries); 3695 + 3696 + void end_renaming(struct renamedata *rd) 3697 + { 3698 + unlock_rename(rd->old_parent, rd->new_parent); 3699 + dput(rd->old_dentry); 3700 + dput(rd->new_dentry); 3701 + dput(rd->old_parent); 3702 + } 3703 + EXPORT_SYMBOL(end_renaming); 3702 3704 3703 3705 /** 3704 3706 * vfs_prepare_mode - prepare the mode to be used for a new inode ··· 4789 4223 */ 4790 4224 if (last.name[last.len] && !want_dir) 4791 4225 create_flags &= ~LOOKUP_CREATE; 4792 - inode_lock_nested(path->dentry->d_inode, I_MUTEX_PARENT); 4793 - dentry = lookup_one_qstr_excl(&last, path->dentry, 4794 - reval_flag | create_flags); 4226 + dentry = start_dirop(path->dentry, &last, reval_flag | create_flags); 4795 4227 if (IS_ERR(dentry)) 4796 - goto unlock; 4228 + goto out_drop_write; 4797 4229 4798 4230 if (unlikely(error)) 4799 4231 goto fail; 4800 4232 4801 4233 return dentry; 4802 4234 fail: 4803 - dput(dentry); 4235 + end_dirop(dentry); 4804 4236 dentry = ERR_PTR(error); 4805 - unlock: 4806 - inode_unlock(path->dentry->d_inode); 4237 + out_drop_write: 4807 4238 if (!error) 4808 4239 mnt_drop_write(path->mnt); 4809 4240 out: ··· 4819 4256 } 4820 4257 EXPORT_SYMBOL(start_creating_path); 4821 4258 4259 + /** 4260 + * end_creating_path - finish a code section started by start_creating_path() 4261 + * @path: the path instantiated by start_creating_path() 4262 + * @dentry: the dentry returned by start_creating_path() 4263 + * 4264 + * end_creating_path() will unlock and locks taken by start_creating_path() 4265 + * and drop an references that were taken. It should only be called 4266 + * if start_creating_path() returned a non-error. 4267 + * If vfs_mkdir() was called and it returned an error, that error *should* 4268 + * be passed to end_creating_path() together with the path. 4269 + */ 4822 4270 void end_creating_path(const struct path *path, struct dentry *dentry) 4823 4271 { 4824 - if (!IS_ERR(dentry)) 4825 - dput(dentry); 4826 - inode_unlock(path->dentry->d_inode); 4272 + end_creating(dentry); 4827 4273 mnt_drop_write(path->mnt); 4828 4274 path_put(path); 4829 4275 } ··· 5034 4462 return dentry; 5035 4463 5036 4464 err: 5037 - dput(dentry); 4465 + end_creating(dentry); 5038 4466 return ERR_PTR(error); 5039 4467 } 5040 4468 EXPORT_SYMBOL(vfs_mkdir); ··· 5164 4592 if (error) 5165 4593 goto exit2; 5166 4594 5167 - inode_lock_nested(path.dentry->d_inode, I_MUTEX_PARENT); 5168 - dentry = lookup_one_qstr_excl(&last, path.dentry, lookup_flags); 4595 + dentry = start_dirop(path.dentry, &last, lookup_flags); 5169 4596 error = PTR_ERR(dentry); 5170 4597 if (IS_ERR(dentry)) 5171 4598 goto exit3; ··· 5173 4602 goto exit4; 5174 4603 error = vfs_rmdir(mnt_idmap(path.mnt), path.dentry->d_inode, dentry); 5175 4604 exit4: 5176 - dput(dentry); 4605 + end_dirop(dentry); 5177 4606 exit3: 5178 - inode_unlock(path.dentry->d_inode); 5179 4607 mnt_drop_write(path.mnt); 5180 4608 exit2: 5181 4609 path_put(&path); ··· 5275 4705 struct path path; 5276 4706 struct qstr last; 5277 4707 int type; 5278 - struct inode *inode = NULL; 4708 + struct inode *inode; 5279 4709 struct inode *delegated_inode = NULL; 5280 4710 unsigned int lookup_flags = 0; 5281 4711 retry: 5282 4712 error = filename_parentat(dfd, name, lookup_flags, &path, &last, &type); 5283 4713 if (error) 5284 - goto exit1; 4714 + goto exit_putname; 5285 4715 5286 4716 error = -EISDIR; 5287 4717 if (type != LAST_NORM) 5288 - goto exit2; 4718 + goto exit_path_put; 5289 4719 5290 4720 error = mnt_want_write(path.mnt); 5291 4721 if (error) 5292 - goto exit2; 4722 + goto exit_path_put; 5293 4723 retry_deleg: 5294 - inode_lock_nested(path.dentry->d_inode, I_MUTEX_PARENT); 5295 - dentry = lookup_one_qstr_excl(&last, path.dentry, lookup_flags); 4724 + dentry = start_dirop(path.dentry, &last, lookup_flags); 5296 4725 error = PTR_ERR(dentry); 5297 - if (!IS_ERR(dentry)) { 4726 + if (IS_ERR(dentry)) 4727 + goto exit_drop_write; 5298 4728 5299 - /* Why not before? Because we want correct error value */ 5300 - if (last.name[last.len]) 5301 - goto slashes; 5302 - inode = dentry->d_inode; 5303 - ihold(inode); 5304 - error = security_path_unlink(&path, dentry); 5305 - if (error) 5306 - goto exit3; 5307 - error = vfs_unlink(mnt_idmap(path.mnt), path.dentry->d_inode, 5308 - dentry, &delegated_inode); 5309 - exit3: 5310 - dput(dentry); 4729 + /* Why not before? Because we want correct error value */ 4730 + if (unlikely(last.name[last.len])) { 4731 + if (d_is_dir(dentry)) 4732 + error = -EISDIR; 4733 + else 4734 + error = -ENOTDIR; 4735 + end_dirop(dentry); 4736 + goto exit_drop_write; 5311 4737 } 5312 - inode_unlock(path.dentry->d_inode); 5313 - if (inode) 5314 - iput(inode); /* truncate the inode here */ 5315 - inode = NULL; 4738 + inode = dentry->d_inode; 4739 + ihold(inode); 4740 + error = security_path_unlink(&path, dentry); 4741 + if (error) 4742 + goto exit_end_dirop; 4743 + error = vfs_unlink(mnt_idmap(path.mnt), path.dentry->d_inode, 4744 + dentry, &delegated_inode); 4745 + exit_end_dirop: 4746 + end_dirop(dentry); 4747 + iput(inode); /* truncate the inode here */ 5316 4748 if (delegated_inode) { 5317 4749 error = break_deleg_wait(&delegated_inode); 5318 4750 if (!error) 5319 4751 goto retry_deleg; 5320 4752 } 4753 + exit_drop_write: 5321 4754 mnt_drop_write(path.mnt); 5322 - exit2: 4755 + exit_path_put: 5323 4756 path_put(&path); 5324 4757 if (retry_estale(error, lookup_flags)) { 5325 4758 lookup_flags |= LOOKUP_REVAL; 5326 - inode = NULL; 5327 4759 goto retry; 5328 4760 } 5329 - exit1: 4761 + exit_putname: 5330 4762 putname(name); 5331 4763 return error; 5332 - 5333 - slashes: 5334 - if (d_is_dir(dentry)) 5335 - error = -EISDIR; 5336 - else 5337 - error = -ENOTDIR; 5338 - goto exit3; 5339 4764 } 5340 4765 5341 4766 SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag) ··· 5821 5256 struct filename *to, unsigned int flags) 5822 5257 { 5823 5258 struct renamedata rd; 5824 - struct dentry *old_dentry, *new_dentry; 5825 - struct dentry *trap; 5826 5259 struct path old_path, new_path; 5827 5260 struct qstr old_last, new_last; 5828 5261 int old_type, new_type; 5829 5262 struct inode *delegated_inode = NULL; 5830 - unsigned int lookup_flags = 0, target_flags = 5831 - LOOKUP_RENAME_TARGET | LOOKUP_CREATE; 5263 + unsigned int lookup_flags = 0; 5832 5264 bool should_retry = false; 5833 5265 int error = -EINVAL; 5834 5266 ··· 5835 5273 if ((flags & (RENAME_NOREPLACE | RENAME_WHITEOUT)) && 5836 5274 (flags & RENAME_EXCHANGE)) 5837 5275 goto put_names; 5838 - 5839 - if (flags & RENAME_EXCHANGE) 5840 - target_flags = 0; 5841 - if (flags & RENAME_NOREPLACE) 5842 - target_flags |= LOOKUP_EXCL; 5843 5276 5844 5277 retry: 5845 5278 error = filename_parentat(olddfd, from, lookup_flags, &old_path, ··· 5865 5308 goto exit2; 5866 5309 5867 5310 retry_deleg: 5868 - trap = lock_rename(new_path.dentry, old_path.dentry); 5869 - if (IS_ERR(trap)) { 5870 - error = PTR_ERR(trap); 5871 - goto exit_lock_rename; 5872 - } 5311 + rd.old_parent = old_path.dentry; 5312 + rd.mnt_idmap = mnt_idmap(old_path.mnt); 5313 + rd.new_parent = new_path.dentry; 5314 + rd.delegated_inode = &delegated_inode; 5315 + rd.flags = flags; 5873 5316 5874 - old_dentry = lookup_one_qstr_excl(&old_last, old_path.dentry, 5875 - lookup_flags); 5876 - error = PTR_ERR(old_dentry); 5877 - if (IS_ERR(old_dentry)) 5878 - goto exit3; 5879 - new_dentry = lookup_one_qstr_excl(&new_last, new_path.dentry, 5880 - lookup_flags | target_flags); 5881 - error = PTR_ERR(new_dentry); 5882 - if (IS_ERR(new_dentry)) 5883 - goto exit4; 5317 + error = __start_renaming(&rd, lookup_flags, &old_last, &new_last); 5318 + if (error) 5319 + goto exit_lock_rename; 5320 + 5884 5321 if (flags & RENAME_EXCHANGE) { 5885 - if (!d_is_dir(new_dentry)) { 5322 + if (!d_is_dir(rd.new_dentry)) { 5886 5323 error = -ENOTDIR; 5887 5324 if (new_last.name[new_last.len]) 5888 - goto exit5; 5325 + goto exit_unlock; 5889 5326 } 5890 5327 } 5891 5328 /* unless the source is a directory trailing slashes give -ENOTDIR */ 5892 - if (!d_is_dir(old_dentry)) { 5329 + if (!d_is_dir(rd.old_dentry)) { 5893 5330 error = -ENOTDIR; 5894 5331 if (old_last.name[old_last.len]) 5895 - goto exit5; 5332 + goto exit_unlock; 5896 5333 if (!(flags & RENAME_EXCHANGE) && new_last.name[new_last.len]) 5897 - goto exit5; 5334 + goto exit_unlock; 5898 5335 } 5899 - /* source should not be ancestor of target */ 5900 - error = -EINVAL; 5901 - if (old_dentry == trap) 5902 - goto exit5; 5903 - /* target should not be an ancestor of source */ 5904 - if (!(flags & RENAME_EXCHANGE)) 5905 - error = -ENOTEMPTY; 5906 - if (new_dentry == trap) 5907 - goto exit5; 5908 5336 5909 - error = security_path_rename(&old_path, old_dentry, 5910 - &new_path, new_dentry, flags); 5337 + error = security_path_rename(&old_path, rd.old_dentry, 5338 + &new_path, rd.new_dentry, flags); 5911 5339 if (error) 5912 - goto exit5; 5340 + goto exit_unlock; 5913 5341 5914 - rd.old_parent = old_path.dentry; 5915 - rd.old_dentry = old_dentry; 5916 - rd.mnt_idmap = mnt_idmap(old_path.mnt); 5917 - rd.new_parent = new_path.dentry; 5918 - rd.new_dentry = new_dentry; 5919 - rd.delegated_inode = &delegated_inode; 5920 - rd.flags = flags; 5921 5342 error = vfs_rename(&rd); 5922 - exit5: 5923 - dput(new_dentry); 5924 - exit4: 5925 - dput(old_dentry); 5926 - exit3: 5927 - unlock_rename(new_path.dentry, old_path.dentry); 5343 + exit_unlock: 5344 + end_renaming(&rd); 5928 5345 exit_lock_rename: 5929 5346 if (delegated_inode) { 5930 5347 error = break_deleg_wait(&delegated_inode);
+5 -9
fs/nfsd/nfs3proc.c
··· 281 281 if (host_err) 282 282 return nfserrno(host_err); 283 283 284 - inode_lock_nested(inode, I_MUTEX_PARENT); 285 - 286 - child = lookup_one(&nop_mnt_idmap, 287 - &QSTR_LEN(argp->name, argp->len), 288 - parent); 284 + child = start_creating(&nop_mnt_idmap, parent, 285 + &QSTR_LEN(argp->name, argp->len)); 289 286 if (IS_ERR(child)) { 290 287 status = nfserrno(PTR_ERR(child)); 291 - goto out; 288 + goto out_write; 292 289 } 293 290 294 291 if (d_really_is_negative(child)) { ··· 364 367 status = nfsd_create_setattr(rqstp, fhp, resfhp, &attrs); 365 368 366 369 out: 367 - inode_unlock(inode); 368 - if (child && !IS_ERR(child)) 369 - dput(child); 370 + end_creating(child); 371 + out_write: 370 372 fh_drop_write(fhp); 371 373 return status; 372 374 }
+5 -9
fs/nfsd/nfs4proc.c
··· 264 264 if (is_create_with_attrs(open)) 265 265 nfsd4_acl_to_attr(NF4REG, open->op_acl, &attrs); 266 266 267 - inode_lock_nested(inode, I_MUTEX_PARENT); 268 - 269 - child = lookup_one(&nop_mnt_idmap, 270 - &QSTR_LEN(open->op_fname, open->op_fnamelen), 271 - parent); 267 + child = start_creating(&nop_mnt_idmap, parent, 268 + &QSTR_LEN(open->op_fname, open->op_fnamelen)); 272 269 if (IS_ERR(child)) { 273 270 status = nfserrno(PTR_ERR(child)); 274 - goto out; 271 + goto out_write; 275 272 } 276 273 277 274 if (d_really_is_negative(child)) { ··· 376 379 if (attrs.na_aclerr) 377 380 open->op_bmval[0] &= ~FATTR4_WORD0_ACL; 378 381 out: 379 - inode_unlock(inode); 382 + end_creating(child); 380 383 nfsd_attrs_free(&attrs); 381 - if (child && !IS_ERR(child)) 382 - dput(child); 384 + out_write: 383 385 fh_drop_write(fhp); 384 386 return status; 385 387 }
+11 -23
fs/nfsd/nfs4recover.c
··· 195 195 goto out_creds; 196 196 197 197 dir = nn->rec_file->f_path.dentry; 198 - /* lock the parent */ 199 - inode_lock(d_inode(dir)); 200 198 201 - dentry = lookup_one(&nop_mnt_idmap, &QSTR(dname), dir); 199 + dentry = start_creating(&nop_mnt_idmap, dir, &QSTR(dname)); 202 200 if (IS_ERR(dentry)) { 203 201 status = PTR_ERR(dentry); 204 - goto out_unlock; 202 + goto out; 205 203 } 206 204 if (d_really_is_positive(dentry)) 207 205 /* ··· 210 212 * In the 4.0 case, we should never get here; but we may 211 213 * as well be forgiving and just succeed silently. 212 214 */ 213 - goto out_put; 215 + goto out_end; 214 216 dentry = vfs_mkdir(&nop_mnt_idmap, d_inode(dir), dentry, S_IRWXU); 215 217 if (IS_ERR(dentry)) 216 218 status = PTR_ERR(dentry); 217 - out_put: 218 - if (!status) 219 - dput(dentry); 220 - out_unlock: 221 - inode_unlock(d_inode(dir)); 219 + out_end: 220 + end_creating(dentry); 221 + out: 222 222 if (status == 0) { 223 223 if (nn->in_grace) 224 224 __nfsd4_create_reclaim_record_grace(clp, dname, ··· 324 328 dprintk("NFSD: nfsd4_unlink_clid_dir. name %s\n", name); 325 329 326 330 dir = nn->rec_file->f_path.dentry; 327 - inode_lock_nested(d_inode(dir), I_MUTEX_PARENT); 328 - dentry = lookup_one(&nop_mnt_idmap, &QSTR(name), dir); 329 - if (IS_ERR(dentry)) { 330 - status = PTR_ERR(dentry); 331 - goto out_unlock; 332 - } 333 - status = -ENOENT; 334 - if (d_really_is_negative(dentry)) 335 - goto out; 331 + dentry = start_removing(&nop_mnt_idmap, dir, &QSTR(name)); 332 + if (IS_ERR(dentry)) 333 + return PTR_ERR(dentry); 334 + 336 335 status = vfs_rmdir(&nop_mnt_idmap, d_inode(dir), dentry); 337 - out: 338 - dput(dentry); 339 - out_unlock: 340 - inode_unlock(d_inode(dir)); 336 + end_removing(dentry); 341 337 return status; 342 338 } 343 339
+5 -6
fs/nfsd/nfsproc.c
··· 306 306 goto done; 307 307 } 308 308 309 - inode_lock_nested(dirfhp->fh_dentry->d_inode, I_MUTEX_PARENT); 310 - dchild = lookup_one(&nop_mnt_idmap, &QSTR_LEN(argp->name, argp->len), 311 - dirfhp->fh_dentry); 309 + dchild = start_creating(&nop_mnt_idmap, dirfhp->fh_dentry, 310 + &QSTR_LEN(argp->name, argp->len)); 312 311 if (IS_ERR(dchild)) { 313 312 resp->status = nfserrno(PTR_ERR(dchild)); 314 - goto out_unlock; 313 + goto out_write; 315 314 } 316 315 fh_init(newfhp, NFS_FHSIZE); 317 316 resp->status = fh_compose(newfhp, dirfhp->fh_export, dchild, dirfhp); 318 317 if (!resp->status && d_really_is_negative(dchild)) 319 318 resp->status = nfserr_noent; 320 - dput(dchild); 321 319 if (resp->status) { 322 320 if (resp->status != nfserr_noent) 323 321 goto out_unlock; ··· 421 423 } 422 424 423 425 out_unlock: 424 - inode_unlock(dirfhp->fh_dentry->d_inode); 426 + end_creating(dchild); 427 + out_write: 425 428 fh_drop_write(dirfhp); 426 429 done: 427 430 fh_put(dirfhp);
+55 -94
fs/nfsd/vfs.c
··· 1521 1521 iap->ia_valid &= ~ATTR_SIZE; 1522 1522 } 1523 1523 1524 - /* The parent directory should already be locked: */ 1524 + /* The parent directory should already be locked - we will unlock */ 1525 1525 __be32 1526 1526 nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp, 1527 1527 struct nfsd_attrs *attrs, ··· 1587 1587 err = nfsd_create_setattr(rqstp, fhp, resfhp, attrs); 1588 1588 1589 1589 out: 1590 - if (!IS_ERR(dchild)) 1591 - dput(dchild); 1590 + if (!err) 1591 + fh_fill_post_attrs(fhp); 1592 + end_creating(dchild); 1592 1593 return err; 1593 1594 1594 1595 out_nfserr: ··· 1627 1626 if (host_err) 1628 1627 return nfserrno(host_err); 1629 1628 1630 - inode_lock_nested(dentry->d_inode, I_MUTEX_PARENT); 1631 - dchild = lookup_one(&nop_mnt_idmap, &QSTR_LEN(fname, flen), dentry); 1629 + dchild = start_creating(&nop_mnt_idmap, dentry, &QSTR_LEN(fname, flen)); 1632 1630 host_err = PTR_ERR(dchild); 1633 - if (IS_ERR(dchild)) { 1634 - err = nfserrno(host_err); 1635 - goto out_unlock; 1636 - } 1631 + if (IS_ERR(dchild)) 1632 + return nfserrno(host_err); 1633 + 1637 1634 err = fh_compose(resfhp, fhp->fh_export, dchild, fhp); 1638 1635 /* 1639 1636 * We unconditionally drop our ref to dchild as fh_compose will have 1640 1637 * already grabbed its own ref for it. 1641 1638 */ 1642 - dput(dchild); 1643 1639 if (err) 1644 1640 goto out_unlock; 1645 1641 err = fh_fill_pre_attrs(fhp); 1646 1642 if (err != nfs_ok) 1647 1643 goto out_unlock; 1648 1644 err = nfsd_create_locked(rqstp, fhp, attrs, type, rdev, resfhp); 1649 - fh_fill_post_attrs(fhp); 1645 + return err; 1646 + 1650 1647 out_unlock: 1651 - inode_unlock(dentry->d_inode); 1648 + end_creating(dchild); 1652 1649 return err; 1653 1650 } 1654 1651 ··· 1732 1733 } 1733 1734 1734 1735 dentry = fhp->fh_dentry; 1735 - inode_lock_nested(dentry->d_inode, I_MUTEX_PARENT); 1736 - dnew = lookup_one(&nop_mnt_idmap, &QSTR_LEN(fname, flen), dentry); 1736 + dnew = start_creating(&nop_mnt_idmap, dentry, &QSTR_LEN(fname, flen)); 1737 1737 if (IS_ERR(dnew)) { 1738 1738 err = nfserrno(PTR_ERR(dnew)); 1739 - inode_unlock(dentry->d_inode); 1740 1739 goto out_drop_write; 1741 1740 } 1742 1741 err = fh_fill_pre_attrs(fhp); ··· 1747 1750 nfsd_create_setattr(rqstp, fhp, resfhp, attrs); 1748 1751 fh_fill_post_attrs(fhp); 1749 1752 out_unlock: 1750 - inode_unlock(dentry->d_inode); 1753 + end_creating(dnew); 1751 1754 if (!err) 1752 1755 err = nfserrno(commit_metadata(fhp)); 1753 - dput(dnew); 1754 - if (err==0) err = cerr; 1756 + if (!err) 1757 + err = cerr; 1755 1758 out_drop_write: 1756 1759 fh_drop_write(fhp); 1757 1760 out: ··· 1806 1809 1807 1810 ddir = ffhp->fh_dentry; 1808 1811 dirp = d_inode(ddir); 1809 - inode_lock_nested(dirp, I_MUTEX_PARENT); 1812 + dnew = start_creating(&nop_mnt_idmap, ddir, &QSTR_LEN(name, len)); 1810 1813 1811 - dnew = lookup_one(&nop_mnt_idmap, &QSTR_LEN(name, len), ddir); 1812 1814 if (IS_ERR(dnew)) { 1813 1815 host_err = PTR_ERR(dnew); 1814 - goto out_unlock; 1816 + goto out_drop_write; 1815 1817 } 1816 1818 1817 1819 dold = tfhp->fh_dentry; 1818 1820 1819 1821 err = nfserr_noent; 1820 1822 if (d_really_is_negative(dold)) 1821 - goto out_dput; 1823 + goto out_unlock; 1822 1824 err = fh_fill_pre_attrs(ffhp); 1823 1825 if (err != nfs_ok) 1824 - goto out_dput; 1826 + goto out_unlock; 1825 1827 host_err = vfs_link(dold, &nop_mnt_idmap, dirp, dnew, NULL); 1826 1828 fh_fill_post_attrs(ffhp); 1827 - inode_unlock(dirp); 1829 + out_unlock: 1830 + end_creating(dnew); 1828 1831 if (!host_err) { 1829 1832 host_err = commit_metadata(ffhp); 1830 1833 if (!host_err) 1831 1834 host_err = commit_metadata(tfhp); 1832 1835 } 1833 1836 1834 - dput(dnew); 1835 1837 out_drop_write: 1836 1838 fh_drop_write(tfhp); 1837 1839 if (host_err == -EBUSY) { ··· 1845 1849 } 1846 1850 out: 1847 1851 return err != nfs_ok ? err : nfserrno(host_err); 1848 - 1849 - out_dput: 1850 - dput(dnew); 1851 - out_unlock: 1852 - inode_unlock(dirp); 1853 - goto out_drop_write; 1854 1852 } 1855 1853 1856 1854 static void ··· 1885 1895 nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, 1886 1896 struct svc_fh *tfhp, char *tname, int tlen) 1887 1897 { 1888 - struct dentry *fdentry, *tdentry, *odentry, *ndentry, *trap; 1898 + struct dentry *fdentry, *tdentry; 1889 1899 int type = S_IFDIR; 1900 + struct renamedata rd = {}; 1890 1901 __be32 err; 1891 1902 int host_err; 1892 - bool close_cached = false; 1903 + struct dentry *close_cached; 1893 1904 1894 1905 trace_nfsd_vfs_rename(rqstp, ffhp, tfhp, fname, flen, tname, tlen); 1895 1906 ··· 1916 1925 goto out; 1917 1926 1918 1927 retry: 1928 + close_cached = NULL; 1919 1929 host_err = fh_want_write(ffhp); 1920 1930 if (host_err) { 1921 1931 err = nfserrno(host_err); 1922 1932 goto out; 1923 1933 } 1924 1934 1925 - trap = lock_rename(tdentry, fdentry); 1926 - if (IS_ERR(trap)) { 1927 - err = nfserr_xdev; 1935 + rd.mnt_idmap = &nop_mnt_idmap; 1936 + rd.old_parent = fdentry; 1937 + rd.new_parent = tdentry; 1938 + 1939 + host_err = start_renaming(&rd, 0, &QSTR_LEN(fname, flen), 1940 + &QSTR_LEN(tname, tlen)); 1941 + 1942 + if (host_err) { 1943 + err = nfserrno(host_err); 1928 1944 goto out_want_write; 1929 1945 } 1930 1946 err = fh_fill_pre_attrs(ffhp); ··· 1941 1943 if (err != nfs_ok) 1942 1944 goto out_unlock; 1943 1945 1944 - odentry = lookup_one(&nop_mnt_idmap, &QSTR_LEN(fname, flen), fdentry); 1945 - host_err = PTR_ERR(odentry); 1946 - if (IS_ERR(odentry)) 1947 - goto out_nfserr; 1946 + type = d_inode(rd.old_dentry)->i_mode & S_IFMT; 1948 1947 1949 - host_err = -ENOENT; 1950 - if (d_really_is_negative(odentry)) 1951 - goto out_dput_old; 1952 - host_err = -EINVAL; 1953 - if (odentry == trap) 1954 - goto out_dput_old; 1955 - type = d_inode(odentry)->i_mode & S_IFMT; 1948 + if (d_inode(rd.new_dentry)) 1949 + type = d_inode(rd.new_dentry)->i_mode & S_IFMT; 1956 1950 1957 - ndentry = lookup_one(&nop_mnt_idmap, &QSTR_LEN(tname, tlen), tdentry); 1958 - host_err = PTR_ERR(ndentry); 1959 - if (IS_ERR(ndentry)) 1960 - goto out_dput_old; 1961 - if (d_inode(ndentry)) 1962 - type = d_inode(ndentry)->i_mode & S_IFMT; 1963 - host_err = -ENOTEMPTY; 1964 - if (ndentry == trap) 1965 - goto out_dput_new; 1966 - 1967 - if ((ndentry->d_sb->s_export_op->flags & EXPORT_OP_CLOSE_BEFORE_UNLINK) && 1968 - nfsd_has_cached_files(ndentry)) { 1969 - close_cached = true; 1970 - goto out_dput_old; 1951 + if ((rd.new_dentry->d_sb->s_export_op->flags & EXPORT_OP_CLOSE_BEFORE_UNLINK) && 1952 + nfsd_has_cached_files(rd.new_dentry)) { 1953 + close_cached = dget(rd.new_dentry); 1954 + goto out_unlock; 1971 1955 } else { 1972 - struct renamedata rd = { 1973 - .mnt_idmap = &nop_mnt_idmap, 1974 - .old_parent = fdentry, 1975 - .old_dentry = odentry, 1976 - .new_parent = tdentry, 1977 - .new_dentry = ndentry, 1978 - }; 1979 1956 int retries; 1980 1957 1981 1958 for (retries = 1;;) { 1982 1959 host_err = vfs_rename(&rd); 1983 1960 if (host_err != -EAGAIN || !retries--) 1984 1961 break; 1985 - if (!nfsd_wait_for_delegreturn(rqstp, d_inode(odentry))) 1962 + if (!nfsd_wait_for_delegreturn(rqstp, d_inode(rd.old_dentry))) 1986 1963 break; 1987 1964 } 1988 1965 if (!host_err) { ··· 1966 1993 host_err = commit_metadata(ffhp); 1967 1994 } 1968 1995 } 1969 - out_dput_new: 1970 - dput(ndentry); 1971 - out_dput_old: 1972 - dput(odentry); 1973 - out_nfserr: 1974 1996 if (host_err == -EBUSY) { 1975 1997 /* 1976 1998 * See RFC 8881 Section 18.26.4 para 1-3: NFSv4 RENAME ··· 1984 2016 fh_fill_post_attrs(tfhp); 1985 2017 } 1986 2018 out_unlock: 1987 - unlock_rename(tdentry, fdentry); 2019 + end_renaming(&rd); 1988 2020 out_want_write: 1989 2021 fh_drop_write(ffhp); 1990 2022 ··· 1995 2027 * until this point and then reattempt the whole shebang. 1996 2028 */ 1997 2029 if (close_cached) { 1998 - close_cached = false; 1999 - nfsd_close_cached_files(ndentry); 2000 - dput(ndentry); 2030 + nfsd_close_cached_files(close_cached); 2031 + dput(close_cached); 2001 2032 goto retry; 2002 2033 } 2003 2034 out: ··· 2021 2054 { 2022 2055 struct dentry *dentry, *rdentry; 2023 2056 struct inode *dirp; 2024 - struct inode *rinode; 2057 + struct inode *rinode = NULL; 2025 2058 __be32 err; 2026 2059 int host_err; 2027 2060 ··· 2040 2073 2041 2074 dentry = fhp->fh_dentry; 2042 2075 dirp = d_inode(dentry); 2043 - inode_lock_nested(dirp, I_MUTEX_PARENT); 2044 2076 2045 - rdentry = lookup_one(&nop_mnt_idmap, &QSTR_LEN(fname, flen), dentry); 2077 + rdentry = start_removing(&nop_mnt_idmap, dentry, &QSTR_LEN(fname, flen)); 2078 + 2046 2079 host_err = PTR_ERR(rdentry); 2047 2080 if (IS_ERR(rdentry)) 2048 - goto out_unlock; 2081 + goto out_drop_write; 2049 2082 2050 - if (d_really_is_negative(rdentry)) { 2051 - dput(rdentry); 2052 - host_err = -ENOENT; 2053 - goto out_unlock; 2054 - } 2055 - rinode = d_inode(rdentry); 2056 2083 err = fh_fill_pre_attrs(fhp); 2057 2084 if (err != nfs_ok) 2058 2085 goto out_unlock; 2059 2086 2087 + rinode = d_inode(rdentry); 2088 + /* Prevent truncation until after locks dropped */ 2060 2089 ihold(rinode); 2090 + 2061 2091 if (!type) 2062 2092 type = d_inode(rdentry)->i_mode & S_IFMT; 2063 2093 ··· 2076 2112 } 2077 2113 fh_fill_post_attrs(fhp); 2078 2114 2079 - inode_unlock(dirp); 2080 - if (!host_err) 2115 + out_unlock: 2116 + end_removing(rdentry); 2117 + if (!err && !host_err) 2081 2118 host_err = commit_metadata(fhp); 2082 - dput(rdentry); 2083 2119 iput(rinode); /* truncate the inode here */ 2084 2120 2085 2121 out_drop_write: ··· 2097 2133 } 2098 2134 out: 2099 2135 return err != nfs_ok ? err : nfserrno(host_err); 2100 - out_unlock: 2101 - inode_unlock(dirp); 2102 - goto out_drop_write; 2103 2136 } 2104 2137 2105 2138 /*
+31 -42
fs/overlayfs/copy_up.c
··· 523 523 { 524 524 struct ovl_fs *ofs = OVL_FS(dentry->d_sb); 525 525 struct dentry *indexdir = ovl_indexdir(dentry->d_sb); 526 - struct dentry *index = NULL; 527 526 struct dentry *temp = NULL; 527 + struct renamedata rd = {}; 528 528 struct qstr name = { }; 529 529 int err; 530 530 ··· 556 556 if (err) 557 557 goto out; 558 558 559 - err = ovl_parent_lock(indexdir, temp); 559 + rd.mnt_idmap = ovl_upper_mnt_idmap(ofs); 560 + rd.old_parent = indexdir; 561 + rd.new_parent = indexdir; 562 + err = start_renaming_dentry(&rd, 0, temp, &name); 560 563 if (err) 561 564 goto out; 562 - index = ovl_lookup_upper(ofs, name.name, indexdir, name.len); 563 - if (IS_ERR(index)) { 564 - err = PTR_ERR(index); 565 - } else { 566 - err = ovl_do_rename(ofs, indexdir, temp, indexdir, index, 0); 567 - dput(index); 568 - } 569 - ovl_parent_unlock(indexdir); 565 + 566 + err = ovl_do_rename_rd(&rd); 567 + end_renaming(&rd); 570 568 out: 571 569 if (err) 572 570 ovl_cleanup(ofs, indexdir, temp); ··· 611 613 if (err) 612 614 goto out; 613 615 614 - inode_lock_nested(udir, I_MUTEX_PARENT); 615 - upper = ovl_lookup_upper(ofs, c->dentry->d_name.name, upperdir, 616 - c->dentry->d_name.len); 616 + upper = ovl_start_creating_upper(ofs, upperdir, 617 + &QSTR_LEN(c->dentry->d_name.name, 618 + c->dentry->d_name.len)); 617 619 err = PTR_ERR(upper); 618 620 if (!IS_ERR(upper)) { 619 621 err = ovl_do_link(ofs, ovl_dentry_upper(c->dentry), udir, upper); ··· 624 626 ovl_dentry_set_upper_alias(c->dentry); 625 627 ovl_dentry_update_reval(c->dentry, upper); 626 628 } 627 - dput(upper); 629 + end_creating(upper); 628 630 } 629 - inode_unlock(udir); 630 631 if (err) 631 632 goto out; 632 633 ··· 761 764 struct ovl_fs *ofs = OVL_FS(c->dentry->d_sb); 762 765 struct inode *inode; 763 766 struct path path = { .mnt = ovl_upper_mnt(ofs) }; 764 - struct dentry *temp, *upper, *trap; 767 + struct renamedata rd = {}; 768 + struct dentry *temp; 765 769 struct ovl_cu_creds cc; 766 770 int err; 767 771 struct ovl_cattr cattr = { ··· 806 808 * ovl_copy_up_data(), so lock workdir and destdir and make sure that 807 809 * temp wasn't moved before copy up completion or cleanup. 808 810 */ 809 - trap = lock_rename(c->workdir, c->destdir); 810 - if (trap || temp->d_parent != c->workdir) { 811 - /* temp or workdir moved underneath us? abort without cleanup */ 812 - dput(temp); 811 + rd.mnt_idmap = ovl_upper_mnt_idmap(ofs); 812 + rd.old_parent = c->workdir; 813 + rd.new_parent = c->destdir; 814 + rd.flags = 0; 815 + err = start_renaming_dentry(&rd, 0, temp, 816 + &QSTR_LEN(c->destname.name, c->destname.len)); 817 + if (err) { 818 + /* temp or workdir moved underneath us? map to -EIO */ 813 819 err = -EIO; 814 - if (!IS_ERR(trap)) 815 - unlock_rename(c->workdir, c->destdir); 816 - goto out; 817 820 } 821 + if (err) 822 + goto cleanup_unlocked; 818 823 819 824 err = ovl_copy_up_metadata(c, temp); 820 - if (err) 821 - goto cleanup; 825 + if (!err) 826 + err = ovl_do_rename_rd(&rd); 827 + end_renaming(&rd); 822 828 823 - upper = ovl_lookup_upper(ofs, c->destname.name, c->destdir, 824 - c->destname.len); 825 - err = PTR_ERR(upper); 826 - if (IS_ERR(upper)) 827 - goto cleanup; 828 - 829 - err = ovl_do_rename(ofs, c->workdir, temp, c->destdir, upper, 0); 830 - unlock_rename(c->workdir, c->destdir); 831 - dput(upper); 832 829 if (err) 833 830 goto cleanup_unlocked; 834 831 ··· 844 851 845 852 return err; 846 853 847 - cleanup: 848 - unlock_rename(c->workdir, c->destdir); 849 854 cleanup_unlocked: 850 855 ovl_cleanup(ofs, c->workdir, temp); 851 856 dput(temp); ··· 885 894 if (err) 886 895 goto out; 887 896 888 - inode_lock_nested(udir, I_MUTEX_PARENT); 889 - 890 - upper = ovl_lookup_upper(ofs, c->destname.name, c->destdir, 891 - c->destname.len); 897 + upper = ovl_start_creating_upper(ofs, c->destdir, 898 + &QSTR_LEN(c->destname.name, 899 + c->destname.len)); 892 900 err = PTR_ERR(upper); 893 901 if (!IS_ERR(upper)) { 894 902 err = ovl_do_link(ofs, temp, udir, upper); 895 - dput(upper); 903 + end_creating(upper); 896 904 } 897 - inode_unlock(udir); 898 905 899 906 if (err) 900 907 goto out;
+118 -123
fs/overlayfs/dir.c
··· 47 47 int ovl_cleanup(struct ovl_fs *ofs, struct dentry *workdir, 48 48 struct dentry *wdentry) 49 49 { 50 - int err; 51 - 52 - err = ovl_parent_lock(workdir, wdentry); 53 - if (err) 54 - return err; 50 + wdentry = start_removing_dentry(workdir, wdentry); 51 + if (IS_ERR(wdentry)) 52 + return PTR_ERR(wdentry); 55 53 56 54 ovl_cleanup_locked(ofs, workdir->d_inode, wdentry); 57 - ovl_parent_unlock(workdir); 55 + end_removing(wdentry); 58 56 59 57 return 0; 60 58 } 61 59 62 - struct dentry *ovl_lookup_temp(struct ovl_fs *ofs, struct dentry *workdir) 60 + void ovl_tempname(char name[OVL_TEMPNAME_SIZE]) 63 61 { 64 - struct dentry *temp; 65 - char name[20]; 66 62 static atomic_t temp_id = ATOMIC_INIT(0); 67 63 68 64 /* counter is allowed to wrap, since temp dentries are ephemeral */ 69 - snprintf(name, sizeof(name), "#%x", atomic_inc_return(&temp_id)); 65 + snprintf(name, OVL_TEMPNAME_SIZE, "#%x", atomic_inc_return(&temp_id)); 66 + } 70 67 71 - temp = ovl_lookup_upper(ofs, name, workdir, strlen(name)); 72 - if (!IS_ERR(temp) && temp->d_inode) { 73 - pr_err("workdir/%s already exists\n", name); 74 - dput(temp); 75 - temp = ERR_PTR(-EIO); 76 - } 68 + static struct dentry *ovl_start_creating_temp(struct ovl_fs *ofs, 69 + struct dentry *workdir) 70 + { 71 + char name[OVL_TEMPNAME_SIZE]; 77 72 78 - return temp; 73 + ovl_tempname(name); 74 + return start_creating(ovl_upper_mnt_idmap(ofs), workdir, 75 + &QSTR(name)); 79 76 } 80 77 81 78 static struct dentry *ovl_whiteout(struct ovl_fs *ofs) 82 79 { 83 80 int err; 84 - struct dentry *whiteout; 81 + struct dentry *whiteout, *link; 85 82 struct dentry *workdir = ofs->workdir; 86 83 struct inode *wdir = workdir->d_inode; 87 84 88 85 guard(mutex)(&ofs->whiteout_lock); 89 86 90 87 if (!ofs->whiteout) { 91 - inode_lock_nested(wdir, I_MUTEX_PARENT); 92 - whiteout = ovl_lookup_temp(ofs, workdir); 93 - if (!IS_ERR(whiteout)) { 94 - err = ovl_do_whiteout(ofs, wdir, whiteout); 95 - if (err) { 96 - dput(whiteout); 97 - whiteout = ERR_PTR(err); 98 - } 99 - } 100 - inode_unlock(wdir); 88 + whiteout = ovl_start_creating_temp(ofs, workdir); 101 89 if (IS_ERR(whiteout)) 102 90 return whiteout; 103 - ofs->whiteout = whiteout; 91 + err = ovl_do_whiteout(ofs, wdir, whiteout); 92 + if (!err) 93 + ofs->whiteout = dget(whiteout); 94 + end_creating(whiteout); 95 + if (err) 96 + return ERR_PTR(err); 104 97 } 105 98 106 99 if (!ofs->no_shared_whiteout) { 107 - inode_lock_nested(wdir, I_MUTEX_PARENT); 108 - whiteout = ovl_lookup_temp(ofs, workdir); 109 - if (!IS_ERR(whiteout)) { 110 - err = ovl_do_link(ofs, ofs->whiteout, wdir, whiteout); 111 - if (err) { 112 - dput(whiteout); 113 - whiteout = ERR_PTR(err); 114 - } 115 - } 116 - inode_unlock(wdir); 117 - if (!IS_ERR(whiteout)) 118 - return whiteout; 119 - if (PTR_ERR(whiteout) != -EMLINK) { 120 - pr_warn("Failed to link whiteout - disabling whiteout inode sharing(nlink=%u, err=%lu)\n", 100 + link = ovl_start_creating_temp(ofs, workdir); 101 + if (IS_ERR(link)) 102 + return link; 103 + err = ovl_do_link(ofs, ofs->whiteout, wdir, link); 104 + if (!err) 105 + whiteout = dget(link); 106 + end_creating(link); 107 + if (!err) 108 + return whiteout;; 109 + 110 + if (err != -EMLINK) { 111 + pr_warn("Failed to link whiteout - disabling whiteout inode sharing(nlink=%u, err=%u)\n", 121 112 ofs->whiteout->d_inode->i_nlink, 122 - PTR_ERR(whiteout)); 113 + err); 123 114 ofs->no_shared_whiteout = true; 124 115 } 125 116 } ··· 123 132 struct dentry *dentry) 124 133 { 125 134 struct dentry *whiteout; 135 + struct renamedata rd = {}; 126 136 int err; 127 137 int flags = 0; 128 138 ··· 135 143 if (d_is_dir(dentry)) 136 144 flags = RENAME_EXCHANGE; 137 145 138 - err = ovl_lock_rename_workdir(ofs->workdir, whiteout, dir, dentry); 146 + rd.mnt_idmap = ovl_upper_mnt_idmap(ofs); 147 + rd.old_parent = ofs->workdir; 148 + rd.new_parent = dir; 149 + rd.flags = flags; 150 + err = start_renaming_two_dentries(&rd, whiteout, dentry); 139 151 if (!err) { 140 - err = ovl_do_rename(ofs, ofs->workdir, whiteout, dir, dentry, flags); 141 - unlock_rename(ofs->workdir, dir); 152 + err = ovl_do_rename_rd(&rd); 153 + end_renaming(&rd); 142 154 } 143 155 if (err) 144 156 goto kill_whiteout; ··· 187 191 if (!err && ofs->casefold != ovl_dentry_casefolded(newdentry)) { 188 192 pr_warn_ratelimited("wrong inherited casefold (%pd2)\n", 189 193 newdentry); 190 - dput(newdentry); 194 + end_creating(newdentry); 191 195 err = -EINVAL; 192 196 } 193 197 break; ··· 237 241 } 238 242 out: 239 243 if (err) { 240 - if (!IS_ERR(newdentry)) 241 - dput(newdentry); 244 + end_creating(newdentry); 242 245 return ERR_PTR(err); 243 246 } 244 247 return newdentry; ··· 247 252 struct ovl_cattr *attr) 248 253 { 249 254 struct dentry *ret; 250 - inode_lock_nested(workdir->d_inode, I_MUTEX_PARENT); 251 - ret = ovl_create_real(ofs, workdir, 252 - ovl_lookup_temp(ofs, workdir), attr); 253 - inode_unlock(workdir->d_inode); 254 - return ret; 255 + ret = ovl_start_creating_temp(ofs, workdir); 256 + if (IS_ERR(ret)) 257 + return ret; 258 + ret = ovl_create_real(ofs, workdir, ret, attr); 259 + return end_creating_keep(ret); 255 260 } 256 261 257 262 static int ovl_set_opaque_xerr(struct dentry *dentry, struct dentry *upper, ··· 349 354 { 350 355 struct ovl_fs *ofs = OVL_FS(dentry->d_sb); 351 356 struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent); 352 - struct inode *udir = upperdir->d_inode; 353 357 struct dentry *newdentry; 354 358 int err; 355 359 356 - inode_lock_nested(udir, I_MUTEX_PARENT); 357 - newdentry = ovl_create_real(ofs, upperdir, 358 - ovl_lookup_upper(ofs, dentry->d_name.name, 359 - upperdir, dentry->d_name.len), 360 - attr); 361 - inode_unlock(udir); 360 + newdentry = ovl_start_creating_upper(ofs, upperdir, 361 + &QSTR_LEN(dentry->d_name.name, 362 + dentry->d_name.len)); 362 363 if (IS_ERR(newdentry)) 363 364 return PTR_ERR(newdentry); 365 + newdentry = ovl_create_real(ofs, upperdir, newdentry, attr); 366 + if (IS_ERR(newdentry)) 367 + return PTR_ERR(newdentry); 368 + 369 + end_creating_keep(newdentry); 364 370 365 371 if (ovl_type_merge(dentry->d_parent) && d_is_dir(newdentry) && 366 372 !ovl_allow_offline_changes(ofs)) { ··· 387 391 struct ovl_fs *ofs = OVL_FS(dentry->d_sb); 388 392 struct dentry *workdir = ovl_workdir(dentry); 389 393 struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent); 394 + struct renamedata rd = {}; 390 395 struct path upperpath; 391 396 struct dentry *upper; 392 397 struct dentry *opaquedir; ··· 413 416 if (IS_ERR(opaquedir)) 414 417 goto out; 415 418 416 - err = ovl_lock_rename_workdir(workdir, opaquedir, upperdir, upper); 419 + rd.mnt_idmap = ovl_upper_mnt_idmap(ofs); 420 + rd.old_parent = workdir; 421 + rd.new_parent = upperdir; 422 + rd.flags = RENAME_EXCHANGE; 423 + err = start_renaming_two_dentries(&rd, opaquedir, upper); 417 424 if (err) 418 425 goto out_cleanup_unlocked; 419 426 ··· 435 434 if (err) 436 435 goto out_cleanup; 437 436 438 - err = ovl_do_rename(ofs, workdir, opaquedir, upperdir, upper, RENAME_EXCHANGE); 439 - unlock_rename(workdir, upperdir); 437 + err = ovl_do_rename_rd(&rd); 438 + end_renaming(&rd); 440 439 if (err) 441 440 goto out_cleanup_unlocked; 442 441 ··· 449 448 return opaquedir; 450 449 451 450 out_cleanup: 452 - unlock_rename(workdir, upperdir); 451 + end_renaming(&rd); 453 452 out_cleanup_unlocked: 454 453 ovl_cleanup(ofs, workdir, opaquedir); 455 454 dput(opaquedir); ··· 472 471 struct ovl_fs *ofs = OVL_FS(dentry->d_sb); 473 472 struct dentry *workdir = ovl_workdir(dentry); 474 473 struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent); 474 + struct renamedata rd = {}; 475 475 struct dentry *upper; 476 476 struct dentry *newdentry; 477 477 int err; ··· 504 502 if (IS_ERR(newdentry)) 505 503 goto out_dput; 506 504 507 - err = ovl_lock_rename_workdir(workdir, newdentry, upperdir, upper); 505 + rd.mnt_idmap = ovl_upper_mnt_idmap(ofs); 506 + rd.old_parent = workdir; 507 + rd.new_parent = upperdir; 508 + rd.flags = 0; 509 + err = start_renaming_two_dentries(&rd, newdentry, upper); 508 510 if (err) 509 511 goto out_cleanup_unlocked; 510 512 ··· 545 539 if (err) 546 540 goto out_cleanup; 547 541 548 - err = ovl_do_rename(ofs, workdir, newdentry, upperdir, upper, 549 - RENAME_EXCHANGE); 550 - unlock_rename(workdir, upperdir); 542 + rd.flags = RENAME_EXCHANGE; 543 + err = ovl_do_rename_rd(&rd); 544 + end_renaming(&rd); 551 545 if (err) 552 546 goto out_cleanup_unlocked; 553 547 554 548 ovl_cleanup(ofs, workdir, upper); 555 549 } else { 556 - err = ovl_do_rename(ofs, workdir, newdentry, upperdir, upper, 0); 557 - unlock_rename(workdir, upperdir); 550 + err = ovl_do_rename_rd(&rd); 551 + end_renaming(&rd); 558 552 if (err) 559 553 goto out_cleanup_unlocked; 560 554 } ··· 574 568 return err; 575 569 576 570 out_cleanup: 577 - unlock_rename(workdir, upperdir); 571 + end_renaming(&rd); 578 572 out_cleanup_unlocked: 579 573 ovl_cleanup(ofs, workdir, newdentry); 580 574 dput(newdentry); ··· 856 850 goto out; 857 851 } 858 852 859 - inode_lock_nested(dir, I_MUTEX_PARENT); 860 - upper = ovl_lookup_upper(ofs, dentry->d_name.name, upperdir, 861 - dentry->d_name.len); 853 + upper = ovl_start_removing_upper(ofs, upperdir, 854 + &QSTR_LEN(dentry->d_name.name, 855 + dentry->d_name.len)); 862 856 err = PTR_ERR(upper); 863 857 if (IS_ERR(upper)) 864 - goto out_unlock; 858 + goto out_dput; 865 859 866 860 err = -ESTALE; 867 861 if ((opaquedir && upper != opaquedir) || 868 862 (!opaquedir && !ovl_matches_upper(dentry, upper))) 869 - goto out_dput_upper; 863 + goto out_unlock; 870 864 871 865 if (is_dir) 872 866 err = ovl_do_rmdir(ofs, dir, upper); ··· 882 876 */ 883 877 if (!err) 884 878 d_drop(dentry); 885 - out_dput_upper: 886 - dput(upper); 887 879 out_unlock: 888 - inode_unlock(dir); 880 + end_removing(upper); 881 + out_dput: 889 882 dput(opaquedir); 890 883 out: 891 884 return err; ··· 1116 1111 int err; 1117 1112 struct dentry *old_upperdir; 1118 1113 struct dentry *new_upperdir; 1119 - struct dentry *olddentry = NULL; 1120 - struct dentry *newdentry = NULL; 1121 - struct dentry *trap, *de; 1114 + struct renamedata rd = {}; 1122 1115 bool old_opaque; 1123 1116 bool new_opaque; 1124 1117 bool cleanup_whiteout = false; ··· 1126 1123 bool new_is_dir = d_is_dir(new); 1127 1124 bool samedir = olddir == newdir; 1128 1125 struct dentry *opaquedir = NULL; 1126 + struct dentry *whiteout = NULL; 1129 1127 const struct cred *old_cred = NULL; 1130 1128 struct ovl_fs *ofs = OVL_FS(old->d_sb); 1131 1129 LIST_HEAD(list); ··· 1224 1220 } 1225 1221 } 1226 1222 1227 - trap = lock_rename(new_upperdir, old_upperdir); 1228 - if (IS_ERR(trap)) { 1229 - err = PTR_ERR(trap); 1230 - goto out_revert_creds; 1231 - } 1223 + rd.mnt_idmap = ovl_upper_mnt_idmap(ofs); 1224 + rd.old_parent = old_upperdir; 1225 + rd.new_parent = new_upperdir; 1226 + rd.flags = flags; 1232 1227 1233 - de = ovl_lookup_upper(ofs, old->d_name.name, old_upperdir, 1234 - old->d_name.len); 1235 - err = PTR_ERR(de); 1236 - if (IS_ERR(de)) 1237 - goto out_unlock; 1238 - olddentry = de; 1228 + err = start_renaming(&rd, 0, 1229 + &QSTR_LEN(old->d_name.name, old->d_name.len), 1230 + &QSTR_LEN(new->d_name.name, new->d_name.len)); 1231 + 1232 + if (err) 1233 + goto out_revert_creds; 1239 1234 1240 1235 err = -ESTALE; 1241 - if (!ovl_matches_upper(old, olddentry)) 1236 + if (!ovl_matches_upper(old, rd.old_dentry)) 1242 1237 goto out_unlock; 1243 - 1244 - de = ovl_lookup_upper(ofs, new->d_name.name, new_upperdir, 1245 - new->d_name.len); 1246 - err = PTR_ERR(de); 1247 - if (IS_ERR(de)) 1248 - goto out_unlock; 1249 - newdentry = de; 1250 1238 1251 1239 old_opaque = ovl_dentry_is_opaque(old); 1252 1240 new_opaque = ovl_dentry_is_opaque(new); ··· 1246 1250 err = -ESTALE; 1247 1251 if (d_inode(new) && ovl_dentry_upper(new)) { 1248 1252 if (opaquedir) { 1249 - if (newdentry != opaquedir) 1253 + if (rd.new_dentry != opaquedir) 1250 1254 goto out_unlock; 1251 1255 } else { 1252 - if (!ovl_matches_upper(new, newdentry)) 1256 + if (!ovl_matches_upper(new, rd.new_dentry)) 1253 1257 goto out_unlock; 1254 1258 } 1255 1259 } else { 1256 - if (!d_is_negative(newdentry)) { 1257 - if (!new_opaque || !ovl_upper_is_whiteout(ofs, newdentry)) 1260 + if (!d_is_negative(rd.new_dentry)) { 1261 + if (!new_opaque || !ovl_upper_is_whiteout(ofs, rd.new_dentry)) 1258 1262 goto out_unlock; 1259 1263 } else { 1260 1264 if (flags & RENAME_EXCHANGE) ··· 1262 1266 } 1263 1267 } 1264 1268 1265 - if (olddentry == trap) 1266 - goto out_unlock; 1267 - if (newdentry == trap) 1268 - goto out_unlock; 1269 - 1270 - if (olddentry->d_inode == newdentry->d_inode) 1269 + if (rd.old_dentry->d_inode == rd.new_dentry->d_inode) 1271 1270 goto out_unlock; 1272 1271 1273 1272 err = 0; 1274 1273 if (ovl_type_merge_or_lower(old)) 1275 1274 err = ovl_set_redirect(old, samedir); 1276 1275 else if (is_dir && !old_opaque && ovl_type_merge(new->d_parent)) 1277 - err = ovl_set_opaque_xerr(old, olddentry, -EXDEV); 1276 + err = ovl_set_opaque_xerr(old, rd.old_dentry, -EXDEV); 1278 1277 if (err) 1279 1278 goto out_unlock; 1280 1279 ··· 1277 1286 err = ovl_set_redirect(new, samedir); 1278 1287 else if (!overwrite && new_is_dir && !new_opaque && 1279 1288 ovl_type_merge(old->d_parent)) 1280 - err = ovl_set_opaque_xerr(new, newdentry, -EXDEV); 1289 + err = ovl_set_opaque_xerr(new, rd.new_dentry, -EXDEV); 1281 1290 if (err) 1282 1291 goto out_unlock; 1283 1292 1284 - err = ovl_do_rename(ofs, old_upperdir, olddentry, 1285 - new_upperdir, newdentry, flags); 1286 - unlock_rename(new_upperdir, old_upperdir); 1293 + err = ovl_do_rename_rd(&rd); 1294 + 1295 + if (!err && cleanup_whiteout) 1296 + whiteout = dget(rd.new_dentry); 1297 + 1298 + end_renaming(&rd); 1299 + 1287 1300 if (err) 1288 1301 goto out_revert_creds; 1289 1302 1290 - if (cleanup_whiteout) 1291 - ovl_cleanup(ofs, old_upperdir, newdentry); 1303 + if (whiteout) { 1304 + ovl_cleanup(ofs, old_upperdir, whiteout); 1305 + dput(whiteout); 1306 + } 1292 1307 1293 1308 if (overwrite && d_inode(new)) { 1294 1309 if (new_is_dir) ··· 1320 1323 else 1321 1324 ovl_drop_write(old); 1322 1325 out: 1323 - dput(newdentry); 1324 - dput(olddentry); 1325 1326 dput(opaquedir); 1326 1327 ovl_cache_free(&list); 1327 1328 return err; 1328 1329 1329 1330 out_unlock: 1330 - unlock_rename(new_upperdir, old_upperdir); 1331 + end_renaming(&rd); 1331 1332 goto out_revert_creds; 1332 1333 } 1333 1334
+33 -14
fs/overlayfs/overlayfs.h
··· 355 355 return vfs_remove_acl(ovl_upper_mnt_idmap(ofs), dentry, acl_name); 356 356 } 357 357 358 + static inline int ovl_do_rename_rd(struct renamedata *rd) 359 + { 360 + int err; 361 + 362 + pr_debug("rename(%pd2, %pd2, 0x%x)\n", rd->old_dentry, rd->new_dentry, 363 + rd->flags); 364 + err = vfs_rename(rd); 365 + if (err) { 366 + pr_debug("...rename(%pd2, %pd2, ...) = %i\n", 367 + rd->old_dentry, rd->new_dentry, err); 368 + } 369 + return err; 370 + } 371 + 358 372 static inline int ovl_do_rename(struct ovl_fs *ofs, struct dentry *olddir, 359 373 struct dentry *olddentry, struct dentry *newdir, 360 374 struct dentry *newdentry, unsigned int flags) 361 375 { 362 - int err; 363 376 struct renamedata rd = { 364 377 .mnt_idmap = ovl_upper_mnt_idmap(ofs), 365 378 .old_parent = olddir, ··· 382 369 .flags = flags, 383 370 }; 384 371 385 - pr_debug("rename(%pd2, %pd2, 0x%x)\n", olddentry, newdentry, flags); 386 - err = vfs_rename(&rd); 387 - if (err) { 388 - pr_debug("...rename(%pd2, %pd2, ...) = %i\n", 389 - olddentry, newdentry, err); 390 - } 391 - return err; 372 + return ovl_do_rename_rd(&rd); 392 373 } 393 374 394 375 static inline int ovl_do_whiteout(struct ovl_fs *ofs, ··· 422 415 &QSTR_LEN(name, len), base); 423 416 } 424 417 418 + static inline struct dentry *ovl_start_creating_upper(struct ovl_fs *ofs, 419 + struct dentry *parent, 420 + struct qstr *name) 421 + { 422 + return start_creating(ovl_upper_mnt_idmap(ofs), 423 + parent, name); 424 + } 425 + 426 + static inline struct dentry *ovl_start_removing_upper(struct ovl_fs *ofs, 427 + struct dentry *parent, 428 + struct qstr *name) 429 + { 430 + return start_removing(ovl_upper_mnt_idmap(ofs), 431 + parent, name); 432 + } 433 + 425 434 static inline bool ovl_open_flags_need_copy_up(int flags) 426 435 { 427 436 if (!flags) ··· 447 424 } 448 425 449 426 /* util.c */ 450 - int ovl_parent_lock(struct dentry *parent, struct dentry *child); 451 - static inline void ovl_parent_unlock(struct dentry *parent) 452 - { 453 - inode_unlock(parent->d_inode); 454 - } 455 427 int ovl_get_write_access(struct dentry *dentry); 456 428 void ovl_put_write_access(struct dentry *dentry); 457 429 void ovl_start_write(struct dentry *dentry); ··· 883 865 struct dentry *parent, struct dentry *newdentry, 884 866 struct ovl_cattr *attr); 885 867 int ovl_cleanup(struct ovl_fs *ofs, struct dentry *workdir, struct dentry *dentry); 886 - struct dentry *ovl_lookup_temp(struct ovl_fs *ofs, struct dentry *workdir); 868 + #define OVL_TEMPNAME_SIZE 20 869 + void ovl_tempname(char name[OVL_TEMPNAME_SIZE]); 887 870 struct dentry *ovl_create_temp(struct ovl_fs *ofs, struct dentry *workdir, 888 871 struct ovl_cattr *attr); 889 872
+4 -4
fs/overlayfs/readdir.c
··· 1242 1242 if (!d_is_dir(dentry) || level > 1) 1243 1243 return ovl_cleanup(ofs, parent, dentry); 1244 1244 1245 - err = ovl_parent_lock(parent, dentry); 1246 - if (err) 1247 - return err; 1245 + dentry = start_removing_dentry(parent, dentry); 1246 + if (IS_ERR(dentry)) 1247 + return PTR_ERR(dentry); 1248 1248 err = ovl_do_rmdir(ofs, parent->d_inode, dentry); 1249 - ovl_parent_unlock(parent); 1249 + end_removing(dentry); 1250 1250 if (err) { 1251 1251 struct path path = { .mnt = mnt, .dentry = dentry }; 1252 1252
+23 -28
fs/overlayfs/super.c
··· 310 310 bool retried = false; 311 311 312 312 retry: 313 - inode_lock_nested(dir, I_MUTEX_PARENT); 314 - work = ovl_lookup_upper(ofs, name, ofs->workbasedir, strlen(name)); 313 + work = ovl_start_creating_upper(ofs, ofs->workbasedir, &QSTR(name)); 315 314 316 315 if (!IS_ERR(work)) { 317 316 struct iattr attr = { ··· 319 320 }; 320 321 321 322 if (work->d_inode) { 322 - err = -EEXIST; 323 - inode_unlock(dir); 324 - if (retried) 325 - goto out_dput; 326 - 323 + end_creating_keep(work); 327 324 if (persist) 328 325 return work; 329 - 326 + err = -EEXIST; 327 + if (retried) 328 + goto out_dput; 330 329 retried = true; 331 330 err = ovl_workdir_cleanup(ofs, ofs->workbasedir, mnt, work, 0); 332 331 dput(work); ··· 335 338 } 336 339 337 340 work = ovl_do_mkdir(ofs, dir, work, attr.ia_mode); 338 - inode_unlock(dir); 341 + end_creating_keep(work); 339 342 err = PTR_ERR(work); 340 343 if (IS_ERR(work)) 341 344 goto out_err; ··· 373 376 if (err) 374 377 goto out_dput; 375 378 } else { 376 - inode_unlock(dir); 377 379 err = PTR_ERR(work); 378 380 goto out_err; 379 381 } ··· 563 567 { 564 568 struct dentry *workdir = ofs->workdir; 565 569 struct dentry *temp; 566 - struct dentry *dest; 567 570 struct dentry *whiteout; 568 571 struct name_snapshot name; 572 + struct renamedata rd = {}; 573 + char name2[OVL_TEMPNAME_SIZE]; 569 574 int err; 570 575 571 576 temp = ovl_create_temp(ofs, workdir, OVL_CATTR(S_IFREG | 0)); ··· 574 577 if (IS_ERR(temp)) 575 578 return err; 576 579 577 - err = ovl_parent_lock(workdir, temp); 580 + rd.mnt_idmap = ovl_upper_mnt_idmap(ofs); 581 + rd.old_parent = workdir; 582 + rd.new_parent = workdir; 583 + rd.flags = RENAME_WHITEOUT; 584 + ovl_tempname(name2); 585 + err = start_renaming_dentry(&rd, 0, temp, &QSTR(name2)); 578 586 if (err) { 579 587 dput(temp); 580 - return err; 581 - } 582 - dest = ovl_lookup_temp(ofs, workdir); 583 - err = PTR_ERR(dest); 584 - if (IS_ERR(dest)) { 585 - dput(temp); 586 - ovl_parent_unlock(workdir); 587 588 return err; 588 589 } 589 590 590 591 /* Name is inline and stable - using snapshot as a copy helper */ 591 592 take_dentry_name_snapshot(&name, temp); 592 - err = ovl_do_rename(ofs, workdir, temp, workdir, dest, RENAME_WHITEOUT); 593 - ovl_parent_unlock(workdir); 593 + err = ovl_do_rename_rd(&rd); 594 + end_renaming(&rd); 594 595 if (err) { 595 596 if (err == -EINVAL) 596 597 err = 0; ··· 612 617 ovl_cleanup(ofs, workdir, temp); 613 618 release_dentry_name_snapshot(&name); 614 619 dput(temp); 615 - dput(dest); 616 620 617 621 return err; 618 622 } ··· 620 626 struct dentry *parent, 621 627 const char *name, umode_t mode) 622 628 { 623 - size_t len = strlen(name); 624 629 struct dentry *child; 625 630 626 - inode_lock_nested(parent->d_inode, I_MUTEX_PARENT); 627 - child = ovl_lookup_upper(ofs, name, parent, len); 628 - if (!IS_ERR(child) && !child->d_inode) 629 - child = ovl_create_real(ofs, parent, child, OVL_CATTR(mode)); 630 - inode_unlock(parent->d_inode); 631 + child = ovl_start_creating_upper(ofs, parent, &QSTR(name)); 632 + if (!IS_ERR(child)) { 633 + if (!child->d_inode) 634 + child = ovl_create_real(ofs, parent, child, 635 + OVL_CATTR(mode)); 636 + end_creating_keep(child); 637 + } 631 638 dput(parent); 632 639 633 640 return child;
-11
fs/overlayfs/util.c
··· 1548 1548 i_size_write(inode, i_size_read(realinode)); 1549 1549 spin_unlock(&inode->i_lock); 1550 1550 } 1551 - 1552 - int ovl_parent_lock(struct dentry *parent, struct dentry *child) 1553 - { 1554 - inode_lock_nested(parent->d_inode, I_MUTEX_PARENT); 1555 - if (!child || 1556 - (!d_unhashed(child) && child->d_parent == parent)) 1557 - return 0; 1558 - 1559 - inode_unlock(parent->d_inode); 1560 - return -EINVAL; 1561 - }
+3 -3
fs/smb/server/smb2pdu.c
··· 6084 6084 } 6085 6085 6086 6086 ksmbd_debug(SMB, "target name is %s\n", target_name); 6087 - rc = ksmbd_vfs_kern_path_locked(work, link_name, LOOKUP_NO_SYMLINKS, 6088 - &path, 0); 6087 + rc = ksmbd_vfs_kern_path_start_removing(work, link_name, LOOKUP_NO_SYMLINKS, 6088 + &path, 0); 6089 6089 if (rc) { 6090 6090 if (rc != -ENOENT) 6091 6091 goto out; ··· 6103 6103 ksmbd_debug(SMB, "link already exists\n"); 6104 6104 goto out; 6105 6105 } 6106 - ksmbd_vfs_kern_path_unlock(&path); 6106 + ksmbd_vfs_kern_path_end_removing(&path); 6107 6107 } 6108 6108 rc = ksmbd_vfs_link(work, target_name, link_name); 6109 6109 if (rc)
+26 -88
fs/smb/server/vfs.c
··· 49 49 i_uid_write(inode, i_uid_read(parent_inode)); 50 50 } 51 51 52 - /** 53 - * ksmbd_vfs_lock_parent() - lock parent dentry if it is stable 54 - * @parent: parent dentry 55 - * @child: child dentry 56 - * 57 - * Returns: %0 on success, %-ENOENT if the parent dentry is not stable 58 - */ 59 - int ksmbd_vfs_lock_parent(struct dentry *parent, struct dentry *child) 60 - { 61 - inode_lock_nested(d_inode(parent), I_MUTEX_PARENT); 62 - if (child->d_parent != parent) { 63 - inode_unlock(d_inode(parent)); 64 - return -ENOENT; 65 - } 66 - 67 - return 0; 68 - } 69 - 70 52 static int ksmbd_vfs_path_lookup(struct ksmbd_share_config *share_conf, 71 53 char *pathname, unsigned int flags, 72 - struct path *path, bool do_lock) 54 + struct path *path, bool for_remove) 73 55 { 74 56 struct qstr last; 75 57 struct filename *filename __free(putname) = NULL; ··· 81 99 return -ENOENT; 82 100 } 83 101 84 - if (do_lock) { 102 + if (for_remove) { 85 103 err = mnt_want_write(path->mnt); 86 104 if (err) { 87 105 path_put(path); 88 106 return -ENOENT; 89 107 } 90 108 91 - inode_lock_nested(path->dentry->d_inode, I_MUTEX_PARENT); 92 - d = lookup_one_qstr_excl(&last, path->dentry, 0); 109 + d = start_removing_noperm(path->dentry, &last); 93 110 94 111 if (!IS_ERR(d)) { 95 112 dput(path->dentry); 96 113 path->dentry = d; 97 114 return 0; 98 115 } 99 - inode_unlock(path->dentry->d_inode); 100 116 mnt_drop_write(path->mnt); 101 117 path_put(path); 102 118 return -ENOENT; ··· 661 681 int ksmbd_vfs_rename(struct ksmbd_work *work, const struct path *old_path, 662 682 char *newname, int flags) 663 683 { 664 - struct dentry *old_parent, *new_dentry, *trap; 665 684 struct dentry *old_child = old_path->dentry; 666 685 struct path new_path; 667 686 struct qstr new_last; ··· 670 691 struct ksmbd_file *parent_fp; 671 692 int new_type; 672 693 int err, lookup_flags = LOOKUP_NO_SYMLINKS; 673 - int target_lookup_flags = LOOKUP_RENAME_TARGET | LOOKUP_CREATE; 674 694 675 695 if (ksmbd_override_fsids(work)) 676 696 return -ENOMEM; ··· 679 701 err = PTR_ERR(to); 680 702 goto revert_fsids; 681 703 } 682 - 683 - /* 684 - * explicitly handle file overwrite case, for compatibility with 685 - * filesystems that may not support rename flags (e.g: fuse) 686 - */ 687 - if (flags & RENAME_NOREPLACE) 688 - target_lookup_flags |= LOOKUP_EXCL; 689 - flags &= ~(RENAME_NOREPLACE); 690 704 691 705 retry: 692 706 err = vfs_path_parent_lookup(to, lookup_flags | LOOKUP_BENEATH, ··· 696 726 if (err) 697 727 goto out2; 698 728 699 - trap = lock_rename_child(old_child, new_path.dentry); 700 - if (IS_ERR(trap)) { 701 - err = PTR_ERR(trap); 729 + rd.mnt_idmap = mnt_idmap(old_path->mnt); 730 + rd.old_parent = NULL; 731 + rd.new_parent = new_path.dentry; 732 + rd.flags = flags; 733 + rd.delegated_inode = NULL, 734 + err = start_renaming_dentry(&rd, lookup_flags, old_child, &new_last); 735 + if (err) 702 736 goto out_drop_write; 703 - } 704 - 705 - old_parent = dget(old_child->d_parent); 706 - if (d_unhashed(old_child)) { 707 - err = -EINVAL; 708 - goto out3; 709 - } 710 737 711 738 parent_fp = ksmbd_lookup_fd_inode(old_child->d_parent); 712 739 if (parent_fp) { ··· 716 749 ksmbd_fd_put(work, parent_fp); 717 750 } 718 751 719 - new_dentry = lookup_one_qstr_excl(&new_last, new_path.dentry, 720 - lookup_flags | target_lookup_flags); 721 - if (IS_ERR(new_dentry)) { 722 - err = PTR_ERR(new_dentry); 752 + if (d_is_symlink(rd.new_dentry)) { 753 + err = -EACCES; 723 754 goto out3; 724 755 } 725 756 726 - if (d_is_symlink(new_dentry)) { 727 - err = -EACCES; 728 - goto out4; 729 - } 730 - 731 - if (old_child == trap) { 732 - err = -EINVAL; 733 - goto out4; 734 - } 735 - 736 - if (new_dentry == trap) { 737 - err = -ENOTEMPTY; 738 - goto out4; 739 - } 740 - 741 - rd.mnt_idmap = mnt_idmap(old_path->mnt), 742 - rd.old_parent = old_parent, 743 - rd.old_dentry = old_child, 744 - rd.new_parent = new_path.dentry, 745 - rd.new_dentry = new_dentry, 746 - rd.flags = flags, 747 - rd.delegated_inode = NULL, 748 757 err = vfs_rename(&rd); 749 758 if (err) 750 759 ksmbd_debug(VFS, "vfs_rename failed err %d\n", err); 751 760 752 - out4: 753 - dput(new_dentry); 754 761 out3: 755 - dput(old_parent); 756 - unlock_rename(old_parent, new_path.dentry); 762 + end_renaming(&rd); 757 763 out_drop_write: 758 764 mnt_drop_write(old_path->mnt); 759 765 out2: ··· 1024 1084 return err; 1025 1085 1026 1086 dir = dget_parent(dentry); 1027 - err = ksmbd_vfs_lock_parent(dir, dentry); 1028 - if (err) 1087 + dentry = start_removing_dentry(dir, dentry); 1088 + err = PTR_ERR(dentry); 1089 + if (IS_ERR(dentry)) 1029 1090 goto out; 1030 - dget(dentry); 1031 1091 1032 1092 if (S_ISDIR(d_inode(dentry)->i_mode)) 1033 1093 err = vfs_rmdir(idmap, d_inode(dir), dentry); 1034 1094 else 1035 1095 err = vfs_unlink(idmap, d_inode(dir), dentry, NULL); 1036 1096 1037 - dput(dentry); 1038 - inode_unlock(d_inode(dir)); 1097 + end_removing(dentry); 1039 1098 if (err) 1040 1099 ksmbd_debug(VFS, "failed to delete, err %d\n", err); 1041 1100 out: ··· 1146 1207 static 1147 1208 int __ksmbd_vfs_kern_path(struct ksmbd_work *work, char *filepath, 1148 1209 unsigned int flags, 1149 - struct path *path, bool caseless, bool do_lock) 1210 + struct path *path, bool caseless, bool for_remove) 1150 1211 { 1151 1212 struct ksmbd_share_config *share_conf = work->tcon->share_conf; 1152 1213 struct path parent_path; ··· 1154 1215 int err; 1155 1216 1156 1217 retry: 1157 - err = ksmbd_vfs_path_lookup(share_conf, filepath, flags, path, do_lock); 1218 + err = ksmbd_vfs_path_lookup(share_conf, filepath, flags, path, for_remove); 1158 1219 if (!err || !caseless) 1159 1220 return err; 1160 1221 ··· 1225 1286 } 1226 1287 1227 1288 /** 1228 - * ksmbd_vfs_kern_path_locked() - lookup a file and get path info 1289 + * ksmbd_vfs_kern_path_start_remove() - lookup a file and get path info prior to removal 1229 1290 * @work: work 1230 1291 * @filepath: file path that is relative to share 1231 1292 * @flags: lookup flags ··· 1237 1298 * filesystem will have been gained. 1238 1299 * Return: 0 on if file was found, otherwise error 1239 1300 */ 1240 - int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *filepath, 1241 - unsigned int flags, 1242 - struct path *path, bool caseless) 1301 + int ksmbd_vfs_kern_path_start_removing(struct ksmbd_work *work, char *filepath, 1302 + unsigned int flags, 1303 + struct path *path, bool caseless) 1243 1304 { 1244 1305 return __ksmbd_vfs_kern_path(work, filepath, flags, path, 1245 1306 caseless, true); 1246 1307 } 1247 1308 1248 - void ksmbd_vfs_kern_path_unlock(const struct path *path) 1309 + void ksmbd_vfs_kern_path_end_removing(const struct path *path) 1249 1310 { 1250 - /* While lock is still held, ->d_parent is safe */ 1251 - inode_unlock(d_inode(path->dentry->d_parent)); 1311 + end_removing(path->dentry); 1252 1312 mnt_drop_write(path->mnt); 1253 - path_put(path); 1313 + mntput(path->mnt); 1254 1314 } 1255 1315 1256 1316 struct dentry *ksmbd_vfs_kern_path_create(struct ksmbd_work *work,
+4 -4
fs/smb/server/vfs.h
··· 120 120 int ksmbd_vfs_kern_path(struct ksmbd_work *work, char *name, 121 121 unsigned int flags, 122 122 struct path *path, bool caseless); 123 - int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name, 124 - unsigned int flags, 125 - struct path *path, bool caseless); 126 - void ksmbd_vfs_kern_path_unlock(const struct path *path); 123 + int ksmbd_vfs_kern_path_start_removing(struct ksmbd_work *work, char *name, 124 + unsigned int flags, 125 + struct path *path, bool caseless); 126 + void ksmbd_vfs_kern_path_end_removing(const struct path *path); 127 127 struct dentry *ksmbd_vfs_kern_path_create(struct ksmbd_work *work, 128 128 const char *name, 129 129 unsigned int flags,
+4 -7
fs/xfs/scrub/orphanage.c
··· 152 152 } 153 153 154 154 /* Try to find the orphanage directory. */ 155 - inode_lock_nested(root_inode, I_MUTEX_PARENT); 156 - orphanage_dentry = lookup_noperm(&QSTR(ORPHANAGE), root_dentry); 155 + orphanage_dentry = start_creating_noperm(root_dentry, &QSTR(ORPHANAGE)); 157 156 if (IS_ERR(orphanage_dentry)) { 158 157 error = PTR_ERR(orphanage_dentry); 159 - goto out_unlock_root; 158 + goto out_dput_root; 160 159 } 161 160 162 161 /* ··· 169 170 orphanage_dentry, 0750); 170 171 error = PTR_ERR(orphanage_dentry); 171 172 if (IS_ERR(orphanage_dentry)) 172 - goto out_unlock_root; 173 + goto out_dput_orphanage; 173 174 } 174 175 175 176 /* Not a directory? Bail out. */ ··· 199 200 sc->orphanage_ilock_flags = 0; 200 201 201 202 out_dput_orphanage: 202 - dput(orphanage_dentry); 203 - out_unlock_root: 204 - inode_unlock(VFS_I(sc->mp->m_rootip)); 203 + end_creating(orphanage_dentry); 205 204 out_dput_root: 206 205 dput(root_dentry); 207 206 out:
+2
include/linux/fs.h
··· 3609 3609 void filesystems_freeze(void); 3610 3610 void filesystems_thaw(void); 3611 3611 3612 + void end_dirop(struct dentry *de); 3613 + 3612 3614 extern int dcache_dir_open(struct inode *, struct file *); 3613 3615 extern int dcache_dir_close(struct inode *, struct file *); 3614 3616 extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
+82
include/linux/namei.h
··· 88 88 struct qstr *name, 89 89 struct dentry *base); 90 90 91 + struct dentry *start_creating(struct mnt_idmap *idmap, struct dentry *parent, 92 + struct qstr *name); 93 + struct dentry *start_removing(struct mnt_idmap *idmap, struct dentry *parent, 94 + struct qstr *name); 95 + struct dentry *start_creating_killable(struct mnt_idmap *idmap, 96 + struct dentry *parent, 97 + struct qstr *name); 98 + struct dentry *start_removing_killable(struct mnt_idmap *idmap, 99 + struct dentry *parent, 100 + struct qstr *name); 101 + struct dentry *start_creating_noperm(struct dentry *parent, struct qstr *name); 102 + struct dentry *start_removing_noperm(struct dentry *parent, struct qstr *name); 103 + struct dentry *start_creating_dentry(struct dentry *parent, 104 + struct dentry *child); 105 + struct dentry *start_removing_dentry(struct dentry *parent, 106 + struct dentry *child); 107 + 108 + /* end_creating - finish action started with start_creating 109 + * @child: dentry returned by start_creating() or vfs_mkdir() 110 + * 111 + * Unlock and release the child. This can be called after 112 + * start_creating() whether that function succeeded or not, 113 + * but it is not needed on failure. 114 + * 115 + * If vfs_mkdir() was called then the value returned from that function 116 + * should be given for @child rather than the original dentry, as vfs_mkdir() 117 + * may have provided a new dentry. 118 + * 119 + * 120 + * If vfs_mkdir() was not called, then @child will be a valid dentry and 121 + * @parent will be ignored. 122 + */ 123 + static inline void end_creating(struct dentry *child) 124 + { 125 + end_dirop(child); 126 + } 127 + 128 + /* end_creating_keep - finish action started with start_creating() and return result 129 + * @child: dentry returned by start_creating() or vfs_mkdir() 130 + * 131 + * Unlock and return the child. This can be called after 132 + * start_creating() whether that function succeeded or not, 133 + * but it is not needed on failure. 134 + * 135 + * If vfs_mkdir() was called then the value returned from that function 136 + * should be given for @child rather than the original dentry, as vfs_mkdir() 137 + * may have provided a new dentry. 138 + * 139 + * Returns: @child, which may be a dentry or an error. 140 + * 141 + */ 142 + static inline struct dentry *end_creating_keep(struct dentry *child) 143 + { 144 + if (!IS_ERR(child)) 145 + dget(child); 146 + end_dirop(child); 147 + return child; 148 + } 149 + 150 + /** 151 + * end_removing - finish action started with start_removing 152 + * @child: dentry returned by start_removing() 153 + * @parent: dentry given to start_removing() 154 + * 155 + * Unlock and release the child. 156 + * 157 + * This is identical to end_dirop(). It can be passed the result of 158 + * start_removing() whether that was successful or not, but it not needed 159 + * if start_removing() failed. 160 + */ 161 + static inline void end_removing(struct dentry *child) 162 + { 163 + end_dirop(child); 164 + } 165 + 91 166 extern int follow_down_one(struct path *); 92 167 extern int follow_down(struct path *path, unsigned int flags); 93 168 extern int follow_up(struct path *); ··· 170 95 extern struct dentry *lock_rename(struct dentry *, struct dentry *); 171 96 extern struct dentry *lock_rename_child(struct dentry *, struct dentry *); 172 97 extern void unlock_rename(struct dentry *, struct dentry *); 98 + int start_renaming(struct renamedata *rd, int lookup_flags, 99 + struct qstr *old_last, struct qstr *new_last); 100 + int start_renaming_dentry(struct renamedata *rd, int lookup_flags, 101 + struct dentry *old_dentry, struct qstr *new_last); 102 + int start_renaming_two_dentries(struct renamedata *rd, 103 + struct dentry *old_dentry, struct dentry *new_dentry); 104 + void end_renaming(struct renamedata *rd); 173 105 174 106 /** 175 107 * mode_strip_umask - handle vfs umask stripping
+12 -20
ipc/mqueue.c
··· 913 913 goto out_putname; 914 914 915 915 ro = mnt_want_write(mnt); /* we'll drop it in any case */ 916 - inode_lock(d_inode(root)); 917 - path.dentry = lookup_noperm(&QSTR(name->name), root); 916 + path.dentry = start_creating_noperm(root, &QSTR(name->name)); 918 917 if (IS_ERR(path.dentry)) { 919 918 error = PTR_ERR(path.dentry); 920 919 goto out_putfd; 921 920 } 922 - path.mnt = mntget(mnt); 921 + path.mnt = mnt; 923 922 error = prepare_open(path.dentry, oflag, ro, mode, name, attr); 924 923 if (!error) { 925 924 struct file *file = dentry_open(&path, oflag, current_cred()); ··· 927 928 else 928 929 error = PTR_ERR(file); 929 930 } 930 - path_put(&path); 931 931 out_putfd: 932 932 if (error) { 933 933 put_unused_fd(fd); 934 934 fd = error; 935 935 } 936 - inode_unlock(d_inode(root)); 936 + end_creating(path.dentry); 937 937 if (!ro) 938 938 mnt_drop_write(mnt); 939 939 out_putname: ··· 955 957 int err; 956 958 struct filename *name; 957 959 struct dentry *dentry; 958 - struct inode *inode = NULL; 960 + struct inode *inode; 959 961 struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; 960 962 struct vfsmount *mnt = ipc_ns->mq_mnt; 961 963 ··· 967 969 err = mnt_want_write(mnt); 968 970 if (err) 969 971 goto out_name; 970 - inode_lock_nested(d_inode(mnt->mnt_root), I_MUTEX_PARENT); 971 - dentry = lookup_noperm(&QSTR(name->name), mnt->mnt_root); 972 + dentry = start_removing_noperm(mnt->mnt_root, &QSTR(name->name)); 972 973 if (IS_ERR(dentry)) { 973 974 err = PTR_ERR(dentry); 974 - goto out_unlock; 975 + goto out_drop_write; 975 976 } 976 977 977 978 inode = d_inode(dentry); 978 - if (!inode) { 979 - err = -ENOENT; 980 - } else { 981 - ihold(inode); 982 - err = vfs_unlink(&nop_mnt_idmap, d_inode(dentry->d_parent), 983 - dentry, NULL); 984 - } 985 - dput(dentry); 986 - 987 - out_unlock: 988 - inode_unlock(d_inode(mnt->mnt_root)); 979 + ihold(inode); 980 + err = vfs_unlink(&nop_mnt_idmap, d_inode(mnt->mnt_root), 981 + dentry, NULL); 982 + end_removing(dentry); 989 983 iput(inode); 984 + 985 + out_drop_write: 990 986 mnt_drop_write(mnt); 991 987 out_name: 992 988 putname(name);
+4 -4
security/apparmor/apparmorfs.c
··· 355 355 if (!dentry || IS_ERR(dentry)) 356 356 return; 357 357 358 + /* ->d_parent is stable as rename is not supported */ 358 359 dir = d_inode(dentry->d_parent); 359 - inode_lock(dir); 360 - if (simple_positive(dentry)) { 360 + dentry = start_removing_dentry(dentry->d_parent, dentry); 361 + if (!IS_ERR(dentry) && simple_positive(dentry)) { 361 362 if (d_is_dir(dentry)) 362 363 simple_rmdir(dir, dentry); 363 364 else 364 365 simple_unlink(dir, dentry); 365 366 d_delete(dentry); 366 - dput(dentry); 367 367 } 368 - inode_unlock(dir); 368 + end_removing(dentry); 369 369 simple_release_fs(&aafs_mnt, &aafs_count); 370 370 } 371 371
+13 -2
security/selinux/selinuxfs.c
··· 506 506 { 507 507 int ret = 0; 508 508 struct dentry *tmp_parent, *tmp_bool_dir, *tmp_class_dir; 509 + struct renamedata rd = {}; 509 510 unsigned int bool_num = 0; 510 511 char **bool_names = NULL; 511 512 int *bool_values = NULL; ··· 540 539 if (ret) 541 540 goto out; 542 541 543 - lock_rename(tmp_parent, fsi->sb->s_root); 542 + rd.old_parent = tmp_parent; 543 + rd.new_parent = fsi->sb->s_root; 544 544 545 545 /* booleans */ 546 + ret = start_renaming_two_dentries(&rd, tmp_bool_dir, fsi->bool_dir); 547 + if (ret) 548 + goto out; 549 + 546 550 d_exchange(tmp_bool_dir, fsi->bool_dir); 547 551 548 552 swap(fsi->bool_num, bool_num); ··· 555 549 swap(fsi->bool_pending_values, bool_values); 556 550 557 551 fsi->bool_dir = tmp_bool_dir; 552 + end_renaming(&rd); 558 553 559 554 /* classes */ 555 + ret = start_renaming_two_dentries(&rd, tmp_class_dir, fsi->class_dir); 556 + if (ret) 557 + goto out; 558 + 560 559 d_exchange(tmp_class_dir, fsi->class_dir); 561 560 fsi->class_dir = tmp_class_dir; 562 561 563 - unlock_rename(tmp_parent, fsi->sb->s_root); 562 + end_renaming(&rd); 564 563 565 564 out: 566 565 sel_remove_old_bool_data(bool_num, bool_names, bool_values);