]> Zhao Yanbai Git Server - minix.git/commitdiff
VFS: improve crashed FS resource cleanup
authorThomas Veerman <thomas@minix3.org>
Wed, 22 Feb 2012 13:54:35 +0000 (13:54 +0000)
committerThomas Veerman <thomas@minix3.org>
Wed, 22 Feb 2012 13:54:35 +0000 (13:54 +0000)
When VFS detects that an FS has crashed and tries to clean up
resources, it marks fairly late in the process that a vmnt is not
to be used again (to send requests to). This allows a thread to
become blocked on a vmnt after all blocked threads were stopped, but
before it finds out it shouldn't try to send to that vmnt.

servers/vfs/mount.c
servers/vfs/proto.h
servers/vfs/vmnt.c

index 4e4666d5a509bee257384d8fbf9a2105b74e05bf..a89c1c2142ba3a6e8779dd79e2a76f3dd3480480 100644 (file)
@@ -273,8 +273,7 @@ char mount_label[LABEL_MAX] )
   new_vmp->m_flags &= ~VMNT_MOUNTING;
 
   if (r != OK) {
-       new_vmp->m_fs_e = NONE;
-       new_vmp->m_dev = NO_DEV;
+       mark_vmnt_free(new_vmp);
        unlock_vnode(root_node);
        if (vp != NULL) {
                unlock_vnode(vp);
@@ -349,11 +348,10 @@ char mount_label[LABEL_MAX] )
   if (r != OK) {
        unlock_vnode(vp);
        unlock_vnode(root_node);
+       mark_vmnt_free(new_vmp);
        unlock_vmnt(new_vmp);
        put_vnode(vp);
        put_vnode(root_node);
-       new_vmp->m_dev = NO_DEV;
-       new_vmp->m_flags = 0;
        unlock_bsf();
        return(r);
   }
@@ -505,8 +503,7 @@ PUBLIC int unmount(
        vmp->m_root_node->v_sdev = NO_DEV;
        vmp->m_root_node = NULL;
   }
-  vmp->m_dev = NO_DEV;
-  vmp->m_fs_e = NONE;
+  mark_vmnt_free(vmp);
 
   unlock_vmnt(vmp);
 
index 432ef3a521d2f8f910353e0ecbcd82bc1ad52637..ddb4859c9e1eed65e48dac6f571fc890423d3575 100644 (file)
@@ -331,6 +331,7 @@ _PROTOTYPE( int in_group, (struct fproc *rfp, gid_t grp)            );
 /* vmnt.c */
 _PROTOTYPE( void check_vmnt_locks, (void)                              );
 _PROTOTYPE( void check_vmnt_locks_by_me, (struct fproc *rfp)           );
+_PROTOTYPE( void mark_vmnt_free, (struct vmnt *vmp)                    );
 _PROTOTYPE( struct vmnt *get_free_vmnt, (void)                         );
 _PROTOTYPE( struct vmnt *find_vmnt, (endpoint_t fs_e)                  );
 _PROTOTYPE( struct vmnt *get_locked_vmnt, (struct fproc *rfp)          );
index bb3dc0746705a4f1ad746eaa4108ca55ae9ade91..6e4c9ed0d4f7d9fbb934a4ea6c60af92ef1457f0 100644 (file)
@@ -59,6 +59,17 @@ PUBLIC void check_vmnt_locks()
 #endif
 }
 
+/*===========================================================================*
+ *                             mark_vmnt_free                               *
+ *===========================================================================*/
+PUBLIC void mark_vmnt_free(struct vmnt *vmp)
+{
+  ASSERTVMP(vmp);
+
+  vmp->m_fs_e = NONE;
+  vmp->m_dev = NO_DEV;
+}
+
 /*===========================================================================*
  *                             clear_vmnt                                   *
  *===========================================================================*/
@@ -83,10 +94,14 @@ PRIVATE void clear_vmnt(struct vmnt *vmp)
  *===========================================================================*/
 PUBLIC struct vmnt *get_free_vmnt(void)
 {
-  struct vmnt *vp;
+  struct vmnt *vmp;
 
-  for (vp = &vmnt[0]; vp < &vmnt[NR_MNTS]; ++vp)
-      if (vp->m_dev == NO_DEV) return(vp);
+  for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) {
+       if (vmp->m_dev == NO_DEV) {
+               clear_vmnt(vmp);
+               return(vmp);
+       }
+  }
 
   return(NULL);
 }
@@ -167,6 +182,7 @@ PUBLIC void vmnt_unmap_by_endpt(endpoint_t proc_e)
   struct vmnt *vmp;
 
   if ((vmp = find_vmnt(proc_e)) != NULL) {
+       mark_vmnt_free(vmp);
        fs_cancel(vmp);
        invalidate_filp_by_endpt(proc_e);
        if (vmp->m_mounted_on) {
@@ -174,7 +190,6 @@ PUBLIC void vmnt_unmap_by_endpt(endpoint_t proc_e)
                 * point. That is, the mount was succesful. */
                put_vnode(vmp->m_mounted_on);
        }
-       clear_vmnt(vmp);
   }
 }