From fe5f08cda361ea9a13766405ca7e54cdc8764f49 Mon Sep 17 00:00:00 2001 From: Daichi GOTO Date: Fri, 25 Apr 2008 11:37:20 +0000 Subject: [PATCH] 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 --- sys/fs/unionfs/union.h | 4 ++-- sys/fs/unionfs/union_subr.c | 7 ++++--- sys/fs/unionfs/union_vnops.c | 14 +++++++------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/sys/fs/unionfs/union.h b/sys/fs/unionfs/union.h index 67fbd777ff9d..8cb6f03e64ac 100644 --- a/sys/fs/unionfs/union.h +++ b/sys/fs/unionfs/union.h @@ -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); diff --git a/sys/fs/unionfs/union_subr.c b/sys/fs/unionfs/union_subr.c index 66ac7678dba9..b3b58110f32b 100644 --- a/sys/fs/unionfs/union_subr.c +++ b/sys/fs/unionfs/union_subr.c @@ -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")); diff --git a/sys/fs/unionfs/union_vnops.c b/sys/fs/unionfs/union_vnops.c index 73495f58b74e..27d56f1a11b0 100644 --- a/sys/fs/unionfs/union_vnops.c +++ b/sys/fs/unionfs/union_vnops.c @@ -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);