diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/9p/vfs_inode.c | 4 | ||||
| -rw-r--r-- | fs/Kconfig | 2 | ||||
| -rw-r--r-- | fs/affs/namei.c | 5 | ||||
| -rw-r--r-- | fs/afs/dir.c | 5 | ||||
| -rw-r--r-- | fs/autofs4/root.c | 2 | ||||
| -rw-r--r-- | fs/bfs/dir.c | 3 | ||||
| -rw-r--r-- | fs/buffer.c | 59 | ||||
| -rw-r--r-- | fs/coda/dir.c | 5 | ||||
| -rw-r--r-- | fs/configfs/dir.c | 2 | ||||
| -rw-r--r-- | fs/ecryptfs/inode.c | 5 | ||||
| -rw-r--r-- | fs/fat/namei_msdos.c | 5 | ||||
| -rw-r--r-- | fs/fat/namei_vfat.c | 5 | ||||
| -rw-r--r-- | fs/fuse/dir.c | 6 | ||||
| -rw-r--r-- | fs/hfs/dir.c | 6 | ||||
| -rw-r--r-- | fs/hfsplus/dir.c | 8 | ||||
| -rw-r--r-- | fs/hostfs/hostfs_kern.c | 5 | ||||
| -rw-r--r-- | fs/hpfs/namei.c | 9 | ||||
| -rw-r--r-- | fs/jffs2/dir.c | 5 | ||||
| -rw-r--r-- | fs/jfs/namei.c | 5 | ||||
| -rw-r--r-- | fs/logfs/dir.c | 5 | ||||
| -rw-r--r-- | fs/minix/namei.c | 5 | ||||
| -rw-r--r-- | fs/namei.c | 380 | ||||
| -rw-r--r-- | fs/namespace.c | 2 | ||||
| -rw-r--r-- | fs/ncpfs/dir.c | 5 | ||||
| -rw-r--r-- | fs/nilfs2/namei.c | 5 | ||||
| -rw-r--r-- | fs/omfs/dir.c | 11 | ||||
| -rw-r--r-- | fs/reiserfs/namei.c | 5 | ||||
| -rw-r--r-- | fs/reiserfs/xattr.c | 1 | ||||
| -rw-r--r-- | fs/sysv/namei.c | 5 | ||||
| -rw-r--r-- | fs/ubifs/dir.c | 5 | ||||
| -rw-r--r-- | fs/udf/namei.c | 5 | ||||
| -rw-r--r-- | fs/ufs/namei.c | 5 |
32 files changed, 316 insertions, 269 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 7f6c67703195..8d7f3e69ae29 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
| @@ -814,6 +814,7 @@ int v9fs_vfs_unlink(struct inode *i, struct dentry *d) | |||
| 814 | 814 | ||
| 815 | int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) | 815 | int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) |
| 816 | { | 816 | { |
| 817 | dentry_unhash(d); | ||
| 817 | return v9fs_remove(i, d, 1); | 818 | return v9fs_remove(i, d, 1); |
| 818 | } | 819 | } |
| 819 | 820 | ||
| @@ -839,6 +840,9 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 839 | struct p9_fid *newdirfid; | 840 | struct p9_fid *newdirfid; |
| 840 | struct p9_wstat wstat; | 841 | struct p9_wstat wstat; |
| 841 | 842 | ||
| 843 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
| 844 | dentry_unhash(new_dentry); | ||
| 845 | |||
| 842 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); | 846 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); |
| 843 | retval = 0; | 847 | retval = 0; |
| 844 | old_inode = old_dentry->d_inode; | 848 | old_inode = old_dentry->d_inode; |
diff --git a/fs/Kconfig b/fs/Kconfig index f6edba2e069f..19891aab9c6e 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
| @@ -47,7 +47,7 @@ config FS_POSIX_ACL | |||
| 47 | def_bool n | 47 | def_bool n |
| 48 | 48 | ||
| 49 | config EXPORTFS | 49 | config EXPORTFS |
| 50 | bool | 50 | tristate |
| 51 | 51 | ||
| 52 | config FILE_LOCKING | 52 | config FILE_LOCKING |
| 53 | bool "Enable POSIX file locking API" if EXPERT | 53 | bool "Enable POSIX file locking API" if EXPERT |
diff --git a/fs/affs/namei.c b/fs/affs/namei.c index e3e9efc1fdd8..03330e2e390c 100644 --- a/fs/affs/namei.c +++ b/fs/affs/namei.c | |||
| @@ -320,6 +320,8 @@ affs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 320 | dentry->d_inode->i_ino, | 320 | dentry->d_inode->i_ino, |
| 321 | (int)dentry->d_name.len, dentry->d_name.name); | 321 | (int)dentry->d_name.len, dentry->d_name.name); |
| 322 | 322 | ||
| 323 | dentry_unhash(dentry); | ||
| 324 | |||
| 323 | return affs_remove_header(dentry); | 325 | return affs_remove_header(dentry); |
| 324 | } | 326 | } |
| 325 | 327 | ||
| @@ -417,6 +419,9 @@ affs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 417 | struct buffer_head *bh = NULL; | 419 | struct buffer_head *bh = NULL; |
| 418 | int retval; | 420 | int retval; |
| 419 | 421 | ||
| 422 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
| 423 | dentry_unhash(new_dentry); | ||
| 424 | |||
| 420 | pr_debug("AFFS: rename(old=%u,\"%*s\" to new=%u,\"%*s\")\n", | 425 | pr_debug("AFFS: rename(old=%u,\"%*s\" to new=%u,\"%*s\")\n", |
| 421 | (u32)old_dir->i_ino, (int)old_dentry->d_name.len, old_dentry->d_name.name, | 426 | (u32)old_dir->i_ino, (int)old_dentry->d_name.len, old_dentry->d_name.name, |
| 422 | (u32)new_dir->i_ino, (int)new_dentry->d_name.len, new_dentry->d_name.name); | 427 | (u32)new_dir->i_ino, (int)new_dentry->d_name.len, new_dentry->d_name.name); |
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 20c106f24927..2c4e05160042 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
| @@ -845,6 +845,8 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 845 | _enter("{%x:%u},{%s}", | 845 | _enter("{%x:%u},{%s}", |
| 846 | dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name); | 846 | dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name); |
| 847 | 847 | ||
| 848 | dentry_unhash(dentry); | ||
| 849 | |||
| 848 | ret = -ENAMETOOLONG; | 850 | ret = -ENAMETOOLONG; |
| 849 | if (dentry->d_name.len >= AFSNAMEMAX) | 851 | if (dentry->d_name.len >= AFSNAMEMAX) |
| 850 | goto error; | 852 | goto error; |
| @@ -1146,6 +1148,9 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 1146 | struct key *key; | 1148 | struct key *key; |
| 1147 | int ret; | 1149 | int ret; |
| 1148 | 1150 | ||
| 1151 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
| 1152 | dentry_unhash(new_dentry); | ||
| 1153 | |||
| 1149 | vnode = AFS_FS_I(old_dentry->d_inode); | 1154 | vnode = AFS_FS_I(old_dentry->d_inode); |
| 1150 | orig_dvnode = AFS_FS_I(old_dir); | 1155 | orig_dvnode = AFS_FS_I(old_dir); |
| 1151 | new_dvnode = AFS_FS_I(new_dir); | 1156 | new_dvnode = AFS_FS_I(new_dir); |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index f55ae23b137e..87d95a8cddbc 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
| @@ -583,6 +583,8 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry) | |||
| 583 | if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN)) | 583 | if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN)) |
| 584 | return -EACCES; | 584 | return -EACCES; |
| 585 | 585 | ||
| 586 | dentry_unhash(dentry); | ||
| 587 | |||
| 586 | if (atomic_dec_and_test(&ino->count)) { | 588 | if (atomic_dec_and_test(&ino->count)) { |
| 587 | p_ino = autofs4_dentry_ino(dentry->d_parent); | 589 | p_ino = autofs4_dentry_ino(dentry->d_parent); |
| 588 | if (p_ino && dentry->d_parent != dentry) | 590 | if (p_ino && dentry->d_parent != dentry) |
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index b14cebfd9047..c7d1d06b0483 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c | |||
| @@ -224,6 +224,9 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 224 | struct bfs_sb_info *info; | 224 | struct bfs_sb_info *info; |
| 225 | int error = -ENOENT; | 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 | old_bh = new_bh = NULL; | 230 | old_bh = new_bh = NULL; |
| 228 | old_inode = old_dentry->d_inode; | 231 | old_inode = old_dentry->d_inode; |
| 229 | if (S_ISDIR(old_inode->i_mode)) | 232 | if (S_ISDIR(old_inode->i_mode)) |
diff --git a/fs/buffer.c b/fs/buffer.c index a08bb8e61c6f..b0675bfe8207 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
| @@ -2331,24 +2331,26 @@ EXPORT_SYMBOL(block_commit_write); | |||
| 2331 | * page lock we can determine safely if the page is beyond EOF. If it is not | 2331 | * page lock we can determine safely if the page is beyond EOF. If it is not |
| 2332 | * beyond EOF, then the page is guaranteed safe against truncation until we | 2332 | * beyond EOF, then the page is guaranteed safe against truncation until we |
| 2333 | * unlock the page. | 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 | 2338 | int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, |
| 2336 | block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, | 2339 | get_block_t get_block) |
| 2337 | get_block_t get_block) | ||
| 2338 | { | 2340 | { |
| 2339 | struct page *page = vmf->page; | 2341 | struct page *page = vmf->page; |
| 2340 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; | 2342 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; |
| 2341 | unsigned long end; | 2343 | unsigned long end; |
| 2342 | loff_t size; | 2344 | loff_t size; |
| 2343 | int ret = VM_FAULT_NOPAGE; /* make the VM retry the fault */ | 2345 | int ret; |
| 2344 | 2346 | ||
| 2345 | lock_page(page); | 2347 | lock_page(page); |
| 2346 | size = i_size_read(inode); | 2348 | size = i_size_read(inode); |
| 2347 | if ((page->mapping != inode->i_mapping) || | 2349 | if ((page->mapping != inode->i_mapping) || |
| 2348 | (page_offset(page) > size)) { | 2350 | (page_offset(page) > size)) { |
| 2349 | /* page got truncated out from underneath us */ | 2351 | /* We overload EFAULT to mean page got truncated */ |
| 2350 | unlock_page(page); | 2352 | ret = -EFAULT; |
| 2351 | goto out; | 2353 | goto out_unlock; |
| 2352 | } | 2354 | } |
| 2353 | 2355 | ||
| 2354 | /* page is wholly or partially inside EOF */ | 2356 | /* page is wholly or partially inside EOF */ |
| @@ -2361,18 +2363,41 @@ block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, | |||
| 2361 | if (!ret) | 2363 | if (!ret) |
| 2362 | ret = block_commit_write(page, 0, end); | 2364 | ret = block_commit_write(page, 0, end); |
| 2363 | 2365 | ||
| 2364 | if (unlikely(ret)) { | 2366 | if (unlikely(ret < 0)) |
| 2365 | unlock_page(page); | 2367 | goto out_unlock; |
| 2366 | if (ret == -ENOMEM) | 2368 | /* |
| 2367 | ret = VM_FAULT_OOM; | 2369 | * Freezing in progress? We check after the page is marked dirty and |
| 2368 | else /* -ENOSPC, -EIO, etc */ | 2370 | * with page lock held so if the test here fails, we are sure freezing |
| 2369 | ret = VM_FAULT_SIGBUS; | 2371 | * code will wait during syncing until the page fault is done - at that |
| 2370 | } else | 2372 | * point page will be dirty and unlocked so freezing code will write it |
| 2371 | ret = VM_FAULT_LOCKED; | 2373 | * and writeprotect it again. |
| 2372 | 2374 | */ | |
| 2373 | out: | 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 | return ret; | 2383 | return ret; |
| 2375 | } | 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); | ||
| 2400 | } | ||
| 2376 | EXPORT_SYMBOL(block_page_mkwrite); | 2401 | EXPORT_SYMBOL(block_page_mkwrite); |
| 2377 | 2402 | ||
| 2378 | /* | 2403 | /* |
diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 2b8dae4d121e..a46126fd5735 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c | |||
| @@ -336,6 +336,8 @@ static int coda_rmdir(struct inode *dir, struct dentry *de) | |||
| 336 | int len = de->d_name.len; | 336 | int len = de->d_name.len; |
| 337 | int error; | 337 | int error; |
| 338 | 338 | ||
| 339 | dentry_unhash(de); | ||
| 340 | |||
| 339 | error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len); | 341 | error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len); |
| 340 | if (!error) { | 342 | if (!error) { |
| 341 | /* VFS may delete the child */ | 343 | /* VFS may delete the child */ |
| @@ -359,6 +361,9 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 359 | int new_length = new_dentry->d_name.len; | 361 | int new_length = new_dentry->d_name.len; |
| 360 | int error; | 362 | int error; |
| 361 | 363 | ||
| 364 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
| 365 | dentry_unhash(new_dentry); | ||
| 366 | |||
| 362 | error = venus_rename(old_dir->i_sb, coda_i2f(old_dir), | 367 | error = venus_rename(old_dir->i_sb, coda_i2f(old_dir), |
| 363 | coda_i2f(new_dir), old_length, new_length, | 368 | coda_i2f(new_dir), old_length, new_length, |
| 364 | (const char *) old_name, (const char *)new_name); | 369 | (const char *) old_name, (const char *)new_name); |
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 9a37a9b6de3a..9d17d350abc5 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
| @@ -1359,6 +1359,8 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 1359 | struct module *subsys_owner = NULL, *dead_item_owner = NULL; | 1359 | struct module *subsys_owner = NULL, *dead_item_owner = NULL; |
| 1360 | int ret; | 1360 | int ret; |
| 1361 | 1361 | ||
| 1362 | dentry_unhash(dentry); | ||
| 1363 | |||
| 1362 | if (dentry->d_parent == configfs_sb->s_root) | 1364 | if (dentry->d_parent == configfs_sb->s_root) |
| 1363 | return -EPERM; | 1365 | return -EPERM; |
| 1364 | 1366 | ||
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 4d4cc6a90cd5..227b409b8406 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
| @@ -521,6 +521,8 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 521 | struct dentry *lower_dir_dentry; | 521 | struct dentry *lower_dir_dentry; |
| 522 | int rc; | 522 | int rc; |
| 523 | 523 | ||
| 524 | dentry_unhash(dentry); | ||
| 525 | |||
| 524 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 526 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
| 525 | dget(dentry); | 527 | dget(dentry); |
| 526 | lower_dir_dentry = lock_parent(lower_dentry); | 528 | lower_dir_dentry = lock_parent(lower_dentry); |
| @@ -571,6 +573,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 571 | struct dentry *lower_new_dir_dentry; | 573 | struct dentry *lower_new_dir_dentry; |
| 572 | struct dentry *trap = NULL; | 574 | struct dentry *trap = NULL; |
| 573 | 575 | ||
| 576 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
| 577 | dentry_unhash(new_dentry); | ||
| 578 | |||
| 574 | lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); | 579 | lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); |
| 575 | lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); | 580 | lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); |
| 576 | dget(lower_old_dentry); | 581 | dget(lower_old_dentry); |
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index 3b222dafd15b..be15437c272e 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c | |||
| @@ -326,6 +326,8 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 326 | struct fat_slot_info sinfo; | 326 | struct fat_slot_info sinfo; |
| 327 | int err; | 327 | int err; |
| 328 | 328 | ||
| 329 | dentry_unhash(dentry); | ||
| 330 | |||
| 329 | lock_super(sb); | 331 | lock_super(sb); |
| 330 | /* | 332 | /* |
| 331 | * Check whether the directory is not in use, then check | 333 | * Check whether the directory is not in use, then check |
| @@ -457,6 +459,9 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, | |||
| 457 | old_inode = old_dentry->d_inode; | 459 | old_inode = old_dentry->d_inode; |
| 458 | new_inode = new_dentry->d_inode; | 460 | new_inode = new_dentry->d_inode; |
| 459 | 461 | ||
| 462 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
| 463 | dentry_unhash(new_dentry); | ||
| 464 | |||
| 460 | err = fat_scan(old_dir, old_name, &old_sinfo); | 465 | err = fat_scan(old_dir, old_name, &old_sinfo); |
| 461 | if (err) { | 466 | if (err) { |
| 462 | err = -EIO; | 467 | err = -EIO; |
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 20b4ea53fdc4..c61a6789f36c 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c | |||
| @@ -824,6 +824,8 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 824 | struct fat_slot_info sinfo; | 824 | struct fat_slot_info sinfo; |
| 825 | int err; | 825 | int err; |
| 826 | 826 | ||
| 827 | dentry_unhash(dentry); | ||
| 828 | |||
| 827 | lock_super(sb); | 829 | lock_super(sb); |
| 828 | 830 | ||
| 829 | err = fat_dir_empty(inode); | 831 | err = fat_dir_empty(inode); |
| @@ -931,6 +933,9 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 931 | int err, is_dir, update_dotdot, corrupt = 0; | 933 | int err, is_dir, update_dotdot, corrupt = 0; |
| 932 | struct super_block *sb = old_dir->i_sb; | 934 | struct super_block *sb = old_dir->i_sb; |
| 933 | 935 | ||
| 936 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
| 937 | dentry_unhash(new_dentry); | ||
| 938 | |||
| 934 | old_sinfo.bh = sinfo.bh = dotdot_bh = NULL; | 939 | old_sinfo.bh = sinfo.bh = dotdot_bh = NULL; |
| 935 | old_inode = old_dentry->d_inode; | 940 | old_inode = old_dentry->d_inode; |
| 936 | new_inode = new_dentry->d_inode; | 941 | new_inode = new_dentry->d_inode; |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index b32eb29a4e6f..0d0e3faddcfa 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
| @@ -667,6 +667,8 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry) | |||
| 667 | if (IS_ERR(req)) | 667 | if (IS_ERR(req)) |
| 668 | return PTR_ERR(req); | 668 | return PTR_ERR(req); |
| 669 | 669 | ||
| 670 | dentry_unhash(entry); | ||
| 671 | |||
| 670 | req->in.h.opcode = FUSE_RMDIR; | 672 | req->in.h.opcode = FUSE_RMDIR; |
| 671 | req->in.h.nodeid = get_node_id(dir); | 673 | req->in.h.nodeid = get_node_id(dir); |
| 672 | req->in.numargs = 1; | 674 | req->in.numargs = 1; |
| @@ -691,6 +693,10 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent, | |||
| 691 | struct fuse_rename_in inarg; | 693 | struct fuse_rename_in inarg; |
| 692 | struct fuse_conn *fc = get_fuse_conn(olddir); | 694 | struct fuse_conn *fc = get_fuse_conn(olddir); |
| 693 | struct fuse_req *req = fuse_get_req(fc); | 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 | if (IS_ERR(req)) | 700 | if (IS_ERR(req)) |
| 695 | return PTR_ERR(req); | 701 | return PTR_ERR(req); |
| 696 | 702 | ||
diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index b4d70b13be92..1cb70cdba2c1 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c | |||
| @@ -253,6 +253,9 @@ static int hfs_remove(struct inode *dir, struct dentry *dentry) | |||
| 253 | struct inode *inode = dentry->d_inode; | 253 | struct inode *inode = dentry->d_inode; |
| 254 | int res; | 254 | int res; |
| 255 | 255 | ||
| 256 | if (S_ISDIR(inode->i_mode)) | ||
| 257 | dentry_unhash(dentry); | ||
| 258 | |||
| 256 | if (S_ISDIR(inode->i_mode) && inode->i_size != 2) | 259 | if (S_ISDIR(inode->i_mode) && inode->i_size != 2) |
| 257 | return -ENOTEMPTY; | 260 | return -ENOTEMPTY; |
| 258 | res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name); | 261 | res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name); |
| @@ -283,6 +286,9 @@ static int hfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 283 | 286 | ||
| 284 | /* Unlink destination if it already exists */ | 287 | /* Unlink destination if it already exists */ |
| 285 | if (new_dentry->d_inode) { | 288 | if (new_dentry->d_inode) { |
| 289 | if (S_ISDIR(new_dentry->d_inode->i_mode)) | ||
| 290 | dentry_unhash(new_dentry); | ||
| 291 | |||
| 286 | res = hfs_remove(new_dir, new_dentry); | 292 | res = hfs_remove(new_dir, new_dentry); |
| 287 | if (res) | 293 | if (res) |
| 288 | return res; | 294 | return res; |
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 4df5059c25da..b28835091dd0 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c | |||
| @@ -370,6 +370,8 @@ static int hfsplus_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 370 | struct inode *inode = dentry->d_inode; | 370 | struct inode *inode = dentry->d_inode; |
| 371 | int res; | 371 | int res; |
| 372 | 372 | ||
| 373 | dentry_unhash(dentry); | ||
| 374 | |||
| 373 | if (inode->i_size != 2) | 375 | if (inode->i_size != 2) |
| 374 | return -ENOTEMPTY; | 376 | return -ENOTEMPTY; |
| 375 | 377 | ||
| @@ -467,10 +469,12 @@ static int hfsplus_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 467 | 469 | ||
| 468 | /* Unlink destination if it already exists */ | 470 | /* Unlink destination if it already exists */ |
| 469 | if (new_dentry->d_inode) { | 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 | res = hfsplus_rmdir(new_dir, new_dentry); | 474 | res = hfsplus_rmdir(new_dir, new_dentry); |
| 472 | else | 475 | } else { |
| 473 | res = hfsplus_unlink(new_dir, new_dentry); | 476 | res = hfsplus_unlink(new_dir, new_dentry); |
| 477 | } | ||
| 474 | if (res) | 478 | if (res) |
| 475 | return res; | 479 | return res; |
| 476 | } | 480 | } |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 2638c834ed28..e6816b9e6903 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
| @@ -683,6 +683,8 @@ int hostfs_rmdir(struct inode *ino, struct dentry *dentry) | |||
| 683 | char *file; | 683 | char *file; |
| 684 | int err; | 684 | int err; |
| 685 | 685 | ||
| 686 | dentry_unhash(dentry); | ||
| 687 | |||
| 686 | if ((file = dentry_name(dentry)) == NULL) | 688 | if ((file = dentry_name(dentry)) == NULL) |
| 687 | return -ENOMEM; | 689 | return -ENOMEM; |
| 688 | err = do_rmdir(file); | 690 | err = do_rmdir(file); |
| @@ -736,6 +738,9 @@ int hostfs_rename(struct inode *from_ino, struct dentry *from, | |||
| 736 | char *from_name, *to_name; | 738 | char *from_name, *to_name; |
| 737 | int err; | 739 | int err; |
| 738 | 740 | ||
| 741 | if (to->d_inode && S_ISDIR(to->d_inode->i_mode)) | ||
| 742 | dentry_unhash(to); | ||
| 743 | |||
| 739 | if ((from_name = dentry_name(from)) == NULL) | 744 | if ((from_name = dentry_name(from)) == NULL) |
| 740 | return -ENOMEM; | 745 | return -ENOMEM; |
| 741 | if ((to_name = dentry_name(to)) == NULL) { | 746 | if ((to_name = dentry_name(to)) == NULL) { |
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index 1f05839c27a7..ff0ce21c0867 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c | |||
| @@ -395,7 +395,6 @@ again: | |||
| 395 | 395 | ||
| 396 | dentry_unhash(dentry); | 396 | dentry_unhash(dentry); |
| 397 | if (!d_unhashed(dentry)) { | 397 | if (!d_unhashed(dentry)) { |
| 398 | dput(dentry); | ||
| 399 | hpfs_unlock(dir->i_sb); | 398 | hpfs_unlock(dir->i_sb); |
| 400 | return -ENOSPC; | 399 | return -ENOSPC; |
| 401 | } | 400 | } |
| @@ -403,7 +402,6 @@ again: | |||
| 403 | !S_ISREG(inode->i_mode) || | 402 | !S_ISREG(inode->i_mode) || |
| 404 | get_write_access(inode)) { | 403 | get_write_access(inode)) { |
| 405 | d_rehash(dentry); | 404 | d_rehash(dentry); |
| 406 | dput(dentry); | ||
| 407 | } else { | 405 | } else { |
| 408 | struct iattr newattrs; | 406 | struct iattr newattrs; |
| 409 | /*printk("HPFS: truncating file before delete.\n");*/ | 407 | /*printk("HPFS: truncating file before delete.\n");*/ |
| @@ -411,7 +409,6 @@ again: | |||
| 411 | newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; | 409 | newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; |
| 412 | err = notify_change(dentry, &newattrs); | 410 | err = notify_change(dentry, &newattrs); |
| 413 | put_write_access(inode); | 411 | put_write_access(inode); |
| 414 | dput(dentry); | ||
| 415 | if (!err) | 412 | if (!err) |
| 416 | goto again; | 413 | goto again; |
| 417 | } | 414 | } |
| @@ -442,6 +439,8 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 442 | int err; | 439 | int err; |
| 443 | int r; | 440 | int r; |
| 444 | 441 | ||
| 442 | dentry_unhash(dentry); | ||
| 443 | |||
| 445 | hpfs_adjust_length(name, &len); | 444 | hpfs_adjust_length(name, &len); |
| 446 | hpfs_lock(dir->i_sb); | 445 | hpfs_lock(dir->i_sb); |
| 447 | err = -ENOENT; | 446 | err = -ENOENT; |
| @@ -535,6 +534,10 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 535 | struct buffer_head *bh; | 534 | struct buffer_head *bh; |
| 536 | struct fnode *fnode; | 535 | struct fnode *fnode; |
| 537 | int err; | 536 | int err; |
| 537 | |||
| 538 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
| 539 | dentry_unhash(new_dentry); | ||
| 540 | |||
| 538 | if ((err = hpfs_chk_name(new_name, &new_len))) return err; | 541 | if ((err = hpfs_chk_name(new_name, &new_len))) return err; |
| 539 | err = 0; | 542 | err = 0; |
| 540 | hpfs_adjust_length(old_name, &old_len); | 543 | hpfs_adjust_length(old_name, &old_len); |
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 82faddd1f321..05f73328b28b 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c | |||
| @@ -609,6 +609,8 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) | |||
| 609 | int ret; | 609 | int ret; |
| 610 | uint32_t now = get_seconds(); | 610 | uint32_t now = get_seconds(); |
| 611 | 611 | ||
| 612 | dentry_unhash(dentry); | ||
| 613 | |||
| 612 | for (fd = f->dents ; fd; fd = fd->next) { | 614 | for (fd = f->dents ; fd; fd = fd->next) { |
| 613 | if (fd->ino) | 615 | if (fd->ino) |
| 614 | return -ENOTEMPTY; | 616 | return -ENOTEMPTY; |
| @@ -784,6 +786,9 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, | |||
| 784 | uint8_t type; | 786 | uint8_t type; |
| 785 | uint32_t now; | 787 | uint32_t now; |
| 786 | 788 | ||
| 789 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
| 790 | dentry_unhash(new_dentry); | ||
| 791 | |||
| 787 | /* The VFS will check for us and prevent trying to rename a | 792 | /* The VFS will check for us and prevent trying to rename a |
| 788 | * file over a directory and vice versa, but if it's a directory, | 793 | * file over a directory and vice versa, but if it's a directory, |
| 789 | * the VFS can't check whether the victim is empty. The filesystem | 794 | * the VFS can't check whether the victim is empty. The filesystem |
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index eaaf2b511e89..865df16a6cf3 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
| @@ -360,6 +360,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry) | |||
| 360 | 360 | ||
| 361 | jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name); | 361 | jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name); |
| 362 | 362 | ||
| 363 | dentry_unhash(dentry); | ||
| 364 | |||
| 363 | /* Init inode for quota operations. */ | 365 | /* Init inode for quota operations. */ |
| 364 | dquot_initialize(dip); | 366 | dquot_initialize(dip); |
| 365 | dquot_initialize(ip); | 367 | dquot_initialize(ip); |
| @@ -1095,6 +1097,9 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 1095 | jfs_info("jfs_rename: %s %s", old_dentry->d_name.name, | 1097 | jfs_info("jfs_rename: %s %s", old_dentry->d_name.name, |
| 1096 | new_dentry->d_name.name); | 1098 | new_dentry->d_name.name); |
| 1097 | 1099 | ||
| 1100 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
| 1101 | dentry_unhash(new_dentry); | ||
| 1102 | |||
| 1098 | dquot_initialize(old_dir); | 1103 | dquot_initialize(old_dir); |
| 1099 | dquot_initialize(new_dir); | 1104 | dquot_initialize(new_dir); |
| 1100 | 1105 | ||
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c index 9ed89d1663f8..f34c9cde9e94 100644 --- a/fs/logfs/dir.c +++ b/fs/logfs/dir.c | |||
| @@ -273,6 +273,8 @@ static int logfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 273 | { | 273 | { |
| 274 | struct inode *inode = dentry->d_inode; | 274 | struct inode *inode = dentry->d_inode; |
| 275 | 275 | ||
| 276 | dentry_unhash(dentry); | ||
| 277 | |||
| 276 | if (!logfs_empty_dir(inode)) | 278 | if (!logfs_empty_dir(inode)) |
| 277 | return -ENOTEMPTY; | 279 | return -ENOTEMPTY; |
| 278 | 280 | ||
| @@ -622,6 +624,9 @@ static int logfs_rename_cross(struct inode *old_dir, struct dentry *old_dentry, | |||
| 622 | loff_t pos; | 624 | loff_t pos; |
| 623 | int err; | 625 | int err; |
| 624 | 626 | ||
| 627 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
| 628 | dentry_unhash(new_dentry); | ||
| 629 | |||
| 625 | /* 1. locate source dd */ | 630 | /* 1. locate source dd */ |
| 626 | err = logfs_get_dd(old_dir, old_dentry, &dd, &pos); | 631 | err = logfs_get_dd(old_dir, old_dentry, &dd, &pos); |
| 627 | if (err) | 632 | if (err) |
diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 6e6777f1b4b2..f60aed8db9c4 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c | |||
| @@ -168,6 +168,8 @@ static int minix_rmdir(struct inode * dir, struct dentry *dentry) | |||
| 168 | struct inode * inode = dentry->d_inode; | 168 | struct inode * inode = dentry->d_inode; |
| 169 | int err = -ENOTEMPTY; | 169 | int err = -ENOTEMPTY; |
| 170 | 170 | ||
| 171 | dentry_unhash(dentry); | ||
| 172 | |||
| 171 | if (minix_empty_dir(inode)) { | 173 | if (minix_empty_dir(inode)) { |
| 172 | err = minix_unlink(dir, dentry); | 174 | err = minix_unlink(dir, dentry); |
| 173 | if (!err) { | 175 | if (!err) { |
| @@ -190,6 +192,9 @@ static int minix_rename(struct inode * old_dir, struct dentry *old_dentry, | |||
| 190 | struct minix_dir_entry * old_de; | 192 | struct minix_dir_entry * old_de; |
| 191 | int err = -ENOENT; | 193 | int err = -ENOENT; |
| 192 | 194 | ||
| 195 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
| 196 | dentry_unhash(new_dentry); | ||
| 197 | |||
| 193 | old_de = minix_find_entry(old_dentry, &old_page); | 198 | old_de = minix_find_entry(old_dentry, &old_page); |
| 194 | if (!old_de) | 199 | if (!old_de) |
| 195 | goto out; | 200 | goto out; |
diff --git a/fs/namei.c b/fs/namei.c index 6ff858c049c0..2358b326b221 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -391,79 +391,28 @@ void path_put(struct path *path) | |||
| 391 | } | 391 | } |
| 392 | EXPORT_SYMBOL(path_put); | 392 | EXPORT_SYMBOL(path_put); |
| 393 | 393 | ||
| 394 | /** | 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 | * | ||
| 399 | * Path walking has 2 modes, rcu-walk and ref-walk (see | 395 | * Path walking has 2 modes, rcu-walk and ref-walk (see |
| 400 | * Documentation/filesystems/path-lookup.txt). __drop_rcu* functions attempt | 396 | * Documentation/filesystems/path-lookup.txt). In situations when we can't |
| 401 | * to drop out of rcu-walk mode and take normal reference counts on dentries | 397 | * continue in RCU mode, we attempt to drop out of rcu-walk mode and grab |
| 402 | * and vfsmounts to transition to rcu-walk mode. __drop_rcu* functions take | 398 | * normal reference counts on dentries and vfsmounts to transition to rcu-walk |
| 403 | * refcounts at the last known good point before rcu-walk got stuck, so | 399 | * mode. Refcounts are grabbed at the last known good point before rcu-walk |
| 404 | * ref-walk may continue from there. If this is not successful (eg. a seqcount | 400 | * got stuck, so ref-walk may continue from there. If this is not successful |
| 405 | * has changed), then failure is returned and path walk restarts from the | 401 | * (eg. a seqcount has changed), then failure is returned and it's up to caller |
| 406 | * beginning in ref-walk mode. | 402 | * to restart the path walk from the 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. | ||
| 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 | |||
| 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 | 404 | ||
| 456 | /** | 405 | /** |
| 457 | * nameidata_dentry_drop_rcu - drop nameidata and dentry out of rcu-walk | 406 | * unlazy_walk - try to switch to ref-walk mode. |
| 458 | * @nd: nameidata pathwalk data to drop | 407 | * @nd: nameidata pathwalk data |
| 459 | * @dentry: dentry to drop | 408 | * @dentry: child of nd->path.dentry or NULL |
| 460 | * Returns: 0 on success, -ECHILD on failure | 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, | 411 | * unlazy_walk attempts to legitimize the current nd->path, nd->root and dentry |
| 463 | * and dentry into ref-walk. @dentry must be a path found by a do_lookup call on | 412 | * for ref-walk mode. @dentry must be a path found by a do_lookup call on |
| 464 | * @nd. Must be called from rcu-walk context. | 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 | struct fs_struct *fs = current->fs; | 417 | struct fs_struct *fs = current->fs; |
| 469 | struct dentry *parent = nd->path.dentry; | 418 | struct dentry *parent = nd->path.dentry; |
| @@ -478,18 +427,25 @@ static int nameidata_dentry_drop_rcu(struct nameidata *nd, struct dentry *dentry | |||
| 478 | goto err_root; | 427 | goto err_root; |
| 479 | } | 428 | } |
| 480 | spin_lock(&parent->d_lock); | 429 | spin_lock(&parent->d_lock); |
| 481 | spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); | 430 | if (!dentry) { |
| 482 | if (!__d_rcu_to_refcount(dentry, nd->seq)) | 431 | if (!__d_rcu_to_refcount(parent, nd->seq)) |
| 483 | goto err; | 432 | goto err_parent; |
| 484 | /* | 433 | BUG_ON(nd->inode != parent->d_inode); |
| 485 | * If the sequence check on the child dentry passed, then the child has | 434 | } else { |
| 486 | * not been removed from its parent. This means the parent dentry must | 435 | spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); |
| 487 | * be valid and able to take a reference at this point. | 436 | if (!__d_rcu_to_refcount(dentry, nd->seq)) |
| 488 | */ | 437 | goto err_child; |
| 489 | BUG_ON(!IS_ROOT(dentry) && dentry->d_parent != parent); | 438 | /* |
| 490 | BUG_ON(!parent->d_count); | 439 | * If the sequence check on the child dentry passed, then |
| 491 | parent->d_count++; | 440 | * the child has not been removed from its parent. This |
| 492 | spin_unlock(&dentry->d_lock); | 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 | spin_unlock(&parent->d_lock); | 449 | spin_unlock(&parent->d_lock); |
| 494 | if (want_root) { | 450 | if (want_root) { |
| 495 | path_get(&nd->root); | 451 | path_get(&nd->root); |
| @@ -501,8 +457,10 @@ static int nameidata_dentry_drop_rcu(struct nameidata *nd, struct dentry *dentry | |||
| 501 | br_read_unlock(vfsmount_lock); | 457 | br_read_unlock(vfsmount_lock); |
| 502 | nd->flags &= ~LOOKUP_RCU; | 458 | nd->flags &= ~LOOKUP_RCU; |
| 503 | return 0; | 459 | return 0; |
| 504 | err: | 460 | |
| 461 | err_child: | ||
| 505 | spin_unlock(&dentry->d_lock); | 462 | spin_unlock(&dentry->d_lock); |
| 463 | err_parent: | ||
| 506 | spin_unlock(&parent->d_lock); | 464 | spin_unlock(&parent->d_lock); |
| 507 | err_root: | 465 | err_root: |
| 508 | if (want_root) | 466 | if (want_root) |
| @@ -510,59 +468,6 @@ err_root: | |||
| 510 | return -ECHILD; | 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 | /** | ||
| 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 | /** | 471 | /** |
| 567 | * release_open_intent - free up open intent resources | 472 | * release_open_intent - free up open intent resources |
| 568 | * @nd: pointer to nameidata | 473 | * @nd: pointer to nameidata |
| @@ -606,26 +511,39 @@ do_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
| 606 | return dentry; | 511 | return dentry; |
| 607 | } | 512 | } |
| 608 | 513 | ||
| 609 | /* | 514 | /** |
| 610 | * handle_reval_path - force revalidation of a dentry | 515 | * complete_walk - successful completion of path walk |
| 611 | * | 516 | * @nd: pointer nameidata |
| 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 | * | 517 | * |
| 618 | * Returns 0 if the revalidation was successful. If the revalidation fails, | 518 | * If we had been in RCU mode, drop out of it and legitimize nd->path. |
| 619 | * either return the error returned by d_revalidate or -ESTALE if the | 519 | * Revalidate the final result, unless we'd already done that during |
| 620 | * revalidation it just returned 0. If d_revalidate returns 0, we attempt to | 520 | * the path walk or the filesystem doesn't ask for it. Return 0 on |
| 621 | * invalidate the dentry. It's up to the caller to handle putting references | 521 | * success, -error on failure. In case of failure caller does not |
| 622 | * to the path if necessary. | 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 | struct dentry *dentry = nd->path.dentry; | 526 | struct dentry *dentry = nd->path.dentry; |
| 627 | int status; | 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 | if (likely(!(nd->flags & LOOKUP_JUMPED))) | 547 | if (likely(!(nd->flags & LOOKUP_JUMPED))) |
| 630 | return 0; | 548 | return 0; |
| 631 | 549 | ||
| @@ -643,6 +561,7 @@ static inline int handle_reval_path(struct nameidata *nd) | |||
| 643 | if (!status) | 561 | if (!status) |
| 644 | status = -ESTALE; | 562 | status = -ESTALE; |
| 645 | 563 | ||
| 564 | path_put(&nd->path); | ||
| 646 | return status; | 565 | return status; |
| 647 | } | 566 | } |
| 648 | 567 | ||
| @@ -1241,13 +1160,8 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, | |||
| 1241 | if (likely(__follow_mount_rcu(nd, path, inode, false))) | 1160 | if (likely(__follow_mount_rcu(nd, path, inode, false))) |
| 1242 | return 0; | 1161 | return 0; |
| 1243 | unlazy: | 1162 | unlazy: |
| 1244 | if (dentry) { | 1163 | if (unlazy_walk(nd, dentry)) |
| 1245 | if (nameidata_dentry_drop_rcu(nd, dentry)) | 1164 | return -ECHILD; |
| 1246 | return -ECHILD; | ||
| 1247 | } else { | ||
| 1248 | if (nameidata_drop_rcu(nd)) | ||
| 1249 | return -ECHILD; | ||
| 1250 | } | ||
| 1251 | } else { | 1165 | } else { |
| 1252 | dentry = __d_lookup(parent, name); | 1166 | dentry = __d_lookup(parent, name); |
| 1253 | } | 1167 | } |
| @@ -1303,7 +1217,7 @@ static inline int may_lookup(struct nameidata *nd) | |||
| 1303 | int err = exec_permission(nd->inode, IPERM_FLAG_RCU); | 1217 | int err = exec_permission(nd->inode, IPERM_FLAG_RCU); |
| 1304 | if (err != -ECHILD) | 1218 | if (err != -ECHILD) |
| 1305 | return err; | 1219 | return err; |
| 1306 | if (nameidata_drop_rcu(nd)) | 1220 | if (unlazy_walk(nd, NULL)) |
| 1307 | return -ECHILD; | 1221 | return -ECHILD; |
| 1308 | } | 1222 | } |
| 1309 | return exec_permission(nd->inode, 0); | 1223 | return exec_permission(nd->inode, 0); |
| @@ -1357,8 +1271,12 @@ static inline int walk_component(struct nameidata *nd, struct path *path, | |||
| 1357 | return -ENOENT; | 1271 | return -ENOENT; |
| 1358 | } | 1272 | } |
| 1359 | if (unlikely(inode->i_op->follow_link) && follow) { | 1273 | if (unlikely(inode->i_op->follow_link) && follow) { |
| 1360 | if (nameidata_dentry_drop_rcu_maybe(nd, path->dentry)) | 1274 | if (nd->flags & LOOKUP_RCU) { |
| 1361 | return -ECHILD; | 1275 | if (unlikely(unlazy_walk(nd, path->dentry))) { |
| 1276 | terminate_walk(nd); | ||
| 1277 | return -ECHILD; | ||
| 1278 | } | ||
| 1279 | } | ||
| 1362 | BUG_ON(inode != path->dentry->d_inode); | 1280 | BUG_ON(inode != path->dentry->d_inode); |
| 1363 | return 1; | 1281 | return 1; |
| 1364 | } | 1282 | } |
| @@ -1657,18 +1575,8 @@ static int path_lookupat(int dfd, const char *name, | |||
| 1657 | } | 1575 | } |
| 1658 | } | 1576 | } |
| 1659 | 1577 | ||
| 1660 | if (nd->flags & LOOKUP_RCU) { | 1578 | if (!err) |
| 1661 | /* went all way through without dropping RCU */ | 1579 | err = complete_walk(nd); |
| 1662 | BUG_ON(err); | ||
| 1663 | if (nameidata_drop_rcu_last(nd)) | ||
| 1664 | err = -ECHILD; | ||
| 1665 | } | ||
| 1666 | |||
| 1667 | if (!err) { | ||
| 1668 | err = handle_reval_path(nd); | ||
| 1669 | if (err) | ||
| 1670 | path_put(&nd->path); | ||
| 1671 | } | ||
| 1672 | 1580 | ||
| 1673 | if (!err && nd->flags & LOOKUP_DIRECTORY) { | 1581 | if (!err && nd->flags & LOOKUP_DIRECTORY) { |
| 1674 | if (!nd->inode->i_op->lookup) { | 1582 | if (!nd->inode->i_op->lookup) { |
| @@ -2134,13 +2042,9 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
| 2134 | return ERR_PTR(error); | 2042 | return ERR_PTR(error); |
| 2135 | /* fallthrough */ | 2043 | /* fallthrough */ |
| 2136 | case LAST_ROOT: | 2044 | case LAST_ROOT: |
| 2137 | if (nd->flags & LOOKUP_RCU) { | 2045 | error = complete_walk(nd); |
| 2138 | if (nameidata_drop_rcu_last(nd)) | ||
| 2139 | return ERR_PTR(-ECHILD); | ||
| 2140 | } | ||
| 2141 | error = handle_reval_path(nd); | ||
| 2142 | if (error) | 2046 | if (error) |
| 2143 | goto exit; | 2047 | return ERR_PTR(error); |
| 2144 | audit_inode(pathname, nd->path.dentry); | 2048 | audit_inode(pathname, nd->path.dentry); |
| 2145 | if (open_flag & O_CREAT) { | 2049 | if (open_flag & O_CREAT) { |
| 2146 | error = -EISDIR; | 2050 | error = -EISDIR; |
| @@ -2148,10 +2052,9 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
| 2148 | } | 2052 | } |
| 2149 | goto ok; | 2053 | goto ok; |
| 2150 | case LAST_BIND: | 2054 | case LAST_BIND: |
| 2151 | /* can't be RCU mode here */ | 2055 | error = complete_walk(nd); |
| 2152 | error = handle_reval_path(nd); | ||
| 2153 | if (error) | 2056 | if (error) |
| 2154 | goto exit; | 2057 | return ERR_PTR(error); |
| 2155 | audit_inode(pathname, dir); | 2058 | audit_inode(pathname, dir); |
| 2156 | goto ok; | 2059 | goto ok; |
| 2157 | } | 2060 | } |
| @@ -2170,10 +2073,9 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
| 2170 | if (error) /* symlink */ | 2073 | if (error) /* symlink */ |
| 2171 | return NULL; | 2074 | return NULL; |
| 2172 | /* sayonara */ | 2075 | /* sayonara */ |
| 2173 | if (nd->flags & LOOKUP_RCU) { | 2076 | error = complete_walk(nd); |
| 2174 | if (nameidata_drop_rcu_last(nd)) | 2077 | if (error) |
| 2175 | return ERR_PTR(-ECHILD); | 2078 | return ERR_PTR(-ECHILD); |
| 2176 | } | ||
| 2177 | 2079 | ||
| 2178 | error = -ENOTDIR; | 2080 | error = -ENOTDIR; |
| 2179 | if (nd->flags & LOOKUP_DIRECTORY) { | 2081 | if (nd->flags & LOOKUP_DIRECTORY) { |
| @@ -2185,11 +2087,9 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
| 2185 | } | 2087 | } |
| 2186 | 2088 | ||
| 2187 | /* create side of things */ | 2089 | /* create side of things */ |
| 2188 | 2090 | error = complete_walk(nd); | |
| 2189 | if (nd->flags & LOOKUP_RCU) { | 2091 | if (error) |
| 2190 | if (nameidata_drop_rcu_last(nd)) | 2092 | return ERR_PTR(error); |
| 2191 | return ERR_PTR(-ECHILD); | ||
| 2192 | } | ||
| 2193 | 2093 | ||
| 2194 | audit_inode(pathname, dir); | 2094 | audit_inode(pathname, dir); |
| 2195 | error = -EISDIR; | 2095 | error = -EISDIR; |
| @@ -2629,10 +2529,10 @@ SYSCALL_DEFINE2(mkdir, const char __user *, pathname, int, mode) | |||
| 2629 | } | 2529 | } |
| 2630 | 2530 | ||
| 2631 | /* | 2531 | /* |
| 2632 | * We try to drop the dentry early: we should have | 2532 | * The dentry_unhash() helper will try to drop the dentry early: we |
| 2633 | * a usage count of 2 if we're the only user of this | 2533 | * should have a usage count of 2 if we're the only user of this |
| 2634 | * dentry, and if that is true (possibly after pruning | 2534 | * dentry, and if that is true (possibly after pruning the dcache), |
| 2635 | * the dcache), then we drop the dentry now. | 2535 | * then we drop the dentry now. |
| 2636 | * | 2536 | * |
| 2637 | * A low-level filesystem can, if it choses, legally | 2537 | * A low-level filesystem can, if it choses, legally |
| 2638 | * do a | 2538 | * do a |
| @@ -2645,10 +2545,9 @@ SYSCALL_DEFINE2(mkdir, const char __user *, pathname, int, mode) | |||
| 2645 | */ | 2545 | */ |
| 2646 | void dentry_unhash(struct dentry *dentry) | 2546 | void dentry_unhash(struct dentry *dentry) |
| 2647 | { | 2547 | { |
| 2648 | dget(dentry); | ||
| 2649 | shrink_dcache_parent(dentry); | 2548 | shrink_dcache_parent(dentry); |
| 2650 | spin_lock(&dentry->d_lock); | 2549 | spin_lock(&dentry->d_lock); |
| 2651 | if (dentry->d_count == 2) | 2550 | if (dentry->d_count == 1) |
| 2652 | __d_drop(dentry); | 2551 | __d_drop(dentry); |
| 2653 | spin_unlock(&dentry->d_lock); | 2552 | spin_unlock(&dentry->d_lock); |
| 2654 | } | 2553 | } |
| @@ -2664,25 +2563,26 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 2664 | return -EPERM; | 2563 | return -EPERM; |
| 2665 | 2564 | ||
| 2666 | mutex_lock(&dentry->d_inode->i_mutex); | 2565 | mutex_lock(&dentry->d_inode->i_mutex); |
| 2667 | dentry_unhash(dentry); | 2566 | |
| 2567 | error = -EBUSY; | ||
| 2668 | if (d_mountpoint(dentry)) | 2568 | if (d_mountpoint(dentry)) |
| 2669 | error = -EBUSY; | 2569 | goto out; |
| 2670 | else { | 2570 | |
| 2671 | error = security_inode_rmdir(dir, dentry); | 2571 | error = security_inode_rmdir(dir, dentry); |
| 2672 | if (!error) { | 2572 | if (error) |
| 2673 | error = dir->i_op->rmdir(dir, dentry); | 2573 | goto out; |
| 2674 | if (!error) { | 2574 | |
| 2675 | dentry->d_inode->i_flags |= S_DEAD; | 2575 | error = dir->i_op->rmdir(dir, dentry); |
| 2676 | dont_mount(dentry); | 2576 | if (error) |
| 2677 | } | 2577 | goto out; |
| 2678 | } | 2578 | |
| 2679 | } | 2579 | dentry->d_inode->i_flags |= S_DEAD; |
| 2580 | dont_mount(dentry); | ||
| 2581 | |||
| 2582 | out: | ||
| 2680 | mutex_unlock(&dentry->d_inode->i_mutex); | 2583 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 2681 | if (!error) { | 2584 | if (!error) |
| 2682 | d_delete(dentry); | 2585 | d_delete(dentry); |
| 2683 | } | ||
| 2684 | dput(dentry); | ||
| 2685 | |||
| 2686 | return error; | 2586 | return error; |
| 2687 | } | 2587 | } |
| 2688 | 2588 | ||
| @@ -3053,12 +2953,7 @@ SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname | |||
| 3053 | * HOWEVER, it relies on the assumption that any object with ->lookup() | 2953 | * HOWEVER, it relies on the assumption that any object with ->lookup() |
| 3054 | * has no more than 1 dentry. If "hybrid" objects will ever appear, | 2954 | * has no more than 1 dentry. If "hybrid" objects will ever appear, |
| 3055 | * we'd better make sure that there's no link(2) for them. | 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, | 2956 | * d) conversion from fhandle to dentry may come in the wrong moment - when |
| 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 | ||
| 3062 | * we are removing the target. Solution: we will have to grab ->i_mutex | 2957 | * we are removing the target. Solution: we will have to grab ->i_mutex |
| 3063 | * in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on | 2958 | * in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on |
| 3064 | * ->i_mutex on parents, which works but leads to some truly excessive | 2959 | * ->i_mutex on parents, which works but leads to some truly excessive |
| @@ -3068,7 +2963,7 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, | |||
| 3068 | struct inode *new_dir, struct dentry *new_dentry) | 2963 | struct inode *new_dir, struct dentry *new_dentry) |
| 3069 | { | 2964 | { |
| 3070 | int error = 0; | 2965 | int error = 0; |
| 3071 | struct inode *target; | 2966 | struct inode *target = new_dentry->d_inode; |
| 3072 | 2967 | ||
| 3073 | /* | 2968 | /* |
| 3074 | * If we are going to change the parent - check write permissions, | 2969 | * If we are going to change the parent - check write permissions, |
| @@ -3084,26 +2979,24 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, | |||
| 3084 | if (error) | 2979 | if (error) |
| 3085 | return error; | 2980 | return error; |
| 3086 | 2981 | ||
| 3087 | target = new_dentry->d_inode; | ||
| 3088 | if (target) | 2982 | if (target) |
| 3089 | mutex_lock(&target->i_mutex); | 2983 | mutex_lock(&target->i_mutex); |
| 3090 | if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) | 2984 | |
| 3091 | error = -EBUSY; | 2985 | error = -EBUSY; |
| 3092 | else { | 2986 | if (d_mountpoint(old_dentry) || d_mountpoint(new_dentry)) |
| 3093 | if (target) | 2987 | goto out; |
| 3094 | dentry_unhash(new_dentry); | 2988 | |
| 3095 | error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); | 2989 | error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); |
| 3096 | } | 2990 | if (error) |
| 2991 | goto out; | ||
| 2992 | |||
| 3097 | if (target) { | 2993 | if (target) { |
| 3098 | if (!error) { | 2994 | target->i_flags |= S_DEAD; |
| 3099 | target->i_flags |= S_DEAD; | 2995 | dont_mount(new_dentry); |
| 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); | ||
| 3106 | } | 2996 | } |
| 2997 | out: | ||
| 2998 | if (target) | ||
| 2999 | mutex_unlock(&target->i_mutex); | ||
| 3107 | if (!error) | 3000 | if (!error) |
| 3108 | if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) | 3001 | if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) |
| 3109 | d_move(old_dentry,new_dentry); | 3002 | d_move(old_dentry,new_dentry); |
| @@ -3113,7 +3006,7 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, | |||
| 3113 | static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, | 3006 | static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, |
| 3114 | struct inode *new_dir, struct dentry *new_dentry) | 3007 | struct inode *new_dir, struct dentry *new_dentry) |
| 3115 | { | 3008 | { |
| 3116 | struct inode *target; | 3009 | struct inode *target = new_dentry->d_inode; |
| 3117 | int error; | 3010 | int error; |
| 3118 | 3011 | ||
| 3119 | error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry); | 3012 | error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry); |
| @@ -3121,19 +3014,22 @@ static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, | |||
| 3121 | return error; | 3014 | return error; |
| 3122 | 3015 | ||
| 3123 | dget(new_dentry); | 3016 | dget(new_dentry); |
| 3124 | target = new_dentry->d_inode; | ||
| 3125 | if (target) | 3017 | if (target) |
| 3126 | mutex_lock(&target->i_mutex); | 3018 | mutex_lock(&target->i_mutex); |
| 3019 | |||
| 3020 | error = -EBUSY; | ||
| 3127 | if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) | 3021 | if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) |
| 3128 | error = -EBUSY; | 3022 | goto out; |
| 3129 | else | 3023 | |
| 3130 | error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); | 3024 | error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); |
| 3131 | if (!error) { | 3025 | if (error) |
| 3132 | if (target) | 3026 | goto out; |
| 3133 | dont_mount(new_dentry); | 3027 | |
| 3134 | if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) | 3028 | if (target) |
| 3135 | d_move(old_dentry, new_dentry); | 3029 | dont_mount(new_dentry); |
| 3136 | } | 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 | if (target) | 3033 | if (target) |
| 3138 | mutex_unlock(&target->i_mutex); | 3034 | mutex_unlock(&target->i_mutex); |
| 3139 | dput(new_dentry); | 3035 | dput(new_dentry); |
diff --git a/fs/namespace.c b/fs/namespace.c index d99bcf59e4c2..fe59bd145d21 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
| @@ -1695,7 +1695,7 @@ static int graft_tree(struct vfsmount *mnt, struct path *path) | |||
| 1695 | 1695 | ||
| 1696 | static int flags_to_propagation_type(int flags) | 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 | /* Fail if any non-propagation flags are set */ | 1700 | /* Fail if any non-propagation flags are set */ |
| 1701 | if (type & ~(MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) | 1701 | if (type & ~(MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) |
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index f6946bb5cb55..e3e646b06404 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c | |||
| @@ -1033,6 +1033,8 @@ static int ncp_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 1033 | DPRINTK("ncp_rmdir: removing %s/%s\n", | 1033 | DPRINTK("ncp_rmdir: removing %s/%s\n", |
| 1034 | dentry->d_parent->d_name.name, dentry->d_name.name); | 1034 | dentry->d_parent->d_name.name, dentry->d_name.name); |
| 1035 | 1035 | ||
| 1036 | dentry_unhash(dentry); | ||
| 1037 | |||
| 1036 | error = -EBUSY; | 1038 | error = -EBUSY; |
| 1037 | if (!d_unhashed(dentry)) | 1039 | if (!d_unhashed(dentry)) |
| 1038 | goto out; | 1040 | goto out; |
| @@ -1139,6 +1141,9 @@ static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 1139 | old_dentry->d_parent->d_name.name, old_dentry->d_name.name, | 1141 | old_dentry->d_parent->d_name.name, old_dentry->d_name.name, |
| 1140 | new_dentry->d_parent->d_name.name, new_dentry->d_name.name); | 1142 | new_dentry->d_parent->d_name.name, new_dentry->d_name.name); |
| 1141 | 1143 | ||
| 1144 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
| 1145 | dentry_unhash(new_dentry); | ||
| 1146 | |||
| 1142 | ncp_age_dentry(server, old_dentry); | 1147 | ncp_age_dentry(server, old_dentry); |
| 1143 | ncp_age_dentry(server, new_dentry); | 1148 | ncp_age_dentry(server, new_dentry); |
| 1144 | 1149 | ||
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index 546849b3e88f..1102a5fbb744 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c | |||
| @@ -334,6 +334,8 @@ static int nilfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 334 | struct nilfs_transaction_info ti; | 334 | struct nilfs_transaction_info ti; |
| 335 | int err; | 335 | int err; |
| 336 | 336 | ||
| 337 | dentry_unhash(dentry); | ||
| 338 | |||
| 337 | err = nilfs_transaction_begin(dir->i_sb, &ti, 0); | 339 | err = nilfs_transaction_begin(dir->i_sb, &ti, 0); |
| 338 | if (err) | 340 | if (err) |
| 339 | return err; | 341 | return err; |
| @@ -369,6 +371,9 @@ static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 369 | struct nilfs_transaction_info ti; | 371 | struct nilfs_transaction_info ti; |
| 370 | int err; | 372 | int err; |
| 371 | 373 | ||
| 374 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
| 375 | dentry_unhash(new_dentry); | ||
| 376 | |||
| 372 | err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1); | 377 | err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1); |
| 373 | if (unlikely(err)) | 378 | if (unlikely(err)) |
| 374 | return err; | 379 | return err; |
diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c index de4ff29f1e05..c368360c35a1 100644 --- a/fs/omfs/dir.c +++ b/fs/omfs/dir.c | |||
| @@ -240,8 +240,12 @@ static int omfs_remove(struct inode *dir, struct dentry *dentry) | |||
| 240 | struct inode *inode = dentry->d_inode; | 240 | struct inode *inode = dentry->d_inode; |
| 241 | int ret; | 241 | int ret; |
| 242 | 242 | ||
| 243 | if (S_ISDIR(inode->i_mode) && !omfs_dir_is_empty(inode)) | 243 | |
| 244 | return -ENOTEMPTY; | 244 | if (S_ISDIR(inode->i_mode)) { |
| 245 | dentry_unhash(dentry); | ||
| 246 | if (!omfs_dir_is_empty(inode)) | ||
| 247 | return -ENOTEMPTY; | ||
| 248 | } | ||
| 245 | 249 | ||
| 246 | ret = omfs_delete_entry(dentry); | 250 | ret = omfs_delete_entry(dentry); |
| 247 | if (ret) | 251 | if (ret) |
| @@ -378,6 +382,9 @@ static int omfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 378 | int err; | 382 | int err; |
| 379 | 383 | ||
| 380 | if (new_inode) { | 384 | if (new_inode) { |
| 385 | if (S_ISDIR(new_inode->i_mode)) | ||
| 386 | dentry_unhash(new_dentry); | ||
| 387 | |||
| 381 | /* overwriting existing file/dir */ | 388 | /* overwriting existing file/dir */ |
| 382 | err = omfs_remove(new_dir, new_dentry); | 389 | err = omfs_remove(new_dir, new_dentry); |
| 383 | if (err) | 390 | if (err) |
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 118662690cdf..76c8164d5651 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
| @@ -831,6 +831,8 @@ static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 831 | INITIALIZE_PATH(path); | 831 | INITIALIZE_PATH(path); |
| 832 | struct reiserfs_dir_entry de; | 832 | struct reiserfs_dir_entry de; |
| 833 | 833 | ||
| 834 | dentry_unhash(dentry); | ||
| 835 | |||
| 834 | /* we will be doing 2 balancings and update 2 stat data, we change quotas | 836 | /* we will be doing 2 balancings and update 2 stat data, we change quotas |
| 835 | * of the owner of the directory and of the owner of the parent directory. | 837 | * of the owner of the directory and of the owner of the parent directory. |
| 836 | * The quota structure is possibly deleted only on last iput => outside | 838 | * The quota structure is possibly deleted only on last iput => outside |
| @@ -1225,6 +1227,9 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 1225 | unsigned long savelink = 1; | 1227 | unsigned long savelink = 1; |
| 1226 | struct timespec ctime; | 1228 | struct timespec ctime; |
| 1227 | 1229 | ||
| 1230 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
| 1231 | dentry_unhash(new_dentry); | ||
| 1232 | |||
| 1228 | /* three balancings: (1) old name removal, (2) new name insertion | 1233 | /* three balancings: (1) old name removal, (2) new name insertion |
| 1229 | and (3) maybe "save" link insertion | 1234 | and (3) maybe "save" link insertion |
| 1230 | stat data updates: (1) old directory, | 1235 | stat data updates: (1) old directory, |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 47d2a4498b03..50f1abccd1cd 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
| @@ -105,7 +105,6 @@ static int xattr_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 105 | mutex_unlock(&dentry->d_inode->i_mutex); | 105 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 106 | if (!error) | 106 | if (!error) |
| 107 | d_delete(dentry); | 107 | d_delete(dentry); |
| 108 | dput(dentry); | ||
| 109 | 108 | ||
| 110 | return error; | 109 | return error; |
| 111 | } | 110 | } |
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index e474fbcf8bde..e2cc6756f3b1 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c | |||
| @@ -196,6 +196,8 @@ static int sysv_rmdir(struct inode * dir, struct dentry * dentry) | |||
| 196 | struct inode *inode = dentry->d_inode; | 196 | struct inode *inode = dentry->d_inode; |
| 197 | int err = -ENOTEMPTY; | 197 | int err = -ENOTEMPTY; |
| 198 | 198 | ||
| 199 | dentry_unhash(dentry); | ||
| 200 | |||
| 199 | if (sysv_empty_dir(inode)) { | 201 | if (sysv_empty_dir(inode)) { |
| 200 | err = sysv_unlink(dir, dentry); | 202 | err = sysv_unlink(dir, dentry); |
| 201 | if (!err) { | 203 | if (!err) { |
| @@ -222,6 +224,9 @@ static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry, | |||
| 222 | struct sysv_dir_entry * old_de; | 224 | struct sysv_dir_entry * old_de; |
| 223 | int err = -ENOENT; | 225 | int err = -ENOENT; |
| 224 | 226 | ||
| 227 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
| 228 | dentry_unhash(new_dentry); | ||
| 229 | |||
| 225 | old_de = sysv_find_entry(old_dentry, &old_page); | 230 | old_de = sysv_find_entry(old_dentry, &old_page); |
| 226 | if (!old_de) | 231 | if (!old_de) |
| 227 | goto out; | 232 | goto out; |
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index ef5abd38f0bf..c2b80943560d 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
| @@ -656,6 +656,8 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 656 | struct ubifs_inode *dir_ui = ubifs_inode(dir); | 656 | struct ubifs_inode *dir_ui = ubifs_inode(dir); |
| 657 | struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 }; | 657 | struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 }; |
| 658 | 658 | ||
| 659 | dentry_unhash(dentry); | ||
| 660 | |||
| 659 | /* | 661 | /* |
| 660 | * Budget request settings: deletion direntry, deletion inode and | 662 | * Budget request settings: deletion direntry, deletion inode and |
| 661 | * changing the parent inode. If budgeting fails, go ahead anyway | 663 | * changing the parent inode. If budgeting fails, go ahead anyway |
| @@ -976,6 +978,9 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 976 | .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) }; | 978 | .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) }; |
| 977 | struct timespec time; | 979 | struct timespec time; |
| 978 | 980 | ||
| 981 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
| 982 | dentry_unhash(new_dentry); | ||
| 983 | |||
| 979 | /* | 984 | /* |
| 980 | * Budget request settings: deletion direntry, new direntry, removing | 985 | * Budget request settings: deletion direntry, new direntry, removing |
| 981 | * the old inode, and changing old and new parent directory inodes. | 986 | * the old inode, and changing old and new parent directory inodes. |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index f1dce848ef96..4d76594c2a8f 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
| @@ -783,6 +783,8 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 783 | struct fileIdentDesc *fi, cfi; | 783 | struct fileIdentDesc *fi, cfi; |
| 784 | struct kernel_lb_addr tloc; | 784 | struct kernel_lb_addr tloc; |
| 785 | 785 | ||
| 786 | dentry_unhash(dentry); | ||
| 787 | |||
| 786 | retval = -ENOENT; | 788 | retval = -ENOENT; |
| 787 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); | 789 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); |
| 788 | if (!fi) | 790 | if (!fi) |
| @@ -1081,6 +1083,9 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 1081 | struct kernel_lb_addr tloc; | 1083 | struct kernel_lb_addr tloc; |
| 1082 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); | 1084 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); |
| 1083 | 1085 | ||
| 1086 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
| 1087 | dentry_unhash(new_dentry); | ||
| 1088 | |||
| 1084 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); | 1089 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); |
| 1085 | if (ofi) { | 1090 | if (ofi) { |
| 1086 | if (ofibh.sbh != ofibh.ebh) | 1091 | if (ofibh.sbh != ofibh.ebh) |
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index 29309e25417f..953ebdfc5bf7 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c | |||
| @@ -258,6 +258,8 @@ static int ufs_rmdir (struct inode * dir, struct dentry *dentry) | |||
| 258 | struct inode * inode = dentry->d_inode; | 258 | struct inode * inode = dentry->d_inode; |
| 259 | int err= -ENOTEMPTY; | 259 | int err= -ENOTEMPTY; |
| 260 | 260 | ||
| 261 | dentry_unhash(dentry); | ||
| 262 | |||
| 261 | lock_ufs(dir->i_sb); | 263 | lock_ufs(dir->i_sb); |
| 262 | if (ufs_empty_dir (inode)) { | 264 | if (ufs_empty_dir (inode)) { |
| 263 | err = ufs_unlink(dir, dentry); | 265 | err = ufs_unlink(dir, dentry); |
| @@ -282,6 +284,9 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 282 | struct ufs_dir_entry *old_de; | 284 | struct ufs_dir_entry *old_de; |
| 283 | int err = -ENOENT; | 285 | int err = -ENOENT; |
| 284 | 286 | ||
| 287 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
| 288 | dentry_unhash(new_dentry); | ||
| 289 | |||
| 285 | old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page); | 290 | old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page); |
| 286 | if (!old_de) | 291 | if (!old_de) |
| 287 | goto out; | 292 | goto out; |
