diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-26 12:52:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-26 12:52:14 -0400 |
commit | 32e51f141fd8d880f57b6a2eb53ce72856254d4a (patch) | |
tree | d8d7a0d503533a03fb07b2ebd5eccd9043f2d228 | |
parent | ca16d140af91febe25daeb9e032bf8bd46b8c31f (diff) | |
parent | b6ff24a333267a6810e28ee5b9fc539d149c52f0 (diff) |
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
...
-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 | ||||
-rw-r--r-- | include/linux/buffer_head.h | 16 |
33 files changed, 332 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; |
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index f5df23561b96..503c8a6b3079 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h | |||
@@ -217,8 +217,24 @@ int cont_write_begin(struct file *, struct address_space *, loff_t, | |||
217 | get_block_t *, loff_t *); | 217 | get_block_t *, loff_t *); |
218 | int generic_cont_expand_simple(struct inode *inode, loff_t size); | 218 | int generic_cont_expand_simple(struct inode *inode, loff_t size); |
219 | int block_commit_write(struct page *page, unsigned from, unsigned to); | 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 | int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, | 222 | int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, |
221 | get_block_t get_block); | 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 | sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *); | 238 | sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *); |
223 | int block_truncate_page(struct address_space *, loff_t, get_block_t *); | 239 | int block_truncate_page(struct address_space *, loff_t, get_block_t *); |
224 | int nobh_write_begin(struct address_space *, loff_t, unsigned, unsigned, | 240 | int nobh_write_begin(struct address_space *, loff_t, unsigned, unsigned, |