From: Philip Homburg Date: Fri, 22 Feb 2008 13:57:11 +0000 (+0000) Subject: Support for blocking open on char specials (due to asynch message passing), X-Git-Tag: v3.1.4~273 X-Git-Url: http://zhaoyanbai.com/repos/icons/static/man.3.ps?a=commitdiff_plain;h=e5df351245600d9dd827561cb6343b0ab8a87d34;p=minix.git Support for blocking open on char specials (due to asynch message passing), asynch. close, added close_filp function. --- diff --git a/servers/vfs/open.c b/servers/vfs/open.c index 9312b13c4..d32fb57de 100644 --- a/servers/vfs/open.c +++ b/servers/vfs/open.c @@ -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 */ }