]> Zhao Yanbai Git Server - minix.git/commitdiff
Make AVFS resilient against failing back calls
authorThomas Veerman <thomas@minix3.org>
Tue, 6 Sep 2011 10:11:18 +0000 (10:11 +0000)
committerThomas Veerman <thomas@minix3.org>
Tue, 6 Sep 2011 10:38:16 +0000 (10:38 +0000)
servers/avfs/comm.c
servers/avfs/main.c
servers/avfs/mount.c
servers/avfs/proto.h
servers/avfs/vnode.c
servers/avfs/worker.c

index b7254463acdb5a701ff3823442a383d727d5d463..06c08e49bf1ad8927a68e73cd2fe6f8e95b5a8a7 100644 (file)
@@ -24,6 +24,7 @@ struct fproc *rfp;
 
   transid = rfp->fp_wtid + VFS_TRANSID;
   rfp->fp_sendrec->m_type = TRNS_ADD_ID(rfp->fp_sendrec->m_type, transid);
+  rfp->fp_task = vmp->m_fs_e;
   if ((r = asynsend3(vmp->m_fs_e, rfp->fp_sendrec, AMF_NOREPLY)) != OK) {
        printf("VFS: sendmsg: error sending message. "
               "FS_e: %d req_nr: %d err: %d\n", vmp->m_fs_e,
index 2e548b80b684235d12853b8a8dc96ca878be07d8..a47ea73c7e672b4172d1d58b57ef828f15a500c5 100644 (file)
@@ -257,6 +257,7 @@ PRIVATE void *do_fs_reply(struct job *job)
   }
 
   *rfp->fp_sendrec = m_in;
+  rfp->fp_task = NONE;
   vmp->m_comm.c_cur_reqs--;    /* We've got our reply, make room for others */
 
   worker_signal(worker_get(rfp->fp_wtid));/* Continue this worker thread */
@@ -342,7 +343,7 @@ PRIVATE void *do_pending_pipe(void *arg)
              fp->fp_buffer, fp->fp_nbytes);
 
   if (r != SUSPEND)  /* Do we have results to report? */
-       reply(who_e, r);
+       (void) reply(who_e, r);
 
   unlock_filp(f);
 
