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

Merge tag 'vfs-6.19-rc1.directory.locking' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull directory locking updates from Christian Brauner:
"This contains the work to add centralized APIs for directory locking
operations.

This series is part of a larger effort to change directory operation
locking to allow multiple concurrent operations in a directory. The
ultimate goal is to lock the target dentry(s) rather than the whole
parent directory.

To help with changing the locking protocol, this series centralizes
locking and lookup in new helper functions. The helpers establish a
pattern where it is the dentry that is being locked and unlocked
(currently the lock is held on dentry->d_parent->d_inode, but that can
change in the future).

This also changes vfs_mkdir() to unlock the parent on failure, as well
as dput()ing the dentry. This allows end_creating() to only require
the target dentry (which may be IS_ERR() after vfs_mkdir()), not the
parent"

* tag 'vfs-6.19-rc1.directory.locking' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
nfsd: fix end_creating() conversion
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()

+1304 -840
+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, NULL); 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 }
+71 -80
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_dentry, mode, NULL); 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_dentry, mode, NULL); 196 194 if (rc) { 197 195 printk(KERN_ERR "%s: Failure to create dentry in lower fs; " 198 196 "rc = [%d]\n", __func__, rc); ··· 210 204 fsstack_copy_attr_times(directory_inode, lower_dir); 211 205 fsstack_copy_inode_size(directory_inode, lower_dir); 212 206 out_lock: 213 - inode_unlock(lower_dir); 207 + end_creating(lower_dentry); 214 208 return inode; 215 209 } 216 210 ··· 438 432 439 433 file_size_save = i_size_read(d_inode(old_dentry)); 440 434 lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); 441 - rc = lock_parent(new_dentry, &lower_new_dentry, &lower_dir); 442 - if (!rc) 443 - rc = vfs_link(lower_old_dentry, &nop_mnt_idmap, lower_dir, 444 - lower_new_dentry, NULL); 435 + lower_new_dentry = ecryptfs_start_creating_dentry(new_dentry); 436 + if (IS_ERR(lower_new_dentry)) 437 + return PTR_ERR(lower_new_dentry); 438 + lower_dir = lower_new_dentry->d_parent->d_inode; 439 + rc = vfs_link(lower_old_dentry, &nop_mnt_idmap, lower_dir, 440 + lower_new_dentry, NULL); 445 441 if (rc || d_really_is_negative(lower_new_dentry)) 446 442 goto out_lock; 447 443 rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb); ··· 455 447 ecryptfs_inode_to_lower(d_inode(old_dentry))->i_nlink); 456 448 i_size_write(d_inode(new_dentry), file_size_save); 457 449 out_lock: 458 - inode_unlock(lower_dir); 450 + end_creating(lower_new_dentry); 459 451 return rc; 460 452 } 461 453 ··· 475 467 size_t encoded_symlen; 476 468 struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; 477 469 478 - rc = lock_parent(dentry, &lower_dentry, &lower_dir); 479 - if (rc) 480 - goto out_lock; 470 + lower_dentry = ecryptfs_start_creating_dentry(dentry); 471 + if (IS_ERR(lower_dentry)) 472 + return PTR_ERR(lower_dentry); 473 + lower_dir = lower_dentry->d_parent->d_inode; 474 + 481 475 mount_crypt_stat = &ecryptfs_superblock_to_private( 482 476 dir->i_sb)->mount_crypt_stat; 483 477 rc = ecryptfs_encrypt_and_encode_filename(&encoded_symname, ··· 499 489 fsstack_copy_attr_times(dir, lower_dir); 500 490 fsstack_copy_inode_size(dir, lower_dir); 501 491 out_lock: 502 - inode_unlock(lower_dir); 492 + end_creating(lower_dentry); 503 493 if (d_really_is_negative(dentry)) 504 494 d_drop(dentry); 505 495 return rc; ··· 510 500 { 511 501 int rc; 512 502 struct dentry *lower_dentry; 503 + struct dentry *lower_dir_dentry; 513 504 struct inode *lower_dir; 514 505 515 - rc = lock_parent(dentry, &lower_dentry, &lower_dir); 516 - if (rc) 517 - goto out; 518 - 506 + lower_dentry = ecryptfs_start_creating_dentry(dentry); 507 + if (IS_ERR(lower_dentry)) 508 + return lower_dentry; 509 + lower_dir_dentry = dget(lower_dentry->d_parent); 510 + lower_dir = lower_dir_dentry->d_inode; 519 511 lower_dentry = vfs_mkdir(&nop_mnt_idmap, lower_dir, 520 512 lower_dentry, mode, NULL); 521 513 rc = PTR_ERR(lower_dentry); ··· 533 521 fsstack_copy_inode_size(dir, lower_dir); 534 522 set_nlink(dir, lower_dir->i_nlink); 535 523 out: 536 - inode_unlock(lower_dir); 524 + end_creating(lower_dentry); 537 525 if (d_really_is_negative(dentry)) 538 526 d_drop(dentry); 539 527 return ERR_PTR(rc); ··· 545 533 struct inode *lower_dir; 546 534 int rc; 547 535 548 - rc = lock_parent(dentry, &lower_dentry, &lower_dir); 549 - dget(lower_dentry); // don't even try to make the lower negative 550 - if (!rc) { 551 - if (d_unhashed(lower_dentry)) 552 - rc = -EINVAL; 553 - else 554 - rc = vfs_rmdir(&nop_mnt_idmap, lower_dir, lower_dentry, NULL); 555 - } 536 + lower_dentry = ecryptfs_start_removing_dentry(dentry); 537 + if (IS_ERR(lower_dentry)) 538 + return PTR_ERR(lower_dentry); 539 + lower_dir = lower_dentry->d_parent->d_inode; 540 + 541 + rc = vfs_rmdir(&nop_mnt_idmap, lower_dir, lower_dentry, NULL); 556 542 if (!rc) { 557 543 clear_nlink(d_inode(dentry)); 558 544 fsstack_copy_attr_times(dir, lower_dir); 559 545 set_nlink(dir, lower_dir->i_nlink); 560 546 } 561 - dput(lower_dentry); 562 - inode_unlock(lower_dir); 547 + end_removing(lower_dentry); 563 548 if (!rc) 564 549 d_drop(dentry); 565 550 return rc; ··· 570 561 struct dentry *lower_dentry; 571 562 struct inode *lower_dir; 572 563 573 - rc = lock_parent(dentry, &lower_dentry, &lower_dir); 574 - if (!rc) 575 - rc = vfs_mknod(&nop_mnt_idmap, lower_dir, 576 - lower_dentry, mode, dev, NULL); 564 + lower_dentry = ecryptfs_start_creating_dentry(dentry); 565 + if (IS_ERR(lower_dentry)) 566 + return PTR_ERR(lower_dentry); 567 + lower_dir = lower_dentry->d_parent->d_inode; 568 + 569 + rc = vfs_mknod(&nop_mnt_idmap, lower_dir, lower_dentry, mode, dev, NULL); 577 570 if (rc || d_really_is_negative(lower_dentry)) 578 571 goto out; 579 572 rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); ··· 584 573 fsstack_copy_attr_times(dir, lower_dir); 585 574 fsstack_copy_inode_size(dir, lower_dir); 586 575 out: 587 - inode_unlock(lower_dir); 576 + end_removing(lower_dentry); 588 577 if (d_really_is_negative(dentry)) 589 578 d_drop(dentry); 590 579 return rc; ··· 600 589 struct dentry *lower_new_dentry; 601 590 struct dentry *lower_old_dir_dentry; 602 591 struct dentry *lower_new_dir_dentry; 603 - struct dentry *trap; 604 592 struct inode *target_inode; 605 593 struct renamedata rd = {}; 606 594 ··· 614 604 615 605 target_inode = d_inode(new_dentry); 616 606 617 - trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); 618 - if (IS_ERR(trap)) 619 - return PTR_ERR(trap); 620 - dget(lower_new_dentry); 621 - rc = -EINVAL; 622 - if (lower_old_dentry->d_parent != lower_old_dir_dentry) 623 - goto out_lock; 624 - if (lower_new_dentry->d_parent != lower_new_dir_dentry) 625 - goto out_lock; 626 - if (d_unhashed(lower_old_dentry) || d_unhashed(lower_new_dentry)) 627 - goto out_lock; 628 - /* source should not be ancestor of target */ 629 - if (trap == lower_old_dentry) 630 - goto out_lock; 631 - /* target should not be ancestor of source */ 632 - if (trap == lower_new_dentry) { 633 - rc = -ENOTEMPTY; 634 - goto out_lock; 635 - } 607 + rd.mnt_idmap = &nop_mnt_idmap; 608 + rd.old_parent = lower_old_dir_dentry; 609 + rd.new_parent = lower_new_dir_dentry; 610 + rc = start_renaming_two_dentries(&rd, lower_old_dentry, lower_new_dentry); 611 + if (rc) 612 + return rc; 636 613 637 - rd.mnt_idmap = &nop_mnt_idmap; 638 - rd.old_parent = lower_old_dir_dentry; 639 - rd.old_dentry = lower_old_dentry; 640 - rd.new_parent = lower_new_dir_dentry; 641 - rd.new_dentry = lower_new_dentry; 642 614 rc = vfs_rename(&rd); 643 615 if (rc) 644 616 goto out_lock; ··· 631 639 if (new_dir != old_dir) 632 640 fsstack_copy_attr_all(old_dir, d_inode(lower_old_dir_dentry)); 633 641 out_lock: 634 - dput(lower_new_dentry); 635 - unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); 642 + end_renaming(&rd); 636 643 return rc; 637 644 } 638 645
+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
··· 2290 2290 cmpxchg(stashed, dentry, NULL); 2291 2291 } 2292 2292 2293 - /* parent must be held exclusive */ 2293 + /** 2294 + * simple_start_creating - prepare to create a given name 2295 + * @parent: directory in which to prepare to create the name 2296 + * @name: the name to be created 2297 + * 2298 + * Required lock is taken and a lookup in performed prior to creating an 2299 + * object in a directory. No permission checking is performed. 2300 + * 2301 + * Returns: a negative dentry on which vfs_create() or similar may 2302 + * be attempted, or an error. 2303 + */ 2294 2304 struct dentry *simple_start_creating(struct dentry *parent, const char *name) 2295 2305 { 2296 - struct dentry *dentry; 2297 - struct inode *dir = d_inode(parent); 2306 + struct qstr qname = QSTR(name); 2307 + int err; 2298 2308 2299 - inode_lock(dir); 2300 - if (unlikely(IS_DEADDIR(dir))) { 2301 - inode_unlock(dir); 2302 - return ERR_PTR(-ENOENT); 2303 - } 2304 - dentry = lookup_noperm(&QSTR(name), parent); 2305 - if (IS_ERR(dentry)) { 2306 - inode_unlock(dir); 2307 - return dentry; 2308 - } 2309 - if (dentry->d_inode) { 2310 - dput(dentry); 2311 - inode_unlock(dir); 2312 - return ERR_PTR(-EEXIST); 2313 - } 2314 - return dentry; 2309 + err = lookup_noperm_common(&qname, parent); 2310 + if (err) 2311 + return ERR_PTR(err); 2312 + return start_dirop(parent, &qname, LOOKUP_CREATE | LOOKUP_EXCL); 2315 2313 } 2316 2314 EXPORT_SYMBOL(simple_start_creating);
+640 -109
fs/namei.c
··· 2835 2835 return __filename_parentat(dfd, name, flags, parent, last, type, NULL); 2836 2836 } 2837 2837 2838 + /** 2839 + * start_dirop - begin a create or remove dirop, performing locking and lookup 2840 + * @parent: the dentry of the parent in which the operation will occur 2841 + * @name: a qstr holding the name within that parent 2842 + * @lookup_flags: intent and other lookup flags. 2843 + * 2844 + * The lookup is performed and necessary locks are taken so that, on success, 2845 + * the returned dentry can be operated on safely. 2846 + * The qstr must already have the hash value calculated. 2847 + * 2848 + * Returns: a locked dentry, or an error. 2849 + * 2850 + */ 2851 + static struct dentry *__start_dirop(struct dentry *parent, struct qstr *name, 2852 + unsigned int lookup_flags, 2853 + unsigned int state) 2854 + { 2855 + struct dentry *dentry; 2856 + struct inode *dir = d_inode(parent); 2857 + 2858 + if (state == TASK_KILLABLE) { 2859 + int ret = down_write_killable_nested(&dir->i_rwsem, 2860 + I_MUTEX_PARENT); 2861 + if (ret) 2862 + return ERR_PTR(ret); 2863 + } else { 2864 + inode_lock_nested(dir, I_MUTEX_PARENT); 2865 + } 2866 + dentry = lookup_one_qstr_excl(name, parent, lookup_flags); 2867 + if (IS_ERR(dentry)) 2868 + inode_unlock(dir); 2869 + return dentry; 2870 + } 2871 + 2872 + struct dentry *start_dirop(struct dentry *parent, struct qstr *name, 2873 + unsigned int lookup_flags) 2874 + { 2875 + return __start_dirop(parent, name, lookup_flags, TASK_NORMAL); 2876 + } 2877 + 2878 + /** 2879 + * end_dirop - signal completion of a dirop 2880 + * @de: the dentry which was returned by start_dirop or similar. 2881 + * 2882 + * If the de is an error, nothing happens. Otherwise any lock taken to 2883 + * protect the dentry is dropped and the dentry itself is release (dput()). 2884 + */ 2885 + void end_dirop(struct dentry *de) 2886 + { 2887 + if (!IS_ERR(de)) { 2888 + inode_unlock(de->d_parent->d_inode); 2889 + dput(de); 2890 + } 2891 + } 2892 + EXPORT_SYMBOL(end_dirop); 2893 + 2838 2894 /* does lookup, returns the object with parent locked */ 2839 2895 static struct dentry *__start_removing_path(int dfd, struct filename *name, 2840 2896 struct path *path) ··· 2907 2851 return ERR_PTR(-EINVAL); 2908 2852 /* don't fail immediately if it's r/o, at least try to report other errors */ 2909 2853 error = mnt_want_write(parent_path.mnt); 2910 - inode_lock_nested(parent_path.dentry->d_inode, I_MUTEX_PARENT); 2911 - d = lookup_one_qstr_excl(&last, parent_path.dentry, 0); 2854 + d = start_dirop(parent_path.dentry, &last, 0); 2912 2855 if (IS_ERR(d)) 2913 - goto unlock; 2856 + goto drop; 2914 2857 if (error) 2915 2858 goto fail; 2916 2859 path->dentry = no_free_ptr(parent_path.dentry); ··· 2917 2862 return d; 2918 2863 2919 2864 fail: 2920 - dput(d); 2865 + end_dirop(d); 2921 2866 d = ERR_PTR(error); 2922 - unlock: 2923 - inode_unlock(parent_path.dentry->d_inode); 2867 + drop: 2924 2868 if (!error) 2925 2869 mnt_drop_write(parent_path.mnt); 2926 2870 return d; ··· 3034 2980 } 3035 2981 EXPORT_SYMBOL(vfs_path_lookup); 3036 2982 3037 - static int lookup_noperm_common(struct qstr *qname, struct dentry *base) 2983 + int lookup_noperm_common(struct qstr *qname, struct dentry *base) 3038 2984 { 3039 2985 const char *name = qname->name; 3040 2986 u32 len = qname->len; ··· 3305 3251 } 3306 3252 EXPORT_SYMBOL(lookup_noperm_positive_unlocked); 3307 3253 3254 + /** 3255 + * start_creating - prepare to create a given name with permission checking 3256 + * @idmap: idmap of the mount 3257 + * @parent: directory in which to prepare to create the name 3258 + * @name: the name to be created 3259 + * 3260 + * Locks are taken and a lookup is performed prior to creating 3261 + * an object in a directory. Permission checking (MAY_EXEC) is performed 3262 + * against @idmap. 3263 + * 3264 + * If the name already exists, a positive dentry is returned, so 3265 + * behaviour is similar to O_CREAT without O_EXCL, which doesn't fail 3266 + * with -EEXIST. 3267 + * 3268 + * Returns: a negative or positive dentry, or an error. 3269 + */ 3270 + struct dentry *start_creating(struct mnt_idmap *idmap, struct dentry *parent, 3271 + struct qstr *name) 3272 + { 3273 + int err = lookup_one_common(idmap, name, parent); 3274 + 3275 + if (err) 3276 + return ERR_PTR(err); 3277 + return start_dirop(parent, name, LOOKUP_CREATE); 3278 + } 3279 + EXPORT_SYMBOL(start_creating); 3280 + 3281 + /** 3282 + * start_removing - prepare to remove a given name with permission checking 3283 + * @idmap: idmap of the mount 3284 + * @parent: directory in which to find the name 3285 + * @name: the name to be removed 3286 + * 3287 + * Locks are taken and a lookup in performed prior to removing 3288 + * an object from a directory. Permission checking (MAY_EXEC) is performed 3289 + * against @idmap. 3290 + * 3291 + * If the name doesn't exist, an error is returned. 3292 + * 3293 + * end_removing() should be called when removal is complete, or aborted. 3294 + * 3295 + * Returns: a positive dentry, or an error. 3296 + */ 3297 + struct dentry *start_removing(struct mnt_idmap *idmap, struct dentry *parent, 3298 + struct qstr *name) 3299 + { 3300 + int err = lookup_one_common(idmap, name, parent); 3301 + 3302 + if (err) 3303 + return ERR_PTR(err); 3304 + return start_dirop(parent, name, 0); 3305 + } 3306 + EXPORT_SYMBOL(start_removing); 3307 + 3308 + /** 3309 + * start_creating_killable - prepare to create a given name with permission checking 3310 + * @idmap: idmap of the mount 3311 + * @parent: directory in which to prepare to create the name 3312 + * @name: the name to be created 3313 + * 3314 + * Locks are taken and a lookup in performed prior to creating 3315 + * an object in a directory. Permission checking (MAY_EXEC) is performed 3316 + * against @idmap. 3317 + * 3318 + * If the name already exists, a positive dentry is returned. 3319 + * 3320 + * If a signal is received or was already pending, the function aborts 3321 + * with -EINTR; 3322 + * 3323 + * Returns: a negative or positive dentry, or an error. 3324 + */ 3325 + struct dentry *start_creating_killable(struct mnt_idmap *idmap, 3326 + struct dentry *parent, 3327 + struct qstr *name) 3328 + { 3329 + int err = lookup_one_common(idmap, name, parent); 3330 + 3331 + if (err) 3332 + return ERR_PTR(err); 3333 + return __start_dirop(parent, name, LOOKUP_CREATE, TASK_KILLABLE); 3334 + } 3335 + EXPORT_SYMBOL(start_creating_killable); 3336 + 3337 + /** 3338 + * start_removing_killable - prepare to remove a given name with permission checking 3339 + * @idmap: idmap of the mount 3340 + * @parent: directory in which to find the name 3341 + * @name: the name to be removed 3342 + * 3343 + * Locks are taken and a lookup in performed prior to removing 3344 + * an object from a directory. Permission checking (MAY_EXEC) is performed 3345 + * against @idmap. 3346 + * 3347 + * If the name doesn't exist, an error is returned. 3348 + * 3349 + * end_removing() should be called when removal is complete, or aborted. 3350 + * 3351 + * If a signal is received or was already pending, the function aborts 3352 + * with -EINTR; 3353 + * 3354 + * Returns: a positive dentry, or an error. 3355 + */ 3356 + struct dentry *start_removing_killable(struct mnt_idmap *idmap, 3357 + struct dentry *parent, 3358 + struct qstr *name) 3359 + { 3360 + int err = lookup_one_common(idmap, name, parent); 3361 + 3362 + if (err) 3363 + return ERR_PTR(err); 3364 + return __start_dirop(parent, name, 0, TASK_KILLABLE); 3365 + } 3366 + EXPORT_SYMBOL(start_removing_killable); 3367 + 3368 + /** 3369 + * start_creating_noperm - prepare to create a given name without permission checking 3370 + * @parent: directory in which to prepare to create the name 3371 + * @name: the name to be created 3372 + * 3373 + * Locks are taken and a lookup in performed prior to creating 3374 + * an object in a directory. 3375 + * 3376 + * If the name already exists, a positive dentry is returned. 3377 + * 3378 + * Returns: a negative or positive dentry, or an error. 3379 + */ 3380 + struct dentry *start_creating_noperm(struct dentry *parent, 3381 + struct qstr *name) 3382 + { 3383 + int err = lookup_noperm_common(name, parent); 3384 + 3385 + if (err) 3386 + return ERR_PTR(err); 3387 + return start_dirop(parent, name, LOOKUP_CREATE); 3388 + } 3389 + EXPORT_SYMBOL(start_creating_noperm); 3390 + 3391 + /** 3392 + * start_removing_noperm - prepare to remove a given name without permission checking 3393 + * @parent: directory in which to find the name 3394 + * @name: the name to be removed 3395 + * 3396 + * Locks are taken and a lookup in performed prior to removing 3397 + * an object from a directory. 3398 + * 3399 + * If the name doesn't exist, an error is returned. 3400 + * 3401 + * end_removing() should be called when removal is complete, or aborted. 3402 + * 3403 + * Returns: a positive dentry, or an error. 3404 + */ 3405 + struct dentry *start_removing_noperm(struct dentry *parent, 3406 + struct qstr *name) 3407 + { 3408 + int err = lookup_noperm_common(name, parent); 3409 + 3410 + if (err) 3411 + return ERR_PTR(err); 3412 + return start_dirop(parent, name, 0); 3413 + } 3414 + EXPORT_SYMBOL(start_removing_noperm); 3415 + 3416 + /** 3417 + * start_creating_dentry - prepare to create a given dentry 3418 + * @parent: directory from which dentry should be removed 3419 + * @child: the dentry to be removed 3420 + * 3421 + * A lock is taken to protect the dentry again other dirops and 3422 + * the validity of the dentry is checked: correct parent and still hashed. 3423 + * 3424 + * If the dentry is valid and negative a reference is taken and 3425 + * returned. If not an error is returned. 3426 + * 3427 + * end_creating() should be called when creation is complete, or aborted. 3428 + * 3429 + * Returns: the valid dentry, or an error. 3430 + */ 3431 + struct dentry *start_creating_dentry(struct dentry *parent, 3432 + struct dentry *child) 3433 + { 3434 + inode_lock_nested(parent->d_inode, I_MUTEX_PARENT); 3435 + if (unlikely(IS_DEADDIR(parent->d_inode) || 3436 + child->d_parent != parent || 3437 + d_unhashed(child))) { 3438 + inode_unlock(parent->d_inode); 3439 + return ERR_PTR(-EINVAL); 3440 + } 3441 + if (d_is_positive(child)) { 3442 + inode_unlock(parent->d_inode); 3443 + return ERR_PTR(-EEXIST); 3444 + } 3445 + return dget(child); 3446 + } 3447 + EXPORT_SYMBOL(start_creating_dentry); 3448 + 3449 + /** 3450 + * start_removing_dentry - prepare to remove a given dentry 3451 + * @parent: directory from which dentry should be removed 3452 + * @child: the dentry to be removed 3453 + * 3454 + * A lock is taken to protect the dentry again other dirops and 3455 + * the validity of the dentry is checked: correct parent and still hashed. 3456 + * 3457 + * If the dentry is valid and positive, a reference is taken and 3458 + * returned. If not an error is returned. 3459 + * 3460 + * end_removing() should be called when removal is complete, or aborted. 3461 + * 3462 + * Returns: the valid dentry, or an error. 3463 + */ 3464 + struct dentry *start_removing_dentry(struct dentry *parent, 3465 + struct dentry *child) 3466 + { 3467 + inode_lock_nested(parent->d_inode, I_MUTEX_PARENT); 3468 + if (unlikely(IS_DEADDIR(parent->d_inode) || 3469 + child->d_parent != parent || 3470 + d_unhashed(child))) { 3471 + inode_unlock(parent->d_inode); 3472 + return ERR_PTR(-EINVAL); 3473 + } 3474 + if (d_is_negative(child)) { 3475 + inode_unlock(parent->d_inode); 3476 + return ERR_PTR(-ENOENT); 3477 + } 3478 + return dget(child); 3479 + } 3480 + EXPORT_SYMBOL(start_removing_dentry); 3481 + 3308 3482 #ifdef CONFIG_UNIX98_PTYS 3309 3483 int path_pts(struct path *path) 3310 3484 { ··· 3769 3487 } 3770 3488 } 3771 3489 EXPORT_SYMBOL(unlock_rename); 3490 + 3491 + /** 3492 + * __start_renaming - lookup and lock names for rename 3493 + * @rd: rename data containing parents and flags, and 3494 + * for receiving found dentries 3495 + * @lookup_flags: extra flags to pass to ->lookup (e.g. LOOKUP_REVAL, 3496 + * LOOKUP_NO_SYMLINKS etc). 3497 + * @old_last: name of object in @rd.old_parent 3498 + * @new_last: name of object in @rd.new_parent 3499 + * 3500 + * Look up two names and ensure locks are in place for 3501 + * rename. 3502 + * 3503 + * On success the found dentries are stored in @rd.old_dentry, 3504 + * @rd.new_dentry and an extra ref is taken on @rd.old_parent. 3505 + * These references and the lock are dropped by end_renaming(). 3506 + * 3507 + * The passed in qstrs must have the hash calculated, and no permission 3508 + * checking is performed. 3509 + * 3510 + * Returns: zero or an error. 3511 + */ 3512 + static int 3513 + __start_renaming(struct renamedata *rd, int lookup_flags, 3514 + struct qstr *old_last, struct qstr *new_last) 3515 + { 3516 + struct dentry *trap; 3517 + struct dentry *d1, *d2; 3518 + int target_flags = LOOKUP_RENAME_TARGET | LOOKUP_CREATE; 3519 + int err; 3520 + 3521 + if (rd->flags & RENAME_EXCHANGE) 3522 + target_flags = 0; 3523 + if (rd->flags & RENAME_NOREPLACE) 3524 + target_flags |= LOOKUP_EXCL; 3525 + 3526 + trap = lock_rename(rd->old_parent, rd->new_parent); 3527 + if (IS_ERR(trap)) 3528 + return PTR_ERR(trap); 3529 + 3530 + d1 = lookup_one_qstr_excl(old_last, rd->old_parent, 3531 + lookup_flags); 3532 + err = PTR_ERR(d1); 3533 + if (IS_ERR(d1)) 3534 + goto out_unlock; 3535 + 3536 + d2 = lookup_one_qstr_excl(new_last, rd->new_parent, 3537 + lookup_flags | target_flags); 3538 + err = PTR_ERR(d2); 3539 + if (IS_ERR(d2)) 3540 + goto out_dput_d1; 3541 + 3542 + if (d1 == trap) { 3543 + /* source is an ancestor of target */ 3544 + err = -EINVAL; 3545 + goto out_dput_d2; 3546 + } 3547 + 3548 + if (d2 == trap) { 3549 + /* target is an ancestor of source */ 3550 + if (rd->flags & RENAME_EXCHANGE) 3551 + err = -EINVAL; 3552 + else 3553 + err = -ENOTEMPTY; 3554 + goto out_dput_d2; 3555 + } 3556 + 3557 + rd->old_dentry = d1; 3558 + rd->new_dentry = d2; 3559 + dget(rd->old_parent); 3560 + return 0; 3561 + 3562 + out_dput_d2: 3563 + dput(d2); 3564 + out_dput_d1: 3565 + dput(d1); 3566 + out_unlock: 3567 + unlock_rename(rd->old_parent, rd->new_parent); 3568 + return err; 3569 + } 3570 + 3571 + /** 3572 + * start_renaming - lookup and lock names for rename with permission checking 3573 + * @rd: rename data containing parents and flags, and 3574 + * for receiving found dentries 3575 + * @lookup_flags: extra flags to pass to ->lookup (e.g. LOOKUP_REVAL, 3576 + * LOOKUP_NO_SYMLINKS etc). 3577 + * @old_last: name of object in @rd.old_parent 3578 + * @new_last: name of object in @rd.new_parent 3579 + * 3580 + * Look up two names and ensure locks are in place for 3581 + * rename. 3582 + * 3583 + * On success the found dentries are stored in @rd.old_dentry, 3584 + * @rd.new_dentry. Also the refcount on @rd->old_parent is increased. 3585 + * These references and the lock are dropped by end_renaming(). 3586 + * 3587 + * The passed in qstrs need not have the hash calculated, and basic 3588 + * eXecute permission checking is performed against @rd.mnt_idmap. 3589 + * 3590 + * Returns: zero or an error. 3591 + */ 3592 + int start_renaming(struct renamedata *rd, int lookup_flags, 3593 + struct qstr *old_last, struct qstr *new_last) 3594 + { 3595 + int err; 3596 + 3597 + err = lookup_one_common(rd->mnt_idmap, old_last, rd->old_parent); 3598 + if (err) 3599 + return err; 3600 + err = lookup_one_common(rd->mnt_idmap, new_last, rd->new_parent); 3601 + if (err) 3602 + return err; 3603 + return __start_renaming(rd, lookup_flags, old_last, new_last); 3604 + } 3605 + EXPORT_SYMBOL(start_renaming); 3606 + 3607 + static int 3608 + __start_renaming_dentry(struct renamedata *rd, int lookup_flags, 3609 + struct dentry *old_dentry, struct qstr *new_last) 3610 + { 3611 + struct dentry *trap; 3612 + struct dentry *d2; 3613 + int target_flags = LOOKUP_RENAME_TARGET | LOOKUP_CREATE; 3614 + int err; 3615 + 3616 + if (rd->flags & RENAME_EXCHANGE) 3617 + target_flags = 0; 3618 + if (rd->flags & RENAME_NOREPLACE) 3619 + target_flags |= LOOKUP_EXCL; 3620 + 3621 + /* Already have the dentry - need to be sure to lock the correct parent */ 3622 + trap = lock_rename_child(old_dentry, rd->new_parent); 3623 + if (IS_ERR(trap)) 3624 + return PTR_ERR(trap); 3625 + if (d_unhashed(old_dentry) || 3626 + (rd->old_parent && rd->old_parent != old_dentry->d_parent)) { 3627 + /* dentry was removed, or moved and explicit parent requested */ 3628 + err = -EINVAL; 3629 + goto out_unlock; 3630 + } 3631 + 3632 + d2 = lookup_one_qstr_excl(new_last, rd->new_parent, 3633 + lookup_flags | target_flags); 3634 + err = PTR_ERR(d2); 3635 + if (IS_ERR(d2)) 3636 + goto out_unlock; 3637 + 3638 + if (old_dentry == trap) { 3639 + /* source is an ancestor of target */ 3640 + err = -EINVAL; 3641 + goto out_dput_d2; 3642 + } 3643 + 3644 + if (d2 == trap) { 3645 + /* target is an ancestor of source */ 3646 + if (rd->flags & RENAME_EXCHANGE) 3647 + err = -EINVAL; 3648 + else 3649 + err = -ENOTEMPTY; 3650 + goto out_dput_d2; 3651 + } 3652 + 3653 + rd->old_dentry = dget(old_dentry); 3654 + rd->new_dentry = d2; 3655 + rd->old_parent = dget(old_dentry->d_parent); 3656 + return 0; 3657 + 3658 + out_dput_d2: 3659 + dput(d2); 3660 + out_unlock: 3661 + unlock_rename(old_dentry->d_parent, rd->new_parent); 3662 + return err; 3663 + } 3664 + 3665 + /** 3666 + * start_renaming_dentry - lookup and lock name for rename with permission checking 3667 + * @rd: rename data containing parents and flags, and 3668 + * for receiving found dentries 3669 + * @lookup_flags: extra flags to pass to ->lookup (e.g. LOOKUP_REVAL, 3670 + * LOOKUP_NO_SYMLINKS etc). 3671 + * @old_dentry: dentry of name to move 3672 + * @new_last: name of target in @rd.new_parent 3673 + * 3674 + * Look up target name and ensure locks are in place for 3675 + * rename. 3676 + * 3677 + * On success the found dentry is stored in @rd.new_dentry and 3678 + * @rd.old_parent is confirmed to be the parent of @old_dentry. If it 3679 + * was originally %NULL, it is set. In either case a reference is taken 3680 + * so that end_renaming() can have a stable reference to unlock. 3681 + * 3682 + * References and the lock can be dropped with end_renaming() 3683 + * 3684 + * The passed in qstr need not have the hash calculated, and basic 3685 + * eXecute permission checking is performed against @rd.mnt_idmap. 3686 + * 3687 + * Returns: zero or an error. 3688 + */ 3689 + int start_renaming_dentry(struct renamedata *rd, int lookup_flags, 3690 + struct dentry *old_dentry, struct qstr *new_last) 3691 + { 3692 + int err; 3693 + 3694 + err = lookup_one_common(rd->mnt_idmap, new_last, rd->new_parent); 3695 + if (err) 3696 + return err; 3697 + return __start_renaming_dentry(rd, lookup_flags, old_dentry, new_last); 3698 + } 3699 + EXPORT_SYMBOL(start_renaming_dentry); 3700 + 3701 + /** 3702 + * start_renaming_two_dentries - Lock to dentries in given parents for rename 3703 + * @rd: rename data containing parent 3704 + * @old_dentry: dentry of name to move 3705 + * @new_dentry: dentry to move to 3706 + * 3707 + * Ensure locks are in place for rename and check parentage is still correct. 3708 + * 3709 + * On success the two dentries are stored in @rd.old_dentry and 3710 + * @rd.new_dentry and @rd.old_parent and @rd.new_parent are confirmed to 3711 + * be the parents of the dentries. 3712 + * 3713 + * References and the lock can be dropped with end_renaming() 3714 + * 3715 + * Returns: zero or an error. 3716 + */ 3717 + int 3718 + start_renaming_two_dentries(struct renamedata *rd, 3719 + struct dentry *old_dentry, struct dentry *new_dentry) 3720 + { 3721 + struct dentry *trap; 3722 + int err; 3723 + 3724 + /* Already have the dentry - need to be sure to lock the correct parent */ 3725 + trap = lock_rename_child(old_dentry, rd->new_parent); 3726 + if (IS_ERR(trap)) 3727 + return PTR_ERR(trap); 3728 + err = -EINVAL; 3729 + if (d_unhashed(old_dentry) || 3730 + (rd->old_parent && rd->old_parent != old_dentry->d_parent)) 3731 + /* old_dentry was removed, or moved and explicit parent requested */ 3732 + goto out_unlock; 3733 + if (d_unhashed(new_dentry) || 3734 + rd->new_parent != new_dentry->d_parent) 3735 + /* new_dentry was removed or moved */ 3736 + goto out_unlock; 3737 + 3738 + if (old_dentry == trap) 3739 + /* source is an ancestor of target */ 3740 + goto out_unlock; 3741 + 3742 + if (new_dentry == trap) { 3743 + /* target is an ancestor of source */ 3744 + if (rd->flags & RENAME_EXCHANGE) 3745 + err = -EINVAL; 3746 + else 3747 + err = -ENOTEMPTY; 3748 + goto out_unlock; 3749 + } 3750 + 3751 + err = -EEXIST; 3752 + if (d_is_positive(new_dentry) && (rd->flags & RENAME_NOREPLACE)) 3753 + goto out_unlock; 3754 + 3755 + rd->old_dentry = dget(old_dentry); 3756 + rd->new_dentry = dget(new_dentry); 3757 + rd->old_parent = dget(old_dentry->d_parent); 3758 + return 0; 3759 + 3760 + out_unlock: 3761 + unlock_rename(old_dentry->d_parent, rd->new_parent); 3762 + return err; 3763 + } 3764 + EXPORT_SYMBOL(start_renaming_two_dentries); 3765 + 3766 + void end_renaming(struct renamedata *rd) 3767 + { 3768 + unlock_rename(rd->old_parent, rd->new_parent); 3769 + dput(rd->old_dentry); 3770 + dput(rd->new_dentry); 3771 + dput(rd->old_parent); 3772 + } 3773 + EXPORT_SYMBOL(end_renaming); 3772 3774 3773 3775 /** 3774 3776 * vfs_prepare_mode - prepare the mode to be used for a new inode ··· 4876 4310 */ 4877 4311 if (last.name[last.len] && !want_dir) 4878 4312 create_flags &= ~LOOKUP_CREATE; 4879 - inode_lock_nested(path->dentry->d_inode, I_MUTEX_PARENT); 4880 - dentry = lookup_one_qstr_excl(&last, path->dentry, 4881 - reval_flag | create_flags); 4313 + dentry = start_dirop(path->dentry, &last, reval_flag | create_flags); 4882 4314 if (IS_ERR(dentry)) 4883 - goto unlock; 4315 + goto out_drop_write; 4884 4316 4885 4317 if (unlikely(error)) 4886 4318 goto fail; 4887 4319 4888 4320 return dentry; 4889 4321 fail: 4890 - dput(dentry); 4322 + end_dirop(dentry); 4891 4323 dentry = ERR_PTR(error); 4892 - unlock: 4893 - inode_unlock(path->dentry->d_inode); 4324 + out_drop_write: 4894 4325 if (!error) 4895 4326 mnt_drop_write(path->mnt); 4896 4327 out: ··· 4906 4343 } 4907 4344 EXPORT_SYMBOL(start_creating_path); 4908 4345 4346 + /** 4347 + * end_creating_path - finish a code section started by start_creating_path() 4348 + * @path: the path instantiated by start_creating_path() 4349 + * @dentry: the dentry returned by start_creating_path() 4350 + * 4351 + * end_creating_path() will unlock and locks taken by start_creating_path() 4352 + * and drop an references that were taken. It should only be called 4353 + * if start_creating_path() returned a non-error. 4354 + * If vfs_mkdir() was called and it returned an error, that error *should* 4355 + * be passed to end_creating_path() together with the path. 4356 + */ 4909 4357 void end_creating_path(const struct path *path, struct dentry *dentry) 4910 4358 { 4911 - if (!IS_ERR(dentry)) 4912 - dput(dentry); 4913 - inode_unlock(path->dentry->d_inode); 4359 + end_creating(dentry); 4914 4360 mnt_drop_write(path->mnt); 4915 4361 path_put(path); 4916 4362 } ··· 5139 4567 return dentry; 5140 4568 5141 4569 err: 5142 - dput(dentry); 4570 + end_creating(dentry); 5143 4571 return ERR_PTR(error); 5144 4572 } 5145 4573 EXPORT_SYMBOL(vfs_mkdir); ··· 5281 4709 if (error) 5282 4710 goto exit2; 5283 4711 5284 - inode_lock_nested(path.dentry->d_inode, I_MUTEX_PARENT); 5285 - dentry = lookup_one_qstr_excl(&last, path.dentry, lookup_flags); 4712 + dentry = start_dirop(path.dentry, &last, lookup_flags); 5286 4713 error = PTR_ERR(dentry); 5287 4714 if (IS_ERR(dentry)) 5288 4715 goto exit3; ··· 5291 4720 error = vfs_rmdir(mnt_idmap(path.mnt), path.dentry->d_inode, 5292 4721 dentry, &delegated_inode); 5293 4722 exit4: 5294 - dput(dentry); 4723 + end_dirop(dentry); 5295 4724 exit3: 5296 - inode_unlock(path.dentry->d_inode); 5297 4725 mnt_drop_write(path.mnt); 5298 4726 exit2: 5299 4727 path_put(&path); ··· 5401 4831 struct path path; 5402 4832 struct qstr last; 5403 4833 int type; 5404 - struct inode *inode = NULL; 4834 + struct inode *inode; 5405 4835 struct delegated_inode delegated_inode = { }; 5406 4836 unsigned int lookup_flags = 0; 5407 4837 retry: 5408 4838 error = filename_parentat(dfd, name, lookup_flags, &path, &last, &type); 5409 4839 if (error) 5410 - goto exit1; 4840 + goto exit_putname; 5411 4841 5412 4842 error = -EISDIR; 5413 4843 if (type != LAST_NORM) 5414 - goto exit2; 4844 + goto exit_path_put; 5415 4845 5416 4846 error = mnt_want_write(path.mnt); 5417 4847 if (error) 5418 - goto exit2; 4848 + goto exit_path_put; 5419 4849 retry_deleg: 5420 - inode_lock_nested(path.dentry->d_inode, I_MUTEX_PARENT); 5421 - dentry = lookup_one_qstr_excl(&last, path.dentry, lookup_flags); 4850 + dentry = start_dirop(path.dentry, &last, lookup_flags); 5422 4851 error = PTR_ERR(dentry); 5423 - if (!IS_ERR(dentry)) { 4852 + if (IS_ERR(dentry)) 4853 + goto exit_drop_write; 5424 4854 5425 - /* Why not before? Because we want correct error value */ 5426 - if (last.name[last.len]) 5427 - goto slashes; 5428 - inode = dentry->d_inode; 5429 - ihold(inode); 5430 - error = security_path_unlink(&path, dentry); 5431 - if (error) 5432 - goto exit3; 5433 - error = vfs_unlink(mnt_idmap(path.mnt), path.dentry->d_inode, 5434 - dentry, &delegated_inode); 5435 - exit3: 5436 - dput(dentry); 4855 + /* Why not before? Because we want correct error value */ 4856 + if (unlikely(last.name[last.len])) { 4857 + if (d_is_dir(dentry)) 4858 + error = -EISDIR; 4859 + else 4860 + error = -ENOTDIR; 4861 + end_dirop(dentry); 4862 + goto exit_drop_write; 5437 4863 } 5438 - inode_unlock(path.dentry->d_inode); 5439 - if (inode) 5440 - iput(inode); /* truncate the inode here */ 5441 - inode = NULL; 4864 + inode = dentry->d_inode; 4865 + ihold(inode); 4866 + error = security_path_unlink(&path, dentry); 4867 + if (error) 4868 + goto exit_end_dirop; 4869 + error = vfs_unlink(mnt_idmap(path.mnt), path.dentry->d_inode, 4870 + dentry, &delegated_inode); 4871 + exit_end_dirop: 4872 + end_dirop(dentry); 4873 + iput(inode); /* truncate the inode here */ 5442 4874 if (is_delegated(&delegated_inode)) { 5443 4875 error = break_deleg_wait(&delegated_inode); 5444 4876 if (!error) 5445 4877 goto retry_deleg; 5446 4878 } 4879 + exit_drop_write: 5447 4880 mnt_drop_write(path.mnt); 5448 - exit2: 4881 + exit_path_put: 5449 4882 path_put(&path); 5450 4883 if (retry_estale(error, lookup_flags)) { 5451 4884 lookup_flags |= LOOKUP_REVAL; 5452 - inode = NULL; 5453 4885 goto retry; 5454 4886 } 5455 - exit1: 4887 + exit_putname: 5456 4888 putname(name); 5457 4889 return error; 5458 - 5459 - slashes: 5460 - if (d_is_dir(dentry)) 5461 - error = -EISDIR; 5462 - else 5463 - error = -ENOTDIR; 5464 - goto exit3; 5465 4890 } 5466 4891 5467 4892 SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag) ··· 5969 5404 struct filename *to, unsigned int flags) 5970 5405 { 5971 5406 struct renamedata rd; 5972 - struct dentry *old_dentry, *new_dentry; 5973 - struct dentry *trap; 5974 5407 struct path old_path, new_path; 5975 5408 struct qstr old_last, new_last; 5976 5409 int old_type, new_type; 5977 5410 struct delegated_inode delegated_inode = { }; 5978 - unsigned int lookup_flags = 0, target_flags = 5979 - LOOKUP_RENAME_TARGET | LOOKUP_CREATE; 5411 + unsigned int lookup_flags = 0; 5980 5412 bool should_retry = false; 5981 5413 int error = -EINVAL; 5982 5414 ··· 5983 5421 if ((flags & (RENAME_NOREPLACE | RENAME_WHITEOUT)) && 5984 5422 (flags & RENAME_EXCHANGE)) 5985 5423 goto put_names; 5986 - 5987 - if (flags & RENAME_EXCHANGE) 5988 - target_flags = 0; 5989 - if (flags & RENAME_NOREPLACE) 5990 - target_flags |= LOOKUP_EXCL; 5991 5424 5992 5425 retry: 5993 5426 error = filename_parentat(olddfd, from, lookup_flags, &old_path, ··· 6013 5456 goto exit2; 6014 5457 6015 5458 retry_deleg: 6016 - trap = lock_rename(new_path.dentry, old_path.dentry); 6017 - if (IS_ERR(trap)) { 6018 - error = PTR_ERR(trap); 6019 - goto exit_lock_rename; 6020 - } 5459 + rd.old_parent = old_path.dentry; 5460 + rd.mnt_idmap = mnt_idmap(old_path.mnt); 5461 + rd.new_parent = new_path.dentry; 5462 + rd.delegated_inode = &delegated_inode; 5463 + rd.flags = flags; 6021 5464 6022 - old_dentry = lookup_one_qstr_excl(&old_last, old_path.dentry, 6023 - lookup_flags); 6024 - error = PTR_ERR(old_dentry); 6025 - if (IS_ERR(old_dentry)) 6026 - goto exit3; 6027 - new_dentry = lookup_one_qstr_excl(&new_last, new_path.dentry, 6028 - lookup_flags | target_flags); 6029 - error = PTR_ERR(new_dentry); 6030 - if (IS_ERR(new_dentry)) 6031 - goto exit4; 5465 + error = __start_renaming(&rd, lookup_flags, &old_last, &new_last); 5466 + if (error) 5467 + goto exit_lock_rename; 5468 + 6032 5469 if (flags & RENAME_EXCHANGE) { 6033 - if (!d_is_dir(new_dentry)) { 5470 + if (!d_is_dir(rd.new_dentry)) { 6034 5471 error = -ENOTDIR; 6035 5472 if (new_last.name[new_last.len]) 6036 - goto exit5; 5473 + goto exit_unlock; 6037 5474 } 6038 5475 } 6039 5476 /* unless the source is a directory trailing slashes give -ENOTDIR */ 6040 - if (!d_is_dir(old_dentry)) { 5477 + if (!d_is_dir(rd.old_dentry)) { 6041 5478 error = -ENOTDIR; 6042 5479 if (old_last.name[old_last.len]) 6043 - goto exit5; 5480 + goto exit_unlock; 6044 5481 if (!(flags & RENAME_EXCHANGE) && new_last.name[new_last.len]) 6045 - goto exit5; 5482 + goto exit_unlock; 6046 5483 } 6047 - /* source should not be ancestor of target */ 6048 - error = -EINVAL; 6049 - if (old_dentry == trap) 6050 - goto exit5; 6051 - /* target should not be an ancestor of source */ 6052 - if (!(flags & RENAME_EXCHANGE)) 6053 - error = -ENOTEMPTY; 6054 - if (new_dentry == trap) 6055 - goto exit5; 6056 5484 6057 - error = security_path_rename(&old_path, old_dentry, 6058 - &new_path, new_dentry, flags); 5485 + error = security_path_rename(&old_path, rd.old_dentry, 5486 + &new_path, rd.new_dentry, flags); 6059 5487 if (error) 6060 - goto exit5; 5488 + goto exit_unlock; 6061 5489 6062 - rd.old_parent = old_path.dentry; 6063 - rd.old_dentry = old_dentry; 6064 - rd.mnt_idmap = mnt_idmap(old_path.mnt); 6065 - rd.new_parent = new_path.dentry; 6066 - rd.new_dentry = new_dentry; 6067 - rd.delegated_inode = &delegated_inode; 6068 - rd.flags = flags; 6069 5490 error = vfs_rename(&rd); 6070 - exit5: 6071 - dput(new_dentry); 6072 - exit4: 6073 - dput(old_dentry); 6074 - exit3: 6075 - unlock_rename(new_path.dentry, old_path.dentry); 5491 + exit_unlock: 5492 + end_renaming(&rd); 6076 5493 exit_lock_rename: 6077 5494 if (is_delegated(&delegated_inode)) { 6078 5495 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, 0700, NULL); 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, NULL); 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
+8 -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; ··· 407 409 /* File doesn't exist. Create it and set attrs */ 408 410 resp->status = nfsd_create_locked(rqstp, dirfhp, &attrs, type, 409 411 rdev, newfhp); 412 + /* nfsd_create_locked() unlocked the parent */ 413 + dput(dchild); 414 + goto out_write; 410 415 } else if (type == S_IFREG) { 411 416 dprintk("nfsd: existing %s, valid=%x, size=%ld\n", 412 417 argp->name, attr->ia_valid, (long) attr->ia_size); ··· 424 423 } 425 424 426 425 out_unlock: 427 - inode_unlock(dirfhp->fh_dentry->d_inode); 426 + end_creating(dchild); 427 + out_write: 428 428 fh_drop_write(dirfhp); 429 429 done: 430 430 fh_put(dirfhp);
+57 -98
fs/nfsd/vfs.c
··· 1522 1522 iap->ia_valid &= ~ATTR_SIZE; 1523 1523 } 1524 1524 1525 - /* The parent directory should already be locked: */ 1525 + /* The parent directory should already be locked - we will unlock */ 1526 1526 __be32 1527 1527 nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp, 1528 1528 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 - /* 1639 - * We unconditionally drop our ref to dchild as fh_compose will have 1640 - * already grabbed its own ref for it. 1641 - */ 1642 - dput(dchild); 1643 1635 if (err) 1644 1636 goto out_unlock; 1645 1637 err = fh_fill_pre_attrs(fhp); 1646 1638 if (err != nfs_ok) 1647 1639 goto out_unlock; 1648 1640 err = nfsd_create_locked(rqstp, fhp, attrs, type, rdev, resfhp); 1649 - fh_fill_post_attrs(fhp); 1641 + /* nfsd_create_locked() unlocked the parent */ 1642 + dput(dchild); 1643 + return err; 1644 + 1650 1645 out_unlock: 1651 - inode_unlock(dentry->d_inode); 1646 + end_creating(dchild); 1652 1647 return err; 1653 1648 } 1654 1649 ··· 1730 1733 } 1731 1734 1732 1735 dentry = fhp->fh_dentry; 1733 - inode_lock_nested(dentry->d_inode, I_MUTEX_PARENT); 1734 - dnew = lookup_one(&nop_mnt_idmap, &QSTR_LEN(fname, flen), dentry); 1736 + dnew = start_creating(&nop_mnt_idmap, dentry, &QSTR_LEN(fname, flen)); 1735 1737 if (IS_ERR(dnew)) { 1736 1738 err = nfserrno(PTR_ERR(dnew)); 1737 - inode_unlock(dentry->d_inode); 1738 1739 goto out_drop_write; 1739 1740 } 1740 1741 err = fh_fill_pre_attrs(fhp); ··· 1745 1750 nfsd_create_setattr(rqstp, fhp, resfhp, attrs); 1746 1751 fh_fill_post_attrs(fhp); 1747 1752 out_unlock: 1748 - inode_unlock(dentry->d_inode); 1753 + end_creating(dnew); 1749 1754 if (!err) 1750 1755 err = nfserrno(commit_metadata(fhp)); 1751 - dput(dnew); 1752 - if (err==0) err = cerr; 1756 + if (!err) 1757 + err = cerr; 1753 1758 out_drop_write: 1754 1759 fh_drop_write(fhp); 1755 1760 out: ··· 1804 1809 1805 1810 ddir = ffhp->fh_dentry; 1806 1811 dirp = d_inode(ddir); 1807 - inode_lock_nested(dirp, I_MUTEX_PARENT); 1812 + dnew = start_creating(&nop_mnt_idmap, ddir, &QSTR_LEN(name, len)); 1808 1813 1809 - dnew = lookup_one(&nop_mnt_idmap, &QSTR_LEN(name, len), ddir); 1810 1814 if (IS_ERR(dnew)) { 1811 1815 host_err = PTR_ERR(dnew); 1812 - goto out_unlock; 1816 + goto out_drop_write; 1813 1817 } 1814 1818 1815 1819 dold = tfhp->fh_dentry; 1816 1820 1817 1821 err = nfserr_noent; 1818 1822 if (d_really_is_negative(dold)) 1819 - goto out_dput; 1823 + goto out_unlock; 1820 1824 err = fh_fill_pre_attrs(ffhp); 1821 1825 if (err != nfs_ok) 1822 - goto out_dput; 1826 + goto out_unlock; 1823 1827 host_err = vfs_link(dold, &nop_mnt_idmap, dirp, dnew, NULL); 1824 1828 fh_fill_post_attrs(ffhp); 1825 - inode_unlock(dirp); 1829 + out_unlock: 1830 + end_creating(dnew); 1826 1831 if (!host_err) { 1827 1832 host_err = commit_metadata(ffhp); 1828 1833 if (!host_err) 1829 1834 host_err = commit_metadata(tfhp); 1830 1835 } 1831 1836 1832 - dput(dnew); 1833 1837 out_drop_write: 1834 1838 fh_drop_write(tfhp); 1835 1839 if (host_err == -EBUSY) { ··· 1843 1849 } 1844 1850 out: 1845 1851 return err != nfs_ok ? err : nfserrno(host_err); 1846 - 1847 - out_dput: 1848 - dput(dnew); 1849 - out_unlock: 1850 - inode_unlock(dirp); 1851 - goto out_drop_write; 1852 1852 } 1853 1853 1854 1854 static void ··· 1883 1895 nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, 1884 1896 struct svc_fh *tfhp, char *tname, int tlen) 1885 1897 { 1886 - struct dentry *fdentry, *tdentry, *odentry, *ndentry, *trap; 1898 + struct dentry *fdentry, *tdentry; 1887 1899 int type = S_IFDIR; 1900 + struct renamedata rd = {}; 1888 1901 __be32 err; 1889 1902 int host_err; 1890 - bool close_cached = false; 1903 + struct dentry *close_cached; 1891 1904 1892 1905 trace_nfsd_vfs_rename(rqstp, ffhp, tfhp, fname, flen, tname, tlen); 1893 1906 ··· 1914 1925 goto out; 1915 1926 1916 1927 retry: 1928 + close_cached = NULL; 1917 1929 host_err = fh_want_write(ffhp); 1918 1930 if (host_err) { 1919 1931 err = nfserrno(host_err); 1920 1932 goto out; 1921 1933 } 1922 1934 1923 - trap = lock_rename(tdentry, fdentry); 1924 - if (IS_ERR(trap)) { 1925 - 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); 1926 1944 goto out_want_write; 1927 1945 } 1928 1946 err = fh_fill_pre_attrs(ffhp); ··· 1939 1943 if (err != nfs_ok) 1940 1944 goto out_unlock; 1941 1945 1942 - odentry = lookup_one(&nop_mnt_idmap, &QSTR_LEN(fname, flen), fdentry); 1943 - host_err = PTR_ERR(odentry); 1944 - if (IS_ERR(odentry)) 1945 - goto out_nfserr; 1946 + type = d_inode(rd.old_dentry)->i_mode & S_IFMT; 1946 1947 1947 - host_err = -ENOENT; 1948 - if (d_really_is_negative(odentry)) 1949 - goto out_dput_old; 1950 - host_err = -EINVAL; 1951 - if (odentry == trap) 1952 - goto out_dput_old; 1953 - 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; 1954 1950 1955 - ndentry = lookup_one(&nop_mnt_idmap, &QSTR_LEN(tname, tlen), tdentry); 1956 - host_err = PTR_ERR(ndentry); 1957 - if (IS_ERR(ndentry)) 1958 - goto out_dput_old; 1959 - if (d_inode(ndentry)) 1960 - type = d_inode(ndentry)->i_mode & S_IFMT; 1961 - host_err = -ENOTEMPTY; 1962 - if (ndentry == trap) 1963 - goto out_dput_new; 1964 - 1965 - if ((ndentry->d_sb->s_export_op->flags & EXPORT_OP_CLOSE_BEFORE_UNLINK) && 1966 - nfsd_has_cached_files(ndentry)) { 1967 - close_cached = true; 1968 - 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; 1969 1955 } else { 1970 - struct renamedata rd = { 1971 - .mnt_idmap = &nop_mnt_idmap, 1972 - .old_parent = fdentry, 1973 - .old_dentry = odentry, 1974 - .new_parent = tdentry, 1975 - .new_dentry = ndentry, 1976 - }; 1977 1956 int retries; 1978 1957 1979 1958 for (retries = 1;;) { 1980 1959 host_err = vfs_rename(&rd); 1981 1960 if (host_err != -EAGAIN || !retries--) 1982 1961 break; 1983 - if (!nfsd_wait_for_delegreturn(rqstp, d_inode(odentry))) 1962 + if (!nfsd_wait_for_delegreturn(rqstp, d_inode(rd.old_dentry))) 1984 1963 break; 1985 1964 } 1986 1965 if (!host_err) { ··· 1964 1993 host_err = commit_metadata(ffhp); 1965 1994 } 1966 1995 } 1967 - out_dput_new: 1968 - dput(ndentry); 1969 - out_dput_old: 1970 - dput(odentry); 1971 - out_nfserr: 1972 1996 if (host_err == -EBUSY) { 1973 1997 /* 1974 1998 * See RFC 8881 Section 18.26.4 para 1-3: NFSv4 RENAME ··· 1982 2016 fh_fill_post_attrs(tfhp); 1983 2017 } 1984 2018 out_unlock: 1985 - unlock_rename(tdentry, fdentry); 2019 + end_renaming(&rd); 1986 2020 out_want_write: 1987 2021 fh_drop_write(ffhp); 1988 2022 ··· 1993 2027 * until this point and then reattempt the whole shebang. 1994 2028 */ 1995 2029 if (close_cached) { 1996 - close_cached = false; 1997 - nfsd_close_cached_files(ndentry); 1998 - dput(ndentry); 2030 + nfsd_close_cached_files(close_cached); 2031 + dput(close_cached); 1999 2032 goto retry; 2000 2033 } 2001 2034 out: ··· 2019 2054 { 2020 2055 struct dentry *dentry, *rdentry; 2021 2056 struct inode *dirp; 2022 - struct inode *rinode; 2057 + struct inode *rinode = NULL; 2023 2058 __be32 err; 2024 2059 int host_err; 2025 2060 ··· 2038 2073 2039 2074 dentry = fhp->fh_dentry; 2040 2075 dirp = d_inode(dentry); 2041 - inode_lock_nested(dirp, I_MUTEX_PARENT); 2042 2076 2043 - rdentry = lookup_one(&nop_mnt_idmap, &QSTR_LEN(fname, flen), dentry); 2077 + rdentry = start_removing(&nop_mnt_idmap, dentry, &QSTR_LEN(fname, flen)); 2078 + 2044 2079 host_err = PTR_ERR(rdentry); 2045 2080 if (IS_ERR(rdentry)) 2046 - goto out_unlock; 2081 + goto out_drop_write; 2047 2082 2048 - if (d_really_is_negative(rdentry)) { 2049 - dput(rdentry); 2050 - host_err = -ENOENT; 2051 - goto out_unlock; 2052 - } 2053 - rinode = d_inode(rdentry); 2054 2083 err = fh_fill_pre_attrs(fhp); 2055 2084 if (err != nfs_ok) 2056 2085 goto out_unlock; 2057 2086 2087 + rinode = d_inode(rdentry); 2088 + /* Prevent truncation until after locks dropped */ 2058 2089 ihold(rinode); 2090 + 2059 2091 if (!type) 2060 2092 type = d_inode(rdentry)->i_mode & S_IFMT; 2061 2093 ··· 2074 2112 } 2075 2113 fh_fill_post_attrs(fhp); 2076 2114 2077 - inode_unlock(dirp); 2078 - if (!host_err) 2115 + out_unlock: 2116 + end_removing(rdentry); 2117 + if (!err && !host_err) 2079 2118 host_err = commit_metadata(fhp); 2080 - dput(rdentry); 2081 2119 iput(rinode); /* truncate the inode here */ 2082 2120 2083 2121 out_drop_write: ··· 2095 2133 } 2096 2134 out: 2097 2135 return err != nfs_ok ? err : nfserrno(host_err); 2098 - out_unlock: 2099 - inode_unlock(dirp); 2100 - goto out_drop_write; 2101 2136 } 2102 2137 2103 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
··· 6092 6092 } 6093 6093 6094 6094 ksmbd_debug(SMB, "target name is %s\n", target_name); 6095 - rc = ksmbd_vfs_kern_path_locked(work, link_name, LOOKUP_NO_SYMLINKS, 6096 - &path, 0); 6095 + rc = ksmbd_vfs_kern_path_start_removing(work, link_name, LOOKUP_NO_SYMLINKS, 6096 + &path, 0); 6097 6097 if (rc) { 6098 6098 if (rc != -ENOENT) 6099 6099 goto out; ··· 6111 6111 ksmbd_debug(SMB, "link already exists\n"); 6112 6112 goto out; 6113 6113 } 6114 - ksmbd_vfs_kern_path_unlock(&path); 6114 + ksmbd_vfs_kern_path_end_removing(&path); 6115 6115 } 6116 6116 rc = ksmbd_vfs_link(work, target_name, link_name); 6117 6117 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; ··· 660 680 int ksmbd_vfs_rename(struct ksmbd_work *work, const struct path *old_path, 661 681 char *newname, int flags) 662 682 { 663 - struct dentry *old_parent, *new_dentry, *trap; 664 683 struct dentry *old_child = old_path->dentry; 665 684 struct path new_path; 666 685 struct qstr new_last; ··· 669 690 struct ksmbd_file *parent_fp; 670 691 int new_type; 671 692 int err, lookup_flags = LOOKUP_NO_SYMLINKS; 672 - int target_lookup_flags = LOOKUP_RENAME_TARGET | LOOKUP_CREATE; 673 693 674 694 if (ksmbd_override_fsids(work)) 675 695 return -ENOMEM; ··· 678 700 err = PTR_ERR(to); 679 701 goto revert_fsids; 680 702 } 681 - 682 - /* 683 - * explicitly handle file overwrite case, for compatibility with 684 - * filesystems that may not support rename flags (e.g: fuse) 685 - */ 686 - if (flags & RENAME_NOREPLACE) 687 - target_lookup_flags |= LOOKUP_EXCL; 688 - flags &= ~(RENAME_NOREPLACE); 689 703 690 704 retry: 691 705 err = vfs_path_parent_lookup(to, lookup_flags | LOOKUP_BENEATH, ··· 695 725 if (err) 696 726 goto out2; 697 727 698 - trap = lock_rename_child(old_child, new_path.dentry); 699 - if (IS_ERR(trap)) { 700 - err = PTR_ERR(trap); 728 + rd.mnt_idmap = mnt_idmap(old_path->mnt); 729 + rd.old_parent = NULL; 730 + rd.new_parent = new_path.dentry; 731 + rd.flags = flags; 732 + rd.delegated_inode = NULL, 733 + err = start_renaming_dentry(&rd, lookup_flags, old_child, &new_last); 734 + if (err) 701 735 goto out_drop_write; 702 - } 703 - 704 - old_parent = dget(old_child->d_parent); 705 - if (d_unhashed(old_child)) { 706 - err = -EINVAL; 707 - goto out3; 708 - } 709 736 710 737 parent_fp = ksmbd_lookup_fd_inode(old_child->d_parent); 711 738 if (parent_fp) { ··· 715 748 ksmbd_fd_put(work, parent_fp); 716 749 } 717 750 718 - new_dentry = lookup_one_qstr_excl(&new_last, new_path.dentry, 719 - lookup_flags | target_lookup_flags); 720 - if (IS_ERR(new_dentry)) { 721 - err = PTR_ERR(new_dentry); 751 + if (d_is_symlink(rd.new_dentry)) { 752 + err = -EACCES; 722 753 goto out3; 723 754 } 724 755 725 - if (d_is_symlink(new_dentry)) { 726 - err = -EACCES; 727 - goto out4; 728 - } 729 - 730 - if (old_child == trap) { 731 - err = -EINVAL; 732 - goto out4; 733 - } 734 - 735 - if (new_dentry == trap) { 736 - err = -ENOTEMPTY; 737 - goto out4; 738 - } 739 - 740 - rd.mnt_idmap = mnt_idmap(old_path->mnt), 741 - rd.old_parent = old_parent, 742 - rd.old_dentry = old_child, 743 - rd.new_parent = new_path.dentry, 744 - rd.new_dentry = new_dentry, 745 - rd.flags = flags, 746 - rd.delegated_inode = NULL, 747 756 err = vfs_rename(&rd); 748 757 if (err) 749 758 ksmbd_debug(VFS, "vfs_rename failed err %d\n", err); 750 759 751 - out4: 752 - dput(new_dentry); 753 760 out3: 754 - dput(old_parent); 755 - unlock_rename(old_parent, new_path.dentry); 761 + end_renaming(&rd); 756 762 out_drop_write: 757 763 mnt_drop_write(old_path->mnt); 758 764 out2: ··· 1023 1083 return err; 1024 1084 1025 1085 dir = dget_parent(dentry); 1026 - err = ksmbd_vfs_lock_parent(dir, dentry); 1027 - if (err) 1086 + dentry = start_removing_dentry(dir, dentry); 1087 + err = PTR_ERR(dentry); 1088 + if (IS_ERR(dentry)) 1028 1089 goto out; 1029 - dget(dentry); 1030 1090 1031 1091 if (S_ISDIR(d_inode(dentry)->i_mode)) 1032 1092 err = vfs_rmdir(idmap, d_inode(dir), dentry, NULL); 1033 1093 else 1034 1094 err = vfs_unlink(idmap, d_inode(dir), dentry, NULL); 1035 1095 1036 - dput(dentry); 1037 - inode_unlock(d_inode(dir)); 1096 + end_removing(dentry); 1038 1097 if (err) 1039 1098 ksmbd_debug(VFS, "failed to delete, err %d\n", err); 1040 1099 out: ··· 1145 1206 static 1146 1207 int __ksmbd_vfs_kern_path(struct ksmbd_work *work, char *filepath, 1147 1208 unsigned int flags, 1148 - struct path *path, bool caseless, bool do_lock) 1209 + struct path *path, bool caseless, bool for_remove) 1149 1210 { 1150 1211 struct ksmbd_share_config *share_conf = work->tcon->share_conf; 1151 1212 struct path parent_path; ··· 1153 1214 int err; 1154 1215 1155 1216 retry: 1156 - err = ksmbd_vfs_path_lookup(share_conf, filepath, flags, path, do_lock); 1217 + err = ksmbd_vfs_path_lookup(share_conf, filepath, flags, path, for_remove); 1157 1218 if (!err || !caseless) 1158 1219 return err; 1159 1220 ··· 1224 1285 } 1225 1286 1226 1287 /** 1227 - * ksmbd_vfs_kern_path_locked() - lookup a file and get path info 1288 + * ksmbd_vfs_kern_path_start_remove() - lookup a file and get path info prior to removal 1228 1289 * @work: work 1229 1290 * @filepath: file path that is relative to share 1230 1291 * @flags: lookup flags ··· 1236 1297 * filesystem will have been gained. 1237 1298 * Return: 0 on if file was found, otherwise error 1238 1299 */ 1239 - int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *filepath, 1240 - unsigned int flags, 1241 - struct path *path, bool caseless) 1300 + int ksmbd_vfs_kern_path_start_removing(struct ksmbd_work *work, char *filepath, 1301 + unsigned int flags, 1302 + struct path *path, bool caseless) 1242 1303 { 1243 1304 return __ksmbd_vfs_kern_path(work, filepath, flags, path, 1244 1305 caseless, true); 1245 1306 } 1246 1307 1247 - void ksmbd_vfs_kern_path_unlock(const struct path *path) 1308 + void ksmbd_vfs_kern_path_end_removing(const struct path *path) 1248 1309 { 1249 - /* While lock is still held, ->d_parent is safe */ 1250 - inode_unlock(d_inode(path->dentry->d_parent)); 1310 + end_removing(path->dentry); 1251 1311 mnt_drop_write(path->mnt); 1252 - path_put(path); 1312 + mntput(path->mnt); 1253 1313 } 1254 1314 1255 1315 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, NULL); 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
··· 3175 3175 void filesystems_freeze(bool freeze_all); 3176 3176 void filesystems_thaw(void); 3177 3177 3178 + void end_dirop(struct dentry *de); 3179 + 3178 3180 extern int dcache_dir_open(struct inode *, struct file *); 3179 3181 extern int dcache_dir_close(struct inode *, struct file *); 3180 3182 extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
+82
include/linux/namei.h
··· 89 89 struct qstr *name, 90 90 struct dentry *base); 91 91 92 + struct dentry *start_creating(struct mnt_idmap *idmap, struct dentry *parent, 93 + struct qstr *name); 94 + struct dentry *start_removing(struct mnt_idmap *idmap, struct dentry *parent, 95 + struct qstr *name); 96 + struct dentry *start_creating_killable(struct mnt_idmap *idmap, 97 + struct dentry *parent, 98 + struct qstr *name); 99 + struct dentry *start_removing_killable(struct mnt_idmap *idmap, 100 + struct dentry *parent, 101 + struct qstr *name); 102 + struct dentry *start_creating_noperm(struct dentry *parent, struct qstr *name); 103 + struct dentry *start_removing_noperm(struct dentry *parent, struct qstr *name); 104 + struct dentry *start_creating_dentry(struct dentry *parent, 105 + struct dentry *child); 106 + struct dentry *start_removing_dentry(struct dentry *parent, 107 + struct dentry *child); 108 + 109 + /* end_creating - finish action started with start_creating 110 + * @child: dentry returned by start_creating() or vfs_mkdir() 111 + * 112 + * Unlock and release the child. This can be called after 113 + * start_creating() whether that function succeeded or not, 114 + * but it is not needed on failure. 115 + * 116 + * If vfs_mkdir() was called then the value returned from that function 117 + * should be given for @child rather than the original dentry, as vfs_mkdir() 118 + * may have provided a new dentry. 119 + * 120 + * 121 + * If vfs_mkdir() was not called, then @child will be a valid dentry and 122 + * @parent will be ignored. 123 + */ 124 + static inline void end_creating(struct dentry *child) 125 + { 126 + end_dirop(child); 127 + } 128 + 129 + /* end_creating_keep - finish action started with start_creating() and return result 130 + * @child: dentry returned by start_creating() or vfs_mkdir() 131 + * 132 + * Unlock and return the child. This can be called after 133 + * start_creating() whether that function succeeded or not, 134 + * but it is not needed on failure. 135 + * 136 + * If vfs_mkdir() was called then the value returned from that function 137 + * should be given for @child rather than the original dentry, as vfs_mkdir() 138 + * may have provided a new dentry. 139 + * 140 + * Returns: @child, which may be a dentry or an error. 141 + * 142 + */ 143 + static inline struct dentry *end_creating_keep(struct dentry *child) 144 + { 145 + if (!IS_ERR(child)) 146 + dget(child); 147 + end_dirop(child); 148 + return child; 149 + } 150 + 151 + /** 152 + * end_removing - finish action started with start_removing 153 + * @child: dentry returned by start_removing() 154 + * @parent: dentry given to start_removing() 155 + * 156 + * Unlock and release the child. 157 + * 158 + * This is identical to end_dirop(). It can be passed the result of 159 + * start_removing() whether that was successful or not, but it not needed 160 + * if start_removing() failed. 161 + */ 162 + static inline void end_removing(struct dentry *child) 163 + { 164 + end_dirop(child); 165 + } 166 + 92 167 extern int follow_down_one(struct path *); 93 168 extern int follow_down(struct path *path, unsigned int flags); 94 169 extern int follow_up(struct path *); ··· 171 96 extern struct dentry *lock_rename(struct dentry *, struct dentry *); 172 97 extern struct dentry *lock_rename_child(struct dentry *, struct dentry *); 173 98 extern void unlock_rename(struct dentry *, struct dentry *); 99 + int start_renaming(struct renamedata *rd, int lookup_flags, 100 + struct qstr *old_last, struct qstr *new_last); 101 + int start_renaming_dentry(struct renamedata *rd, int lookup_flags, 102 + struct dentry *old_dentry, struct qstr *new_last); 103 + int start_renaming_two_dentries(struct renamedata *rd, 104 + struct dentry *old_dentry, struct dentry *new_dentry); 105 + void end_renaming(struct renamedata *rd); 174 106 175 107 /** 176 108 * 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);