Commit 3c59366
NFS: don't unhash dentry during unlink/rename
NFS unlink() (and rename over existing target) must determine if the
file is open, and must perform a "silly rename" instead of an unlink (or
before rename) if it is. Otherwise the client might hold a file open
which has been removed on the server.
Consequently if it determines that the file isn't open, it must block
any subsequent opens until the unlink/rename has been completed on the
server.
This is currently achieved by unhashing the dentry. This forces any
open attempt to the slow-path for lookup which will block on i_rwsem on
the directory until the unlink/rename completes. A future patch will
change the VFS to only get a shared lock on i_rwsem for unlink, so this
will no longer work.
Instead we introduce an explicit interlock. A special value is stored
in dentry->d_fsdata while the unlink/rename is running and
->d_revalidate blocks while that value is present. When ->d_revalidate
unblocks, the dentry will be invalid. This closes the race
without requiring exclusion on i_rwsem.
d_fsdata is already used in two different ways.
1/ an IS_ROOT directory dentry might have a "devname" stored in
d_fsdata. Such a dentry doesn't have a name and so cannot be the
target of unlink or rename. For safety we check if an old devname
is still stored, and remove it if it is.
2/ a dentry with DCACHE_NFSFS_RENAMED set will have a 'struct
nfs_unlinkdata' stored in d_fsdata. While this is set maydelete()
will fail, so an unlink or rename will never proceed on such
a dentry.
Neither of these can be in effect when a dentry is the target of unlink
or rename. So we can expect d_fsdata to be NULL, and store a special
value ((void*)1) which is given the name NFS_FSDATA_BLOCKED to indicate
that any lookup will be blocked.
The d_count() is incremented under d_lock() when a lookup finds the
dentry, so we check d_count() is low, and set NFS_FSDATA_BLOCKED under
the same lock to avoid any races.
Signed-off-by: NeilBrown <[email protected]>
Signed-off-by: Trond Myklebust <[email protected]>1 parent 2135e5d commit 3c59366
2 files changed
+63
-18
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1782 | 1782 | | |
1783 | 1783 | | |
1784 | 1784 | | |
| 1785 | + | |
| 1786 | + | |
1785 | 1787 | | |
1786 | 1788 | | |
1787 | 1789 | | |
| |||
1790 | 1792 | | |
1791 | 1793 | | |
1792 | 1794 | | |
| 1795 | + | |
| 1796 | + | |
| 1797 | + | |
1793 | 1798 | | |
1794 | 1799 | | |
1795 | 1800 | | |
| |||
2458 | 2463 | | |
2459 | 2464 | | |
2460 | 2465 | | |
2461 | | - | |
2462 | 2466 | | |
2463 | 2467 | | |
2464 | 2468 | | |
| |||
2473 | 2477 | | |
2474 | 2478 | | |
2475 | 2479 | | |
2476 | | - | |
2477 | | - | |
2478 | | - | |
2479 | | - | |
| 2480 | + | |
| 2481 | + | |
| 2482 | + | |
| 2483 | + | |
| 2484 | + | |
| 2485 | + | |
| 2486 | + | |
| 2487 | + | |
| 2488 | + | |
| 2489 | + | |
| 2490 | + | |
| 2491 | + | |
| 2492 | + | |
| 2493 | + | |
2480 | 2494 | | |
2481 | 2495 | | |
2482 | 2496 | | |
2483 | | - | |
2484 | | - | |
| 2497 | + | |
| 2498 | + | |
2485 | 2499 | | |
2486 | 2500 | | |
2487 | 2501 | | |
| |||
2588 | 2602 | | |
2589 | 2603 | | |
2590 | 2604 | | |
| 2605 | + | |
| 2606 | + | |
| 2607 | + | |
| 2608 | + | |
| 2609 | + | |
| 2610 | + | |
| 2611 | + | |
| 2612 | + | |
| 2613 | + | |
2591 | 2614 | | |
2592 | 2615 | | |
2593 | 2616 | | |
| |||
2618 | 2641 | | |
2619 | 2642 | | |
2620 | 2643 | | |
2621 | | - | |
| 2644 | + | |
2622 | 2645 | | |
| 2646 | + | |
2623 | 2647 | | |
2624 | 2648 | | |
2625 | 2649 | | |
| |||
2637 | 2661 | | |
2638 | 2662 | | |
2639 | 2663 | | |
2640 | | - | |
2641 | | - | |
2642 | | - | |
| 2664 | + | |
| 2665 | + | |
| 2666 | + | |
| 2667 | + | |
2643 | 2668 | | |
2644 | | - | |
2645 | | - | |
2646 | | - | |
| 2669 | + | |
| 2670 | + | |
| 2671 | + | |
| 2672 | + | |
| 2673 | + | |
| 2674 | + | |
| 2675 | + | |
| 2676 | + | |
2647 | 2677 | | |
2648 | 2678 | | |
| 2679 | + | |
2649 | 2680 | | |
2650 | 2681 | | |
2651 | 2682 | | |
| 2683 | + | |
| 2684 | + | |
2652 | 2685 | | |
2653 | 2686 | | |
2654 | 2687 | | |
| |||
2661 | 2694 | | |
2662 | 2695 | | |
2663 | 2696 | | |
2664 | | - | |
2665 | 2697 | | |
| 2698 | + | |
| 2699 | + | |
| 2700 | + | |
| 2701 | + | |
2666 | 2702 | | |
| 2703 | + | |
2667 | 2704 | | |
2668 | 2705 | | |
2669 | 2706 | | |
2670 | 2707 | | |
2671 | | - | |
| 2708 | + | |
| 2709 | + | |
2672 | 2710 | | |
2673 | 2711 | | |
2674 | 2712 | | |
| |||
2692 | 2730 | | |
2693 | 2731 | | |
2694 | 2732 | | |
2695 | | - | |
2696 | | - | |
2697 | 2733 | | |
2698 | 2734 | | |
2699 | 2735 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
617 | 617 | | |
618 | 618 | | |
619 | 619 | | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
620 | 629 | | |
621 | 630 | | |
622 | 631 | | |
| |||
0 commit comments