diff options
-rw-r--r-- | fs/dax.c | 35 |
1 files changed, 22 insertions, 13 deletions
@@ -373,6 +373,22 @@ restart: | |||
373 | } | 373 | } |
374 | spin_lock_irq(&mapping->tree_lock); | 374 | spin_lock_irq(&mapping->tree_lock); |
375 | 375 | ||
376 | if (!entry) { | ||
377 | /* | ||
378 | * We needed to drop the page_tree lock while calling | ||
379 | * radix_tree_preload() and we didn't have an entry to | ||
380 | * lock. See if another thread inserted an entry at | ||
381 | * our index during this time. | ||
382 | */ | ||
383 | entry = __radix_tree_lookup(&mapping->page_tree, index, | ||
384 | NULL, &slot); | ||
385 | if (entry) { | ||
386 | radix_tree_preload_end(); | ||
387 | spin_unlock_irq(&mapping->tree_lock); | ||
388 | goto restart; | ||
389 | } | ||
390 | } | ||
391 | |||
376 | if (pmd_downgrade) { | 392 | if (pmd_downgrade) { |
377 | radix_tree_delete(&mapping->page_tree, index); | 393 | radix_tree_delete(&mapping->page_tree, index); |
378 | mapping->nrexceptional--; | 394 | mapping->nrexceptional--; |
@@ -388,19 +404,12 @@ restart: | |||
388 | if (err) { | 404 | if (err) { |
389 | spin_unlock_irq(&mapping->tree_lock); | 405 | spin_unlock_irq(&mapping->tree_lock); |
390 | /* | 406 | /* |
391 | * Someone already created the entry? This is a | 407 | * Our insertion of a DAX entry failed, most likely |
392 | * normal failure when inserting PMDs in a range | 408 | * because we were inserting a PMD entry and it |
393 | * that already contains PTEs. In that case we want | 409 | * collided with a PTE sized entry at a different |
394 | * to return -EEXIST immediately. | 410 | * index in the PMD range. We haven't inserted |
395 | */ | 411 | * anything into the radix tree and have no waiters to |
396 | if (err == -EEXIST && !(size_flag & RADIX_DAX_PMD)) | 412 | * wake. |
397 | goto restart; | ||
398 | /* | ||
399 | * Our insertion of a DAX PMD entry failed, most | ||
400 | * likely because it collided with a PTE sized entry | ||
401 | * at a different index in the PMD range. We haven't | ||
402 | * inserted anything into the radix tree and have no | ||
403 | * waiters to wake. | ||
404 | */ | 413 | */ |
405 | return ERR_PTR(err); | 414 | return ERR_PTR(err); |
406 | } | 415 | } |