|
Lines 124-139
Link Here
|
| 124 |
} |
124 |
} |
| 125 |
|
125 |
|
| 126 |
int |
126 |
int |
| 127 |
devfs_allocv(struct devfs_dirent *de, struct mount *mp, struct vnode **vpp, struct thread *td) |
127 |
devfs_allocv(struct devfs_dirent *de, struct mount *mp, struct vnode **vpp, |
|
|
128 |
int *dm_unlock, struct thread *td) |
| 128 |
{ |
129 |
{ |
| 129 |
int error; |
130 |
int error; |
| 130 |
struct vnode *vp; |
131 |
struct vnode *vp; |
| 131 |
struct cdev *dev; |
132 |
struct cdev *dev; |
|
|
133 |
struct devfs_mount *dmp; |
| 132 |
|
134 |
|
| 133 |
KASSERT(td == curthread, ("devfs_allocv: td != curthread")); |
135 |
KASSERT(td == curthread, ("devfs_allocv: td != curthread")); |
|
|
136 |
dmp = VFSTODEVFS(mp); |
| 134 |
loop: |
137 |
loop: |
| 135 |
vp = de->de_vnode; |
138 |
vp = de->de_vnode; |
| 136 |
if (vp != NULL) { |
139 |
if (vp != NULL) { |
|
|
140 |
if (*dm_unlock) { |
| 141 |
sx_xunlock(&dmp->dm_lock); |
| 142 |
*dm_unlock = 0; |
| 143 |
} |
| 137 |
if (vget(vp, LK_EXCLUSIVE, td)) |
144 |
if (vget(vp, LK_EXCLUSIVE, td)) |
| 138 |
goto loop; |
145 |
goto loop; |
| 139 |
*vpp = vp; |
146 |
*vpp = vp; |
|
Lines 173-178
Link Here
|
| 173 |
} |
180 |
} |
| 174 |
vp->v_data = de; |
181 |
vp->v_data = de; |
| 175 |
de->de_vnode = vp; |
182 |
de->de_vnode = vp; |
|
|
183 |
if (*dm_unlock) { |
| 184 |
sx_xunlock(&dmp->dm_lock); |
| 185 |
*dm_unlock = 0; |
| 186 |
} |
| 176 |
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); |
187 |
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); |
| 177 |
#ifdef MAC |
188 |
#ifdef MAC |
| 178 |
mac_associate_vnode_devfs(mp, de, vp); |
189 |
mac_associate_vnode_devfs(mp, de, vp); |
|
Lines 453-459
Link Here
|
| 453 |
} |
464 |
} |
| 454 |
|
465 |
|
| 455 |
static int |
466 |
static int |
| 456 |
devfs_lookupx(struct vop_lookup_args *ap) |
467 |
devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock) |
| 457 |
{ |
468 |
{ |
| 458 |
struct componentname *cnp; |
469 |
struct componentname *cnp; |
| 459 |
struct vnode *dvp, **vpp; |
470 |
struct vnode *dvp, **vpp; |
|
Lines 504-510
Link Here
|
| 504 |
de = TAILQ_FIRST(&dd->de_dlist); /* "." */ |
515 |
de = TAILQ_FIRST(&dd->de_dlist); /* "." */ |
| 505 |
de = TAILQ_NEXT(de, de_list); /* ".." */ |
516 |
de = TAILQ_NEXT(de, de_list); /* ".." */ |
| 506 |
de = de->de_dir; |
517 |
de = de->de_dir; |
| 507 |
error = devfs_allocv(de, dvp->v_mount, vpp, td); |
518 |
error = devfs_allocv(de, dvp->v_mount, vpp, dm_unlock, td); |
| 508 |
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td); |
519 |
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td); |
| 509 |
return (error); |
520 |
return (error); |
| 510 |
} |
521 |
} |
|
Lines 561-567
Link Here
|
| 561 |
return (0); |
572 |
return (0); |
| 562 |
} |
573 |
} |
| 563 |
} |
574 |
} |
| 564 |
error = devfs_allocv(de, dvp->v_mount, vpp, td); |
575 |
error = devfs_allocv(de, dvp->v_mount, vpp, dm_unlock, td); |
| 565 |
return (error); |
576 |
return (error); |
| 566 |
} |
577 |
} |
| 567 |
|
578 |
|
|
Lines 570-580
Link Here
|
| 570 |
{ |
581 |
{ |
| 571 |
int j; |
582 |
int j; |
| 572 |
struct devfs_mount *dmp; |
583 |
struct devfs_mount *dmp; |
|
|
584 |
int dm_unlock; |
| 573 |
|
585 |
|
| 574 |
dmp = VFSTODEVFS(ap->a_dvp->v_mount); |
586 |
dmp = VFSTODEVFS(ap->a_dvp->v_mount); |
|
|
587 |
dm_unlock = 1; |
| 575 |
sx_xlock(&dmp->dm_lock); |
588 |
sx_xlock(&dmp->dm_lock); |
| 576 |
j = devfs_lookupx(ap); |
589 |
j = devfs_lookupx(ap, &dm_unlock); |
| 577 |
sx_xunlock(&dmp->dm_lock); |
590 |
if (dm_unlock == 1) |
|
|
591 |
sx_xunlock(&dmp->dm_lock); |
| 578 |
return (j); |
592 |
return (j); |
| 579 |
} |
593 |
} |
| 580 |
|
594 |
|
|
Lines 586-591
Link Here
|
| 586 |
struct thread *td; |
600 |
struct thread *td; |
| 587 |
struct devfs_dirent *dd, *de; |
601 |
struct devfs_dirent *dd, *de; |
| 588 |
struct devfs_mount *dmp; |
602 |
struct devfs_mount *dmp; |
|
|
603 |
int dm_unlock; |
| 589 |
int error; |
604 |
int error; |
| 590 |
|
605 |
|
| 591 |
/* |
606 |
/* |
|
Lines 597-602
Link Here
|
| 597 |
dvp = ap->a_dvp; |
612 |
dvp = ap->a_dvp; |
| 598 |
dmp = VFSTODEVFS(dvp->v_mount); |
613 |
dmp = VFSTODEVFS(dvp->v_mount); |
| 599 |
sx_xlock(&dmp->dm_lock); |
614 |
sx_xlock(&dmp->dm_lock); |
|
|
615 |
dm_unlock = 1; |
| 600 |
|
616 |
|
| 601 |
cnp = ap->a_cnp; |
617 |
cnp = ap->a_cnp; |
| 602 |
vpp = ap->a_vpp; |
618 |
vpp = ap->a_vpp; |
|
Lines 617-625
Link Here
|
| 617 |
if (de == NULL) |
633 |
if (de == NULL) |
| 618 |
goto notfound; |
634 |
goto notfound; |
| 619 |
de->de_flags &= ~DE_WHITEOUT; |
635 |
de->de_flags &= ~DE_WHITEOUT; |
| 620 |
error = devfs_allocv(de, dvp->v_mount, vpp, td); |
636 |
error = devfs_allocv(de, dvp->v_mount, vpp, &dm_unlock, td); |
| 621 |
notfound: |
637 |
notfound: |
| 622 |
sx_xunlock(&dmp->dm_lock); |
638 |
if (dm_unlock == 1) |
|
|
639 |
sx_xunlock(&dmp->dm_lock); |
| 623 |
return (error); |
640 |
return (error); |
| 624 |
} |
641 |
} |
| 625 |
|
642 |
|
|
Lines 1101-1106
Link Here
|
| 1101 |
struct devfs_dirent *de; |
1118 |
struct devfs_dirent *de; |
| 1102 |
struct devfs_mount *dmp; |
1119 |
struct devfs_mount *dmp; |
| 1103 |
struct thread *td; |
1120 |
struct thread *td; |
|
|
1121 |
int dm_unlock; |
| 1104 |
|
1122 |
|
| 1105 |
td = ap->a_cnp->cn_thread; |
1123 |
td = ap->a_cnp->cn_thread; |
| 1106 |
KASSERT(td == curthread, ("devfs_symlink: td != curthread")); |
1124 |
KASSERT(td == curthread, ("devfs_symlink: td != curthread")); |
|
Lines 1119-1130
Link Here
|
| 1119 |
de->de_symlink = malloc(i, M_DEVFS, M_WAITOK); |
1137 |
de->de_symlink = malloc(i, M_DEVFS, M_WAITOK); |
| 1120 |
bcopy(ap->a_target, de->de_symlink, i); |
1138 |
bcopy(ap->a_target, de->de_symlink, i); |
| 1121 |
sx_xlock(&dmp->dm_lock); |
1139 |
sx_xlock(&dmp->dm_lock); |
|
|
1140 |
dm_unlock = 1; |
| 1122 |
#ifdef MAC |
1141 |
#ifdef MAC |
| 1123 |
mac_create_devfs_symlink(ap->a_cnp->cn_cred, dmp->dm_mount, dd, de); |
1142 |
mac_create_devfs_symlink(ap->a_cnp->cn_cred, dmp->dm_mount, dd, de); |
| 1124 |
#endif |
1143 |
#endif |
| 1125 |
TAILQ_INSERT_TAIL(&dd->de_dlist, de, de_list); |
1144 |
TAILQ_INSERT_TAIL(&dd->de_dlist, de, de_list); |
| 1126 |
devfs_allocv(de, ap->a_dvp->v_mount, ap->a_vpp, td); |
1145 |
devfs_allocv(de, ap->a_dvp->v_mount, ap->a_vpp, &dm_unlock, td); |
| 1127 |
sx_xunlock(&dmp->dm_lock); |
1146 |
if (dm_unlock == 1) |
|
|
1147 |
sx_xunlock(&dmp->dm_lock); |
| 1128 |
return (0); |
1148 |
return (0); |
| 1129 |
} |
1149 |
} |
| 1130 |
|
1150 |
|