]> Zhao Yanbai Git Server - minix.git/commitdiff
Support for blocking open on char specials (due to asynch message passing),
authorPhilip Homburg <philip@cs.vu.nl>
Fri, 22 Feb 2008 13:57:11 +0000 (13:57 +0000)
committerPhilip Homburg <philip@cs.vu.nl>
Fri, 22 Feb 2008 13:57:11 +0000 (13:57 +0000)
asynch. close, added close_filp function.

servers/vfs/open.c

index 9312b13c4ab2e5c6da323c78dee97df3d40cfdf7..d32fb57de5a6b9aad5951e3e702266f38b011f30 100644 (file)
@@ -143,6 +143,8 @@ PRIVATE int common_open(register int oflags, mode_t omode)
       case I_CHAR_SPECIAL:
           /* Invoke the driver for special processing. */
           r = dev_open(vp->v_sdev, who_e, bits | (oflags & ~O_ACCMODE));
+         if (r == SUSPEND)
+               suspend(XDOPEN);        /* suspend caller */
           break;
 
       case I_BLOCK_SPECIAL:
@@ -509,8 +511,6 @@ PRIVATE int pipe_open(register struct vnode *vp, register mode_t bits,
 }
 
 
-
-
 /*===========================================================================*
  *                             do_mknod                                     *
  *===========================================================================*/
@@ -707,15 +707,44 @@ int fd_nr;
   register struct filp *rfilp;
   register struct vnode *vp;
   struct file_lock *flp;
-  int rw, mode_word, lock_count;
-  dev_t dev;
+  int lock_count;
 
   /* First locate the vnode that belongs to the file descriptor. */
   if ( (rfilp = get_filp2(rfp, fd_nr)) == NIL_FILP) return(err_code);
-
   vp = rfilp->filp_vno;
+  close_filp(rfilp);
 
-  if (rfilp->filp_count - 1 == 0 && rfilp->filp_mode != FILP_CLOSED) {
+  FD_CLR(fd_nr, &rfp->fp_cloexec_set);
+  rfp->fp_filp[fd_nr] = NIL_FILP;
+  FD_CLR(fd_nr, &rfp->fp_filp_inuse);
+
+  /* Check to see if the file is locked.  If so, release all locks. */
+  if (nr_locks == 0) return(OK);
+  lock_count = nr_locks;       /* save count of locks */
+  for (flp = &file_lock[0]; flp < &file_lock[NR_LOCKS]; flp++) {
+       if (flp->lock_type == 0) continue;      /* slot not in use */
+       if (flp->lock_vnode == vp && flp->lock_pid == rfp->fp_pid) {
+               flp->lock_type = 0;
+               nr_locks--;
+       }
+  }
+  if (nr_locks < lock_count) lock_revive();    /* lock released */
+  return(OK);
+}
+
+
+/*===========================================================================*
+ *                             close_filp                                   *
+ *===========================================================================*/
+PUBLIC void close_filp(fp)
+struct filp *fp;
+{
+  int mode_word, rw;
+  dev_t dev;
+  struct vnode *vp;
+
+  vp = fp->filp_vno;
+  if (fp->filp_count - 1 == 0 && fp->filp_mode != FILP_CLOSED) {
        /* Check to see if the file is special. */
        mode_word = vp->v_mode & I_TYPE;
        if (mode_word == I_CHAR_SPECIAL || mode_word == I_BLOCK_SPECIAL) {
@@ -731,18 +760,20 @@ int fd_nr;
                        }
                }
                /* Do any special processing on device close. */
-               dev_close(dev);
+               (void) dev_close(dev, fp-filp);
+
+               /* Ignore any errors, even SUSPEND. */
        }
   }
 
   /* If the inode being closed is a pipe, release everyone hanging on it. */
   if (vp->v_pipe == I_PIPE) {
-       rw = (rfilp->filp_mode & R_BIT ? WRITE : READ);
+       rw = (fp->filp_mode & R_BIT ? WRITE : READ);
        release(vp, rw, NR_PROCS);
   }
 
   /* If a write has been done, the inode is already marked as DIRTY. */
-  if (--rfilp->filp_count == 0) {
+  if (--fp->filp_count == 0) {
        if (vp->v_pipe == I_PIPE) {
                /* Last reader or writer is going. Tell MFS about latest
                 * pipe size.
@@ -750,25 +781,17 @@ int fd_nr;
                truncate_vn(vp, vp->v_size);
        }
                
-       put_vnode(rfilp->filp_vno);
+       put_vnode(fp->filp_vno);
   }
 
-  FD_CLR(fd_nr, &rfp->fp_cloexec_set);
-  rfp->fp_filp[fd_nr] = NIL_FILP;
-  FD_CLR(fd_nr, &rfp->fp_filp_inuse);
+}
 
-  /* Check to see if the file is locked.  If so, release all locks. */
-  if (nr_locks == 0) return(OK);
-  lock_count = nr_locks;       /* save count of locks */
-  for (flp = &file_lock[0]; flp < &file_lock[NR_LOCKS]; flp++) {
-       if (flp->lock_type == 0) continue;      /* slot not in use */
-       if (flp->lock_vnode == vp && flp->lock_pid == rfp->fp_pid) {
-               flp->lock_type = 0;
-               nr_locks--;
-       }
-  }
-  if (nr_locks < lock_count) lock_revive();    /* lock released */
-  return(OK);
+/*===========================================================================*
+ *                             close_reply                                  *
+ *===========================================================================*/
+PUBLIC void close_reply()
+{
+       /* No need to do anything */
 }