aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c111
1 files changed, 37 insertions, 74 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index d30ce699ae4b..cb25a1a5e307 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -106,8 +106,7 @@ static inline struct hlist_bl_head *d_hash(const struct dentry *parent,
106 unsigned int hash) 106 unsigned int hash)
107{ 107{
108 hash += (unsigned long) parent / L1_CACHE_BYTES; 108 hash += (unsigned long) parent / L1_CACHE_BYTES;
109 hash = hash + (hash >> d_hash_shift); 109 return dentry_hashtable + hash_32(hash, d_hash_shift);
110 return dentry_hashtable + (hash & d_hash_mask);
111} 110}
112 111
113/* Statistics gathering. */ 112/* Statistics gathering. */
@@ -2373,7 +2372,8 @@ void dentry_update_name_case(struct dentry *dentry, struct qstr *name)
2373} 2372}
2374EXPORT_SYMBOL(dentry_update_name_case); 2373EXPORT_SYMBOL(dentry_update_name_case);
2375 2374
2376static void switch_names(struct dentry *dentry, struct dentry *target) 2375static void switch_names(struct dentry *dentry, struct dentry *target,
2376 bool exchange)
2377{ 2377{
2378 if (dname_external(target)) { 2378 if (dname_external(target)) {
2379 if (dname_external(dentry)) { 2379 if (dname_external(dentry)) {
@@ -2407,13 +2407,19 @@ static void switch_names(struct dentry *dentry, struct dentry *target)
2407 */ 2407 */
2408 unsigned int i; 2408 unsigned int i;
2409 BUILD_BUG_ON(!IS_ALIGNED(DNAME_INLINE_LEN, sizeof(long))); 2409 BUILD_BUG_ON(!IS_ALIGNED(DNAME_INLINE_LEN, sizeof(long)));
2410 if (!exchange) {
2411 memcpy(dentry->d_iname, target->d_name.name,
2412 target->d_name.len + 1);
2413 dentry->d_name.hash_len = target->d_name.hash_len;
2414 return;
2415 }
2410 for (i = 0; i < DNAME_INLINE_LEN / sizeof(long); i++) { 2416 for (i = 0; i < DNAME_INLINE_LEN / sizeof(long); i++) {
2411 swap(((long *) &dentry->d_iname)[i], 2417 swap(((long *) &dentry->d_iname)[i],
2412 ((long *) &target->d_iname)[i]); 2418 ((long *) &target->d_iname)[i]);
2413 } 2419 }
2414 } 2420 }
2415 } 2421 }
2416 swap(dentry->d_name.len, target->d_name.len); 2422 swap(dentry->d_name.hash_len, target->d_name.hash_len);
2417} 2423}
2418 2424
2419static void dentry_lock_for_move(struct dentry *dentry, struct dentry *target) 2425static void dentry_lock_for_move(struct dentry *dentry, struct dentry *target)
@@ -2443,25 +2449,29 @@ static void dentry_lock_for_move(struct dentry *dentry, struct dentry *target)
2443 } 2449 }
2444} 2450}
2445 2451
2446static void dentry_unlock_parents_for_move(struct dentry *dentry, 2452static void dentry_unlock_for_move(struct dentry *dentry, struct dentry *target)
2447 struct dentry *target)
2448{ 2453{
2449 if (target->d_parent != dentry->d_parent) 2454 if (target->d_parent != dentry->d_parent)
2450 spin_unlock(&dentry->d_parent->d_lock); 2455 spin_unlock(&dentry->d_parent->d_lock);
2451 if (target->d_parent != target) 2456 if (target->d_parent != target)
2452 spin_unlock(&target->d_parent->d_lock); 2457 spin_unlock(&target->d_parent->d_lock);
2458 spin_unlock(&target->d_lock);
2459 spin_unlock(&dentry->d_lock);
2453} 2460}
2454 2461
2455/* 2462/*
2456 * When switching names, the actual string doesn't strictly have to 2463 * When switching names, the actual string doesn't strictly have to
2457 * be preserved in the target - because we're dropping the target 2464 * be preserved in the target - because we're dropping the target
2458 * anyway. As such, we can just do a simple memcpy() to copy over 2465 * anyway. As such, we can just do a simple memcpy() to copy over
2459 * the new name before we switch. 2466 * the new name before we switch, unless we are going to rehash
2460 * 2467 * it. Note that if we *do* unhash the target, we are not allowed
2461 * Note that we have to be a lot more careful about getting the hash 2468 * to rehash it without giving it a new name/hash key - whether
2462 * switched - we have to switch the hash value properly even if it 2469 * we swap or overwrite the names here, resulting name won't match
2463 * then no longer matches the actual (corrupted) string of the target. 2470 * the reality in filesystem; it's only there for d_path() purposes.
2464 * The hash value has to match the hash queue that the dentry is on.. 2471 * Note that all of this is happening under rename_lock, so the
2472 * any hash lookup seeing it in the middle of manipulations will
2473 * be discarded anyway. So we do not care what happens to the hash
2474 * key in that case.
2465 */ 2475 */
2466/* 2476/*
2467 * __d_move - move a dentry 2477 * __d_move - move a dentry
@@ -2507,36 +2517,30 @@ static void __d_move(struct dentry *dentry, struct dentry *target,
2507 d_hash(dentry->d_parent, dentry->d_name.hash)); 2517 d_hash(dentry->d_parent, dentry->d_name.hash));
2508 } 2518 }
2509 2519
2510 list_del(&dentry->d_u.d_child);
2511 list_del(&target->d_u.d_child);
2512
2513 /* Switch the names.. */ 2520 /* Switch the names.. */
2514 switch_names(dentry, target); 2521 switch_names(dentry, target, exchange);
2515 swap(dentry->d_name.hash, target->d_name.hash);
2516 2522
2517 /* ... and switch the parents */ 2523 /* ... and switch them in the tree */
2518 if (IS_ROOT(dentry)) { 2524 if (IS_ROOT(dentry)) {
2525 /* splicing a tree */
2519 dentry->d_parent = target->d_parent; 2526 dentry->d_parent = target->d_parent;
2520 target->d_parent = target; 2527 target->d_parent = target;
2521 INIT_LIST_HEAD(&target->d_u.d_child); 2528 list_del_init(&target->d_u.d_child);
2529 list_move(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs);
2522 } else { 2530 } else {
2531 /* swapping two dentries */
2523 swap(dentry->d_parent, target->d_parent); 2532 swap(dentry->d_parent, target->d_parent);
2524 2533 list_move(&target->d_u.d_child, &target->d_parent->d_subdirs);
2525 /* And add them back to the (new) parent lists */ 2534 list_move(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs);
2526 list_add(&target->d_u.d_child, &target->d_parent->d_subdirs); 2535 if (exchange)
2536 fsnotify_d_move(target);
2537 fsnotify_d_move(dentry);
2527 } 2538 }
2528 2539
2529 list_add(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs);
2530
2531 write_seqcount_end(&target->d_seq); 2540 write_seqcount_end(&target->d_seq);
2532 write_seqcount_end(&dentry->d_seq); 2541 write_seqcount_end(&dentry->d_seq);
2533 2542
2534 dentry_unlock_parents_for_move(dentry, target); 2543 dentry_unlock_for_move(dentry, target);
2535 if (exchange)
2536 fsnotify_d_move(target);
2537 spin_unlock(&target->d_lock);
2538 fsnotify_d_move(dentry);
2539 spin_unlock(&dentry->d_lock);
2540} 2544}
2541 2545
2542/* 2546/*
@@ -2634,39 +2638,6 @@ out_err:
2634 return ret; 2638 return ret;
2635} 2639}
2636 2640
2637/*
2638 * Prepare an anonymous dentry for life in the superblock's dentry tree as a
2639 * named dentry in place of the dentry to be replaced.
2640 * returns with anon->d_lock held!
2641 */
2642static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon)
2643{
2644 struct dentry *dparent;
2645
2646 dentry_lock_for_move(anon, dentry);
2647
2648 write_seqcount_begin(&dentry->d_seq);
2649 write_seqcount_begin_nested(&anon->d_seq, DENTRY_D_LOCK_NESTED);
2650
2651 dparent = dentry->d_parent;
2652
2653 switch_names(dentry, anon);
2654 swap(dentry->d_name.hash, anon->d_name.hash);
2655
2656 dentry->d_parent = dentry;
2657 list_del_init(&dentry->d_u.d_child);
2658 anon->d_parent = dparent;
2659 list_move(&anon->d_u.d_child, &dparent->d_subdirs);
2660
2661 write_seqcount_end(&dentry->d_seq);
2662 write_seqcount_end(&anon->d_seq);
2663
2664 dentry_unlock_parents_for_move(anon, dentry);
2665 spin_unlock(&dentry->d_lock);
2666
2667 /* anon->d_lock still locked, returns locked */
2668}
2669
2670/** 2641/**
2671 * d_splice_alias - splice a disconnected dentry into the tree if one exists 2642 * d_splice_alias - splice a disconnected dentry into the tree if one exists
2672 * @inode: the inode which may have a disconnected dentry 2643 * @inode: the inode which may have a disconnected dentry
@@ -2712,11 +2683,8 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
2712 return ERR_PTR(-EIO); 2683 return ERR_PTR(-EIO);
2713 } 2684 }
2714 write_seqlock(&rename_lock); 2685 write_seqlock(&rename_lock);
2715 __d_materialise_dentry(dentry, new); 2686 __d_move(new, dentry, false);
2716 write_sequnlock(&rename_lock); 2687 write_sequnlock(&rename_lock);
2717 __d_drop(new);
2718 _d_rehash(new);
2719 spin_unlock(&new->d_lock);
2720 spin_unlock(&inode->i_lock); 2688 spin_unlock(&inode->i_lock);
2721 security_d_instantiate(new, inode); 2689 security_d_instantiate(new, inode);
2722 iput(inode); 2690 iput(inode);
@@ -2776,9 +2744,8 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
2776 } else if (IS_ROOT(alias)) { 2744 } else if (IS_ROOT(alias)) {
2777 /* Is this an anonymous mountpoint that we 2745 /* Is this an anonymous mountpoint that we
2778 * could splice into our tree? */ 2746 * could splice into our tree? */
2779 __d_materialise_dentry(dentry, alias); 2747 __d_move(alias, dentry, false);
2780 write_sequnlock(&rename_lock); 2748 write_sequnlock(&rename_lock);
2781 __d_drop(alias);
2782 goto found; 2749 goto found;
2783 } else { 2750 } else {
2784 /* Nope, but we must(!) avoid directory 2751 /* Nope, but we must(!) avoid directory
@@ -2804,13 +2771,9 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
2804 actual = __d_instantiate_unique(dentry, inode); 2771 actual = __d_instantiate_unique(dentry, inode);
2805 if (!actual) 2772 if (!actual)
2806 actual = dentry; 2773 actual = dentry;
2807 else
2808 BUG_ON(!d_unhashed(actual));
2809 2774
2810 spin_lock(&actual->d_lock); 2775 d_rehash(actual);
2811found: 2776found:
2812 _d_rehash(actual);
2813 spin_unlock(&actual->d_lock);
2814 spin_unlock(&inode->i_lock); 2777 spin_unlock(&inode->i_lock);
2815out_nolock: 2778out_nolock:
2816 if (actual == dentry) { 2779 if (actual == dentry) {