diff options
author | rvb <rvb@FreeBSD.org> | 1998-10-28 20:31:13 +0000 |
---|---|---|
committer | rvb <rvb@FreeBSD.org> | 1998-10-28 20:31:13 +0000 |
commit | dc7a9e560ac1e8675641456afa252791270ec714 (patch) | |
tree | 74ce2ec5a5e0975fdab61f5fcf4ca397bfeee3b2 /sys/fs | |
parent | ff30297a7a9c12c0292e418588206a945e4aeae5 (diff) | |
download | FreeBSD-src-dc7a9e560ac1e8675641456afa252791270ec714.zip FreeBSD-src-dc7a9e560ac1e8675641456afa252791270ec714.tar.gz |
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.
Diffstat (limited to 'sys/fs')
-rw-r--r-- | sys/fs/coda/coda_psdev.c | 71 | ||||
-rw-r--r-- | sys/fs/coda/coda_vnops.c | 11 |
2 files changed, 61 insertions, 21 deletions
diff --git a/sys/fs/coda/coda_psdev.c b/sys/fs/coda/coda_psdev.c index 3abbff0..07df46d 100644 --- a/sys/fs/coda/coda_psdev.c +++ b/sys/fs/coda/coda_psdev.c @@ -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; @@ -637,6 +660,11 @@ coda_call(mntinfo, inSize, outSize, buffer) #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); printf("coda_call: siglist = %x, sigmask = %x, mask %x\n", @@ -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); diff --git a/sys/fs/coda/coda_vnops.c b/sys/fs/coda/coda_vnops.c index c3225d0..bcf713d 100644 --- a/sys/fs/coda/coda_vnops.c +++ b/sys/fs/coda/coda_vnops.c @@ -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); |