]> Zhao Yanbai Git Server - minix.git/commitdiff
Reenable backcall detection
authorThomas Veerman <thomas@minix3.org>
Thu, 27 Oct 2011 15:26:08 +0000 (15:26 +0000)
committerThomas Veerman <thomas@minix3.org>
Thu, 27 Oct 2011 15:29:37 +0000 (15:29 +0000)
servers/avfs/comm.c
servers/avfs/dmap.c
servers/avfs/fproc.h
servers/avfs/main.c
servers/avfs/mount.c
servers/avfs/vmnt.h

index 8546622ac17fb03116fcca2d7a0bfc642406da96..b11b06e05cfc560c908f6577672e3d0b88301311 100644 (file)
@@ -62,7 +62,7 @@ PUBLIC void fs_sendmore(struct vmnt *vmp)
        return;
   if (vmp->m_comm.c_cur_reqs >= vmp->m_comm.c_max_reqs)/*No room to send more*/
        return;
-  if (vmp->m_flags & VMNT_BACKCALL)    /* Hold off for now */
+  if (vmp->m_flags & VMNT_CALLBACK)    /* Hold off for now */
        return;
 
   vmp->m_comm.c_req_queue = worker->w_next; /* Remove head */
@@ -88,7 +88,7 @@ PUBLIC int fs_sendrec(endpoint_t fs_e, message *reqmp)
        fp->fp_sendrec = reqmp; /* Where to store request and reply */
 
        /* Find out whether we can send right away or have to enqueue */
