summaryrefslogtreecommitdiffstats
path: root/sys/coda/coda_psdev.c
diff options
context:
space:
mode:
authorrvb <rvb@FreeBSD.org>1998-10-28 20:31:13 +0000
committerrvb <rvb@FreeBSD.org>1998-10-28 20:31:13 +0000
commitdc7a9e560ac1e8675641456afa252791270ec714 (patch)
tree74ce2ec5a5e0975fdab61f5fcf4ca397bfeee3b2 /sys/coda/coda_psdev.c
parentff30297a7a9c12c0292e418588206a945e4aeae5 (diff)
downloadFreeBSD-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/coda/coda_psdev.c')
-rw-r--r--sys/coda/coda_psdev.c71
1 files changed, 51 insertions, 20 deletions
diff --git a/sys/coda/coda_psdev.c b/sys/coda/coda_psdev.c
index 3abbff0..07df46d 100644
--- a/sys/coda/coda_psdev.c
+++ b/sys/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);
OpenPOWER on IntegriCloud