Change the way unmounting happens to guarantee that the
client programs are allowed to finish up (coda_call is forced to complete) and release their locks. Thus there is a reasonable chance that the vflush implicit in the unmount will not get hung on held locks.
This commit is contained in:
parent
ff30297a7a
commit
dc7a9e560a
@ -27,7 +27,7 @@
|
||||
* Mellon the rights to redistribute these changes without encumbrance.
|
||||
*
|
||||
* @(#) src/sys/coda/coda_psdev.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
|
||||
* $Id: coda_psdev.c,v 1.6 1998/09/28 20:52:58 rvb Exp $
|
||||
* $Id: coda_psdev.c,v 1.7 1998/09/29 20:19:45 rvb Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -53,6 +53,11 @@
|
||||
/*
|
||||
* HISTORY
|
||||
* $Log: coda_psdev.c,v $
|
||||
* Revision 1.7 1998/09/29 20:19:45 rvb
|
||||
* Fixes for lkm:
|
||||
* 1. use VFS_LKM vs ACTUALLY_LKM_NOT_KERNEL
|
||||
* 2. don't pass -DCODA to lkm build
|
||||
*
|
||||
* Revision 1.6 1998/09/28 20:52:58 rvb
|
||||
* Cleanup and fix THE bug
|
||||
*
|
||||
@ -195,6 +200,13 @@ extern int coda_nc_initialized; /* Set if cache has been initialized */
|
||||
#define CTL_C
|
||||
|
||||
int coda_psdev_print_entry = 0;
|
||||
static
|
||||
int outstanding_upcalls = 0;
|
||||
int coda_call_sleep = PZERO - 1;
|
||||
#ifdef CTL_C
|
||||
int coda_pcatch = PCATCH;
|
||||
#else
|
||||
#endif
|
||||
|
||||
#define ENTRY if(coda_psdev_print_entry) myprintf(("Entered %s\n",__FUNCTION__))
|
||||
|
||||
@ -283,16 +295,17 @@ vc_nb_close (dev, flag, mode, p)
|
||||
* Put this before WAKEUPs to avoid queuing new messages between
|
||||
* the WAKEUP and the unmount (which can happen if we're unlucky)
|
||||
*/
|
||||
if (mi->mi_rootvp) {
|
||||
/* Let unmount know this is for real */
|
||||
VTOC(mi->mi_rootvp)->c_flags |= C_UNMOUNTING;
|
||||
coda_unmounting(mi->mi_vfsp);
|
||||
err = dounmount(mi->mi_vfsp, flag, p);
|
||||
if (err)
|
||||
myprintf(("Error %d unmounting vfs in vcclose(%d)\n",
|
||||
err, minor(dev)));
|
||||
if (!mi->mi_rootvp) {
|
||||
/* just a simple open/close w no mount */
|
||||
MARK_VC_CLOSED(vcp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Let unmount know this is for real */
|
||||
VTOC(mi->mi_rootvp)->c_flags |= C_UNMOUNTING;
|
||||
coda_unmounting(mi->mi_vfsp);
|
||||
|
||||
outstanding_upcalls = 0;
|
||||
/* Wakeup clients so they can return. */
|
||||
for (vmp = (struct vmsg *)GETNEXT(vcp->vc_requests);
|
||||
!EOQ(vmp, vcp->vc_requests);
|
||||
@ -305,18 +318,34 @@ vc_nb_close (dev, flag, mode, p)
|
||||
CODA_FREE((caddr_t)vmp, (u_int)sizeof(struct vmsg));
|
||||
continue;
|
||||
}
|
||||
|
||||
outstanding_upcalls++;
|
||||
wakeup(&vmp->vm_sleep);
|
||||
}
|
||||
|
||||
|
||||
for (vmp = (struct vmsg *)GETNEXT(vcp->vc_replys);
|
||||
!EOQ(vmp, vcp->vc_replys);
|
||||
vmp = (struct vmsg *)GETNEXT(vmp->vm_chain))
|
||||
{
|
||||
outstanding_upcalls++;
|
||||
wakeup(&vmp->vm_sleep);
|
||||
}
|
||||
|
||||
|
||||
MARK_VC_CLOSED(vcp);
|
||||
|
||||
if (outstanding_upcalls) {
|
||||
#ifdef CODA_VERBOSE
|
||||
printf("presleep: outstanding_upcalls = %d\n", outstanding_upcalls);
|
||||
(void) tsleep(&outstanding_upcalls, coda_call_sleep, "coda_umount", 0);
|
||||
printf("postsleep: outstanding_upcalls = %d\n", outstanding_upcalls);
|
||||
#else
|
||||
(void) tsleep(&outstanding_upcalls, coda_call_sleep, "coda_umount", 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
err = dounmount(mi->mi_vfsp, flag, p);
|
||||
if (err)
|
||||
myprintf(("Error %d unmounting vfs in vcclose(%d)\n",
|
||||
err, minor(dev)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -554,12 +583,6 @@ struct coda_clstat coda_clstat;
|
||||
* (e.g. kill -9).
|
||||
*/
|
||||
|
||||
int coda_call_sleep = PZERO - 1;
|
||||
#ifdef CTL_C
|
||||
int coda_pcatch = PCATCH;
|
||||
#else
|
||||
#endif
|
||||
|
||||
int
|
||||
coda_call(mntinfo, inSize, outSize, buffer)
|
||||
struct coda_mntinfo *mntinfo; int inSize; int *outSize; caddr_t buffer;
|
||||
@ -636,6 +659,11 @@ coda_call(mntinfo, inSize, outSize, buffer)
|
||||
p->p_sigmask |= p->p_siglist;
|
||||
#ifdef CODA_VERBOSE
|
||||
printf("coda_call: tsleep returns %d SIGIO, cnt %d\n", error, i);
|
||||
#endif
|
||||
} else if (p->p_siglist == sigmask(SIGALRM)) {
|
||||
p->p_sigmask |= p->p_siglist;
|
||||
#ifdef CODA_VERBOSE
|
||||
printf("coda_call: tsleep returns %d SIGALRM, cnt %d\n", error, i);
|
||||
#endif
|
||||
} else {
|
||||
printf("coda_call: tsleep returns %d, cnt %d\n", error, i);
|
||||
@ -650,7 +678,7 @@ coda_call(mntinfo, inSize, outSize, buffer)
|
||||
p->p_siglist & ~p->p_sigmask);
|
||||
#endif
|
||||
}
|
||||
} while (error && i++ < 128);
|
||||
} while (error && i++ < 128 && VC_OPEN(vcp));
|
||||
p->p_sigmask = psig_omask;
|
||||
#else
|
||||
(void) tsleep(&vmp->vm_sleep, coda_call_sleep, "coda_call", 0);
|
||||
@ -724,6 +752,9 @@ coda_call(mntinfo, inSize, outSize, buffer)
|
||||
|
||||
CODA_FREE(vmp, sizeof(struct vmsg));
|
||||
|
||||
if (outstanding_upcalls > 0 && (--outstanding_upcalls == 0))
|
||||
wakeup(&outstanding_upcalls);
|
||||
|
||||
if (!error)
|
||||
error = ((struct coda_out_hdr *)buffer)->result;
|
||||
return(error);
|
||||
|
@ -27,7 +27,7 @@
|
||||
* Mellon the rights to redistribute these changes without encumbrance.
|
||||
*
|
||||
* @(#) src/sys/coda/coda_vnops.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
|
||||
* $Id: coda_vnops.c,v 1.6 1998/09/28 20:52:58 rvb Exp $
|
||||
* $Id: coda_vnops.c,v 1.7 1998/10/25 17:44:41 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -48,6 +48,10 @@
|
||||
/*
|
||||
* HISTORY
|
||||
* $Log: coda_vnops.c,v $
|
||||
* Revision 1.7 1998/10/25 17:44:41 phk
|
||||
* Nitpicking and dusting performed on a train. Removes trivial warnings
|
||||
* about unused variables, labels and other lint.
|
||||
*
|
||||
* Revision 1.6 1998/09/28 20:52:58 rvb
|
||||
* Cleanup and fix THE bug
|
||||
*
|
||||
@ -527,7 +531,12 @@ coda_close(v)
|
||||
printf("coda_close: destroying container ref %d, ufs vp %p of vp %p/cp %p\n",
|
||||
vp->v_usecount, cp->c_ovp, vp, cp);
|
||||
#endif
|
||||
#ifdef hmm
|
||||
vgone(cp->c_ovp);
|
||||
#else
|
||||
VOP_CLOSE(cp->c_ovp, flag, cred, p); /* Do errors matter here? */
|
||||
vrele(cp->c_ovp);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef CODA_VERBOSE
|
||||
printf("coda_close: NO container vp %p/cp %p\n", vp, cp);
|
||||
|
@ -27,7 +27,7 @@
|
||||
* Mellon the rights to redistribute these changes without encumbrance.
|
||||
*
|
||||
* @(#) src/sys/coda/coda_psdev.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
|
||||
* $Id: coda_psdev.c,v 1.6 1998/09/28 20:52:58 rvb Exp $
|
||||
* $Id: coda_psdev.c,v 1.7 1998/09/29 20:19:45 rvb Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -53,6 +53,11 @@
|
||||
/*
|
||||
* HISTORY
|
||||
* $Log: coda_psdev.c,v $
|
||||
* Revision 1.7 1998/09/29 20:19:45 rvb
|
||||
* Fixes for lkm:
|
||||
* 1. use VFS_LKM vs ACTUALLY_LKM_NOT_KERNEL
|
||||
* 2. don't pass -DCODA to lkm build
|
||||
*
|
||||
* Revision 1.6 1998/09/28 20:52:58 rvb
|
||||
* Cleanup and fix THE bug
|
||||
*
|
||||
@ -195,6 +200,13 @@ extern int coda_nc_initialized; /* Set if cache has been initialized */
|
||||
#define CTL_C
|
||||
|
||||
int coda_psdev_print_entry = 0;
|
||||
static
|
||||
int outstanding_upcalls = 0;
|
||||
int coda_call_sleep = PZERO - 1;
|
||||
#ifdef CTL_C
|
||||
int coda_pcatch = PCATCH;
|
||||
#else
|
||||
#endif
|
||||
|
||||
#define ENTRY if(coda_psdev_print_entry) myprintf(("Entered %s\n",__FUNCTION__))
|
||||
|
||||
@ -283,16 +295,17 @@ vc_nb_close (dev, flag, mode, p)
|
||||
* Put this before WAKEUPs to avoid queuing new messages between
|
||||
* the WAKEUP and the unmount (which can happen if we're unlucky)
|
||||
*/
|
||||
if (mi->mi_rootvp) {
|
||||
/* Let unmount know this is for real */
|
||||
VTOC(mi->mi_rootvp)->c_flags |= C_UNMOUNTING;
|
||||
coda_unmounting(mi->mi_vfsp);
|
||||
err = dounmount(mi->mi_vfsp, flag, p);
|
||||
if (err)
|
||||
myprintf(("Error %d unmounting vfs in vcclose(%d)\n",
|
||||
err, minor(dev)));
|
||||
if (!mi->mi_rootvp) {
|
||||
/* just a simple open/close w no mount */
|
||||
MARK_VC_CLOSED(vcp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Let unmount know this is for real */
|
||||
VTOC(mi->mi_rootvp)->c_flags |= C_UNMOUNTING;
|
||||
coda_unmounting(mi->mi_vfsp);
|
||||
|
||||
outstanding_upcalls = 0;
|
||||
/* Wakeup clients so they can return. */
|
||||
for (vmp = (struct vmsg *)GETNEXT(vcp->vc_requests);
|
||||
!EOQ(vmp, vcp->vc_requests);
|
||||
@ -305,18 +318,34 @@ vc_nb_close (dev, flag, mode, p)
|
||||
CODA_FREE((caddr_t)vmp, (u_int)sizeof(struct vmsg));
|
||||
continue;
|
||||
}
|
||||
|
||||
outstanding_upcalls++;
|
||||
wakeup(&vmp->vm_sleep);
|
||||
}
|
||||
|
||||
|
||||
for (vmp = (struct vmsg *)GETNEXT(vcp->vc_replys);
|
||||
!EOQ(vmp, vcp->vc_replys);
|
||||
vmp = (struct vmsg *)GETNEXT(vmp->vm_chain))
|
||||
{
|
||||
outstanding_upcalls++;
|
||||
wakeup(&vmp->vm_sleep);
|
||||
}
|
||||
|
||||
|
||||
MARK_VC_CLOSED(vcp);
|
||||
|
||||
if (outstanding_upcalls) {
|
||||
#ifdef CODA_VERBOSE
|
||||
printf("presleep: outstanding_upcalls = %d\n", outstanding_upcalls);
|
||||
(void) tsleep(&outstanding_upcalls, coda_call_sleep, "coda_umount", 0);
|
||||
printf("postsleep: outstanding_upcalls = %d\n", outstanding_upcalls);
|
||||
#else
|
||||
(void) tsleep(&outstanding_upcalls, coda_call_sleep, "coda_umount", 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
err = dounmount(mi->mi_vfsp, flag, p);
|
||||
if (err)
|
||||
myprintf(("Error %d unmounting vfs in vcclose(%d)\n",
|
||||
err, minor(dev)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -554,12 +583,6 @@ struct coda_clstat coda_clstat;
|
||||
* (e.g. kill -9).
|
||||
*/
|
||||
|
||||
int coda_call_sleep = PZERO - 1;
|
||||
#ifdef CTL_C
|
||||
int coda_pcatch = PCATCH;
|
||||
#else
|
||||
#endif
|
||||
|
||||
int
|
||||
coda_call(mntinfo, inSize, outSize, buffer)
|
||||
struct coda_mntinfo *mntinfo; int inSize; int *outSize; caddr_t buffer;
|
||||
@ -636,6 +659,11 @@ coda_call(mntinfo, inSize, outSize, buffer)
|
||||
p->p_sigmask |= p->p_siglist;
|
||||
#ifdef CODA_VERBOSE
|
||||
printf("coda_call: tsleep returns %d SIGIO, cnt %d\n", error, i);
|
||||
#endif
|
||||
} else if (p->p_siglist == sigmask(SIGALRM)) {
|
||||
p->p_sigmask |= p->p_siglist;
|
||||
#ifdef CODA_VERBOSE
|
||||
printf("coda_call: tsleep returns %d SIGALRM, cnt %d\n", error, i);
|
||||
#endif
|
||||
} else {
|
||||
printf("coda_call: tsleep returns %d, cnt %d\n", error, i);
|
||||
@ -650,7 +678,7 @@ coda_call(mntinfo, inSize, outSize, buffer)
|
||||
p->p_siglist & ~p->p_sigmask);
|
||||
#endif
|
||||
}
|
||||
} while (error && i++ < 128);
|
||||
} while (error && i++ < 128 && VC_OPEN(vcp));
|
||||
p->p_sigmask = psig_omask;
|
||||
#else
|
||||
(void) tsleep(&vmp->vm_sleep, coda_call_sleep, "coda_call", 0);
|
||||
@ -724,6 +752,9 @@ coda_call(mntinfo, inSize, outSize, buffer)
|
||||
|
||||
CODA_FREE(vmp, sizeof(struct vmsg));
|
||||
|
||||
if (outstanding_upcalls > 0 && (--outstanding_upcalls == 0))
|
||||
wakeup(&outstanding_upcalls);
|
||||
|
||||
if (!error)
|
||||
error = ((struct coda_out_hdr *)buffer)->result;
|
||||
return(error);
|
||||
|
@ -27,7 +27,7 @@
|
||||
* Mellon the rights to redistribute these changes without encumbrance.
|
||||
*
|
||||
* @(#) src/sys/coda/coda_vnops.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $
|
||||
* $Id: coda_vnops.c,v 1.6 1998/09/28 20:52:58 rvb Exp $
|
||||
* $Id: coda_vnops.c,v 1.7 1998/10/25 17:44:41 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -48,6 +48,10 @@
|
||||
/*
|
||||
* HISTORY
|
||||
* $Log: coda_vnops.c,v $
|
||||
* Revision 1.7 1998/10/25 17:44:41 phk
|
||||
* Nitpicking and dusting performed on a train. Removes trivial warnings
|
||||
* about unused variables, labels and other lint.
|
||||
*
|
||||
* Revision 1.6 1998/09/28 20:52:58 rvb
|
||||
* Cleanup and fix THE bug
|
||||
*
|
||||
@ -527,7 +531,12 @@ coda_close(v)
|
||||
printf("coda_close: destroying container ref %d, ufs vp %p of vp %p/cp %p\n",
|
||||
vp->v_usecount, cp->c_ovp, vp, cp);
|
||||
#endif
|
||||
#ifdef hmm
|
||||
vgone(cp->c_ovp);
|
||||
#else
|
||||
VOP_CLOSE(cp->c_ovp, flag, cred, p); /* Do errors matter here? */
|
||||
vrele(cp->c_ovp);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef CODA_VERBOSE
|
||||
printf("coda_close: NO container vp %p/cp %p\n", vp, cp);
|
||||
|
Loading…
Reference in New Issue
Block a user