From: Philip Homburg Date: Wed, 15 Aug 2007 12:53:52 +0000 (+0000) Subject: Return EIO if a filedescriptor cannot be re-opened after a driver restart. X-Git-Tag: v3.1.4~329 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/invmod.png?a=commitdiff_plain;h=4b1cd8c0ec87c64e077c281a362a7543a2fdf1eb;p=minix.git Return EIO if a filedescriptor cannot be re-opened after a driver restart. Select now returns such a filedescriptor as ready (instead of EBADF). Reply before dev_up in FSSIGNON to avoid the problem that a DEV_OPEN request is received by a driver that expects a reply from the FSSIGNON. --- diff --git a/servers/vfs/device.c b/servers/vfs/device.c index be6933a3b..36b449b2d 100644 --- a/servers/vfs/device.c +++ b/servers/vfs/device.c @@ -807,10 +807,12 @@ printf("VFSdev_up: error sending new driver endpoint. FS_e: %d req_nr: %d\n", minor = ((vp->v_sdev >> MINOR) & BYTE); - printf("VFS: reopening special %d/%d..\n", maj, minor); + printf("vfs:dev_up: reopening special %d/%d..\n", maj, minor); - if((r = dev_open(vp->v_sdev, FS_PROC_NR, - vp->v_mode & (R_BIT|W_BIT))) != OK) { + printf("vfs:dev_up: before dev_open\n"); + r = dev_open(vp->v_sdev, FS_PROC_NR, vp->v_mode & (R_BIT|W_BIT)); + printf("vfs:dev_up: after dev_open: result = %d\n", r); + if (r != OK) { int n; /* This function will set the fp_filp[]s of processes * holding that fp to NULL, but _not_ clear diff --git a/servers/vfs/filedes.c b/servers/vfs/filedes.c index 6e57d8f6c..f1fae581c 100644 --- a/servers/vfs/filedes.c +++ b/servers/vfs/filedes.c @@ -84,6 +84,13 @@ int fild; /* file descriptor */ err_code = EBADF; if (fild < 0 || fild >= OPEN_MAX ) return(NIL_FILP); + if (rfp->fp_filp[fild] == NIL_FILP && FD_ISSET(fild, &rfp->fp_filp_inuse)) + { + printf("get_filp2: setting err_code to EIO for proc %d fd %d\n", + rfp->fp_endpoint, fild); + err_code = EIO; /* The filedes is not there, but is not closed either. + */ + } return(rfp->fp_filp[fild]); /* may also be NIL_FILP */ } diff --git a/servers/vfs/misc.c b/servers/vfs/misc.c index 240fd03fb..5d24df96c 100644 --- a/servers/vfs/misc.c +++ b/servers/vfs/misc.c @@ -550,7 +550,11 @@ PUBLIC int do_svrctl() * to be up. */ if(fproc[proc_nr_n].fp_execced) { + /* Reply before calling dev_up */ + printf("do_svrctl: replying before dev_up\n"); + reply(who_e, r); dev_up(major); + r= SUSPEND; } else { dmap[major].dmap_flags |= DMAP_BABY; } diff --git a/servers/vfs/read.c b/servers/vfs/read.c index 46ee6c88d..d3660d6cf 100644 --- a/servers/vfs/read.c +++ b/servers/vfs/read.c @@ -71,7 +71,8 @@ int rw_flag; /* READING or WRITING */ if ((f = get_filp(m_in.fd)) == NIL_FILP) { - printf("vfs:read_write: returning %d\n", err_code); + printf("vfs:read_write: returning %d to endpoint %d\n", + err_code, who_e); return(err_code); } if (((f->filp_mode) & (rw_flag == READING ? R_BIT : W_BIT)) == 0) { diff --git a/servers/vfs/select.c b/servers/vfs/select.c index 05fd10c79..710e3ed63 100644 --- a/servers/vfs/select.c +++ b/servers/vfs/select.c @@ -278,9 +278,17 @@ PUBLIC int do_select(void) if (!(orig_ops = ops = tab2ops(fd, &selecttab[s]))) continue; - if (!(filp = selecttab[s].filps[fd] = get_filp(fd))) { - select_cancel_all(&selecttab[s]); - return EBADF; + filp = selecttab[s].filps[fd] = get_filp(fd); + if (filp == NULL) { + if (err_code == EBADF) { + select_cancel_all(&selecttab[s]); + return EBADF; + } + + /* File descriptor is 'ready' to return EIO */ + printf("vfs:do_select: EIO after driver failure\n"); + ops2tab(SEL_RD|SEL_WR|SEL_ERR, fd, &selecttab[s]); + continue; } for(t = 0; t < SEL_FDS; t++) {