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 /fs/namei.c | |
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
...
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 380 |
1 files changed, 138 insertions, 242 deletions
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); |