Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/vfs_subr.c
Show First 20 Lines • Show All 764 Lines • ▼ Show 20 Lines | |||||
* | * | ||||
* When traversing across mounts, the system follows that lock order: | * When traversing across mounts, the system follows that lock order: | ||||
* | * | ||||
* C->A->B | * C->A->B | ||||
* | | * | | ||||
* +->F->D->E | * +->F->D->E | ||||
* | * | ||||
* The lookup() process for namei("/var") illustrates the process: | * The lookup() process for namei("/var") illustrates the process: | ||||
* VOP_LOOKUP() obtains B while A is held | * 1. VOP_LOOKUP() obtains B while A is held | ||||
* vfs_busy() obtains a shared lock on F while A and B are held | * 2. vfs_busy() obtains a shared lock on F while A and B are held | ||||
* vput() releases lock on B | * 3. vput() releases lock on B | ||||
* vput() releases lock on A | * 4. vput() releases lock on A | ||||
* VFS_ROOT() obtains lock on D while shared lock on F is held | * 5. VFS_ROOT() obtains lock on D while shared lock on F is held | ||||
* vfs_unbusy() releases shared lock on F | * 6. vfs_unbusy() releases shared lock on F | ||||
* vn_lock() obtains lock on deadfs vnode vp_crossmp instead of A. | * 7. vn_lock() obtains lock on deadfs vnode vp_crossmp instead of A. | ||||
* Attempt to lock A (instead of vp_crossmp) while D is held would | * Attempt to lock A (instead of vp_crossmp) while D is held would | ||||
* violate the global order, causing deadlocks. | * violate the global order, causing deadlocks. | ||||
* | * | ||||
* dounmount() locks B while F is drained. | * dounmount() locks B while F is drained. Note that for stacked | ||||
* filesystems, D and B in the example above may be the same lock, | |||||
* which introdues potential lock order reversal deadlock between | |||||
* dounmount() and step 5 above. These filesystems may avoid the LOR | |||||
* by setting VV_CROSSLOCK on the covered vnode so that lock B will | |||||
* remain held until after step 5. | |||||
*/ | */ | ||||
int | int | ||||
vfs_busy(struct mount *mp, int flags) | vfs_busy(struct mount *mp, int flags) | ||||
{ | { | ||||
struct mount_pcpu *mpcpu; | struct mount_pcpu *mpcpu; | ||||
MPASS((flags & ~MBF_MASK) == 0); | MPASS((flags & ~MBF_MASK) == 0); | ||||
CTR3(KTR_VFS, "%s: mp %p with flags %d", __func__, mp, flags); | CTR3(KTR_VFS, "%s: mp %p with flags %d", __func__, mp, flags); | ||||
▲ Show 20 Lines • Show All 6,288 Lines • Show Last 20 Lines |