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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'vfs-6.17-rc1.ovl' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull overlayfs updates from Christian Brauner:
"This contains overlayfs updates for this cycle.

The changes for overlayfs in here are primarily focussed on preparing
for some proposed changes to directory locking.

Overlayfs currently will sometimes lock a directory on the upper
filesystem and do a few different things while holding the lock. This
is incompatible with the new potential scheme.

This series narrows the region of code protected by the directory
lock, taking it multiple times when necessary. This theoretically
opens up the possibilty of other changes happening on the upper
filesytem between the unlock and the lock. To some extent the patches
guard against that by checking the dentries still have the expect
parent after retaking the lock. In general, concurrent changes to the
upper and lower filesystems aren't supported properly anyway"

* tag 'vfs-6.17-rc1.ovl' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (25 commits)
ovl: properly print correct variable
ovl: rename ovl_cleanup_unlocked() to ovl_cleanup()
ovl: change ovl_create_real() to receive dentry parent
ovl: narrow locking in ovl_check_rename_whiteout()
ovl: narrow locking in ovl_whiteout()
ovl: change ovl_cleanup_and_whiteout() to take rename lock as needed
ovl: narrow locking on ovl_remove_and_whiteout()
ovl: change ovl_workdir_cleanup() to take dir lock as needed.
ovl: narrow locking in ovl_workdir_cleanup_recurse()
ovl: narrow locking in ovl_indexdir_cleanup()
ovl: narrow locking in ovl_workdir_create()
ovl: narrow locking in ovl_cleanup_index()
ovl: narrow locking in ovl_cleanup_whiteouts()
ovl: narrow locking in ovl_rename()
ovl: simplify gotos in ovl_rename()
ovl: narrow locking in ovl_create_over_whiteout()
ovl: narrow locking in ovl_clear_empty()
ovl: narrow locking in ovl_create_upper()
ovl: narrow the locked region in ovl_copy_up_workdir()
ovl: Call ovl_create_temp() without lock held.
...

