aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/dcache.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 7599d35b4ae5..cb25a1a5e307 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -2372,7 +2372,8 @@ void dentry_update_name_case(struct dentry *dentry, struct qstr *name)
2372} 2372}
2373EXPORT_SYMBOL(dentry_update_name_case); 2373EXPORT_SYMBOL(dentry_update_name_case);
2374 2374
2375static void switch_names(struct dentry *dentry, struct dentry *target) 2375static void switch_names(struct dentry *dentry, struct dentry *target,
2376 bool exchange)
2376{ 2377{
2377 if (dname_external(target)) { 2378 if (dname_external(target)) {
2378 if (dname_external(dentry)) { 2379 if (dname_external(dentry)) {
@@ -2406,6 +2407,12 @@ static void switch_names(struct dentry *dentry, struct dentry *target)
2406 */ 2407 */
2407 unsigned int i; 2408 unsigned int i;
2408 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 }
2409 for (i = 0; i < DNAME_INLINE_LEN / sizeof(long); i++) { 2416 for (i = 0; i < DNAME_INLINE_LEN / sizeof(long); i++) {
2410 swap(((long *) &dentry->d_iname)[i], 2417 swap(((long *) &dentry->d_iname)[i],
2411 ((long *) &target->d_iname)[i]); 2418 ((long *) &target->d_iname)[i]);
@@ -2456,12 +2463,15 @@ static void dentry_unlock_for_move(struct dentry *dentry, struct dentry *target)
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,9 +2517,8 @@ 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
2511 /* Switch the names.. */ 2520 /* Switch the names.. */
2512 switch_names(dentry, target); 2521 switch_names(dentry, target, exchange);
2513 2522
2514 /* ... and switch them in the tree */ 2523 /* ... and switch them in the tree */
2515 if (IS_ROOT(dentry)) { 2524 if (IS_ROOT(dentry)) {