@@ -376,8 +377,10 @@ PUBLIC void *do_dummy(void *arg)
  *===========================================================================*/
 PRIVATE void *do_work(void *arg)
 {
-  int error;
+  int error, i;
   struct job my_job;
+  struct fproc *rfp;
+  struct vmnt *vmp;
 
   my_job = *((struct job *) arg);
   fp = my_job.j_fp;
@@ -422,14 +425,24 @@ PRIVATE void *do_work(void *arg)
   /* Copy the results back to the user and send reply. */
   if (error != SUSPEND) {
        if (deadlock_resolving) {
-               struct vmnt *vmp;
                if ((vmp = find_vmnt(who_e)) != NULL)
                        vmp->m_flags &= ~VMNT_BACKCALL;
 
                if (fp->fp_wtid == dl_worker.w_tid)
                        deadlock_resolving = 0;
        }
-       reply(who_e, error );
+       if (reply(who_e, error) != OK) {
+               if ((vmp = find_vmnt(who_e)) != NULL) {
+                       for (i = 0; i < NR_PROCS; i++) {
+                               rfp = &fproc[i];
+                               if (rfp->fp_task == vmp->m_fs_e) {
+                                       /* We found a process waiting for a
+                                        * reply from non-responsive FS */
+                                       worker_stop(worker_get(rfp->fp_wtid));
+                               }
+                       }
+               }
+       }
   }
 
   thread_cleanup(fp);
@@ -751,7 +764,7 @@ PRIVATE void get_work()
 /*===========================================================================*
  *                             reply                                        *
  *===========================================================================*/
-PUBLIC void reply(whom, result)
+PUBLIC int reply(whom, result)
 int whom;                      /* process to reply to */
 int result;                    /* result of the call (usually OK or error #) */
 {
@@ -762,8 +775,8 @@ int result;                 /* result of the call (usually OK or error #) */
   r = sendnb(whom, &m_out);
   if (r != OK) {
        printf("VFS: couldn't send reply %d to %d: %d\n", result, whom, r);
-       panic("Yikes %d", call_nr);
   }
+  return(r);
 }
 
 /*===========================================================================*
@@ -895,7 +908,8 @@ PRIVATE void service_pm()
 
        break;
     case PM_SETGROUPS:
-       pm_setgroups(m_in.PM_PROC, m_in.PM_GROUP_NO, m_in.PM_GROUP_ADDR);
+       pm_setgroups(m_in.PM_PROC, m_in.PM_GROUP_NO,
+                       (gid_t *) m_in.PM_GROUP_ADDR);
 
        m_out.m_type = PM_SETGROUPS_REPLY;
        m_out.PM_PROC = m_in.PM_PROC;
index 64f42407f4a2f1af6556a267be236d39979aebfa..05e4ff0b2a79ea40151bcf7fe27701191bbd16cc 100644 (file)
@@ -222,8 +222,11 @@ char mount_label[LABEL_MAX] )
        } else
                r = EBUSY;
 
-       if (vp != NULL)
+       if (vp != NULL) {
+               /* Quickly unlock to allow back calls (from e.g. FUSE) to
+                * relock */
                unlock_vmnt(parent_vmp);
+       }
 
        if (r != OK) {
                if (vp != NULL) {
index f7da182ecd47224f841a847c349ab5e3f3fd1340..54eb107a38089bbe34d4ed1316d1ef60ea6bd667 100644 (file)
@@ -116,7 +116,7 @@ _PROTOTYPE( void lock_revive, (void)                                        );
 
 /* main.c */
 _PROTOTYPE( int main, (void)                                           );
-_PROTOTYPE( void reply, (int whom, int result)                         );
+_PROTOTYPE( int reply, (int whom, int result)                          );
 _PROTOTYPE( void lock_proc, (struct fproc *rfp, int force_lock)                );
 _PROTOTYPE( void unlock_proc, (struct fproc *rfp)                      );
 _PROTOTYPE( void *do_dummy, (void *arg)                                        );
@@ -366,8 +366,9 @@ _PROTOTYPE( struct worker_thread *worker_get, (thread_t worker_tid) );
 _PROTOTYPE( struct job *worker_getjob, (thread_t worker_tid)           );
 _PROTOTYPE( void worker_init, (struct worker_thread *worker)           );
 _PROTOTYPE( struct worker_thread *worker_self, (void)                  );
-_PROTOTYPE( void worker_start, (void *(*func)(void *arg))              );
 _PROTOTYPE( void worker_signal, (struct worker_thread *worker)         );
+_PROTOTYPE( void worker_start, (void *(*func)(void *arg))              );
+_PROTOTYPE( void worker_stop, (struct worker_thread *worker)           );
 _PROTOTYPE( void worker_wait, (void)                                   );
 _PROTOTYPE( void sys_worker_start, (void *(*func)(void *arg))          );
 _PROTOTYPE( void dl_worker_start, (void *(*func)(void *arg))           );
index 5cd6417801074d8cdbb9d4ab7af2e19e57e79db1..ad854f7320a6f97c4094d00255b97104fb9de209 100644 (file)
@@ -177,9 +177,11 @@ PUBLIC int lock_vnode(struct vnode *vp, tll_access_t locktype)
  *===========================================================================*/
 PUBLIC void unlock_vnode(struct vnode *vp)
 {
+#if LOCK_DEBUG
   int i;
   register struct vnode *rvp;
   struct worker_thread *w;
+#endif
   ASSERTVP(vp);
 
 #if LOCK_DEBUG
index f8449109e0a8463c0b38e537be47eef92ae4fdf1..e5ae0c0e8084f6d9056e78b0b75457a321af034e 100644 (file)
@@ -286,6 +286,16 @@ PUBLIC void worker_signal(struct worker_thread *worker)
   worker_wake(worker);
 }
 
+/*===========================================================================*
+ *                             worker_stop                                  *
+ *===========================================================================*/
+PUBLIC void worker_stop(struct worker_thread *worker)
+{
+  ASSERTW(worker);             /* Make sure we have a valid thread */
+  worker->w_job.j_m_in.m_type = -EIO;
+  worker_wake(worker);
+}
+
 /*===========================================================================*
  *                             worker_self                                  *
  *===========================================================================*/