+303 -226
+2 -2
fs/backing-file.c
··· 41 41 return f; 42 42 43 43 path_get(user_path); 44 - *backing_file_user_path(f) = *user_path; 44 + backing_file_set_user_path(f, user_path); 45 45 error = vfs_open(real_path, f); 46 46 if (error) { 47 47 fput(f); ··· 65 65 return f; 66 66 67 67 path_get(user_path); 68 - *backing_file_user_path(f) = *user_path; 68 + backing_file_set_user_path(f, user_path); 69 69 error = vfs_tmpfile(real_idmap, real_parentpath, f, mode); 70 70 if (error) { 71 71 fput(f);
+8 -5
fs/file_table.c
··· 52 52 }; 53 53 }; 54 54 55 - static inline struct backing_file *backing_file(struct file *f) 56 - { 57 - return container_of(f, struct backing_file, file); 58 - } 55 + #define backing_file(f) container_of(f, struct backing_file, file) 59 56 60 - struct path *backing_file_user_path(struct file *f) 57 + struct path *backing_file_user_path(const struct file *f) 61 58 { 62 59 return &backing_file(f)->user_path; 63 60 } 64 61 EXPORT_SYMBOL_GPL(backing_file_user_path); 62 + 63 + void backing_file_set_user_path(struct file *f, const struct path *path) 64 + { 65 + backing_file(f)->user_path = *path; 66 + } 67 + EXPORT_SYMBOL_GPL(backing_file_set_user_path); 65 68 66 69 static inline void file_free(struct file *f) 67 70 {
+1
fs/internal.h
··· 101 101 struct file *alloc_empty_file(int flags, const struct cred *cred); 102 102 struct file *alloc_empty_file_noaccount(int flags, const struct cred *cred); 103 103 struct file *alloc_empty_backing_file(int flags, const struct cred *cred); 104 + void backing_file_set_user_path(struct file *f, const struct path *path); 104 105 105 106 static inline void file_put_write_access(struct file *file) 106 107 {
+24 -24
fs/overlayfs/copy_up.c
··· 517 517 518 518 /* 519 519 * Create and install index entry. 520 - * 521 - * Caller must hold i_mutex on indexdir. 522 520 */ 523 521 static int ovl_create_index(struct dentry *dentry, const struct ovl_fh *fh, 524 522 struct dentry *upper) 525 523 { 526 524 struct ovl_fs *ofs = OVL_FS(dentry->d_sb); 527 525 struct dentry *indexdir = ovl_indexdir(dentry->d_sb); 528 - struct inode *dir = d_inode(indexdir); 529 526 struct dentry *index = NULL; 530 527 struct dentry *temp = NULL; 531 528 struct qstr name = { }; ··· 556 559 if (err) 557 560 goto out; 558 561 562 + err = ovl_parent_lock(indexdir, temp); 563 + if (err) 564 + goto out; 559 565 index = ovl_lookup_upper(ofs, name.name, indexdir, name.len); 560 566 if (IS_ERR(index)) { 561 567 err = PTR_ERR(index); ··· 566 566 err = ovl_do_rename(ofs, indexdir, temp, indexdir, index, 0); 567 567 dput(index); 568 568 } 569 + ovl_parent_unlock(indexdir); 569 570 out: 570 571 if (err) 571 - ovl_cleanup(ofs, dir, temp); 572 + ovl_cleanup(ofs, indexdir, temp); 572 573 dput(temp); 573 574 free_name: 574 575 kfree(name.name); ··· 763 762 { 764 763 struct ovl_fs *ofs = OVL_FS(c->dentry->d_sb); 765 764 struct inode *inode; 766 - struct inode *wdir = d_inode(c->workdir); 767 765 struct path path = { .mnt = ovl_upper_mnt(ofs) }; 768 766 struct dentry *temp, *upper, *trap; 769 767 struct ovl_cu_creds cc; ··· 779 779 return err; 780 780 781 781 ovl_start_write(c->dentry); 782 - inode_lock(wdir); 783 782 temp = ovl_create_temp(ofs, c->workdir, &cattr); 784 - inode_unlock(wdir); 785 783 ovl_end_write(c->dentry); 786 784 ovl_revert_cu_creds(&cc); 787 785 ··· 792 794 */ 793 795 path.dentry = temp; 794 796 err = ovl_copy_up_data(c, &path); 797 + ovl_start_write(c->dentry); 798 + if (err) 799 + goto cleanup_unlocked; 800 + 801 + if (S_ISDIR(c->stat.mode) && c->indexed) { 802 + err = ovl_create_index(c->dentry, c->origin_fh, temp); 803 + if (err) 804 + goto cleanup_unlocked; 805 + } 806 + 795 807 /* 796 808 * We cannot hold lock_rename() throughout this helper, because of 797 809 * lock ordering with sb_writers, which shouldn't be held when calling 798 810 * ovl_copy_up_data(), so lock workdir and destdir and make sure that 799 811 * temp wasn't moved before copy up completion or cleanup. 800 812 */ 801 - ovl_start_write(c->dentry); 802 813 trap = lock_rename(c->workdir, c->destdir); 803 814 if (trap || temp->d_parent != c->workdir) { 804 815 /* temp or workdir moved underneath us? abort without cleanup */ 805 816 dput(temp); 806 817 err = -EIO; 807 - if (IS_ERR(trap)) 808 - goto out; 809 - goto unlock; 810 - } else if (err) { 811 - goto cleanup; 818 + if (!IS_ERR(trap)) 819 + unlock_rename(c->workdir, c->destdir); 820 + goto out; 812 821 } 813 822 814 823 err = ovl_copy_up_metadata(c, temp); 815 824 if (err) 816 825 goto cleanup; 817 - 818 - if (S_ISDIR(c->stat.mode) && c->indexed) { 819 - err = ovl_create_index(c->dentry, c->origin_fh, temp); 820 - if (err) 821 - goto cleanup; 822 - } 823 826 824 827 upper = ovl_lookup_upper(ofs, c->destname.name, c->destdir, 825 828 c->destname.len); ··· 829 830 goto cleanup; 830 831 831 832 err = ovl_do_rename(ofs, c->workdir, temp, c->destdir, upper, 0); 833 + unlock_rename(c->workdir, c->destdir); 832 834 dput(upper); 833 835 if (err) 834 - goto cleanup; 836 + goto cleanup_unlocked; 835 837 836 838 inode = d_inode(c->dentry); 837 839 if (c->metacopy_digest) ··· 846 846 ovl_inode_update(inode, temp); 847 847 if (S_ISDIR(inode->i_mode)) 848 848 ovl_set_flag(OVL_WHITEOUTS, inode); 849 - unlock: 850 - unlock_rename(c->workdir, c->destdir); 851 849 out: 852 850 ovl_end_write(c->dentry); 853 851 854 852 return err; 855 853 856 854 cleanup: 857 - ovl_cleanup(ofs, wdir, temp); 855 + unlock_rename(c->workdir, c->destdir); 856 + cleanup_unlocked: 857 + ovl_cleanup(ofs, c->workdir, temp); 858 858 dput(temp); 859 - goto unlock; 859 + goto out; 860 860 } 861 861 862 862 /* Copyup using O_TMPFILE which does not require cross dir locking */
+133 -115
fs/overlayfs/dir.c
··· 24 24 25 25 static int ovl_set_redirect(struct dentry *dentry, bool samedir); 26 26 27 - int ovl_cleanup(struct ovl_fs *ofs, struct inode *wdir, struct dentry *wdentry) 27 + static int ovl_cleanup_locked(struct ovl_fs *ofs, struct inode *wdir, 28 + struct dentry *wdentry) 28 29 { 29 30 int err; 30 31 ··· 42 41 } 43 42 44 43 return err; 44 + } 45 + 46 + int ovl_cleanup(struct ovl_fs *ofs, struct dentry *workdir, 47 + struct dentry *wdentry) 48 + { 49 + int err; 50 + 51 + err = ovl_parent_lock(workdir, wdentry); 52 + if (err) 53 + return err; 54 + 55 + ovl_cleanup_locked(ofs, workdir->d_inode, wdentry); 56 + ovl_parent_unlock(workdir); 57 + 58 + return 0; 45 59 } 46 60 47 61 struct dentry *ovl_lookup_temp(struct ovl_fs *ofs, struct dentry *workdir) ··· 78 62 return temp; 79 63 } 80 64 81 - /* caller holds i_mutex on workdir */ 82 65 static struct dentry *ovl_whiteout(struct ovl_fs *ofs) 83 66 { 84 67 int err; ··· 85 70 struct dentry *workdir = ofs->workdir; 86 71 struct inode *wdir = workdir->d_inode; 87 72 88 - if (!ofs->whiteout) { 89 - whiteout = ovl_lookup_temp(ofs, workdir); 90 - if (IS_ERR(whiteout)) 91 - goto out; 73 + guard(mutex)(&ofs->whiteout_lock); 92 74 93 - err = ovl_do_whiteout(ofs, wdir, whiteout); 94 - if (err) { 95 - dput(whiteout); 96 - whiteout = ERR_PTR(err); 97 - goto out; 75 + if (!ofs->whiteout) { 76 + inode_lock_nested(wdir, I_MUTEX_PARENT); 77 + whiteout = ovl_lookup_temp(ofs, workdir); 78 + if (!IS_ERR(whiteout)) { 79 + err = ovl_do_whiteout(ofs, wdir, whiteout); 80 + if (err) { 81 + dput(whiteout); 82 + whiteout = ERR_PTR(err); 83 + } 98 84 } 85 + inode_unlock(wdir); 86 + if (IS_ERR(whiteout)) 87 + return whiteout; 99 88 ofs->whiteout = whiteout; 100 89 } 101 90 102 91 if (!ofs->no_shared_whiteout) { 92 + inode_lock_nested(wdir, I_MUTEX_PARENT); 103 93 whiteout = ovl_lookup_temp(ofs, workdir); 104 - if (IS_ERR(whiteout)) 105 - goto out; 106 - 107 - err = ovl_do_link(ofs, ofs->whiteout, wdir, whiteout); 108 - if (!err) 109 - goto out; 110 - 111 - if (err != -EMLINK) { 112 - pr_warn("Failed to link whiteout - disabling whiteout inode sharing(nlink=%u, err=%i)\n", 113 - ofs->whiteout->d_inode->i_nlink, err); 94 + if (!IS_ERR(whiteout)) { 95 + err = ovl_do_link(ofs, ofs->whiteout, wdir, whiteout); 96 + if (err) { 97 + dput(whiteout); 98 + whiteout = ERR_PTR(err); 99 + } 100 + } 101 + inode_unlock(wdir); 102 + if (!IS_ERR(whiteout)) 103 + return whiteout; 104 + if (PTR_ERR(whiteout) != -EMLINK) { 105 + pr_warn("Failed to link whiteout - disabling whiteout inode sharing(nlink=%u, err=%lu)\n", 106 + ofs->whiteout->d_inode->i_nlink, 107 + PTR_ERR(whiteout)); 114 108 ofs->no_shared_whiteout = true; 115 109 } 116 - dput(whiteout); 117 110 } 118 111 whiteout = ofs->whiteout; 119 112 ofs->whiteout = NULL; 120 - out: 121 113 return whiteout; 122 114 } 123 115 124 - /* Caller must hold i_mutex on both workdir and dir */ 125 116 int ovl_cleanup_and_whiteout(struct ovl_fs *ofs, struct dentry *dir, 126 117 struct dentry *dentry) 127 118 { 128 - struct inode *wdir = ofs->workdir->d_inode; 129 119 struct dentry *whiteout; 130 120 int err; 131 121 int flags = 0; ··· 143 123 if (d_is_dir(dentry)) 144 124 flags = RENAME_EXCHANGE; 145 125 146 - err = ovl_do_rename(ofs, ofs->workdir, whiteout, dir, dentry, flags); 126 + err = ovl_lock_rename_workdir(ofs->workdir, whiteout, dir, dentry); 127 + if (!err) { 128 + err = ovl_do_rename(ofs, ofs->workdir, whiteout, dir, dentry, flags); 129 + unlock_rename(ofs->workdir, dir); 130 + } 147 131 if (err) 148 132 goto kill_whiteout; 149 133 if (flags) 150 - ovl_cleanup(ofs, wdir, dentry); 134 + ovl_cleanup(ofs, ofs->workdir, dentry); 151 135 152 136 out: 153 137 dput(whiteout); 154 138 return err; 155 139 156 140 kill_whiteout: 157 - ovl_cleanup(ofs, wdir, whiteout); 141 + ovl_cleanup(ofs, ofs->workdir, whiteout); 158 142 goto out; 159 143 } 160 144 161 - struct dentry *ovl_create_real(struct ovl_fs *ofs, struct inode *dir, 145 + struct dentry *ovl_create_real(struct ovl_fs *ofs, struct dentry *parent, 162 146 struct dentry *newdentry, struct ovl_cattr *attr) 163 147 { 148 + struct inode *dir = parent->d_inode; 164 149 int err; 165 150 166 151 if (IS_ERR(newdentry)) ··· 224 199 struct dentry *ovl_create_temp(struct ovl_fs *ofs, struct dentry *workdir, 225 200 struct ovl_cattr *attr) 226 201 { 227 - return ovl_create_real(ofs, d_inode(workdir), 228 - ovl_lookup_temp(ofs, workdir), attr); 202 + struct dentry *ret; 203 + inode_lock(workdir->d_inode); 204 + ret = ovl_create_real(ofs, workdir, 205 + ovl_lookup_temp(ofs, workdir), attr); 206 + inode_unlock(workdir->d_inode); 207 + return ret; 229 208 } 230 209 231 210 static int ovl_set_opaque_xerr(struct dentry *dentry, struct dentry *upper, ··· 332 303 int err; 333 304 334 305 inode_lock_nested(udir, I_MUTEX_PARENT); 335 - newdentry = ovl_create_real(ofs, udir, 306 + newdentry = ovl_create_real(ofs, upperdir, 336 307 ovl_lookup_upper(ofs, dentry->d_name.name, 337 308 upperdir, dentry->d_name.len), 338 309 attr); 339 - err = PTR_ERR(newdentry); 310 + inode_unlock(udir); 340 311 if (IS_ERR(newdentry)) 341 - goto out_unlock; 312 + return PTR_ERR(newdentry); 342 313 343 314 if (ovl_type_merge(dentry->d_parent) && d_is_dir(newdentry) && 344 315 !ovl_allow_offline_changes(ofs)) { ··· 350 321 err = ovl_instantiate(dentry, inode, newdentry, !!attr->hardlink, NULL); 351 322 if (err) 352 323 goto out_cleanup; 353 - out_unlock: 354 - inode_unlock(udir); 355 - return err; 324 + return 0; 356 325 357 326 out_cleanup: 358 - ovl_cleanup(ofs, udir, newdentry); 327 + ovl_cleanup(ofs, upperdir, newdentry); 359 328 dput(newdentry); 360 - goto out_unlock; 329 + return err; 361 330 } 362 331 363 332 static struct dentry *ovl_clear_empty(struct dentry *dentry, ··· 363 336 { 364 337 struct ovl_fs *ofs = OVL_FS(dentry->d_sb); 365 338 struct dentry *workdir = ovl_workdir(dentry); 366 - struct inode *wdir = workdir->d_inode; 367 339 struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent); 368 - struct inode *udir = upperdir->d_inode; 369 340 struct path upperpath; 370 341 struct dentry *upper; 371 342 struct dentry *opaquedir; ··· 373 348 if (WARN_ON(!workdir)) 374 349 return ERR_PTR(-EROFS); 375 350 376 - err = ovl_lock_rename_workdir(workdir, upperdir); 377 - if (err) 378 - goto out; 379 - 380 351 ovl_path_upper(dentry, &upperpath); 381 352 err = vfs_getattr(&upperpath, &stat, 382 353 STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT); 383 354 if (err) 384 - goto out_unlock; 355 + goto out; 385 356 386 357 err = -ESTALE; 387 358 if (!S_ISDIR(stat.mode)) 388 - goto out_unlock; 359 + goto out; 389 360 upper = upperpath.dentry; 390 - if (upper->d_parent->d_inode != udir) 391 - goto out_unlock; 392 361 393 362 opaquedir = ovl_create_temp(ofs, workdir, OVL_CATTR(stat.mode)); 394 363 err = PTR_ERR(opaquedir); 395 364 if (IS_ERR(opaquedir)) 396 - goto out_unlock; 365 + goto out; 366 + 367 + err = ovl_lock_rename_workdir(workdir, opaquedir, upperdir, upper); 368 + if (err) 369 + goto out_cleanup_unlocked; 397 370 398 371 err = ovl_copy_xattr(dentry->d_sb, &upperpath, opaquedir); 399 372 if (err) ··· 408 385 goto out_cleanup; 409 386 410 387 err = ovl_do_rename(ofs, workdir, opaquedir, upperdir, upper, RENAME_EXCHANGE); 388 + unlock_rename(workdir, upperdir); 411 389 if (err) 412 - goto out_cleanup; 390 + goto out_cleanup_unlocked; 413 391 414 392 ovl_cleanup_whiteouts(ofs, upper, list); 415 - ovl_cleanup(ofs, wdir, upper); 416 - unlock_rename(workdir, upperdir); 393 + ovl_cleanup(ofs, workdir, upper); 417 394 418 395 /* dentry's upper doesn't match now, get rid of it */ 419 396 d_drop(dentry); ··· 421 398 return opaquedir; 422 399 423 400 out_cleanup: 424 - ovl_cleanup(ofs, wdir, opaquedir); 425 - dput(opaquedir); 426 - out_unlock: 427 401 unlock_rename(workdir, upperdir); 402 + out_cleanup_unlocked: 403 + ovl_cleanup(ofs, workdir, opaquedir); 404 + dput(opaquedir); 428 405 out: 429 406 return ERR_PTR(err); 430 407 } ··· 443 420 { 444 421 struct ovl_fs *ofs = OVL_FS(dentry->d_sb); 445 422 struct dentry *workdir = ovl_workdir(dentry); 446 - struct inode *wdir = workdir->d_inode; 447 423 struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent); 448 - struct inode *udir = upperdir->d_inode; 449 424 struct dentry *upper; 450 425 struct dentry *newdentry; 451 426 int err; ··· 460 439 return err; 461 440 } 462 441 463 - err = ovl_lock_rename_workdir(workdir, upperdir); 464 - if (err) 465 - goto out; 466 - 467 - upper = ovl_lookup_upper(ofs, dentry->d_name.name, upperdir, 468 - dentry->d_name.len); 442 + upper = ovl_lookup_upper_unlocked(ofs, dentry->d_name.name, upperdir, 443 + dentry->d_name.len); 469 444 err = PTR_ERR(upper); 470 445 if (IS_ERR(upper)) 471 - goto out_unlock; 446 + goto out; 472 447 473 448 err = -ESTALE; 474 449 if (d_is_negative(upper) || !ovl_upper_is_whiteout(ofs, upper)) ··· 474 457 err = PTR_ERR(newdentry); 475 458 if (IS_ERR(newdentry)) 476 459 goto out_dput; 460 + 461 + err = ovl_lock_rename_workdir(workdir, newdentry, upperdir, upper); 462 + if (err) 463 + goto out_cleanup_unlocked; 477 464 478 465 /* 479 466 * mode could have been mutilated due to umask (e.g. sgid directory) ··· 514 493 515 494 err = ovl_do_rename(ofs, workdir, newdentry, upperdir, upper, 516 495 RENAME_EXCHANGE); 496 + unlock_rename(workdir, upperdir); 517 497 if (err) 518 - goto out_cleanup; 498 + goto out_cleanup_unlocked; 519 499 520 - ovl_cleanup(ofs, wdir, upper); 500 + ovl_cleanup(ofs, workdir, upper); 521 501 } else { 522 502 err = ovl_do_rename(ofs, workdir, newdentry, upperdir, upper, 0); 503 + unlock_rename(workdir, upperdir); 523 504 if (err) 524 - goto out_cleanup; 505 + goto out_cleanup_unlocked; 525 506 } 526 507 ovl_dir_modified(dentry->d_parent, false); 527 508 err = ovl_instantiate(dentry, inode, newdentry, hardlink, NULL); 528 509 if (err) { 529 - ovl_cleanup(ofs, udir, newdentry); 510 + ovl_cleanup(ofs, upperdir, newdentry); 530 511 dput(newdentry); 531 512 } 532 513 out_dput: 533 514 dput(upper); 534 - out_unlock: 535 - unlock_rename(workdir, upperdir); 536 515 out: 537 516 if (!hardlink) { 538 517 posix_acl_release(acl); ··· 541 520 return err; 542 521 543 522 out_cleanup: 544 - ovl_cleanup(ofs, wdir, newdentry); 523 + unlock_rename(workdir, upperdir); 524 + out_cleanup_unlocked: 525 + ovl_cleanup(ofs, workdir, newdentry); 545 526 dput(newdentry); 546 527 goto out_dput; 547 528 } ··· 780 757 goto out; 781 758 } 782 759 783 - err = ovl_lock_rename_workdir(workdir, upperdir); 784 - if (err) 785 - goto out_dput; 786 - 787 - upper = ovl_lookup_upper(ofs, dentry->d_name.name, upperdir, 788 - dentry->d_name.len); 760 + upper = ovl_lookup_upper_unlocked(ofs, dentry->d_name.name, upperdir, 761 + dentry->d_name.len); 789 762 err = PTR_ERR(upper); 790 763 if (IS_ERR(upper)) 791 - goto out_unlock; 764 + goto out_dput; 792 765 793 766 err = -ESTALE; 794 767 if ((opaquedir && upper != opaquedir) || ··· 794 775 } 795 776 796 777 err = ovl_cleanup_and_whiteout(ofs, upperdir, upper); 797 - if (err) 798 - goto out_d_drop; 778 + if (!err) 779 + ovl_dir_modified(dentry->d_parent, true); 799 780 800 - ovl_dir_modified(dentry->d_parent, true); 801 - out_d_drop: 802 781 d_drop(dentry); 803 782 out_dput_upper: 804 783 dput(upper); 805 - out_unlock: 806 - unlock_rename(workdir, upperdir); 807 784 out_dput: 808 785 dput(opaquedir); 809 786 out: ··· 1084 1069 int err; 1085 1070 struct dentry *old_upperdir; 1086 1071 struct dentry *new_upperdir; 1087 - struct dentry *olddentry; 1088 - struct dentry *newdentry; 1089 - struct dentry *trap; 1072 + struct dentry *olddentry = NULL; 1073 + struct dentry *newdentry = NULL; 1074 + struct dentry *trap, *de; 1090 1075 bool old_opaque; 1091 1076 bool new_opaque; 1092 1077 bool cleanup_whiteout = false; ··· 1199 1184 goto out_revert_creds; 1200 1185 } 1201 1186 1202 - olddentry = ovl_lookup_upper(ofs, old->d_name.name, old_upperdir, 1203 - old->d_name.len); 1204 - err = PTR_ERR(olddentry); 1205 - if (IS_ERR(olddentry)) 1187 + de = ovl_lookup_upper(ofs, old->d_name.name, old_upperdir, 1188 + old->d_name.len); 1189 + err = PTR_ERR(de); 1190 + if (IS_ERR(de)) 1206 1191 goto out_unlock; 1192 + olddentry = de; 1207 1193 1208 1194 err = -ESTALE; 1209 1195 if (!ovl_matches_upper(old, olddentry)) 1210 - goto out_dput_old; 1196 + goto out_unlock; 1211 1197 1212 - newdentry = ovl_lookup_upper(ofs, new->d_name.name, new_upperdir, 1213 - new->d_name.len); 1214 - err = PTR_ERR(newdentry); 1215 - if (IS_ERR(newdentry)) 1216 - goto out_dput_old; 1198 + de = ovl_lookup_upper(ofs, new->d_name.name, new_upperdir, 1199 + new->d_name.len); 1200 + err = PTR_ERR(de); 1201 + if (IS_ERR(de)) 1202 + goto out_unlock; 1203 + newdentry = de; 1217 1204 1218 1205 old_opaque = ovl_dentry_is_opaque(old); 1219 1206 new_opaque = ovl_dentry_is_opaque(new); ··· 1224 1207 if (d_inode(new) && ovl_dentry_upper(new)) { 1225 1208 if (opaquedir) { 1226 1209 if (newdentry != opaquedir) 1227 - goto out_dput; 1210 + goto out_unlock; 1228 1211 } else { 1229 1212 if (!ovl_matches_upper(new, newdentry)) 1230 - goto out_dput; 1213 + goto out_unlock; 1231 1214 } 1232 1215 } else { 1233 1216 if (!d_is_negative(newdentry)) { 1234 1217 if (!new_opaque || !ovl_upper_is_whiteout(ofs, newdentry)) 1235 - goto out_dput; 1218 + goto out_unlock; 1236 1219 } else { 1237 1220 if (flags & RENAME_EXCHANGE) 1238 - goto out_dput; 1221 + goto out_unlock; 1239 1222 } 1240 1223 } 1241 1224 1242 1225 if (olddentry == trap) 1243 - goto out_dput; 1226 + goto out_unlock; 1244 1227 if (newdentry == trap) 1245 - goto out_dput; 1228 + goto out_unlock; 1246 1229 1247 1230 if (olddentry->d_inode == newdentry->d_inode) 1248 - goto out_dput; 1231 + goto out_unlock; 1249 1232 1250 1233 err = 0; 1251 1234 if (ovl_type_merge_or_lower(old)) ··· 1253 1236 else if (is_dir && !old_opaque && ovl_type_merge(new->d_parent)) 1254 1237 err = ovl_set_opaque_xerr(old, olddentry, -EXDEV); 1255 1238 if (err) 1256 - goto out_dput; 1239 + goto out_unlock; 1257 1240 1258 1241 if (!overwrite && ovl_type_merge_or_lower(new)) 1259 1242 err = ovl_set_redirect(new, samedir); ··· 1261 1244 ovl_type_merge(old->d_parent)) 1262 1245 err = ovl_set_opaque_xerr(new, newdentry, -EXDEV); 1263 1246 if (err) 1264 - goto out_dput; 1247 + goto out_unlock; 1265 1248 1266 1249 err = ovl_do_rename(ofs, old_upperdir, olddentry, 1267 1250 new_upperdir, newdentry, flags); 1251 + unlock_rename(new_upperdir, old_upperdir); 1268 1252 if (err) 1269 - goto out_dput; 1253 + goto out_revert_creds; 1270 1254 1271 1255 if (cleanup_whiteout) 1272 - ovl_cleanup(ofs, old_upperdir->d_inode, newdentry); 1256 + ovl_cleanup(ofs, old_upperdir, newdentry); 1273 1257 1274 1258 if (overwrite && d_inode(new)) { 1275 1259 if (new_is_dir) ··· 1289 1271 if (d_inode(new) && ovl_dentry_upper(new)) 1290 1272 ovl_copyattr(d_inode(new)); 1291 1273 1292 - out_dput: 1293 - dput(newdentry); 1294 - out_dput_old: 1295 - dput(olddentry); 1296 - out_unlock: 1297 - unlock_rename(new_upperdir, old_upperdir); 1298 1274 out_revert_creds: 1299 1275 ovl_revert_creds(old_cred); 1300 1276 if (update_nlink) ··· 1296 1284 else 1297 1285 ovl_drop_write(old); 1298 1286 out: 1287 + dput(newdentry); 1288 + dput(olddentry); 1299 1289 dput(opaquedir); 1300 1290 ovl_cache_free(&list); 1301 1291 return err; 1292 + 1293 + out_unlock: 1294 + unlock_rename(new_upperdir, old_upperdir); 1295 + goto out_revert_creds; 1302 1296 } 1303 1297 1304 1298 static int ovl_create_tmpfile(struct file *file, struct dentry *dentry,
+1 -1
fs/overlayfs/file.c
··· 48 48 if (!inode_owner_or_capable(real_idmap, realinode)) 49 49 flags &= ~O_NOATIME; 50 50 51 - realfile = backing_file_open(file_user_path((struct file *) file), 51 + realfile = backing_file_open(file_user_path(file), 52 52 flags, realpath, current_cred()); 53 53 } 54 54 ovl_revert_creds(old_cred);
+28 -3
fs/overlayfs/namei.c
··· 230 230 struct dentry **ret, bool drop_negative) 231 231 { 232 232 struct ovl_fs *ofs = OVL_FS(d->sb); 233 - struct dentry *this; 233 + struct dentry *this = NULL; 234 + const char *warn; 234 235 struct path path; 235 236 int err; 236 237 bool last_element = !post[0]; 237 238 bool is_upper = d->layer->idx == 0; 238 239 char val; 240 + 241 + /* 242 + * We allow filesystems that are case-folding capable but deny composing 243 + * ovl stack from case-folded directories. If someone has enabled case 244 + * folding on a directory on underlying layer, the warranty of the ovl 245 + * stack is voided. 246 + */ 247 + if (ovl_dentry_casefolded(base)) { 248 + warn = "case folded parent"; 249 + err = -ESTALE; 250 + goto out_warn; 251 + } 239 252 240 253 this = ovl_lookup_positive_unlocked(d, name, base, namelen, drop_negative); 241 254 if (IS_ERR(this)) { ··· 259 246 goto out_err; 260 247 } 261 248 249 + if (ovl_dentry_casefolded(this)) { 250 + warn = "case folded child"; 251 + err = -EREMOTE; 252 + goto out_warn; 253 + } 254 + 262 255 if (ovl_dentry_weird(this)) { 263 256 /* Don't support traversing automounts and other weirdness */ 257 + warn = "unsupported object type"; 264 258 err = -EREMOTE; 265 - goto out_err; 259 + goto out_warn; 266 260 } 267 261 268 262 path.dentry = this; ··· 303 283 } else { 304 284 if (ovl_lookup_trap_inode(d->sb, this)) { 305 285 /* Caught in a trap of overlapping layers */ 286 + warn = "overlapping layers"; 306 287 err = -ELOOP; 307 - goto out_err; 288 + goto out_warn; 308 289 } 309 290 310 291 if (last_element) ··· 337 316 this = NULL; 338 317 goto out; 339 318 319 + out_warn: 320 + pr_warn_ratelimited("failed lookup in %s (%pd2, name='%.*s', err=%i): %s\n", 321 + is_upper ? "upper" : "lower", base, 322 + namelen, name, err, warn); 340 323 out_err: 341 324 dput(this); 342 325 return err;
+25 -4
fs/overlayfs/overlayfs.h
··· 407 407 return lookup_one(ovl_upper_mnt_idmap(ofs), &QSTR_LEN(name, len), base); 408 408 } 409 409 410 + static inline struct dentry *ovl_lookup_upper_unlocked(struct ovl_fs *ofs, 411 + const char *name, 412 + struct dentry *base, 413 + int len) 414 + { 415 + return lookup_one_unlocked(ovl_upper_mnt_idmap(ofs), 416 + &QSTR_LEN(name, len), base); 417 + } 418 + 410 419 static inline bool ovl_open_flags_need_copy_up(int flags) 411 420 { 412 421 if (!flags) ··· 425 416 } 426 417 427 418 /* util.c */ 419 + int ovl_parent_lock(struct dentry *parent, struct dentry *child); 420 + static inline void ovl_parent_unlock(struct dentry *parent) 421 + { 422 + inode_unlock(parent->d_inode); 423 + } 428 424 int ovl_get_write_access(struct dentry *dentry); 429 425 void ovl_put_write_access(struct dentry *dentry); 430 426 void ovl_start_write(struct dentry *dentry); ··· 462 448 void ovl_dentry_init_flags(struct dentry *dentry, struct dentry *upperdentry, 463 449 struct ovl_entry *oe, unsigned int mask); 464 450 bool ovl_dentry_weird(struct dentry *dentry); 451 + 452 + static inline bool ovl_dentry_casefolded(struct dentry *dentry) 453 + { 454 + return sb_has_encoding(dentry->d_sb) && IS_CASEFOLDED(d_inode(dentry)); 455 + } 456 + 465 457 enum ovl_path_type ovl_path_type(struct dentry *dentry); 466 458 void ovl_path_upper(struct dentry *dentry, struct path *path); 467 459 void ovl_path_lower(struct dentry *dentry, struct path *path); ··· 555 535 bool ovl_need_index(struct dentry *dentry); 556 536 int ovl_nlink_start(struct dentry *dentry); 557 537 void ovl_nlink_end(struct dentry *dentry); 558 - int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir); 538 + int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *work, 539 + struct dentry *upperdir, struct dentry *upper); 559 540 int ovl_check_metacopy_xattr(struct ovl_fs *ofs, const struct path *path, 560 541 struct ovl_metacopy *data); 561 542 int ovl_set_metacopy_xattr(struct ovl_fs *ofs, struct dentry *d, ··· 744 723 void ovl_cache_free(struct list_head *list); 745 724 void ovl_dir_cache_free(struct inode *inode); 746 725 int ovl_check_d_type_supported(const struct path *realpath); 747 - int ovl_workdir_cleanup(struct ovl_fs *ofs, struct inode *dir, 726 + int ovl_workdir_cleanup(struct ovl_fs *ofs, struct dentry *parent, 748 727 struct vfsmount *mnt, struct dentry *dentry, int level); 749 728 int ovl_indexdir_cleanup(struct ovl_fs *ofs); 750 729 ··· 861 840 #define OVL_CATTR(m) (&(struct ovl_cattr) { .mode = (m) }) 862 841 863 842 struct dentry *ovl_create_real(struct ovl_fs *ofs, 864 - struct inode *dir, struct dentry *newdentry, 843 + struct dentry *parent, struct dentry *newdentry, 865 844 struct ovl_cattr *attr); 866 - int ovl_cleanup(struct ovl_fs *ofs, struct inode *dir, struct dentry *dentry); 845 + int ovl_cleanup(struct ovl_fs *ofs, struct dentry *workdir, struct dentry *dentry); 867 846 struct dentry *ovl_lookup_temp(struct ovl_fs *ofs, struct dentry *workdir); 868 847 struct dentry *ovl_create_temp(struct ovl_fs *ofs, struct dentry *workdir, 869 848 struct ovl_cattr *attr);
+1
fs/overlayfs/ovl_entry.h
··· 88 88 /* Shared whiteout cache */ 89 89 struct dentry *whiteout; 90 90 bool no_shared_whiteout; 91 + struct mutex whiteout_lock; 91 92 /* r/o snapshot of upperdir sb's only taken on volatile mounts */ 92 93 errseq_t errseq; 93 94 };
+6 -6
fs/overlayfs/params.c
··· 282 282 return invalfc(fc, "%s is not a directory", name); 283 283 284 284 /* 285 - * Root dentries of case-insensitive capable filesystems might 286 - * not have the dentry operations set, but still be incompatible 287 - * with overlayfs. Check explicitly to prevent post-mount 288 - * failures. 285 + * Allow filesystems that are case-folding capable but deny composing 286 + * ovl stack from case-folded directories. 289 287 */ 290 - if (sb_has_encoding(path->mnt->mnt_sb)) 291 - return invalfc(fc, "case-insensitive capable filesystem on %s not supported", name); 288 + if (ovl_dentry_casefolded(path->dentry)) 289 + return invalfc(fc, "case-insensitive directory on %s not supported", name); 292 290 293 291 if (ovl_dentry_weird(path->dentry)) 294 292 return invalfc(fc, "filesystem on %s not supported", name); ··· 795 797 fc->s_fs_info = ofs; 796 798 fc->fs_private = ctx; 797 799 fc->ops = &ovl_context_ops; 800 + 801 + mutex_init(&ofs->whiteout_lock); 798 802 return 0; 799 803 800 804 out_err:
+18 -24
fs/overlayfs/readdir.c
··· 1034 1034 { 1035 1035 struct ovl_cache_entry *p; 1036 1036 1037 - inode_lock_nested(upper->d_inode, I_MUTEX_CHILD); 1038 1037 list_for_each_entry(p, list, l_node) { 1039 1038 struct dentry *dentry; 1040 1039 1041 1040 if (WARN_ON(!p->is_whiteout || !p->is_upper)) 1042 1041 continue; 1043 1042 1044 - dentry = ovl_lookup_upper(ofs, p->name, upper, p->len); 1043 + dentry = ovl_lookup_upper_unlocked(ofs, p->name, upper, p->len); 1045 1044 if (IS_ERR(dentry)) { 1046 1045 pr_err("lookup '%s/%.*s' failed (%i)\n", 1047 1046 upper->d_name.name, p->len, p->name, ··· 1048 1049 continue; 1049 1050 } 1050 1051 if (dentry->d_inode) 1051 - ovl_cleanup(ofs, upper->d_inode, dentry); 1052 + ovl_cleanup(ofs, upper, dentry); 1052 1053 dput(dentry); 1053 1054 } 1054 - inode_unlock(upper->d_inode); 1055 1055 } 1056 1056 1057 1057 static bool ovl_check_d_type(struct dir_context *ctx, const char *name, ··· 1096 1098 int level) 1097 1099 { 1098 1100 int err; 1099 - struct inode *dir = path->dentry->d_inode; 1100 1101 LIST_HEAD(list); 1101 1102 struct ovl_cache_entry *p; 1102 1103 struct ovl_readdir_data rdd = { ··· 1121 1124 if (err) 1122 1125 goto out; 1123 1126 1124 - inode_lock_nested(dir, I_MUTEX_PARENT); 1125 1127 list_for_each_entry(p, &list, l_node) { 1126 1128 struct dentry *dentry; 1127 1129 ··· 1135 1139 err = -EINVAL; 1136 1140 break; 1137 1141 } 1138 - dentry = ovl_lookup_upper(ofs, p->name, path->dentry, p->len); 1142 + dentry = ovl_lookup_upper_unlocked(ofs, p->name, path->dentry, p->len); 1139 1143 if (IS_ERR(dentry)) 1140 1144 continue; 1141 1145 if (dentry->d_inode) 1142 - err = ovl_workdir_cleanup(ofs, dir, path->mnt, dentry, level); 1146 + err = ovl_workdir_cleanup(ofs, path->dentry, path->mnt, 1147 + dentry, level); 1143 1148 dput(dentry); 1144 1149 if (err) 1145 1150 break; 1146 1151 } 1147 - inode_unlock(dir); 1148 1152 out: 1149 1153 ovl_cache_free(&list); 1150 1154 return err; 1151 1155 } 1152 1156 1153 - int ovl_workdir_cleanup(struct ovl_fs *ofs, struct inode *dir, 1157 + int ovl_workdir_cleanup(struct ovl_fs *ofs, struct dentry *parent, 1154 1158 struct vfsmount *mnt, struct dentry *dentry, int level) 1155 1159 { 1156 1160 int err; 1157 1161 1158 - if (!d_is_dir(dentry) || level > 1) { 1159 - return ovl_cleanup(ofs, dir, dentry); 1160 - } 1162 + if (!d_is_dir(dentry) || level > 1) 1163 + return ovl_cleanup(ofs, parent, dentry); 1161 1164 1162 - err = ovl_do_rmdir(ofs, dir, dentry); 1165 + err = ovl_parent_lock(parent, dentry); 1166 + if (err) 1167 + return err; 1168 + err = ovl_do_rmdir(ofs, parent->d_inode, dentry); 1169 + ovl_parent_unlock(parent); 1163 1170 if (err) { 1164 1171 struct path path = { .mnt = mnt, .dentry = dentry }; 1165 1172 1166 - inode_unlock(dir); 1167 1173 err = ovl_workdir_cleanup_recurse(ofs, &path, level + 1); 1168 - inode_lock_nested(dir, I_MUTEX_PARENT); 1169 1174 if (!err) 1170 - err = ovl_cleanup(ofs, dir, dentry); 1175 + err = ovl_cleanup(ofs, parent, dentry); 1171 1176 } 1172 1177 1173 1178 return err; ··· 1179 1182 int err; 1180 1183 struct dentry *indexdir = ofs->workdir; 1181 1184 struct dentry *index = NULL; 1182 - struct inode *dir = indexdir->d_inode; 1183 1185 struct path path = { .mnt = ovl_upper_mnt(ofs), .dentry = indexdir }; 1184 1186 LIST_HEAD(list); 1185 1187 struct ovl_cache_entry *p; ··· 1192 1196 if (err) 1193 1197 goto out; 1194 1198 1195 - inode_lock_nested(dir, I_MUTEX_PARENT); 1196 1199 list_for_each_entry(p, &list, l_node) { 1197 1200 if (p->name[0] == '.') { 1198 1201 if (p->len == 1) ··· 1199 1204 if (p->len == 2 && p->name[1] == '.') 1200 1205 continue; 1201 1206 } 1202 - index = ovl_lookup_upper(ofs, p->name, indexdir, p->len); 1207 + index = ovl_lookup_upper_unlocked(ofs, p->name, indexdir, p->len); 1203 1208 if (IS_ERR(index)) { 1204 1209 err = PTR_ERR(index); 1205 1210 index = NULL; ··· 1207 1212 } 1208 1213 /* Cleanup leftover from index create/cleanup attempt */ 1209 1214 if (index->d_name.name[0] == '#') { 1210 - err = ovl_workdir_cleanup(ofs, dir, path.mnt, index, 1); 1215 + err = ovl_workdir_cleanup(ofs, indexdir, path.mnt, index, 1); 1211 1216 if (err) 1212 1217 break; 1213 1218 goto next; ··· 1217 1222 goto next; 1218 1223 } else if (err == -ESTALE) { 1219 1224 /* Cleanup stale index entries */ 1220 - err = ovl_cleanup(ofs, dir, index); 1225 + err = ovl_cleanup(ofs, indexdir, index); 1221 1226 } else if (err != -ENOENT) { 1222 1227 /* 1223 1228 * Abort mount to avoid corrupting the index if ··· 1233 1238 err = ovl_cleanup_and_whiteout(ofs, indexdir, index); 1234 1239 } else { 1235 1240 /* Cleanup orphan index entries */ 1236 - err = ovl_cleanup(ofs, dir, index); 1241 + err = ovl_cleanup(ofs, indexdir, index); 1237 1242 } 1238 1243 1239 1244 if (err) ··· 1244 1249 index = NULL; 1245 1250 } 1246 1251 dput(index); 1247 - inode_unlock(dir); 1248 1252 out: 1249 1253 ovl_cache_free(&list); 1250 1254 if (err)
+24 -24
fs/overlayfs/super.c
··· 299 299 int err; 300 300 bool retried = false; 301 301 302 - inode_lock_nested(dir, I_MUTEX_PARENT); 303 302 retry: 303 + inode_lock_nested(dir, I_MUTEX_PARENT); 304 304 work = ovl_lookup_upper(ofs, name, ofs->workbasedir, strlen(name)); 305 305 306 306 if (!IS_ERR(work)) { ··· 311 311 312 312 if (work->d_inode) { 313 313 err = -EEXIST; 314 + inode_unlock(dir); 314 315 if (retried) 315 316 goto out_dput; 316 317 317 318 if (persist) 318 - goto out_unlock; 319 + return work; 319 320 320 321 retried = true; 321 - err = ovl_workdir_cleanup(ofs, dir, mnt, work, 0); 322 + err = ovl_workdir_cleanup(ofs, ofs->workbasedir, mnt, work, 0); 322 323 dput(work); 323 - if (err == -EINVAL) { 324 - work = ERR_PTR(err); 325 - goto out_unlock; 326 - } 324 + if (err == -EINVAL) 325 + return ERR_PTR(err); 326 + 327 327 goto retry; 328 328 } 329 329 330 330 work = ovl_do_mkdir(ofs, dir, work, attr.ia_mode); 331 + inode_unlock(dir); 331 332 err = PTR_ERR(work); 332 333 if (IS_ERR(work)) 333 334 goto out_err; ··· 366 365 if (err) 367 366 goto out_dput; 368 367 } else { 368 + inode_unlock(dir); 369 369 err = PTR_ERR(work); 370 370 goto out_err; 371 371 } 372 - out_unlock: 373 - inode_unlock(dir); 374 372 return work; 375 373 376 374 out_dput: ··· 377 377 out_err: 378 378 pr_warn("failed to create directory %s/%s (errno: %i); mounting read-only\n", 379 379 ofs->config.workdir, name, -err); 380 - work = NULL; 381 - goto out_unlock; 380 + return NULL; 382 381 } 383 382 384 383 static int ovl_check_namelen(const struct path *path, struct ovl_fs *ofs, ··· 556 557 static int ovl_check_rename_whiteout(struct ovl_fs *ofs) 557 558 { 558 559 struct dentry *workdir = ofs->workdir; 559 - struct inode *dir = d_inode(workdir); 560 560 struct dentry *temp; 561 561 struct dentry *dest; 562 562 struct dentry *whiteout; 563 563 struct name_snapshot name; 564 564 int err; 565 565 566 - inode_lock_nested(dir, I_MUTEX_PARENT); 567 - 568 566 temp = ovl_create_temp(ofs, workdir, OVL_CATTR(S_IFREG | 0)); 569 567 err = PTR_ERR(temp); 570 568 if (IS_ERR(temp)) 571 - goto out_unlock; 569 + return err; 572 570 571 + err = ovl_parent_lock(workdir, temp); 572 + if (err) { 573 + dput(temp); 574 + return err; 575 + } 573 576 dest = ovl_lookup_temp(ofs, workdir); 574 577 err = PTR_ERR(dest); 575 578 if (IS_ERR(dest)) { 576 579 dput(temp); 577 - goto out_unlock; 580 + ovl_parent_unlock(workdir); 581 + return err; 578 582 } 579 583 580 584 /* Name is inline and stable - using snapshot as a copy helper */ 581 585 take_dentry_name_snapshot(&name, temp); 582 586 err = ovl_do_rename(ofs, workdir, temp, workdir, dest, RENAME_WHITEOUT); 587 + ovl_parent_unlock(workdir); 583 588 if (err) { 584 589 if (err == -EINVAL) 585 590 err = 0; 586 591 goto cleanup_temp; 587 592 } 588 593 589 - whiteout = ovl_lookup_upper(ofs, name.name.name, workdir, name.name.len); 594 + whiteout = ovl_lookup_upper_unlocked(ofs, name.name.name, 595 + workdir, name.name.len); 590 596 err = PTR_ERR(whiteout); 591 597 if (IS_ERR(whiteout)) 592 598 goto cleanup_temp; ··· 600 596 601 597 /* Best effort cleanup of whiteout and temp file */ 602 598 if (err) 603 - ovl_cleanup(ofs, dir, whiteout); 599 + ovl_cleanup(ofs, workdir, whiteout); 604 600 dput(whiteout); 605 601 606 602 cleanup_temp: 607 - ovl_cleanup(ofs, dir, temp); 603 + ovl_cleanup(ofs, workdir, temp); 608 604 release_dentry_name_snapshot(&name); 609 605 dput(temp); 610 606 dput(dest); 611 - 612 - out_unlock: 613 - inode_unlock(dir); 614 607 615 608 return err; 616 609 } ··· 622 621 inode_lock_nested(parent->d_inode, I_MUTEX_PARENT); 623 622 child = ovl_lookup_upper(ofs, name, parent, len); 624 623 if (!IS_ERR(child) && !child->d_inode) 625 - child = ovl_create_real(ofs, parent->d_inode, child, 626 - OVL_CATTR(mode)); 624 + child = ovl_create_real(ofs, parent, child, OVL_CATTR(mode)); 627 625 inode_unlock(parent->d_inode); 628 626 dput(parent); 629 627
+29 -15
fs/overlayfs/util.c
··· 206 206 if (!d_can_lookup(dentry) && !d_is_file(dentry) && !d_is_symlink(dentry)) 207 207 return true; 208 208 209 - return dentry->d_flags & (DCACHE_NEED_AUTOMOUNT | 210 - DCACHE_MANAGE_TRANSIT | 211 - DCACHE_OP_HASH | 212 - DCACHE_OP_COMPARE); 209 + if (dentry->d_flags & (DCACHE_NEED_AUTOMOUNT | DCACHE_MANAGE_TRANSIT)) 210 + return true; 211 + 212 + /* 213 + * Allow filesystems that are case-folding capable but deny composing 214 + * ovl stack from case-folded directories. 215 + */ 216 + if (sb_has_encoding(dentry->d_sb)) 217 + return IS_CASEFOLDED(d_inode(dentry)); 218 + 219 + return dentry->d_flags & (DCACHE_OP_HASH | DCACHE_OP_COMPARE); 213 220 } 214 221 215 222 enum ovl_path_type ovl_path_type(struct dentry *dentry) ··· 1078 1071 { 1079 1072 struct ovl_fs *ofs = OVL_FS(dentry->d_sb); 1080 1073 struct dentry *indexdir = ovl_indexdir(dentry->d_sb); 1081 - struct inode *dir = indexdir->d_inode; 1082 1074 struct dentry *lowerdentry = ovl_dentry_lower(dentry); 1083 1075 struct dentry *upperdentry = ovl_dentry_upper(dentry); 1084 1076 struct dentry *index = NULL; ··· 1113 1107 goto out; 1114 1108 } 1115 1109 1116 - inode_lock_nested(dir, I_MUTEX_PARENT); 1117 - index = ovl_lookup_upper(ofs, name.name, indexdir, name.len); 1110 + index = ovl_lookup_upper_unlocked(ofs, name.name, indexdir, name.len); 1118 1111 err = PTR_ERR(index); 1119 1112 if (IS_ERR(index)) { 1120 1113 index = NULL; ··· 1123 1118 indexdir, index); 1124 1119 } else { 1125 1120 /* Cleanup orphan index entries */ 1126 - err = ovl_cleanup(ofs, dir, index); 1121 + err = ovl_cleanup(ofs, indexdir, index); 1127 1122 } 1128 - 1129 - inode_unlock(dir); 1130 1123 if (err) 1131 1124 goto fail; 1132 1125 ··· 1223 1220 ovl_inode_unlock(inode); 1224 1221 } 1225 1222 1226 - int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir) 1223 + int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *work, 1224 + struct dentry *upperdir, struct dentry *upper) 1227 1225 { 1228 1226 struct dentry *trap; 1229 - 1230 - /* Workdir should not be the same as upperdir */ 1231 - if (workdir == upperdir) 1232 - goto err; 1233 1227 1234 1228 /* Workdir should not be subdir of upperdir and vice versa */ 1235 1229 trap = lock_rename(workdir, upperdir); 1236 1230 if (IS_ERR(trap)) 1237 1231 goto err; 1238 1232 if (trap) 1233 + goto err_unlock; 1234 + if (work && work->d_parent != workdir) 1235 + goto err_unlock; 1236 + if (upper && upper->d_parent != upperdir) 1239 1237 goto err_unlock; 1240 1238 1241 1239 return 0; ··· 1547 1543 inode_set_ctime_to_ts(inode, inode_get_ctime(realinode)); 1548 1544 i_size_write(inode, i_size_read(realinode)); 1549 1545 spin_unlock(&inode->i_lock); 1546 + } 1547 + 1548 + int ovl_parent_lock(struct dentry *parent, struct dentry *child) 1549 + { 1550 + inode_lock_nested(parent->d_inode, I_MUTEX_PARENT); 1551 + if (!child || child->d_parent == parent) 1552 + return 0; 1553 + 1554 + inode_unlock(parent->d_inode); 1555 + return -EINVAL; 1550 1556 }
+3 -3
include/linux/fs.h
··· 2869 2869 const struct cred *cred); 2870 2870 struct file *dentry_create(const struct path *path, int flags, umode_t mode, 2871 2871 const struct cred *cred); 2872 - struct path *backing_file_user_path(struct file *f); 2872 + struct path *backing_file_user_path(const struct file *f); 2873 2873 2874 2874 /* 2875 2875 * When mmapping a file on a stackable filesystem (e.g., overlayfs), the file ··· 2881 2881 * by fstat() on that same fd. 2882 2882 */ 2883 2883 /* Get the path to display in /proc/<pid>/maps */ 2884 - static inline const struct path *file_user_path(struct file *f) 2884 + static inline const struct path *file_user_path(const struct file *f) 2885 2885 { 2886 2886 if (unlikely(f->f_mode & FMODE_BACKING)) 2887 2887 return backing_file_user_path(f); 2888 2888 return &f->f_path; 2889 2889 } 2890 2890 /* Get the inode whose inode number to display in /proc/<pid>/maps */ 2891 - static inline const struct inode *file_user_inode(struct file *f) 2891 + static inline const struct inode *file_user_inode(const struct file *f) 2892 2892 { 2893 2893 if (unlikely(f->f_mode & FMODE_BACKING)) 2894 2894 return d_inode(backing_file_user_path(f)->dentry);