Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/unionfs/union_subr.c
Show First 20 Lines • Show All 1,233 Lines • ▼ Show 20 Lines | #endif | ||||
/* close vnode */ | /* close vnode */ | ||||
VOP_CLOSE(vp, FREAD, cred, td); | VOP_CLOSE(vp, FREAD, cred, td); | ||||
return (error); | return (error); | ||||
} | } | ||||
#ifdef DIAGNOSTIC | #ifdef DIAGNOSTIC | ||||
struct vnode * | struct vnode * | ||||
unionfs_checkuppervp(struct vnode *vp, char *fil, int lno) | unionfs_checkuppervp(struct vnode *vp, char *fil, int lno) | ||||
{ | { | ||||
struct unionfs_node *unp; | struct unionfs_node *unp; | ||||
unp = VTOUNIONFS(vp); | unp = VTOUNIONFS(vp); | ||||
#ifdef notyet | #ifdef notyet | ||||
if (vp->v_op != unionfs_vnodeop_p) { | if (vp->v_op != unionfs_vnodeop_p) { | ||||
printf("unionfs_checkuppervp: on non-unionfs-node.\n"); | printf("unionfs_checkuppervp: on non-unionfs-node.\n"); | ||||
#ifdef KDB | #ifdef KDB | ||||
kdb_enter(KDB_WHY_UNIONFS, | kdb_enter(KDB_WHY_UNIONFS, | ||||
"unionfs_checkuppervp: on non-unionfs-node.\n"); | "unionfs_checkuppervp: on non-unionfs-node.\n"); | ||||
#endif | #endif | ||||
panic("unionfs_checkuppervp"); | panic("unionfs_checkuppervp"); | ||||
} | } | ||||
#endif | #endif | ||||
return (unp->un_uppervp); | return (unp->un_uppervp); | ||||
} | } | ||||
struct vnode * | struct vnode * | ||||
unionfs_checklowervp(struct vnode *vp, char *fil, int lno) | unionfs_checklowervp(struct vnode *vp, char *fil, int lno) | ||||
{ | { | ||||
struct unionfs_node *unp; | struct unionfs_node *unp; | ||||
unp = VTOUNIONFS(vp); | unp = VTOUNIONFS(vp); | ||||
#ifdef notyet | #ifdef notyet | ||||
if (vp->v_op != unionfs_vnodeop_p) { | if (vp->v_op != unionfs_vnodeop_p) { | ||||
printf("unionfs_checklowervp: on non-unionfs-node.\n"); | printf("unionfs_checklowervp: on non-unionfs-node.\n"); | ||||
#ifdef KDB | #ifdef KDB | ||||
kdb_enter(KDB_WHY_UNIONFS, | kdb_enter(KDB_WHY_UNIONFS, | ||||
"unionfs_checklowervp: on non-unionfs-node.\n"); | "unionfs_checklowervp: on non-unionfs-node.\n"); | ||||
#endif | #endif | ||||
panic("unionfs_checklowervp"); | panic("unionfs_checklowervp"); | ||||
} | } | ||||
#endif | #endif | ||||
return (unp->un_lowervp); | return (unp->un_lowervp); | ||||
} | } | ||||
#endif | #endif | ||||
/* | |||||
* Attempt to mark the underlying mount for a vnode busy so that unionfs | |||||
* can safely access it or issue VFS_* operations against it. | |||||
* Returns NULL on failure. | |||||
*/ | |||||
struct mount * | |||||
unionfs_mount_trybusy(struct vnode *vp) | |||||
{ | |||||
struct mount *mp; | |||||
int error; | |||||
mp = vfs_ref_from_vp(vp); | |||||
jah: Is it actually necessary to do the ref step here?
vfs_busy() appears to perform a superset of… | |||||
if (mp == NULL) | |||||
return (NULL); | |||||
error = vfs_busy(mp, MBF_NOWAIT); | |||||
if (error != 0) { | |||||
vfs_rel(mp); | |||||
return (NULL); | |||||
} | |||||
return (mp); | |||||
} | |||||
void | |||||
unionfs_mount_unbusy(struct mount *mp) | |||||
{ | |||||
if (mp != NULL) { | |||||
vfs_unbusy(mp); | |||||
vfs_rel(mp); | |||||
} | |||||
} |
Is it actually necessary to do the ref step here?
vfs_busy() appears to perform a superset of what vfs_ref() does, so it seems we'd be able to just use a simple atomic load of vp->v_mount followed by a NULL check and vfs_busy().