o Fixed multi thread access issue reported by Alexander V. Chernikov
(admin@su29.net) fixed: kern/109950 PR: kern/109950 Submitted by: Alexander V. Chernikov (admin@su29.net) Reviewed by: Masanori OZAWA (ozawa@ongs.co.jp) MFC after: 1 week
This commit is contained in:
parent
938161d61a
commit
fe5f08cda3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=178491
@ -66,7 +66,7 @@ struct unionfs_mount {
|
||||
/* unionfs status list */
|
||||
struct unionfs_node_status {
|
||||
LIST_ENTRY(unionfs_node_status) uns_list; /* Status list */
|
||||
lwpid_t uns_tid; /* current thread id */
|
||||
pid_t uns_pid; /* current process id */
|
||||
int uns_node_flag; /* uns flag */
|
||||
int uns_lower_opencnt; /* open count of lower */
|
||||
int uns_upper_opencnt; /* open count of upper */
|
||||
@ -109,7 +109,7 @@ int unionfs_uninit(struct vfsconf *vfsp);
|
||||
int unionfs_nodeget(struct mount *mp, struct vnode *uppervp, struct vnode *lowervp, struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, struct thread *td);
|
||||
void unionfs_noderem(struct vnode *vp, struct thread *td);
|
||||
void unionfs_get_node_status(struct unionfs_node *unp, struct thread *td, struct unionfs_node_status **unspp);
|
||||
void unionfs_tryrem_node_status(struct unionfs_node *unp, struct thread *td, struct unionfs_node_status *unsp);
|
||||
void unionfs_tryrem_node_status(struct unionfs_node *unp, struct unionfs_node_status *unsp);
|
||||
|
||||
int unionfs_check_rmdir(struct vnode *vp, struct ucred *cred, struct thread *td);
|
||||
int unionfs_copyfile(struct unionfs_node *unp, int docopy, struct ucred *cred, struct thread *td);
|
||||
|
@ -415,12 +415,13 @@ unionfs_get_node_status(struct unionfs_node *unp, struct thread *td,
|
||||
struct unionfs_node_status **unspp)
|
||||
{
|
||||
struct unionfs_node_status *unsp;
|
||||
pid_t pid = td->td_proc->p_pid;
|
||||
|
||||
KASSERT(NULL != unspp, ("null pointer"));
|
||||
ASSERT_VOP_ELOCKED(UNIONFSTOV(unp), "unionfs_get_node_status");
|
||||
|
||||
LIST_FOREACH(unsp, &(unp->un_unshead), uns_list) {
|
||||
if (unsp->uns_tid == td->td_tid) {
|
||||
if (unsp->uns_pid == pid) {
|
||||
*unspp = unsp;
|
||||
return;
|
||||
}
|
||||
@ -430,7 +431,7 @@ unionfs_get_node_status(struct unionfs_node *unp, struct thread *td,
|
||||
MALLOC(unsp, struct unionfs_node_status *,
|
||||
sizeof(struct unionfs_node_status), M_TEMP, M_WAITOK | M_ZERO);
|
||||
|
||||
unsp->uns_tid = td->td_tid;
|
||||
unsp->uns_pid = pid;
|
||||
LIST_INSERT_HEAD(&(unp->un_unshead), unsp, uns_list);
|
||||
|
||||
*unspp = unsp;
|
||||
@ -441,7 +442,7 @@ unionfs_get_node_status(struct unionfs_node *unp, struct thread *td,
|
||||
* You need exclusive lock this vnode.
|
||||
*/
|
||||
void
|
||||
unionfs_tryrem_node_status(struct unionfs_node *unp, struct thread *td,
|
||||
unionfs_tryrem_node_status(struct unionfs_node *unp,
|
||||
struct unionfs_node_status *unsp)
|
||||
{
|
||||
KASSERT(NULL != unsp, ("null pointer"));
|
||||
|
@ -503,7 +503,7 @@ unionfs_open(struct vop_open_args *ap)
|
||||
|
||||
unionfs_open_abort:
|
||||
if (error != 0)
|
||||
unionfs_tryrem_node_status(unp, td, unsp);
|
||||
unionfs_tryrem_node_status(unp, unsp);
|
||||
|
||||
UNIONFS_INTERNAL_DEBUG("unionfs_open: leave (%d)\n", error);
|
||||
|
||||
@ -569,7 +569,7 @@ unionfs_close(struct vop_close_args *ap)
|
||||
unsp->uns_lower_opencnt--;
|
||||
|
||||
unionfs_close_abort:
|
||||
unionfs_tryrem_node_status(unp, td, unsp);
|
||||
unionfs_tryrem_node_status(unp, unsp);
|
||||
|
||||
if (locked != 0)
|
||||
VOP_UNLOCK(ap->a_vp, 0);
|
||||
@ -877,7 +877,7 @@ unionfs_ioctl(struct vop_ioctl_args *ap)
|
||||
unp = VTOUNIONFS(ap->a_vp);
|
||||
unionfs_get_node_status(unp, ap->a_td, &unsp);
|
||||
ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp);
|
||||
unionfs_tryrem_node_status(unp, ap->a_td, unsp);
|
||||
unionfs_tryrem_node_status(unp, unsp);
|
||||
VOP_UNLOCK(ap->a_vp, 0);
|
||||
|
||||
if (ovp == NULLVP)
|
||||
@ -902,7 +902,7 @@ unionfs_poll(struct vop_poll_args *ap)
|
||||
unp = VTOUNIONFS(ap->a_vp);
|
||||
unionfs_get_node_status(unp, ap->a_td, &unsp);
|
||||
ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp);
|
||||
unionfs_tryrem_node_status(unp, ap->a_td, unsp);
|
||||
unionfs_tryrem_node_status(unp, unsp);
|
||||
VOP_UNLOCK(ap->a_vp, 0);
|
||||
|
||||
if (ovp == NULLVP)
|
||||
@ -921,7 +921,7 @@ unionfs_fsync(struct vop_fsync_args *ap)
|
||||
unp = VTOUNIONFS(ap->a_vp);
|
||||
unionfs_get_node_status(unp, ap->a_td, &unsp);
|
||||
ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp);
|
||||
unionfs_tryrem_node_status(unp, ap->a_td, unsp);
|
||||
unionfs_tryrem_node_status(unp, unsp);
|
||||
|
||||
if (ovp == NULLVP)
|
||||
return (EBADF);
|
||||
@ -1426,7 +1426,7 @@ unionfs_readdir(struct vop_readdir_args *ap)
|
||||
unionfs_get_node_status(unp, td, &unsp);
|
||||
if ((uvp != NULLVP && unsp->uns_upper_opencnt <= 0) ||
|
||||
(lvp != NULLVP && unsp->uns_lower_opencnt <= 0)) {
|
||||
unionfs_tryrem_node_status(unp, td, unsp);
|
||||
unionfs_tryrem_node_status(unp, unsp);
|
||||
error = EBADF;
|
||||
}
|
||||
if (locked == 1)
|
||||
@ -1892,7 +1892,7 @@ unionfs_advlock(struct vop_advlock_args *ap)
|
||||
VOP_CLOSE(unp->un_lowervp, unsp->uns_lower_openmode, td->td_ucred, td);
|
||||
unsp->uns_lower_opencnt--;
|
||||
} else
|
||||
unionfs_tryrem_node_status(unp, td, unsp);
|
||||
unionfs_tryrem_node_status(unp, unsp);
|
||||
}
|
||||
|
||||
VOP_UNLOCK(vp, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user