Lines 300-326
unionfs_lookup(struct vop_cachedlookup_args *ap)
Link Here
|
300 |
error = lerror; |
300 |
error = lerror; |
301 |
if (error != 0) |
301 |
if (error != 0) |
302 |
goto unionfs_lookup_cleanup; |
302 |
goto unionfs_lookup_cleanup; |
303 |
/* |
303 |
error = unionfs_nodeget(dvp->v_mount, uvp, lvp, |
304 |
* get socket vnode. |
304 |
dvp, &vp, cnp); |
305 |
*/ |
|
|
306 |
if (uvp != NULLVP && uvp->v_type == VSOCK) { |
307 |
vp = uvp; |
308 |
vref(vp); |
309 |
if (cnp->cn_lkflags & LK_TYPE_MASK) |
310 |
vn_lock(vp, cnp->cn_lkflags | LK_RETRY); |
311 |
} |
312 |
else if (lvp != NULLVP && lvp->v_type == VSOCK) { |
313 |
vp = lvp; |
314 |
vref(vp); |
315 |
if (cnp->cn_lkflags & LK_TYPE_MASK) |
316 |
vn_lock(vp, cnp->cn_lkflags | LK_RETRY); |
317 |
} |
318 |
/* |
319 |
* get unionfs vnode. |
320 |
*/ |
321 |
else |
322 |
error = unionfs_nodeget(dvp->v_mount, uvp, lvp, |
323 |
dvp, &vp, cnp); |
324 |
if (error != 0) { |
305 |
if (error != 0) { |
325 |
UNIONFSDEBUG( |
306 |
UNIONFSDEBUG( |
326 |
"unionfs_lookup: Unable to create unionfs vnode."); |
307 |
"unionfs_lookup: Unable to create unionfs vnode."); |
Lines 333-339
unionfs_lookup(struct vop_cachedlookup_args *ap)
Link Here
|
333 |
|
314 |
|
334 |
*(ap->a_vpp) = vp; |
315 |
*(ap->a_vpp) = vp; |
335 |
|
316 |
|
336 |
if ((cnflags & MAKEENTRY) && vp->v_type != VSOCK) |
317 |
if (cnflags & MAKEENTRY) |
337 |
cache_enter(dvp, vp, cnp); |
318 |
cache_enter(dvp, vp, cnp); |
338 |
|
319 |
|
339 |
unionfs_lookup_cleanup: |
320 |
unionfs_lookup_cleanup: |
Lines 375-388
unionfs_create(struct vop_create_args *ap)
Link Here
|
375 |
if (error != 0) |
356 |
if (error != 0) |
376 |
goto unionfs_create_abort; |
357 |
goto unionfs_create_abort; |
377 |
|
358 |
|
378 |
if (vp->v_type == VSOCK) |
359 |
VOP_UNLOCK(vp); |
379 |
*(ap->a_vpp) = vp; |
360 |
error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP, |
380 |
else { |
361 |
ap->a_dvp, ap->a_vpp, cnp); |
381 |
VOP_UNLOCK(vp); |
362 |
vrele(vp); |
382 |
error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP, |
|
|
383 |
ap->a_dvp, ap->a_vpp, cnp); |
384 |
vrele(vp); |
385 |
} |
386 |
} |
363 |
} |
387 |
|
364 |
|
388 |
unionfs_create_abort: |
365 |
unionfs_create_abort: |
Lines 449-462
unionfs_mknod(struct vop_mknod_args *ap)
Link Here
|
449 |
if (error != 0) |
426 |
if (error != 0) |
450 |
goto unionfs_mknod_abort; |
427 |
goto unionfs_mknod_abort; |
451 |
|
428 |
|
452 |
if (vp->v_type == VSOCK) |
429 |
VOP_UNLOCK(vp); |
453 |
*(ap->a_vpp) = vp; |
430 |
error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP, |
454 |
else { |
431 |
ap->a_dvp, ap->a_vpp, cnp); |
455 |
VOP_UNLOCK(vp); |
432 |
vrele(vp); |
456 |
error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP, |
|
|
457 |
ap->a_dvp, ap->a_vpp, cnp); |
458 |
vrele(vp); |
459 |
} |
460 |
} |
433 |
} |
461 |
|
434 |
|
462 |
unionfs_mknod_abort: |
435 |
unionfs_mknod_abort: |
Lines 1024-1032
unionfs_remove(struct vop_remove_args *ap)
Link Here
|
1024 |
struct vnode *udvp; |
997 |
struct vnode *udvp; |
1025 |
struct vnode *uvp; |
998 |
struct vnode *uvp; |
1026 |
struct vnode *lvp; |
999 |
struct vnode *lvp; |
1027 |
struct vnode *vp; |
|
|
1028 |
struct componentname *cnp; |
1000 |
struct componentname *cnp; |
1029 |
struct componentname cn; |
|
|
1030 |
struct thread *td; |
1001 |
struct thread *td; |
1031 |
int error; |
1002 |
int error; |
1032 |
int pathlen; |
1003 |
int pathlen; |
Lines 1041-1094
unionfs_remove(struct vop_remove_args *ap)
Link Here
|
1041 |
cnp = ap->a_cnp; |
1012 |
cnp = ap->a_cnp; |
1042 |
td = curthread; |
1013 |
td = curthread; |
1043 |
|
1014 |
|
1044 |
if (ap->a_vp->v_op != &unionfs_vnodeops) { |
1015 |
ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount); |
1045 |
if (ap->a_vp->v_type != VSOCK) |
1016 |
unp = VTOUNIONFS(ap->a_vp); |
1046 |
return (EINVAL); |
1017 |
uvp = unp->un_uppervp; |
1047 |
ump = NULL; |
1018 |
lvp = unp->un_lowervp; |
1048 |
vp = uvp = lvp = NULLVP; |
1019 |
path = unp->un_path; |
1049 |
/* search vnode */ |
1020 |
pathlen = unp->un_pathlen; |
1050 |
VOP_UNLOCK(ap->a_vp); |
|
|
1051 |
error = unionfs_relookup(udvp, &vp, cnp, &cn, td, |
1052 |
cnp->cn_nameptr, cnp->cn_namelen, DELETE); |
1053 |
if (error != 0 && error != ENOENT) { |
1054 |
vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); |
1055 |
return (error); |
1056 |
} |
1057 |
|
1058 |
if (error == 0 && vp == ap->a_vp) { |
1059 |
/* target vnode in upper */ |
1060 |
uvp = vp; |
1061 |
vrele(vp); |
1062 |
} else { |
1063 |
/* target vnode in lower */ |
1064 |
if (vp != NULLVP) { |
1065 |
if (udvp == vp) |
1066 |
vrele(vp); |
1067 |
else |
1068 |
vput(vp); |
1069 |
} |
1070 |
vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); |
1071 |
lvp = ap->a_vp; |
1072 |
} |
1073 |
path = cnp->cn_nameptr; |
1074 |
pathlen = cnp->cn_namelen; |
1075 |
} else { |
1076 |
ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount); |
1077 |
unp = VTOUNIONFS(ap->a_vp); |
1078 |
uvp = unp->un_uppervp; |
1079 |
lvp = unp->un_lowervp; |
1080 |
path = unp->un_path; |
1081 |
pathlen = unp->un_pathlen; |
1082 |
} |
1083 |
|
1021 |
|
1084 |
if (udvp == NULLVP) |
1022 |
if (udvp == NULLVP) |
1085 |
return (EROFS); |
1023 |
return (EROFS); |
1086 |
|
1024 |
|
1087 |
if (uvp != NULLVP) { |
1025 |
if (uvp != NULLVP) { |
1088 |
/* |
|
|
1089 |
* XXX: if the vnode type is VSOCK, it will create whiteout |
1090 |
* after remove. |
1091 |
*/ |
1092 |
if (ump == NULL || ump->um_whitemode == UNIONFS_WHITE_ALWAYS || |
1026 |
if (ump == NULL || ump->um_whitemode == UNIONFS_WHITE_ALWAYS || |
1093 |
lvp != NULLVP) |
1027 |
lvp != NULLVP) |
1094 |
cnp->cn_flags |= DOWHITEOUT; |
1028 |
cnp->cn_flags |= DOWHITEOUT; |
Lines 2777-2782
unionfs_unset_text(struct vop_unset_text_args *ap)
Link Here
|
2777 |
return (0); |
2711 |
return (0); |
2778 |
} |
2712 |
} |
2779 |
|
2713 |
|
|
|
2714 |
static int |
2715 |
unionfs_unp_bind(struct vop_unp_bind_args *ap) |
2716 |
{ |
2717 |
struct vnode *tvp; |
2718 |
struct unionfs_node *unp; |
2719 |
|
2720 |
ASSERT_VOP_LOCKED(ap->a_vp, __func__); |
2721 |
unp = VTOUNIONFS(ap->a_vp); |
2722 |
tvp = unp->un_uppervp != NULL ? unp->un_uppervp : unp->un_lowervp; |
2723 |
VOP_UNP_BIND(tvp, ap->a_unpcb); |
2724 |
return (0); |
2725 |
} |
2726 |
|
2727 |
static int |
2728 |
unionfs_unp_connect(struct vop_unp_connect_args *ap) |
2729 |
{ |
2730 |
struct vnode *tvp; |
2731 |
struct unionfs_node *unp; |
2732 |
|
2733 |
ASSERT_VOP_LOCKED(ap->a_vp, __func__); |
2734 |
unp = VTOUNIONFS(ap->a_vp); |
2735 |
tvp = unp->un_uppervp != NULL ? unp->un_uppervp : unp->un_lowervp; |
2736 |
VOP_UNP_CONNECT(tvp, ap->a_unpcb); |
2737 |
return (0); |
2738 |
} |
2739 |
|
2740 |
static int |
2741 |
unionfs_unp_detach(struct vop_unp_detach_args *ap) |
2742 |
{ |
2743 |
struct vnode *tvp; |
2744 |
struct unionfs_node *unp; |
2745 |
|
2746 |
tvp = NULL; |
2747 |
/* |
2748 |
* VOP_UNP_DETACH() is not guaranteed to be called with the unionfs |
2749 |
* vnode locked, so we take the interlock to prevent a concurrent |
2750 |
* unmount from freeing the unionfs private data. |
2751 |
*/ |
2752 |
VI_LOCK(ap->a_vp); |
2753 |
unp = VTOUNIONFS(ap->a_vp); |
2754 |
if (unp != NULL) { |
2755 |
tvp = unp->un_uppervp != NULL ? |
2756 |
unp->un_uppervp : unp->un_lowervp; |
2757 |
/* |
2758 |
* Hold the target vnode to prevent a concurrent unionfs |
2759 |
* unmount from causing it to be recycled once the interlock |
2760 |
* is dropped. |
2761 |
*/ |
2762 |
vholdnz(tvp); |
2763 |
} |
2764 |
VI_UNLOCK(ap->a_vp); |
2765 |
if (tvp != NULL) { |
2766 |
VOP_UNP_DETACH(tvp); |
2767 |
vdrop(tvp); |
2768 |
} |
2769 |
return (0); |
2770 |
} |
2771 |
|
2780 |
struct vop_vector unionfs_vnodeops = { |
2772 |
struct vop_vector unionfs_vnodeops = { |
2781 |
.vop_default = &default_vnodeops, |
2773 |
.vop_default = &default_vnodeops, |
2782 |
|
2774 |
|
Lines 2830-2834
struct vop_vector unionfs_vnodeops = {
Link Here
|
2830 |
.vop_vput_pair = unionfs_vput_pair, |
2822 |
.vop_vput_pair = unionfs_vput_pair, |
2831 |
.vop_set_text = unionfs_set_text, |
2823 |
.vop_set_text = unionfs_set_text, |
2832 |
.vop_unset_text = unionfs_unset_text, |
2824 |
.vop_unset_text = unionfs_unset_text, |
|
|
2825 |
.vop_unp_bind = unionfs_unp_bind, |
2826 |
.vop_unp_connect = unionfs_unp_connect, |
2827 |
.vop_unp_detach = unionfs_unp_detach, |
2833 |
}; |
2828 |
}; |
2834 |
VFS_VOP_VECTOR_REGISTER(unionfs_vnodeops); |
2829 |
VFS_VOP_VECTOR_REGISTER(unionfs_vnodeops); |