-       if (    !(vmp->m_flags & VMNT_BACKCALL) &&
+       if (    !(vmp->m_flags & VMNT_CALLBACK) &&
                vmp->m_comm.c_cur_reqs < vmp->m_comm.c_max_reqs) {
                /* There's still room to send more and no proc is queued */
                r = sendmsg(vmp, fp);
index d73aa1fac9057b7b3e00f388e1080e9b2e88e0fe..687f0c2aa26c12107ff04a8f1f647b2956adb2ef 100644 (file)
@@ -96,7 +96,7 @@ int flags;                    /* device flags */
   dp = &dmap[major];
 
   /* Check if we're supposed to unmap it. */
- if(proc_nr_e == NONE) {
+ if (proc_nr_e == NONE) {
        dp->dmap_opcl = no_dev;
        dp->dmap_io = no_dev_io;
        dp->dmap_driver = NONE;
@@ -106,8 +106,13 @@ int flags;                 /* device flags */
 
   /* Check process number of new driver if it was alive before mapping */
   if (! (flags & DRV_FORCED)) {
+       struct fproc *rfp;
+
        if (isokendpt(proc_nr_e, &slot) != OK)
                return(EINVAL);
+
+       rfp = &fproc[slot];
+       rfp->fp_flags |= FP_SYS_PROC;   /* Process is a driver */
   }
 
   if (label != NULL) {
index 465c8ed64f5afcef84150fc6cd80f4660e5dfe51..43f2012d287d42e6525f952d4b7f5f434e192699 100644 (file)
@@ -58,11 +58,12 @@ EXTERN struct fproc {
 #define FP_SUSP_REOPEN 01      /* Process is suspended until the reopens are
                                 * completed (after the restart of a driver).
                                 */
-#define FP_REVIVED     02      /* Indicates process is being revived */
-#define FP_SESLDR      04      /* Set if process is session leader */
-#define FP_PENDING     010     /* Set if process has pending work */
-#define FP_EXITING     020     /* Set if process is exiting */
-#define FP_PM_PENDING  040     /* Set if process has pending PM request */
+#define FP_REVIVED      0002   /* Indicates process is being revived */
+#define FP_SESLDR       0004   /* Set if process is session leader */
+#define FP_PENDING      0010   /* Set if process has pending work */
+#define FP_EXITING      0020   /* Set if process is exiting */
+#define FP_PM_PENDING   0040   /* Set if process has pending PM request */
+#define FP_SYS_PROC     0100   /* Set if process is a driver or FS */
 
 /* Field values. */
 #define NOT_REVIVING       0xC0FFEEE   /* process is not being revived */
index 135ab38d870fbe1c8511465fdb6b8f6f0dc2e8da..e07f66ef629b3ea58562c544967748c64f9e9cb4 100644 (file)
@@ -77,7 +77,7 @@ PUBLIC int main(void)
   /* SEF local startup. */
   sef_local_startup();
 
-  printf("Started AVFS\n");
+  printf("Started AVFS: %d worker thread(s)\n", NR_WTHREADS);
   verbose = 0;
 
   /* This is the main loop that gets work, processes it, and sends replies. */
@@ -140,12 +140,16 @@ PRIVATE void handle_work(void *(*func)(void *arg))
 {
 /* Handle asynchronous device replies and new system calls. If the originating
  * endpoint is an FS endpoint, take extra care not to get in deadlock. */
struct vmnt *vmp;
 struct vmnt *vmp = NULL;
 
   if ((vmp = find_vmnt(who_e)) != NULL) {
-       /* A back call or dev result from an FS endpoint */
+       /* A call back or dev result from an FS endpoint */
 
-       /* When an FS point has to make a callback in order to mount, force
+       /* Set call back flag. We assume that an FS does only one call back
+        * at a time */
+       vmp->m_flags |= VMNT_CALLBACK;
+
+       /* When an FS point has to make a call back in order to mount, force
         * its device to a "none device" so block reads/writes will be handled
         * by ROOT_FS_E.
         */
@@ -157,6 +161,7 @@ PRIVATE void handle_work(void *(*func)(void *arg))
                if (deadlock_resolving) {
                        /* Already trying to resolve a deadlock, can't
                         * handle more, sorry */
+                       vmp->m_flags &= ~VMNT_CALLBACK;
                        reply(who_e, EAGAIN);
                        return;
                }
@@ -208,6 +213,13 @@ PRIVATE void *do_async_dev_result(void *arg)
                deadlock_resolving = 0;
   }
 
+  if (fp != NULL && (fp->fp_flags & FP_SYS_PROC)) {
+       struct vmnt *vmp;
+
+       if ((vmp = find_vmnt(fp->fp_endpoint)) != NULL)
+               vmp->m_flags &= ~VMNT_CALLBACK;
+  }
+
   thread_cleanup(NULL);
   return(NULL);
 }
@@ -425,6 +437,14 @@ PRIVATE void *do_work(void *arg)
 
   /* Copy the results back to the user and send reply. */
   if (error != SUSPEND) {
+
+       if ((fp->fp_flags & FP_SYS_PROC)) {
+               struct vmnt *vmp;
+
+               if ((vmp = find_vmnt(fp->fp_endpoint)) != NULL)
+                       vmp->m_flags &= ~VMNT_CALLBACK;
+       }
+
        if (deadlock_resolving) {
                if (fp->fp_wtid == dl_worker.w_tid)
                        deadlock_resolving = 0;
index 65699573213345010ddc67edccdc223095dc71d0..362a2d4ec4cd2c3e95c2fdec5f5d93caf47cc4fe 100644 (file)
@@ -167,8 +167,8 @@ int rdonly,
 char mount_label[LABEL_MAX] )
 {
   int rdir, mdir;               /* TRUE iff {root|mount} file is dir */
-  int i, r = OK, found, isroot, mount_root, con_reqs;
-  struct fproc *tfp;
+  int i, r = OK, found, isroot, mount_root, con_reqs, slot;
+  struct fproc *tfp, *rfp;
   struct dmap *dp;
   struct vnode *root_node, *vp = NULL;
   struct vmnt *new_vmp, *parent_vmp;
@@ -249,6 +249,12 @@ char mount_label[LABEL_MAX] )
 
   lock_vnode(root_node, VNODE_OPCL);
 
+  /* Record process as a system process */
+  if (isokendpt(fs_e, &slot) != OK)
+       return(EINVAL);
+  rfp = &fproc[slot];
+  rfp->fp_flags |= FP_SYS_PROC;        /* Process is an FS */
+
   /* Store some essential vmnt data first */
   new_vmp->m_fs_e = fs_e;
   new_vmp->m_dev = dev;
index 510502c0102296444973b40d7e841ee1c143057f..14d00b3ab377e6133831608f337888e49e003566 100644 (file)
@@ -14,7 +14,7 @@ EXTERN struct vmnt {
 
 /* vmnt flags */
 #define VMNT_READONLY          01      /* Device mounted readonly */
-#define VMNT_BACKCALL          02      /* FS did back call */
+#define VMNT_CALLBACK          02      /* FS did back call */
 #define VMNT_MOUNTING          04      /* Device is being mounted */
 #define VMNT_FORCEROOTBSF      010     /* Force usage of none-device */