Commit 32e51f141fd8d880f57b6a2eb53ce72856254d4a
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (25 commits) cifs: remove unnecessary dentry_unhash on rmdir/rename_dir ocfs2: remove unnecessary dentry_unhash on rmdir/rename_dir exofs: remove unnecessary dentry_unhash on rmdir/rename_dir nfs: remove unnecessary dentry_unhash on rmdir/rename_dir ext2: remove unnecessary dentry_unhash on rmdir/rename_dir ext3: remove unnecessary dentry_unhash on rmdir/rename_dir ext4: remove unnecessary dentry_unhash on rmdir/rename_dir btrfs: remove unnecessary dentry_unhash in rmdir/rename_dir ceph: remove unnecessary dentry_unhash calls vfs: clean up vfs_rename_other vfs: clean up vfs_rename_dir vfs: clean up vfs_rmdir vfs: fix vfs_rename_dir for FS_RENAME_DOES_D_MOVE filesystems libfs: drop unneeded dentry_unhash vfs: update dentry_unhash() comment vfs: push dentry_unhash on rename_dir into file systems vfs: push dentry_unhash on rmdir into file systems vfs: remove dget() from dentry_unhash() vfs: dentry_unhash immediately prior to rmdir vfs: Block mmapped writes while the fs is frozen ...
Showing 33 changed files Side-by-side Diff
- fs/9p/vfs_inode.c
- fs/Kconfig
- fs/affs/namei.c
- fs/afs/dir.c
- fs/autofs4/root.c
- fs/bfs/dir.c
- fs/buffer.c
- fs/coda/dir.c
- fs/configfs/dir.c
- fs/ecryptfs/inode.c
- fs/fat/namei_msdos.c
- fs/fat/namei_vfat.c
- fs/fuse/dir.c
- fs/hfs/dir.c
- fs/hfsplus/dir.c
- fs/hostfs/hostfs_kern.c
- fs/hpfs/namei.c
- fs/jffs2/dir.c
- fs/jfs/namei.c
- fs/logfs/dir.c
- fs/minix/namei.c
- fs/namei.c
- fs/namespace.c
- fs/ncpfs/dir.c
- fs/nilfs2/namei.c
- fs/omfs/dir.c
- fs/reiserfs/namei.c
- fs/reiserfs/xattr.c
- fs/sysv/namei.c
- fs/ubifs/dir.c
- fs/udf/namei.c
- fs/ufs/namei.c
- include/linux/buffer_head.h
fs/9p/vfs_inode.c
... | ... | @@ -814,6 +814,7 @@ |
814 | 814 | |
815 | 815 | int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) |
816 | 816 | { |
817 | + dentry_unhash(d); | |
817 | 818 | return v9fs_remove(i, d, 1); |
818 | 819 | } |
819 | 820 | |
... | ... | @@ -838,6 +839,9 @@ |
838 | 839 | struct p9_fid *olddirfid; |
839 | 840 | struct p9_fid *newdirfid; |
840 | 841 | struct p9_wstat wstat; |
842 | + | |
843 | + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
844 | + dentry_unhash(new_dentry); | |
841 | 845 | |
842 | 846 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); |
843 | 847 | retval = 0; |
fs/Kconfig
fs/affs/namei.c
... | ... | @@ -320,6 +320,8 @@ |
320 | 320 | dentry->d_inode->i_ino, |
321 | 321 | (int)dentry->d_name.len, dentry->d_name.name); |
322 | 322 | |
323 | + dentry_unhash(dentry); | |
324 | + | |
323 | 325 | return affs_remove_header(dentry); |
324 | 326 | } |
325 | 327 | |
... | ... | @@ -416,6 +418,9 @@ |
416 | 418 | struct super_block *sb = old_dir->i_sb; |
417 | 419 | struct buffer_head *bh = NULL; |
418 | 420 | int retval; |
421 | + | |
422 | + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
423 | + dentry_unhash(new_dentry); | |
419 | 424 | |
420 | 425 | pr_debug("AFFS: rename(old=%u,\"%*s\" to new=%u,\"%*s\")\n", |
421 | 426 | (u32)old_dir->i_ino, (int)old_dentry->d_name.len, old_dentry->d_name.name, |
fs/afs/dir.c
... | ... | @@ -845,6 +845,8 @@ |
845 | 845 | _enter("{%x:%u},{%s}", |
846 | 846 | dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name); |
847 | 847 | |
848 | + dentry_unhash(dentry); | |
849 | + | |
848 | 850 | ret = -ENAMETOOLONG; |
849 | 851 | if (dentry->d_name.len >= AFSNAMEMAX) |
850 | 852 | goto error; |
... | ... | @@ -1145,6 +1147,9 @@ |
1145 | 1147 | struct afs_vnode *orig_dvnode, *new_dvnode, *vnode; |
1146 | 1148 | struct key *key; |
1147 | 1149 | int ret; |
1150 | + | |
1151 | + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
1152 | + dentry_unhash(new_dentry); | |
1148 | 1153 | |
1149 | 1154 | vnode = AFS_FS_I(old_dentry->d_inode); |
1150 | 1155 | orig_dvnode = AFS_FS_I(old_dir); |
fs/autofs4/root.c
... | ... | @@ -583,6 +583,8 @@ |
583 | 583 | if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN)) |
584 | 584 | return -EACCES; |
585 | 585 | |
586 | + dentry_unhash(dentry); | |
587 | + | |
586 | 588 | if (atomic_dec_and_test(&ino->count)) { |
587 | 589 | p_ino = autofs4_dentry_ino(dentry->d_parent); |
588 | 590 | if (p_ino && dentry->d_parent != dentry) |
fs/bfs/dir.c
... | ... | @@ -224,6 +224,9 @@ |
224 | 224 | struct bfs_sb_info *info; |
225 | 225 | int error = -ENOENT; |
226 | 226 | |
227 | + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
228 | + dentry_unhash(new_dentry); | |
229 | + | |
227 | 230 | old_bh = new_bh = NULL; |
228 | 231 | old_inode = old_dentry->d_inode; |
229 | 232 | if (S_ISDIR(old_inode->i_mode)) |
fs/buffer.c
... | ... | @@ -2331,24 +2331,26 @@ |
2331 | 2331 | * page lock we can determine safely if the page is beyond EOF. If it is not |
2332 | 2332 | * beyond EOF, then the page is guaranteed safe against truncation until we |
2333 | 2333 | * unlock the page. |
2334 | + * | |
2335 | + * Direct callers of this function should call vfs_check_frozen() so that page | |
2336 | + * fault does not busyloop until the fs is thawed. | |
2334 | 2337 | */ |
2335 | -int | |
2336 | -block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, | |
2337 | - get_block_t get_block) | |
2338 | +int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, | |
2339 | + get_block_t get_block) | |
2338 | 2340 | { |
2339 | 2341 | struct page *page = vmf->page; |
2340 | 2342 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; |
2341 | 2343 | unsigned long end; |
2342 | 2344 | loff_t size; |
2343 | - int ret = VM_FAULT_NOPAGE; /* make the VM retry the fault */ | |
2345 | + int ret; | |
2344 | 2346 | |
2345 | 2347 | lock_page(page); |
2346 | 2348 | size = i_size_read(inode); |
2347 | 2349 | if ((page->mapping != inode->i_mapping) || |
2348 | 2350 | (page_offset(page) > size)) { |
2349 | - /* page got truncated out from underneath us */ | |
2350 | - unlock_page(page); | |
2351 | - goto out; | |
2351 | + /* We overload EFAULT to mean page got truncated */ | |
2352 | + ret = -EFAULT; | |
2353 | + goto out_unlock; | |
2352 | 2354 | } |
2353 | 2355 | |
2354 | 2356 | /* page is wholly or partially inside EOF */ |
2355 | 2357 | |
... | ... | @@ -2361,17 +2363,40 @@ |
2361 | 2363 | if (!ret) |
2362 | 2364 | ret = block_commit_write(page, 0, end); |
2363 | 2365 | |
2364 | - if (unlikely(ret)) { | |
2365 | - unlock_page(page); | |
2366 | - if (ret == -ENOMEM) | |
2367 | - ret = VM_FAULT_OOM; | |
2368 | - else /* -ENOSPC, -EIO, etc */ | |
2369 | - ret = VM_FAULT_SIGBUS; | |
2370 | - } else | |
2371 | - ret = VM_FAULT_LOCKED; | |
2372 | - | |
2373 | -out: | |
2366 | + if (unlikely(ret < 0)) | |
2367 | + goto out_unlock; | |
2368 | + /* | |
2369 | + * Freezing in progress? We check after the page is marked dirty and | |
2370 | + * with page lock held so if the test here fails, we are sure freezing | |
2371 | + * code will wait during syncing until the page fault is done - at that | |
2372 | + * point page will be dirty and unlocked so freezing code will write it | |
2373 | + * and writeprotect it again. | |
2374 | + */ | |
2375 | + set_page_dirty(page); | |
2376 | + if (inode->i_sb->s_frozen != SB_UNFROZEN) { | |
2377 | + ret = -EAGAIN; | |
2378 | + goto out_unlock; | |
2379 | + } | |
2380 | + return 0; | |
2381 | +out_unlock: | |
2382 | + unlock_page(page); | |
2374 | 2383 | return ret; |
2384 | +} | |
2385 | +EXPORT_SYMBOL(__block_page_mkwrite); | |
2386 | + | |
2387 | +int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, | |
2388 | + get_block_t get_block) | |
2389 | +{ | |
2390 | + int ret; | |
2391 | + struct super_block *sb = vma->vm_file->f_path.dentry->d_inode->i_sb; | |
2392 | + | |
2393 | + /* | |
2394 | + * This check is racy but catches the common case. The check in | |
2395 | + * __block_page_mkwrite() is reliable. | |
2396 | + */ | |
2397 | + vfs_check_frozen(sb, SB_FREEZE_WRITE); | |
2398 | + ret = __block_page_mkwrite(vma, vmf, get_block); | |
2399 | + return block_page_mkwrite_return(ret); | |
2375 | 2400 | } |
2376 | 2401 | EXPORT_SYMBOL(block_page_mkwrite); |
2377 | 2402 |
fs/coda/dir.c
... | ... | @@ -336,6 +336,8 @@ |
336 | 336 | int len = de->d_name.len; |
337 | 337 | int error; |
338 | 338 | |
339 | + dentry_unhash(de); | |
340 | + | |
339 | 341 | error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len); |
340 | 342 | if (!error) { |
341 | 343 | /* VFS may delete the child */ |
... | ... | @@ -358,6 +360,9 @@ |
358 | 360 | int old_length = old_dentry->d_name.len; |
359 | 361 | int new_length = new_dentry->d_name.len; |
360 | 362 | int error; |
363 | + | |
364 | + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
365 | + dentry_unhash(new_dentry); | |
361 | 366 | |
362 | 367 | error = venus_rename(old_dir->i_sb, coda_i2f(old_dir), |
363 | 368 | coda_i2f(new_dir), old_length, new_length, |
fs/configfs/dir.c
fs/ecryptfs/inode.c
... | ... | @@ -521,6 +521,8 @@ |
521 | 521 | struct dentry *lower_dir_dentry; |
522 | 522 | int rc; |
523 | 523 | |
524 | + dentry_unhash(dentry); | |
525 | + | |
524 | 526 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
525 | 527 | dget(dentry); |
526 | 528 | lower_dir_dentry = lock_parent(lower_dentry); |
... | ... | @@ -570,6 +572,9 @@ |
570 | 572 | struct dentry *lower_old_dir_dentry; |
571 | 573 | struct dentry *lower_new_dir_dentry; |
572 | 574 | struct dentry *trap = NULL; |
575 | + | |
576 | + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
577 | + dentry_unhash(new_dentry); | |
573 | 578 | |
574 | 579 | lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); |
575 | 580 | lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); |
fs/fat/namei_msdos.c
... | ... | @@ -326,6 +326,8 @@ |
326 | 326 | struct fat_slot_info sinfo; |
327 | 327 | int err; |
328 | 328 | |
329 | + dentry_unhash(dentry); | |
330 | + | |
329 | 331 | lock_super(sb); |
330 | 332 | /* |
331 | 333 | * Check whether the directory is not in use, then check |
... | ... | @@ -456,6 +458,9 @@ |
456 | 458 | old_sinfo.bh = sinfo.bh = dotdot_bh = NULL; |
457 | 459 | old_inode = old_dentry->d_inode; |
458 | 460 | new_inode = new_dentry->d_inode; |
461 | + | |
462 | + if (new_inode && S_ISDIR(new_inode->i_mode)) | |
463 | + dentry_unhash(new_dentry); | |
459 | 464 | |
460 | 465 | err = fat_scan(old_dir, old_name, &old_sinfo); |
461 | 466 | if (err) { |
fs/fat/namei_vfat.c
... | ... | @@ -824,6 +824,8 @@ |
824 | 824 | struct fat_slot_info sinfo; |
825 | 825 | int err; |
826 | 826 | |
827 | + dentry_unhash(dentry); | |
828 | + | |
827 | 829 | lock_super(sb); |
828 | 830 | |
829 | 831 | err = fat_dir_empty(inode); |
... | ... | @@ -930,6 +932,9 @@ |
930 | 932 | loff_t dotdot_i_pos, new_i_pos; |
931 | 933 | int err, is_dir, update_dotdot, corrupt = 0; |
932 | 934 | struct super_block *sb = old_dir->i_sb; |
935 | + | |
936 | + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
937 | + dentry_unhash(new_dentry); | |
933 | 938 | |
934 | 939 | old_sinfo.bh = sinfo.bh = dotdot_bh = NULL; |
935 | 940 | old_inode = old_dentry->d_inode; |
fs/fuse/dir.c
... | ... | @@ -667,6 +667,8 @@ |
667 | 667 | if (IS_ERR(req)) |
668 | 668 | return PTR_ERR(req); |
669 | 669 | |
670 | + dentry_unhash(entry); | |
671 | + | |
670 | 672 | req->in.h.opcode = FUSE_RMDIR; |
671 | 673 | req->in.h.nodeid = get_node_id(dir); |
672 | 674 | req->in.numargs = 1; |
... | ... | @@ -691,6 +693,10 @@ |
691 | 693 | struct fuse_rename_in inarg; |
692 | 694 | struct fuse_conn *fc = get_fuse_conn(olddir); |
693 | 695 | struct fuse_req *req = fuse_get_req(fc); |
696 | + | |
697 | + if (newent->d_inode && S_ISDIR(newent->d_inode->i_mode)) | |
698 | + dentry_unhash(newent); | |
699 | + | |
694 | 700 | if (IS_ERR(req)) |
695 | 701 | return PTR_ERR(req); |
696 | 702 |
fs/hfs/dir.c
... | ... | @@ -253,6 +253,9 @@ |
253 | 253 | struct inode *inode = dentry->d_inode; |
254 | 254 | int res; |
255 | 255 | |
256 | + if (S_ISDIR(inode->i_mode)) | |
257 | + dentry_unhash(dentry); | |
258 | + | |
256 | 259 | if (S_ISDIR(inode->i_mode) && inode->i_size != 2) |
257 | 260 | return -ENOTEMPTY; |
258 | 261 | res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name); |
... | ... | @@ -283,6 +286,9 @@ |
283 | 286 | |
284 | 287 | /* Unlink destination if it already exists */ |
285 | 288 | if (new_dentry->d_inode) { |
289 | + if (S_ISDIR(new_dentry->d_inode->i_mode)) | |
290 | + dentry_unhash(new_dentry); | |
291 | + | |
286 | 292 | res = hfs_remove(new_dir, new_dentry); |
287 | 293 | if (res) |
288 | 294 | return res; |
fs/hfsplus/dir.c
... | ... | @@ -370,6 +370,8 @@ |
370 | 370 | struct inode *inode = dentry->d_inode; |
371 | 371 | int res; |
372 | 372 | |
373 | + dentry_unhash(dentry); | |
374 | + | |
373 | 375 | if (inode->i_size != 2) |
374 | 376 | return -ENOTEMPTY; |
375 | 377 | |
376 | 378 | |
377 | 379 | |
... | ... | @@ -467,10 +469,12 @@ |
467 | 469 | |
468 | 470 | /* Unlink destination if it already exists */ |
469 | 471 | if (new_dentry->d_inode) { |
470 | - if (S_ISDIR(new_dentry->d_inode->i_mode)) | |
472 | + if (S_ISDIR(new_dentry->d_inode->i_mode)) { | |
473 | + dentry_unhash(new_dentry); | |
471 | 474 | res = hfsplus_rmdir(new_dir, new_dentry); |
472 | - else | |
475 | + } else { | |
473 | 476 | res = hfsplus_unlink(new_dir, new_dentry); |
477 | + } | |
474 | 478 | if (res) |
475 | 479 | return res; |
476 | 480 | } |
fs/hostfs/hostfs_kern.c
... | ... | @@ -683,6 +683,8 @@ |
683 | 683 | char *file; |
684 | 684 | int err; |
685 | 685 | |
686 | + dentry_unhash(dentry); | |
687 | + | |
686 | 688 | if ((file = dentry_name(dentry)) == NULL) |
687 | 689 | return -ENOMEM; |
688 | 690 | err = do_rmdir(file); |
... | ... | @@ -735,6 +737,9 @@ |
735 | 737 | { |
736 | 738 | char *from_name, *to_name; |
737 | 739 | int err; |
740 | + | |
741 | + if (to->d_inode && S_ISDIR(to->d_inode->i_mode)) | |
742 | + dentry_unhash(to); | |
738 | 743 | |
739 | 744 | if ((from_name = dentry_name(from)) == NULL) |
740 | 745 | return -ENOMEM; |
fs/hpfs/namei.c
... | ... | @@ -395,7 +395,6 @@ |
395 | 395 | |
396 | 396 | dentry_unhash(dentry); |
397 | 397 | if (!d_unhashed(dentry)) { |
398 | - dput(dentry); | |
399 | 398 | hpfs_unlock(dir->i_sb); |
400 | 399 | return -ENOSPC; |
401 | 400 | } |
... | ... | @@ -403,7 +402,6 @@ |
403 | 402 | !S_ISREG(inode->i_mode) || |
404 | 403 | get_write_access(inode)) { |
405 | 404 | d_rehash(dentry); |
406 | - dput(dentry); | |
407 | 405 | } else { |
408 | 406 | struct iattr newattrs; |
409 | 407 | /*printk("HPFS: truncating file before delete.\n");*/ |
... | ... | @@ -411,7 +409,6 @@ |
411 | 409 | newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; |
412 | 410 | err = notify_change(dentry, &newattrs); |
413 | 411 | put_write_access(inode); |
414 | - dput(dentry); | |
415 | 412 | if (!err) |
416 | 413 | goto again; |
417 | 414 | } |
... | ... | @@ -442,6 +439,8 @@ |
442 | 439 | int err; |
443 | 440 | int r; |
444 | 441 | |
442 | + dentry_unhash(dentry); | |
443 | + | |
445 | 444 | hpfs_adjust_length(name, &len); |
446 | 445 | hpfs_lock(dir->i_sb); |
447 | 446 | err = -ENOENT; |
... | ... | @@ -535,6 +534,10 @@ |
535 | 534 | struct buffer_head *bh; |
536 | 535 | struct fnode *fnode; |
537 | 536 | int err; |
537 | + | |
538 | + if (new_inode && S_ISDIR(new_inode->i_mode)) | |
539 | + dentry_unhash(new_dentry); | |
540 | + | |
538 | 541 | if ((err = hpfs_chk_name(new_name, &new_len))) return err; |
539 | 542 | err = 0; |
540 | 543 | hpfs_adjust_length(old_name, &old_len); |
fs/jffs2/dir.c
... | ... | @@ -609,6 +609,8 @@ |
609 | 609 | int ret; |
610 | 610 | uint32_t now = get_seconds(); |
611 | 611 | |
612 | + dentry_unhash(dentry); | |
613 | + | |
612 | 614 | for (fd = f->dents ; fd; fd = fd->next) { |
613 | 615 | if (fd->ino) |
614 | 616 | return -ENOTEMPTY; |
... | ... | @@ -783,6 +785,9 @@ |
783 | 785 | struct jffs2_inode_info *victim_f = NULL; |
784 | 786 | uint8_t type; |
785 | 787 | uint32_t now; |
788 | + | |
789 | + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
790 | + dentry_unhash(new_dentry); | |
786 | 791 | |
787 | 792 | /* The VFS will check for us and prevent trying to rename a |
788 | 793 | * file over a directory and vice versa, but if it's a directory, |
fs/jfs/namei.c
... | ... | @@ -360,6 +360,8 @@ |
360 | 360 | |
361 | 361 | jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name); |
362 | 362 | |
363 | + dentry_unhash(dentry); | |
364 | + | |
363 | 365 | /* Init inode for quota operations. */ |
364 | 366 | dquot_initialize(dip); |
365 | 367 | dquot_initialize(ip); |
... | ... | @@ -1094,6 +1096,9 @@ |
1094 | 1096 | |
1095 | 1097 | jfs_info("jfs_rename: %s %s", old_dentry->d_name.name, |
1096 | 1098 | new_dentry->d_name.name); |
1099 | + | |
1100 | + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
1101 | + dentry_unhash(new_dentry); | |
1097 | 1102 | |
1098 | 1103 | dquot_initialize(old_dir); |
1099 | 1104 | dquot_initialize(new_dir); |
fs/logfs/dir.c
... | ... | @@ -273,6 +273,8 @@ |
273 | 273 | { |
274 | 274 | struct inode *inode = dentry->d_inode; |
275 | 275 | |
276 | + dentry_unhash(dentry); | |
277 | + | |
276 | 278 | if (!logfs_empty_dir(inode)) |
277 | 279 | return -ENOTEMPTY; |
278 | 280 | |
... | ... | @@ -621,6 +623,9 @@ |
621 | 623 | struct logfs_transaction *ta; |
622 | 624 | loff_t pos; |
623 | 625 | int err; |
626 | + | |
627 | + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
628 | + dentry_unhash(new_dentry); | |
624 | 629 | |
625 | 630 | /* 1. locate source dd */ |
626 | 631 | err = logfs_get_dd(old_dir, old_dentry, &dd, &pos); |
fs/minix/namei.c
... | ... | @@ -168,6 +168,8 @@ |
168 | 168 | struct inode * inode = dentry->d_inode; |
169 | 169 | int err = -ENOTEMPTY; |
170 | 170 | |
171 | + dentry_unhash(dentry); | |
172 | + | |
171 | 173 | if (minix_empty_dir(inode)) { |
172 | 174 | err = minix_unlink(dir, dentry); |
173 | 175 | if (!err) { |
... | ... | @@ -189,6 +191,9 @@ |
189 | 191 | struct page * old_page; |
190 | 192 | struct minix_dir_entry * old_de; |
191 | 193 | int err = -ENOENT; |
194 | + | |
195 | + if (new_inode && S_ISDIR(new_inode->i_mode)) | |
196 | + dentry_unhash(new_dentry); | |
192 | 197 | |
193 | 198 | old_de = minix_find_entry(old_dentry, &old_page); |
194 | 199 | if (!old_de) |
fs/namei.c
... | ... | @@ -391,79 +391,28 @@ |
391 | 391 | } |
392 | 392 | EXPORT_SYMBOL(path_put); |
393 | 393 | |
394 | -/** | |
395 | - * nameidata_drop_rcu - drop this nameidata out of rcu-walk | |
396 | - * @nd: nameidata pathwalk data to drop | |
397 | - * Returns: 0 on success, -ECHILD on failure | |
398 | - * | |
394 | +/* | |
399 | 395 | * Path walking has 2 modes, rcu-walk and ref-walk (see |
400 | - * Documentation/filesystems/path-lookup.txt). __drop_rcu* functions attempt | |
401 | - * to drop out of rcu-walk mode and take normal reference counts on dentries | |
402 | - * and vfsmounts to transition to rcu-walk mode. __drop_rcu* functions take | |
403 | - * refcounts at the last known good point before rcu-walk got stuck, so | |
404 | - * ref-walk may continue from there. If this is not successful (eg. a seqcount | |
405 | - * has changed), then failure is returned and path walk restarts from the | |
406 | - * beginning in ref-walk mode. | |
407 | - * | |
408 | - * nameidata_drop_rcu attempts to drop the current nd->path and nd->root into | |
409 | - * ref-walk. Must be called from rcu-walk context. | |
396 | + * Documentation/filesystems/path-lookup.txt). In situations when we can't | |
397 | + * continue in RCU mode, we attempt to drop out of rcu-walk mode and grab | |
398 | + * normal reference counts on dentries and vfsmounts to transition to rcu-walk | |
399 | + * mode. Refcounts are grabbed at the last known good point before rcu-walk | |
400 | + * got stuck, so ref-walk may continue from there. If this is not successful | |
401 | + * (eg. a seqcount has changed), then failure is returned and it's up to caller | |
402 | + * to restart the path walk from the beginning in ref-walk mode. | |
410 | 403 | */ |
411 | -static int nameidata_drop_rcu(struct nameidata *nd) | |
412 | -{ | |
413 | - struct fs_struct *fs = current->fs; | |
414 | - struct dentry *dentry = nd->path.dentry; | |
415 | - int want_root = 0; | |
416 | 404 | |
417 | - BUG_ON(!(nd->flags & LOOKUP_RCU)); | |
418 | - if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) { | |
419 | - want_root = 1; | |
420 | - spin_lock(&fs->lock); | |
421 | - if (nd->root.mnt != fs->root.mnt || | |
422 | - nd->root.dentry != fs->root.dentry) | |
423 | - goto err_root; | |
424 | - } | |
425 | - spin_lock(&dentry->d_lock); | |
426 | - if (!__d_rcu_to_refcount(dentry, nd->seq)) | |
427 | - goto err; | |
428 | - BUG_ON(nd->inode != dentry->d_inode); | |
429 | - spin_unlock(&dentry->d_lock); | |
430 | - if (want_root) { | |
431 | - path_get(&nd->root); | |
432 | - spin_unlock(&fs->lock); | |
433 | - } | |
434 | - mntget(nd->path.mnt); | |
435 | - | |
436 | - rcu_read_unlock(); | |
437 | - br_read_unlock(vfsmount_lock); | |
438 | - nd->flags &= ~LOOKUP_RCU; | |
439 | - return 0; | |
440 | -err: | |
441 | - spin_unlock(&dentry->d_lock); | |
442 | -err_root: | |
443 | - if (want_root) | |
444 | - spin_unlock(&fs->lock); | |
445 | - return -ECHILD; | |
446 | -} | |
447 | - | |
448 | -/* Try to drop out of rcu-walk mode if we were in it, otherwise do nothing. */ | |
449 | -static inline int nameidata_drop_rcu_maybe(struct nameidata *nd) | |
450 | -{ | |
451 | - if (nd->flags & LOOKUP_RCU) | |
452 | - return nameidata_drop_rcu(nd); | |
453 | - return 0; | |
454 | -} | |
455 | - | |
456 | 405 | /** |
457 | - * nameidata_dentry_drop_rcu - drop nameidata and dentry out of rcu-walk | |
458 | - * @nd: nameidata pathwalk data to drop | |
459 | - * @dentry: dentry to drop | |
406 | + * unlazy_walk - try to switch to ref-walk mode. | |
407 | + * @nd: nameidata pathwalk data | |
408 | + * @dentry: child of nd->path.dentry or NULL | |
460 | 409 | * Returns: 0 on success, -ECHILD on failure |
461 | 410 | * |
462 | - * nameidata_dentry_drop_rcu attempts to drop the current nd->path and nd->root, | |
463 | - * and dentry into ref-walk. @dentry must be a path found by a do_lookup call on | |
464 | - * @nd. Must be called from rcu-walk context. | |
411 | + * unlazy_walk attempts to legitimize the current nd->path, nd->root and dentry | |
412 | + * for ref-walk mode. @dentry must be a path found by a do_lookup call on | |
413 | + * @nd or NULL. Must be called from rcu-walk context. | |
465 | 414 | */ |
466 | -static int nameidata_dentry_drop_rcu(struct nameidata *nd, struct dentry *dentry) | |
415 | +static int unlazy_walk(struct nameidata *nd, struct dentry *dentry) | |
467 | 416 | { |
468 | 417 | struct fs_struct *fs = current->fs; |
469 | 418 | struct dentry *parent = nd->path.dentry; |
... | ... | @@ -478,18 +427,25 @@ |
478 | 427 | goto err_root; |
479 | 428 | } |
480 | 429 | spin_lock(&parent->d_lock); |
481 | - spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); | |
482 | - if (!__d_rcu_to_refcount(dentry, nd->seq)) | |
483 | - goto err; | |
484 | - /* | |
485 | - * If the sequence check on the child dentry passed, then the child has | |
486 | - * not been removed from its parent. This means the parent dentry must | |
487 | - * be valid and able to take a reference at this point. | |
488 | - */ | |
489 | - BUG_ON(!IS_ROOT(dentry) && dentry->d_parent != parent); | |
490 | - BUG_ON(!parent->d_count); | |
491 | - parent->d_count++; | |
492 | - spin_unlock(&dentry->d_lock); | |
430 | + if (!dentry) { | |
431 | + if (!__d_rcu_to_refcount(parent, nd->seq)) | |
432 | + goto err_parent; | |
433 | + BUG_ON(nd->inode != parent->d_inode); | |
434 | + } else { | |
435 | + spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); | |
436 | + if (!__d_rcu_to_refcount(dentry, nd->seq)) | |
437 | + goto err_child; | |
438 | + /* | |
439 | + * If the sequence check on the child dentry passed, then | |
440 | + * the child has not been removed from its parent. This | |
441 | + * means the parent dentry must be valid and able to take | |
442 | + * a reference at this point. | |
443 | + */ | |
444 | + BUG_ON(!IS_ROOT(dentry) && dentry->d_parent != parent); | |
445 | + BUG_ON(!parent->d_count); | |
446 | + parent->d_count++; | |
447 | + spin_unlock(&dentry->d_lock); | |
448 | + } | |
493 | 449 | spin_unlock(&parent->d_lock); |
494 | 450 | if (want_root) { |
495 | 451 | path_get(&nd->root); |
496 | 452 | |
... | ... | @@ -501,8 +457,10 @@ |
501 | 457 | br_read_unlock(vfsmount_lock); |
502 | 458 | nd->flags &= ~LOOKUP_RCU; |
503 | 459 | return 0; |
504 | -err: | |
460 | + | |
461 | +err_child: | |
505 | 462 | spin_unlock(&dentry->d_lock); |
463 | +err_parent: | |
506 | 464 | spin_unlock(&parent->d_lock); |
507 | 465 | err_root: |
508 | 466 | if (want_root) |
509 | 467 | |
... | ... | @@ -510,60 +468,7 @@ |
510 | 468 | return -ECHILD; |
511 | 469 | } |
512 | 470 | |
513 | -/* Try to drop out of rcu-walk mode if we were in it, otherwise do nothing. */ | |
514 | -static inline int nameidata_dentry_drop_rcu_maybe(struct nameidata *nd, struct dentry *dentry) | |
515 | -{ | |
516 | - if (nd->flags & LOOKUP_RCU) { | |
517 | - if (unlikely(nameidata_dentry_drop_rcu(nd, dentry))) { | |
518 | - nd->flags &= ~LOOKUP_RCU; | |
519 | - if (!(nd->flags & LOOKUP_ROOT)) | |
520 | - nd->root.mnt = NULL; | |
521 | - rcu_read_unlock(); | |
522 | - br_read_unlock(vfsmount_lock); | |
523 | - return -ECHILD; | |
524 | - } | |
525 | - } | |
526 | - return 0; | |
527 | -} | |
528 | - | |
529 | 471 | /** |
530 | - * nameidata_drop_rcu_last - drop nameidata ending path walk out of rcu-walk | |
531 | - * @nd: nameidata pathwalk data to drop | |
532 | - * Returns: 0 on success, -ECHILD on failure | |
533 | - * | |
534 | - * nameidata_drop_rcu_last attempts to drop the current nd->path into ref-walk. | |
535 | - * nd->path should be the final element of the lookup, so nd->root is discarded. | |
536 | - * Must be called from rcu-walk context. | |
537 | - */ | |
538 | -static int nameidata_drop_rcu_last(struct nameidata *nd) | |
539 | -{ | |
540 | - struct dentry *dentry = nd->path.dentry; | |
541 | - | |
542 | - BUG_ON(!(nd->flags & LOOKUP_RCU)); | |
543 | - nd->flags &= ~LOOKUP_RCU; | |
544 | - if (!(nd->flags & LOOKUP_ROOT)) | |
545 | - nd->root.mnt = NULL; | |
546 | - spin_lock(&dentry->d_lock); | |
547 | - if (!__d_rcu_to_refcount(dentry, nd->seq)) | |
548 | - goto err_unlock; | |
549 | - BUG_ON(nd->inode != dentry->d_inode); | |
550 | - spin_unlock(&dentry->d_lock); | |
551 | - | |
552 | - mntget(nd->path.mnt); | |
553 | - | |
554 | - rcu_read_unlock(); | |
555 | - br_read_unlock(vfsmount_lock); | |
556 | - | |
557 | - return 0; | |
558 | - | |
559 | -err_unlock: | |
560 | - spin_unlock(&dentry->d_lock); | |
561 | - rcu_read_unlock(); | |
562 | - br_read_unlock(vfsmount_lock); | |
563 | - return -ECHILD; | |
564 | -} | |
565 | - | |
566 | -/** | |
567 | 472 | * release_open_intent - free up open intent resources |
568 | 473 | * @nd: pointer to nameidata |
569 | 474 | */ |
570 | 475 | |
571 | 476 | |
572 | 477 | |
... | ... | @@ -606,26 +511,39 @@ |
606 | 511 | return dentry; |
607 | 512 | } |
608 | 513 | |
609 | -/* | |
610 | - * handle_reval_path - force revalidation of a dentry | |
514 | +/** | |
515 | + * complete_walk - successful completion of path walk | |
516 | + * @nd: pointer nameidata | |
611 | 517 | * |
612 | - * In some situations the path walking code will trust dentries without | |
613 | - * revalidating them. This causes problems for filesystems that depend on | |
614 | - * d_revalidate to handle file opens (e.g. NFSv4). When FS_REVAL_DOT is set | |
615 | - * (which indicates that it's possible for the dentry to go stale), force | |
616 | - * a d_revalidate call before proceeding. | |
617 | - * | |
618 | - * Returns 0 if the revalidation was successful. If the revalidation fails, | |
619 | - * either return the error returned by d_revalidate or -ESTALE if the | |
620 | - * revalidation it just returned 0. If d_revalidate returns 0, we attempt to | |
621 | - * invalidate the dentry. It's up to the caller to handle putting references | |
622 | - * to the path if necessary. | |
518 | + * If we had been in RCU mode, drop out of it and legitimize nd->path. | |
519 | + * Revalidate the final result, unless we'd already done that during | |
520 | + * the path walk or the filesystem doesn't ask for it. Return 0 on | |
521 | + * success, -error on failure. In case of failure caller does not | |
522 | + * need to drop nd->path. | |
623 | 523 | */ |
624 | -static inline int handle_reval_path(struct nameidata *nd) | |
524 | +static int complete_walk(struct nameidata *nd) | |
625 | 525 | { |
626 | 526 | struct dentry *dentry = nd->path.dentry; |
627 | 527 | int status; |
628 | 528 | |
529 | + if (nd->flags & LOOKUP_RCU) { | |
530 | + nd->flags &= ~LOOKUP_RCU; | |
531 | + if (!(nd->flags & LOOKUP_ROOT)) | |
532 | + nd->root.mnt = NULL; | |
533 | + spin_lock(&dentry->d_lock); | |
534 | + if (unlikely(!__d_rcu_to_refcount(dentry, nd->seq))) { | |
535 | + spin_unlock(&dentry->d_lock); | |
536 | + rcu_read_unlock(); | |
537 | + br_read_unlock(vfsmount_lock); | |
538 | + return -ECHILD; | |
539 | + } | |
540 | + BUG_ON(nd->inode != dentry->d_inode); | |
541 | + spin_unlock(&dentry->d_lock); | |
542 | + mntget(nd->path.mnt); | |
543 | + rcu_read_unlock(); | |
544 | + br_read_unlock(vfsmount_lock); | |
545 | + } | |
546 | + | |
629 | 547 | if (likely(!(nd->flags & LOOKUP_JUMPED))) |
630 | 548 | return 0; |
631 | 549 | |
... | ... | @@ -643,6 +561,7 @@ |
643 | 561 | if (!status) |
644 | 562 | status = -ESTALE; |
645 | 563 | |
564 | + path_put(&nd->path); | |
646 | 565 | return status; |
647 | 566 | } |
648 | 567 | |
... | ... | @@ -1241,13 +1160,8 @@ |
1241 | 1160 | if (likely(__follow_mount_rcu(nd, path, inode, false))) |
1242 | 1161 | return 0; |
1243 | 1162 | unlazy: |
1244 | - if (dentry) { | |
1245 | - if (nameidata_dentry_drop_rcu(nd, dentry)) | |
1246 | - return -ECHILD; | |
1247 | - } else { | |
1248 | - if (nameidata_drop_rcu(nd)) | |
1249 | - return -ECHILD; | |
1250 | - } | |
1163 | + if (unlazy_walk(nd, dentry)) | |
1164 | + return -ECHILD; | |
1251 | 1165 | } else { |
1252 | 1166 | dentry = __d_lookup(parent, name); |
1253 | 1167 | } |
... | ... | @@ -1303,7 +1217,7 @@ |
1303 | 1217 | int err = exec_permission(nd->inode, IPERM_FLAG_RCU); |
1304 | 1218 | if (err != -ECHILD) |
1305 | 1219 | return err; |
1306 | - if (nameidata_drop_rcu(nd)) | |
1220 | + if (unlazy_walk(nd, NULL)) | |
1307 | 1221 | return -ECHILD; |
1308 | 1222 | } |
1309 | 1223 | return exec_permission(nd->inode, 0); |
... | ... | @@ -1357,8 +1271,12 @@ |
1357 | 1271 | return -ENOENT; |
1358 | 1272 | } |
1359 | 1273 | if (unlikely(inode->i_op->follow_link) && follow) { |
1360 | - if (nameidata_dentry_drop_rcu_maybe(nd, path->dentry)) | |
1361 | - return -ECHILD; | |
1274 | + if (nd->flags & LOOKUP_RCU) { | |
1275 | + if (unlikely(unlazy_walk(nd, path->dentry))) { | |
1276 | + terminate_walk(nd); | |
1277 | + return -ECHILD; | |
1278 | + } | |
1279 | + } | |
1362 | 1280 | BUG_ON(inode != path->dentry->d_inode); |
1363 | 1281 | return 1; |
1364 | 1282 | } |
1365 | 1283 | |
... | ... | @@ -1657,19 +1575,9 @@ |
1657 | 1575 | } |
1658 | 1576 | } |
1659 | 1577 | |
1660 | - if (nd->flags & LOOKUP_RCU) { | |
1661 | - /* went all way through without dropping RCU */ | |
1662 | - BUG_ON(err); | |
1663 | - if (nameidata_drop_rcu_last(nd)) | |
1664 | - err = -ECHILD; | |
1665 | - } | |
1578 | + if (!err) | |
1579 | + err = complete_walk(nd); | |
1666 | 1580 | |
1667 | - if (!err) { | |
1668 | - err = handle_reval_path(nd); | |
1669 | - if (err) | |
1670 | - path_put(&nd->path); | |
1671 | - } | |
1672 | - | |
1673 | 1581 | if (!err && nd->flags & LOOKUP_DIRECTORY) { |
1674 | 1582 | if (!nd->inode->i_op->lookup) { |
1675 | 1583 | path_put(&nd->path); |
1676 | 1584 | |
... | ... | @@ -2134,13 +2042,9 @@ |
2134 | 2042 | return ERR_PTR(error); |
2135 | 2043 | /* fallthrough */ |
2136 | 2044 | case LAST_ROOT: |
2137 | - if (nd->flags & LOOKUP_RCU) { | |
2138 | - if (nameidata_drop_rcu_last(nd)) | |
2139 | - return ERR_PTR(-ECHILD); | |
2140 | - } | |
2141 | - error = handle_reval_path(nd); | |
2045 | + error = complete_walk(nd); | |
2142 | 2046 | if (error) |
2143 | - goto exit; | |
2047 | + return ERR_PTR(error); | |
2144 | 2048 | audit_inode(pathname, nd->path.dentry); |
2145 | 2049 | if (open_flag & O_CREAT) { |
2146 | 2050 | error = -EISDIR; |
2147 | 2051 | |
... | ... | @@ -2148,10 +2052,9 @@ |
2148 | 2052 | } |
2149 | 2053 | goto ok; |
2150 | 2054 | case LAST_BIND: |
2151 | - /* can't be RCU mode here */ | |
2152 | - error = handle_reval_path(nd); | |
2055 | + error = complete_walk(nd); | |
2153 | 2056 | if (error) |
2154 | - goto exit; | |
2057 | + return ERR_PTR(error); | |
2155 | 2058 | audit_inode(pathname, dir); |
2156 | 2059 | goto ok; |
2157 | 2060 | } |
... | ... | @@ -2170,10 +2073,9 @@ |
2170 | 2073 | if (error) /* symlink */ |
2171 | 2074 | return NULL; |
2172 | 2075 | /* sayonara */ |
2173 | - if (nd->flags & LOOKUP_RCU) { | |
2174 | - if (nameidata_drop_rcu_last(nd)) | |
2175 | - return ERR_PTR(-ECHILD); | |
2176 | - } | |
2076 | + error = complete_walk(nd); | |
2077 | + if (error) | |
2078 | + return ERR_PTR(-ECHILD); | |
2177 | 2079 | |
2178 | 2080 | error = -ENOTDIR; |
2179 | 2081 | if (nd->flags & LOOKUP_DIRECTORY) { |
2180 | 2082 | |
... | ... | @@ -2185,12 +2087,10 @@ |
2185 | 2087 | } |
2186 | 2088 | |
2187 | 2089 | /* create side of things */ |
2090 | + error = complete_walk(nd); | |
2091 | + if (error) | |
2092 | + return ERR_PTR(error); | |
2188 | 2093 | |
2189 | - if (nd->flags & LOOKUP_RCU) { | |
2190 | - if (nameidata_drop_rcu_last(nd)) | |
2191 | - return ERR_PTR(-ECHILD); | |
2192 | - } | |
2193 | - | |
2194 | 2094 | audit_inode(pathname, dir); |
2195 | 2095 | error = -EISDIR; |
2196 | 2096 | /* trailing slashes? */ |
... | ... | @@ -2629,10 +2529,10 @@ |
2629 | 2529 | } |
2630 | 2530 | |
2631 | 2531 | /* |
2632 | - * We try to drop the dentry early: we should have | |
2633 | - * a usage count of 2 if we're the only user of this | |
2634 | - * dentry, and if that is true (possibly after pruning | |
2635 | - * the dcache), then we drop the dentry now. | |
2532 | + * The dentry_unhash() helper will try to drop the dentry early: we | |
2533 | + * should have a usage count of 2 if we're the only user of this | |
2534 | + * dentry, and if that is true (possibly after pruning the dcache), | |
2535 | + * then we drop the dentry now. | |
2636 | 2536 | * |
2637 | 2537 | * A low-level filesystem can, if it choses, legally |
2638 | 2538 | * do a |
2639 | 2539 | |
... | ... | @@ -2645,10 +2545,9 @@ |
2645 | 2545 | */ |
2646 | 2546 | void dentry_unhash(struct dentry *dentry) |
2647 | 2547 | { |
2648 | - dget(dentry); | |
2649 | 2548 | shrink_dcache_parent(dentry); |
2650 | 2549 | spin_lock(&dentry->d_lock); |
2651 | - if (dentry->d_count == 2) | |
2550 | + if (dentry->d_count == 1) | |
2652 | 2551 | __d_drop(dentry); |
2653 | 2552 | spin_unlock(&dentry->d_lock); |
2654 | 2553 | } |
2655 | 2554 | |
2656 | 2555 | |
2657 | 2556 | |
... | ... | @@ -2664,25 +2563,26 @@ |
2664 | 2563 | return -EPERM; |
2665 | 2564 | |
2666 | 2565 | mutex_lock(&dentry->d_inode->i_mutex); |
2667 | - dentry_unhash(dentry); | |
2566 | + | |
2567 | + error = -EBUSY; | |
2668 | 2568 | if (d_mountpoint(dentry)) |
2669 | - error = -EBUSY; | |
2670 | - else { | |
2671 | - error = security_inode_rmdir(dir, dentry); | |
2672 | - if (!error) { | |
2673 | - error = dir->i_op->rmdir(dir, dentry); | |
2674 | - if (!error) { | |
2675 | - dentry->d_inode->i_flags |= S_DEAD; | |
2676 | - dont_mount(dentry); | |
2677 | - } | |
2678 | - } | |
2679 | - } | |
2569 | + goto out; | |
2570 | + | |
2571 | + error = security_inode_rmdir(dir, dentry); | |
2572 | + if (error) | |
2573 | + goto out; | |
2574 | + | |
2575 | + error = dir->i_op->rmdir(dir, dentry); | |
2576 | + if (error) | |
2577 | + goto out; | |
2578 | + | |
2579 | + dentry->d_inode->i_flags |= S_DEAD; | |
2580 | + dont_mount(dentry); | |
2581 | + | |
2582 | +out: | |
2680 | 2583 | mutex_unlock(&dentry->d_inode->i_mutex); |
2681 | - if (!error) { | |
2584 | + if (!error) | |
2682 | 2585 | d_delete(dentry); |
2683 | - } | |
2684 | - dput(dentry); | |
2685 | - | |
2686 | 2586 | return error; |
2687 | 2587 | } |
2688 | 2588 | |
... | ... | @@ -3053,12 +2953,7 @@ |
3053 | 2953 | * HOWEVER, it relies on the assumption that any object with ->lookup() |
3054 | 2954 | * has no more than 1 dentry. If "hybrid" objects will ever appear, |
3055 | 2955 | * we'd better make sure that there's no link(2) for them. |
3056 | - * d) some filesystems don't support opened-but-unlinked directories, | |
3057 | - * either because of layout or because they are not ready to deal with | |
3058 | - * all cases correctly. The latter will be fixed (taking this sort of | |
3059 | - * stuff into VFS), but the former is not going away. Solution: the same | |
3060 | - * trick as in rmdir(). | |
3061 | - * e) conversion from fhandle to dentry may come in the wrong moment - when | |
2956 | + * d) conversion from fhandle to dentry may come in the wrong moment - when | |
3062 | 2957 | * we are removing the target. Solution: we will have to grab ->i_mutex |
3063 | 2958 | * in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on |
3064 | 2959 | * ->i_mutex on parents, which works but leads to some truly excessive |
... | ... | @@ -3068,7 +2963,7 @@ |
3068 | 2963 | struct inode *new_dir, struct dentry *new_dentry) |
3069 | 2964 | { |
3070 | 2965 | int error = 0; |
3071 | - struct inode *target; | |
2966 | + struct inode *target = new_dentry->d_inode; | |
3072 | 2967 | |
3073 | 2968 | /* |
3074 | 2969 | * If we are going to change the parent - check write permissions, |
3075 | 2970 | |
3076 | 2971 | |
3077 | 2972 | |
... | ... | @@ -3084,26 +2979,24 @@ |
3084 | 2979 | if (error) |
3085 | 2980 | return error; |
3086 | 2981 | |
3087 | - target = new_dentry->d_inode; | |
3088 | 2982 | if (target) |
3089 | 2983 | mutex_lock(&target->i_mutex); |
3090 | - if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) | |
3091 | - error = -EBUSY; | |
3092 | - else { | |
3093 | - if (target) | |
3094 | - dentry_unhash(new_dentry); | |
3095 | - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); | |
3096 | - } | |
2984 | + | |
2985 | + error = -EBUSY; | |
2986 | + if (d_mountpoint(old_dentry) || d_mountpoint(new_dentry)) | |
2987 | + goto out; | |
2988 | + | |
2989 | + error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); | |
2990 | + if (error) | |
2991 | + goto out; | |
2992 | + | |
3097 | 2993 | if (target) { |
3098 | - if (!error) { | |
3099 | - target->i_flags |= S_DEAD; | |
3100 | - dont_mount(new_dentry); | |
3101 | - } | |
3102 | - mutex_unlock(&target->i_mutex); | |
3103 | - if (d_unhashed(new_dentry)) | |
3104 | - d_rehash(new_dentry); | |
3105 | - dput(new_dentry); | |
2994 | + target->i_flags |= S_DEAD; | |
2995 | + dont_mount(new_dentry); | |
3106 | 2996 | } |
2997 | +out: | |
2998 | + if (target) | |
2999 | + mutex_unlock(&target->i_mutex); | |
3107 | 3000 | if (!error) |
3108 | 3001 | if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) |
3109 | 3002 | d_move(old_dentry,new_dentry); |
... | ... | @@ -3113,7 +3006,7 @@ |
3113 | 3006 | static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, |
3114 | 3007 | struct inode *new_dir, struct dentry *new_dentry) |
3115 | 3008 | { |
3116 | - struct inode *target; | |
3009 | + struct inode *target = new_dentry->d_inode; | |
3117 | 3010 | int error; |
3118 | 3011 | |
3119 | 3012 | error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry); |
3120 | 3013 | |
3121 | 3014 | |
... | ... | @@ -3121,19 +3014,22 @@ |
3121 | 3014 | return error; |
3122 | 3015 | |
3123 | 3016 | dget(new_dentry); |
3124 | - target = new_dentry->d_inode; | |
3125 | 3017 | if (target) |
3126 | 3018 | mutex_lock(&target->i_mutex); |
3019 | + | |
3020 | + error = -EBUSY; | |
3127 | 3021 | if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) |
3128 | - error = -EBUSY; | |
3129 | - else | |
3130 | - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); | |
3131 | - if (!error) { | |
3132 | - if (target) | |
3133 | - dont_mount(new_dentry); | |
3134 | - if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) | |
3135 | - d_move(old_dentry, new_dentry); | |
3136 | - } | |
3022 | + goto out; | |
3023 | + | |
3024 | + error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); | |
3025 | + if (error) | |
3026 | + goto out; | |
3027 | + | |
3028 | + if (target) | |
3029 | + dont_mount(new_dentry); | |
3030 | + if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) | |
3031 | + d_move(old_dentry, new_dentry); | |
3032 | +out: | |
3137 | 3033 | if (target) |
3138 | 3034 | mutex_unlock(&target->i_mutex); |
3139 | 3035 | dput(new_dentry); |
fs/namespace.c
... | ... | @@ -1695,7 +1695,7 @@ |
1695 | 1695 | |
1696 | 1696 | static int flags_to_propagation_type(int flags) |
1697 | 1697 | { |
1698 | - int type = flags & ~MS_REC; | |
1698 | + int type = flags & ~(MS_REC | MS_SILENT); | |
1699 | 1699 | |
1700 | 1700 | /* Fail if any non-propagation flags are set */ |
1701 | 1701 | if (type & ~(MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) |
fs/ncpfs/dir.c
... | ... | @@ -1033,6 +1033,8 @@ |
1033 | 1033 | DPRINTK("ncp_rmdir: removing %s/%s\n", |
1034 | 1034 | dentry->d_parent->d_name.name, dentry->d_name.name); |
1035 | 1035 | |
1036 | + dentry_unhash(dentry); | |
1037 | + | |
1036 | 1038 | error = -EBUSY; |
1037 | 1039 | if (!d_unhashed(dentry)) |
1038 | 1040 | goto out; |
... | ... | @@ -1138,6 +1140,9 @@ |
1138 | 1140 | DPRINTK("ncp_rename: %s/%s to %s/%s\n", |
1139 | 1141 | old_dentry->d_parent->d_name.name, old_dentry->d_name.name, |
1140 | 1142 | new_dentry->d_parent->d_name.name, new_dentry->d_name.name); |
1143 | + | |
1144 | + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
1145 | + dentry_unhash(new_dentry); | |
1141 | 1146 | |
1142 | 1147 | ncp_age_dentry(server, old_dentry); |
1143 | 1148 | ncp_age_dentry(server, new_dentry); |
fs/nilfs2/namei.c
... | ... | @@ -334,6 +334,8 @@ |
334 | 334 | struct nilfs_transaction_info ti; |
335 | 335 | int err; |
336 | 336 | |
337 | + dentry_unhash(dentry); | |
338 | + | |
337 | 339 | err = nilfs_transaction_begin(dir->i_sb, &ti, 0); |
338 | 340 | if (err) |
339 | 341 | return err; |
... | ... | @@ -368,6 +370,9 @@ |
368 | 370 | struct nilfs_dir_entry *old_de; |
369 | 371 | struct nilfs_transaction_info ti; |
370 | 372 | int err; |
373 | + | |
374 | + if (new_inode && S_ISDIR(new_inode->i_mode)) | |
375 | + dentry_unhash(new_dentry); | |
371 | 376 | |
372 | 377 | err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1); |
373 | 378 | if (unlikely(err)) |
fs/omfs/dir.c
... | ... | @@ -240,9 +240,13 @@ |
240 | 240 | struct inode *inode = dentry->d_inode; |
241 | 241 | int ret; |
242 | 242 | |
243 | - if (S_ISDIR(inode->i_mode) && !omfs_dir_is_empty(inode)) | |
244 | - return -ENOTEMPTY; | |
245 | 243 | |
244 | + if (S_ISDIR(inode->i_mode)) { | |
245 | + dentry_unhash(dentry); | |
246 | + if (!omfs_dir_is_empty(inode)) | |
247 | + return -ENOTEMPTY; | |
248 | + } | |
249 | + | |
246 | 250 | ret = omfs_delete_entry(dentry); |
247 | 251 | if (ret) |
248 | 252 | return ret; |
... | ... | @@ -378,6 +382,9 @@ |
378 | 382 | int err; |
379 | 383 | |
380 | 384 | if (new_inode) { |
385 | + if (S_ISDIR(new_inode->i_mode)) | |
386 | + dentry_unhash(new_dentry); | |
387 | + | |
381 | 388 | /* overwriting existing file/dir */ |
382 | 389 | err = omfs_remove(new_dir, new_dentry); |
383 | 390 | if (err) |
fs/reiserfs/namei.c
... | ... | @@ -831,6 +831,8 @@ |
831 | 831 | INITIALIZE_PATH(path); |
832 | 832 | struct reiserfs_dir_entry de; |
833 | 833 | |
834 | + dentry_unhash(dentry); | |
835 | + | |
834 | 836 | /* we will be doing 2 balancings and update 2 stat data, we change quotas |
835 | 837 | * of the owner of the directory and of the owner of the parent directory. |
836 | 838 | * The quota structure is possibly deleted only on last iput => outside |
... | ... | @@ -1224,6 +1226,9 @@ |
1224 | 1226 | umode_t old_inode_mode; |
1225 | 1227 | unsigned long savelink = 1; |
1226 | 1228 | struct timespec ctime; |
1229 | + | |
1230 | + if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | |
1231 | + dentry_unhash(new_dentry); | |
1227 | 1232 | |
1228 | 1233 | /* three balancings: (1) old name removal, (2) new name insertion |
1229 | 1234 | and (3) maybe "save" link insertion |
fs/reiserfs/xattr.c
fs/sysv/namei.c
... | ... | @@ -196,6 +196,8 @@ |
196 | 196 | struct inode *inode = dentry->d_inode; |
197 | 197 | int err = -ENOTEMPTY; |
198 | 198 | |
199 | + dentry_unhash(dentry); | |
200 | + | |
199 | 201 | if (sysv_empty_dir(inode)) { |
200 | 202 | err = sysv_unlink(dir, dentry); |
201 | 203 | if (!err) { |
... | ... | @@ -221,6 +223,9 @@ |
221 | 223 | struct page * old_page; |
222 | 224 | struct sysv_dir_entry * old_de; |
223 | 225 | int err = -ENOENT; |
226 | + | |
227 | + if (new_inode && S_ISDIR(new_inode->i_mode)) | |
228 | + dentry_unhash(new_dentry); | |
224 | 229 | |
225 | 230 | old_de = sysv_find_entry(old_dentry, &old_page); |
226 | 231 | if (!old_de) |
fs/ubifs/dir.c
... | ... | @@ -656,6 +656,8 @@ |
656 | 656 | struct ubifs_inode *dir_ui = ubifs_inode(dir); |
657 | 657 | struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 }; |
658 | 658 | |
659 | + dentry_unhash(dentry); | |
660 | + | |
659 | 661 | /* |
660 | 662 | * Budget request settings: deletion direntry, deletion inode and |
661 | 663 | * changing the parent inode. If budgeting fails, go ahead anyway |
... | ... | @@ -975,6 +977,9 @@ |
975 | 977 | struct ubifs_budget_req ino_req = { .dirtied_ino = 1, |
976 | 978 | .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) }; |
977 | 979 | struct timespec time; |
980 | + | |
981 | + if (new_inode && S_ISDIR(new_inode->i_mode)) | |
982 | + dentry_unhash(new_dentry); | |
978 | 983 | |
979 | 984 | /* |
980 | 985 | * Budget request settings: deletion direntry, new direntry, removing |
fs/udf/namei.c
... | ... | @@ -783,6 +783,8 @@ |
783 | 783 | struct fileIdentDesc *fi, cfi; |
784 | 784 | struct kernel_lb_addr tloc; |
785 | 785 | |
786 | + dentry_unhash(dentry); | |
787 | + | |
786 | 788 | retval = -ENOENT; |
787 | 789 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); |
788 | 790 | if (!fi) |
... | ... | @@ -1080,6 +1082,9 @@ |
1080 | 1082 | int retval = -ENOENT; |
1081 | 1083 | struct kernel_lb_addr tloc; |
1082 | 1084 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); |
1085 | + | |
1086 | + if (new_inode && S_ISDIR(new_inode->i_mode)) | |
1087 | + dentry_unhash(new_dentry); | |
1083 | 1088 | |
1084 | 1089 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); |
1085 | 1090 | if (ofi) { |
fs/ufs/namei.c
... | ... | @@ -258,6 +258,8 @@ |
258 | 258 | struct inode * inode = dentry->d_inode; |
259 | 259 | int err= -ENOTEMPTY; |
260 | 260 | |
261 | + dentry_unhash(dentry); | |
262 | + | |
261 | 263 | lock_ufs(dir->i_sb); |
262 | 264 | if (ufs_empty_dir (inode)) { |
263 | 265 | err = ufs_unlink(dir, dentry); |
... | ... | @@ -281,6 +283,9 @@ |
281 | 283 | struct page *old_page; |
282 | 284 | struct ufs_dir_entry *old_de; |
283 | 285 | int err = -ENOENT; |
286 | + | |
287 | + if (new_inode && S_ISDIR(new_inode->i_mode)) | |
288 | + dentry_unhash(new_dentry); | |
284 | 289 | |
285 | 290 | old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page); |
286 | 291 | if (!old_de) |
include/linux/buffer_head.h
... | ... | @@ -217,8 +217,24 @@ |
217 | 217 | get_block_t *, loff_t *); |
218 | 218 | int generic_cont_expand_simple(struct inode *inode, loff_t size); |
219 | 219 | int block_commit_write(struct page *page, unsigned from, unsigned to); |
220 | +int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, | |
221 | + get_block_t get_block); | |
220 | 222 | int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, |
221 | 223 | get_block_t get_block); |
224 | +/* Convert errno to return value from ->page_mkwrite() call */ | |
225 | +static inline int block_page_mkwrite_return(int err) | |
226 | +{ | |
227 | + if (err == 0) | |
228 | + return VM_FAULT_LOCKED; | |
229 | + if (err == -EFAULT) | |
230 | + return VM_FAULT_NOPAGE; | |
231 | + if (err == -ENOMEM) | |
232 | + return VM_FAULT_OOM; | |
233 | + if (err == -EAGAIN) | |
234 | + return VM_FAULT_RETRY; | |
235 | + /* -ENOSPC, -EDQUOT, -EIO ... */ | |
236 | + return VM_FAULT_SIGBUS; | |
237 | +} | |
222 | 238 | sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *); |
223 | 239 | int block_truncate_page(struct address_space *, loff_t, get_block_t *); |
224 | 240 | int nobh_write_begin(struct address_space *, loff_t, unsigned, unsigned, |