Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/vfs_default.c
Show First 20 Lines • Show All 674 Lines • ▼ Show 20 Lines | |||||
int | int | ||||
vop_stdgetwritemount(ap) | vop_stdgetwritemount(ap) | ||||
struct vop_getwritemount_args /* { | struct vop_getwritemount_args /* { | ||||
struct vnode *a_vp; | struct vnode *a_vp; | ||||
struct mount **a_mpp; | struct mount **a_mpp; | ||||
} */ *ap; | } */ *ap; | ||||
{ | { | ||||
struct mount *mp; | struct mount *mp; | ||||
struct mount_pcpu *mpcpu; | |||||
struct vnode *vp; | struct vnode *vp; | ||||
/* | /* | ||||
* Note that having a reference does not prevent forced unmount from | * Note that having a reference does not prevent forced unmount from | ||||
* setting ->v_mount to NULL after the lock gets released. This is of | * setting ->v_mount to NULL after the lock gets released. This is of | ||||
* no consequence for typical consumers (most notably vn_start_write) | * no consequence for typical consumers (most notably vn_start_write) | ||||
* since in this case the vnode is VIRF_DOOMED. Unmount might have | * since in this case the vnode is VIRF_DOOMED. Unmount might have | ||||
* progressed far enough that its completion is only delayed by the | * progressed far enough that its completion is only delayed by the | ||||
* reference obtained here. The consumer only needs to concern itself | * reference obtained here. The consumer only needs to concern itself | ||||
* with releasing it. | * with releasing it. | ||||
*/ | */ | ||||
vp = ap->a_vp; | vp = ap->a_vp; | ||||
mp = vp->v_mount; | mp = vfs_ref_from_vp(vp); | ||||
if (mp == NULL) { | |||||
*(ap->a_mpp) = NULL; | |||||
return (0); | |||||
} | |||||
if (vfs_op_thread_enter(mp, mpcpu)) { | |||||
if (mp == vp->v_mount) { | |||||
vfs_mp_count_add_pcpu(mpcpu, ref, 1); | |||||
vfs_op_thread_exit(mp, mpcpu); | |||||
} else { | |||||
vfs_op_thread_exit(mp, mpcpu); | |||||
mp = NULL; | |||||
} | |||||
} else { | |||||
MNT_ILOCK(mp); | |||||
if (mp == vp->v_mount) { | |||||
MNT_REF(mp); | |||||
MNT_IUNLOCK(mp); | |||||
} else { | |||||
MNT_IUNLOCK(mp); | |||||
mp = NULL; | |||||
} | |||||
} | |||||
*(ap->a_mpp) = mp; | *(ap->a_mpp) = mp; | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* If the file system doesn't implement VOP_BMAP, then return sensible defaults: | * If the file system doesn't implement VOP_BMAP, then return sensible defaults: | ||||
* - Return the vnode's bufobj instead of any underlying device's bufobj | * - Return the vnode's bufobj instead of any underlying device's bufobj | ||||
* - Calculate the physical block number as if there were equal size | * - Calculate the physical block number as if there were equal size | ||||
▲ Show 20 Lines • Show All 898 Lines • Show Last 20 Lines |