]> Zhao Yanbai Git Server - minix.git/commitdiff
Remove support for reopening character devices 78/978/2
authorDavid van Moolenbroek <david@minix3.org>
Tue, 10 Sep 2013 14:06:37 +0000 (16:06 +0200)
committerLionel Sambuc <lionel@minix3.org>
Sat, 1 Mar 2014 08:04:52 +0000 (09:04 +0100)
Previously, VFS would reopen a character device after a driver crash
if the associated file descriptor was opened with the O_REOPEN flag.
This patch removes support for this feature. The code was complex,
full of uncovered corner cases, and hard to test. Moreover, it did not
actually hide the crash from user applications: they would get an
error code to indicate that something went wrong, and have to decide
based on the nature of the underlying device how to continue.

- remove support for O_REOPEN, and make playwave(1) reopen its device;
- remove support for the DEV_REOPEN protocol message;
- remove all code in VFS related to reopening character devices;
- no longer change VFS filp reference count and FD bitmap upon filp
  invalidation; instead, make get_filp* fail all calls on invalidated
  FDs except when obtained with the locktype VNODE_OPCL which is used
  by close_fd only;
- remove the VFS fproc file descriptor bitmap entirely, returning to
  the situation that a FD is in use if its slot points to a filp; use
  FILP_CLOSED as single means of marking a filp as invalidated.

Change-Id: I34f6bc69a036b3a8fc667c1f80435ff3af56558f

17 files changed:
commands/playwave/playwave.c
include/minix/com.h
lib/libchardriver/chardriver.c
servers/vfs/README
servers/vfs/device.c
servers/vfs/dmap.c
servers/vfs/exec.c
servers/vfs/file.h
servers/vfs/filedes.c
servers/vfs/fproc.h
servers/vfs/main.c
servers/vfs/misc.c
servers/vfs/open.c
servers/vfs/pipe.c
servers/vfs/proto.h
servers/vfs/read.c
servers/vfs/select.c

index 53b92d8dc5f9cc4a303bdbdb175044900b7a763b..28bdbf5887afdb04a3ff0e17c95d2a66e913f24d 100644 (file)
@@ -66,15 +66,36 @@ void usage()
   exit(-1);
 }
 
+int open_audio(unsigned int *fragment_size, unsigned int channels,
+       unsigned int samples_per_sec, unsigned int bits)
+{
+  unsigned int sign;
+  int audio;
+
+  /* Open DSP */
+  if ((audio = open("/dev/audio", O_RDWR | O_REOPEN)) < 0)
+  {
+    printf("Cannot open /dev/audio: %s\n", strerror(errno));
+    exit(-1);
+  }
+
+  ioctl(audio, DSPIOMAX, fragment_size); /* Get maximum fragment size. */
+
+  /* Set DSP parameters (should check return values..) */
+  ioctl(audio, DSPIOSIZE, fragment_size);      /* Use max. fragment size. */
+  ioctl(audio, DSPIOSTEREO, &channels);
+  ioctl(audio, DSPIORATE, &samples_per_sec);
+  ioctl(audio, DSPIOBITS, &bits);
+  sign = (bits == 16 ? 1 : 0);
+  ioctl(audio, DSPIOSIGN, &sign);
+  return audio;
+}
 
 int main ( int argc, char *argv[] )
 {
   int i, r, audio, file;
   char *buffer, *file_name = NULL;
-  unsigned int sign;
-  unsigned int fragment_size;
-  unsigned int channels;
-  unsigned int bits;
+  unsigned int fragment_size, fragment_size2;
   long data_pos;  
   int showinfo = 0;
 
@@ -91,22 +112,6 @@ int main ( int argc, char *argv[] )
   }
   else file_name = argv[1];
 
-  /* Open DSP */
-  if ((audio = open("/dev/audio", O_RDWR | O_REOPEN)) < 0) 
-  {
-    printf("Cannot open /dev/audio: %s\n", strerror(errno));
-    exit(-1);
-  }
-
-  /* Get maximum fragment size and try to allocate a buffer */
-  ioctl(audio, DSPIOMAX, &fragment_size);
-  if ((buffer = malloc(fragment_size)) == (char *)0)
-  {
-    fprintf(stderr, "Cannot allocate buffer\n");
-    exit(-1);
-  } 
-  ioctl(audio, DSPIOSIZE, &fragment_size);
-
   /* Open wav file */
   if((file = open(file_name, O_RDONLY)) < 0)
   {
@@ -141,15 +146,15 @@ int main ( int argc, char *argv[] )
     exit(1);
   }
 
-  /* Set DSP parameters */
-  channels = c_fields.Channels;
-  channels--;
-  bits = s_fields.BitsPerSample;
-  ioctl(audio, DSPIOSTEREO, &channels); 
-  ioctl(audio, DSPIORATE, &c_fields.SamplesPerSec);
-  ioctl(audio, DSPIOBITS, &bits); 
-  sign = (bits == 16 ? 1 : 0);
-  ioctl(audio, DSPIOSIGN, &sign); 
+  /* Open audio device and set DSP parameters */
+  audio = open_audio(&fragment_size, c_fields.Channels - 1,
+       c_fields.SamplesPerSec, s_fields.BitsPerSample);
+
+  if ((buffer = malloc(fragment_size)) == (char *)0)
+  {
+    fprintf(stderr, "Cannot allocate buffer\n");
+    exit(-1);
+  }
 
   /* Goto data chunk */
   lseek(file, data_pos, SEEK_SET);
@@ -203,6 +208,20 @@ int main ( int argc, char *argv[] )
        {
                fprintf(stderr, "playwave: write to audio device failed: %s\n",
                        strerror(errno));
+
+               /* If we get EIO, the driver might have restarted. Reopen the
+                * audio device.
+                */
+               if (errno == EIO) {
+                       close(audio);
+                       audio = open_audio(&fragment_size2,
+                               c_fields.Channels - 1, c_fields.SamplesPerSec,
+                               s_fields.BitsPerSample);
+                       if (fragment_size2 != fragment_size) {
+                           fprintf(stderr, "Fragment size has changed\n");
+                           exit(1);
+                       }
+               }
        }
        else
        {
index 94faed468577cc444da83547c917fd8398aa12ea..2cf8105736eae4f4267bcff84fa6e575f994bb48 100644 (file)
 #define DEV_OPEN       (DEV_RQ_BASE +  6) /* open a minor device */
 #define DEV_CLOSE      (DEV_RQ_BASE +  7) /* close a minor device */
 #define DEV_SELECT     (DEV_RQ_BASE + 12) /* request select() attention */
-#define DEV_REOPEN             (DEV_RQ_BASE + 14) /* reopen a minor device */
 
 #define DEV_READ_S     (DEV_RQ_BASE + 20) /* (safecopy) read from minor */
 #define DEV_WRITE_S    (DEV_RQ_BASE + 21) /* (safecopy) write to minor */
 #define IS_DEV_RQ(type) (((type) & ~0xff) == DEV_RQ_BASE)
 
 #define DEV_REVIVE      (DEV_RS_BASE + 2) /* driver revives process */
-#define DEV_REOPEN_REPL (DEV_RS_BASE + 5) /* reply to DEV_REOPEN */
 #define DEV_CLOSE_REPL (DEV_RS_BASE + 6) /* reply to DEV_CLOSE */
 #define DEV_SEL_REPL1  (DEV_RS_BASE + 7) /* first reply to DEV_SELECT */
 #define DEV_SEL_REPL2  (DEV_RS_BASE + 8) /* (opt) second reply to DEV_SELECT */
index 4e723e6e1addc2a64f5c080e613be30f0dba659a..cf34dd9f3a4909b82bba2d36a4ef5a646effadd0 100644 (file)
@@ -228,12 +228,6 @@ static void chardriver_reply(message *mess, int ipc_status, int r)
        reply_mess.REP_STATUS = r;
        break;
 
-  case DEV_REOPEN:
-       reply_mess.m_type = DEV_REOPEN_REPL;
-       reply_mess.REP_ENDPT = mess->USER_ENDPT;
-       reply_mess.REP_STATUS = r;
-       break;
-
   case DEV_CLOSE:
        reply_mess.m_type = DEV_CLOSE_REPL;
        reply_mess.REP_ENDPT = mess->USER_ENDPT;
@@ -266,7 +260,7 @@ static void chardriver_reply(message *mess, int ipc_status, int r)
 /*===========================================================================*
  *                             do_open                                      *
  *===========================================================================*/
-static int do_open(struct chardriver *cdp, message *m_ptr, int is_reopen)
+static int do_open(struct chardriver *cdp, message *m_ptr)
 {
 /* Open a minor device. */
   endpoint_t user_endpt;
@@ -280,7 +274,7 @@ static int do_open(struct chardriver *cdp, message *m_ptr, int is_reopen)
   /* Call the open hook. */
   minor = m_ptr->DEVICE;
   access = m_ptr->COUNT;
-  user_endpt = is_reopen ? NONE : m_ptr->USER_ENDPT; /* XXX FIXME */
+  user_endpt = m_ptr->USER_ENDPT;
 
   r = cdp->cdr_open(minor, access, user_endpt);
 
@@ -481,7 +475,7 @@ void chardriver_process(struct chardriver *cdp, message *m_ptr, int ipc_status)
    */
   if (IS_DEV_RQ(m_ptr->m_type) && !is_open_dev(m_ptr->DEVICE)) {
        /* Ignore spurious requests for unopened devices. */
-       if (m_ptr->m_type != DEV_OPEN && m_ptr->m_type != DEV_REOPEN)
+       if (m_ptr->m_type != DEV_OPEN)
                return; /* do not send a reply */
 
        /* Mark the device as opened otherwise. */
@@ -490,8 +484,7 @@ void chardriver_process(struct chardriver *cdp, message *m_ptr, int ipc_status)
 
   /* Call the appropriate function(s) for this request. */
   switch (m_ptr->m_type) {
-  case DEV_OPEN:       r = do_open(cdp, m_ptr, FALSE);         break;
-  case DEV_REOPEN:     r = do_open(cdp, m_ptr, TRUE);          break;
+  case DEV_OPEN:       r = do_open(cdp, m_ptr);                break;
   case DEV_CLOSE:      r = do_close(cdp, m_ptr);               break;
   case DEV_READ_S:     r = do_transfer(cdp, m_ptr, FALSE);     break;
   case DEV_WRITE_S:    r = do_transfer(cdp, m_ptr, TRUE);      break;
index 6c91f6687460e0cd2c2c52512f356b545d0a4777..c2a3d3549f33c563719b4fe0859df8d8f4bc9bb4 100644 (file)
@@ -149,11 +149,10 @@ normal and PM work is the responsibility of the worker thread infrastructure.
 There are several special tasks that require a worker thread, and these are
 implemented as normal work associated with a certain special process that does
 not make regular VFS calls anyway. For example, the initial ramdisk mount
-procedure and the post-crash filp garbage collector use a thread associated
-with the VFS process. Some of these special tasks require protection against
-being started multiple times at once, as this is not only undesirable but also
-disallowed. The full list of worker thread task types and subtypes is shown in
-Table 1.
+procedure uses a thread associated with the VFS process. Some of these special
+tasks require protection against being started multiple times at once, as this
+is not only undesirable but also disallowed. The full list of worker thread
+task types and subtypes is shown in Table 1.
 
 {{{
 -------------------------------------------------------------------------
@@ -167,8 +166,6 @@ Table 1.
 +---------------------------+--------+-----------------+----------------+
 | DS event notification     | normal | DS              | yes            |
 +---------------------------+--------+-----------------+----------------+
-| filp garbage collection   | normal | VFS             | no             |
-+---------------------------+--------+-----------------+----------------+
 | initial ramdisk mounting  | normal | VFS             | no             |
 +---------------------------+--------+-----------------+----------------+
 | reboot sequence           | normal | PM              | no             |
@@ -677,15 +674,15 @@ a request. VFS does this with an arbitrary maximum of 5 attempts.
 
 === Recovery from character driver crashes ===
 ## 5.2 Recovery from character driver crashes
-Character special files are treated differently. Once VFS has found out a
-driver has been restarted, it will stop the current request (if there is
-any). It makes no sense to retry requests due to the nature of character
-special files. If a character special driver can restart without changing
-endpoints, this merely results in the current request (e.g., read, write, or
-ioctl) failing and allows the user process to reissue the same request. On
-the other hand, if a driver restart causes the driver to change endpoint
-number, all associated file descriptors are marked invalid and subsequent
-operations on them will always fail with a bad file descriptor error.
+While VFS used to support minimal recovery from character driver crashes, the
+added complexity has so far proven to outweigh the benefits, especially since
+such crash recovery can never be fully transparent: it depends entirely on the
+character device as to whether repeating an I/O request makes sense at all.
+Currently, all operations except close(2) on a file descriptor that identifies
+a device on a crashed character driver, will result in an EIO error. It is up
+to the application to reopen the character device and retry whatever it was
+doing in the appropriate manner. In the future, automatic reopen and I/O
+restart may be reintroduced for a limited subset of character drivers.
 
 === Recovery from File Server crashes ===
 ## 5.3 Recovery from File Server crashes
index 68afaecf35bec5fac097a93157500be01216316c..dd498529b0395c8348ae63256b769872bd41a0fa 100644 (file)
@@ -3,7 +3,6 @@
  *
  * The entry points in this file are:
  *   dev_open:   open a character device
- *   dev_reopen: reopen a character device after a driver crash
  *   dev_close:  close a character device
  *   cdev_reply: process the result of a character driver request
  *   bdev_open:  open a block device
@@ -44,8 +43,6 @@
 static int block_io(endpoint_t driver_e, message *mess_ptr);
 static cp_grant_id_t make_grant(endpoint_t driver_e, endpoint_t user_e, int op,
        void *buf, unsigned long size);
-static void restart_reopen(devmajor_t major);
-static void reopen_reply(message *m_ptr);
 
 static int dummyproc;
 
@@ -73,34 +70,6 @@ int dev_open(
 }
 
 
-/*===========================================================================*
- *                             dev_reopen                                   *
- *===========================================================================*/
-int dev_reopen(
-  dev_t dev,                   /* device to open */
-  int filp_no,                 /* filp to reopen for */
-  int flags                    /* mode bits and flags */
-)
-{
-/* Reopen a character device after a failing device driver. */
-  devmajor_t major_dev;
-  struct dmap *dp;
-  int r;
-
-  /* Determine the major device number and call the device class specific
-   * open/close routine.  (This is the only routine that must check the device
-   * number for being in range.  All others can trust this check.)
-   */
-  major_dev = major(dev);
-  if (major_dev < 0 || major_dev >= NR_DEVICES) return(ENXIO);
-  dp = &dmap[major_dev];
-  if (dp->dmap_driver == NONE) return(ENXIO);
-  r = (*dp->dmap_opcl)(DEV_REOPEN, dev, filp_no, flags);
-  if (r == SUSPEND) r = OK;
-  return(r);
-}
-
-
 /*===========================================================================*
  *                             dev_close                                    *
  *===========================================================================*/
@@ -317,8 +286,7 @@ int dev_io(
   void *buf,                   /* virtual address of the buffer */
   off_t pos,                   /* byte position */
   size_t bytes,                        /* how many bytes to transfer */
-  int flags,                   /* special flags, like O_NONBLOCK */
-  int suspend_reopen           /* Just suspend the process */
+  int flags                    /* special flags, like O_NONBLOCK */
 )
 {
 /* Initiate a read, write, or ioctl to a device. */
@@ -339,15 +307,6 @@ int dev_io(
   /* See if driver is roughly valid. */
   if (dp->dmap_driver == NONE) return(ENXIO);
 
-  if (suspend_reopen) {
-       /* Suspend user. */
-       fp->fp_grant = GRANT_INVALID;
-       fp->fp_ioproc = NONE;
-       wait_for(dp->dmap_driver);
-       fp->fp_flags |= FP_SUSP_REOPEN;
-       return(SUSPEND);
-  }
-
   if(isokendpt(dp->dmap_driver, &dummyproc) != OK) {
        printf("VFS: dev_io: old driver for major %x (%d)\n", major_dev,
                dp->dmap_driver);
@@ -427,7 +386,7 @@ static int cdev_clone(dev_t dev, endpoint_t proc_e, devminor_t new_minor)
   }
   lock_vnode(vp, VNODE_OPCL);
 
-  assert(FD_ISSET(scratch(fp).file.fd_nr, &fp->fp_filp_inuse));
+  assert(fp->fp_filp[scratch(fp).file.fd_nr] != NULL);
   unlock_vnode(fp->fp_filp[scratch(fp).file.fd_nr]->filp_vno);
   put_vnode(fp->fp_filp[scratch(fp).file.fd_nr]->filp_vno);
 
@@ -450,7 +409,7 @@ static int cdev_clone(dev_t dev, endpoint_t proc_e, devminor_t new_minor)
  *                             gen_opcl                                     *
  *===========================================================================*/
 int gen_opcl(
-  int op,                      /* operation, DEV_OPEN/DEV_REOPEN/DEV_CLOSE */
+  int op,                      /* operation, DEV_OPEN or DEV_CLOSE */
   dev_t dev,                   /* device to open or close */
   endpoint_t proc_e,           /* process to open/close for */
   int flags                    /* mode bits and flags */
@@ -485,17 +444,15 @@ int gen_opcl(
 
   if (r != OK) return(r);
 
-  if (op == DEV_OPEN || op == DEV_CLOSE) {
-       /* Block the thread waiting for a reply. */
-       fp->fp_task = dp->dmap_driver;
-       self->w_task = dp->dmap_driver;
-       self->w_drv_sendrec = &dev_mess;
+  /* Block the thread waiting for a reply. */
+  fp->fp_task = dp->dmap_driver;
+  self->w_task = dp->dmap_driver;
+  self->w_drv_sendrec = &dev_mess;
 
-       worker_wait();
+  worker_wait();
 
-       self->w_task = NONE;
-       self->w_drv_sendrec = NULL;
-  }
+  self->w_task = NONE;
+  self->w_drv_sendrec = NULL;
 
   /* Return the result from the driver. */
   return(dev_mess.REP_STATUS);
@@ -589,7 +546,7 @@ int do_ioctl(message *UNUSED(m_out))
 {
 /* Perform the ioctl(ls_fd, request, argx) system call */
   unsigned long ioctlrequest;
-  int r = OK, suspend_reopen;
+  int r = OK;
   struct filp *f;
   register struct vnode *vp;
   dev_t dev;
@@ -607,14 +564,13 @@ int do_ioctl(message *UNUSED(m_out))
   }
 
   if (r == OK) {
-       suspend_reopen = (f->filp_state & FS_NEEDS_REOPEN);
        dev = (dev_t) vp->v_sdev;
 
        if (S_ISBLK(vp->v_mode))
                r = bdev_ioctl(dev, who_e, ioctlrequest, argx);
        else
                r = dev_io(DEV_IOCTL_S, dev, who_e, argx, 0,
-                          ioctlrequest, f->filp_flags, suspend_reopen);
+                          ioctlrequest, f->filp_flags);
   }
 
   unlock_filp(f);
@@ -924,31 +880,6 @@ void bdev_up(devmajor_t maj)
 }
 
 
-/*===========================================================================*
- *                             cdev_up                                      *
- *===========================================================================*/
-void cdev_up(devmajor_t maj)
-{
-  /* A new character device driver has been mapped in.
-  */
-  int needs_reopen;
-  struct filp *rfilp;
-  struct vnode *vp;
-
-  needs_reopen= FALSE;
-  for (rfilp = filp; rfilp < &filp[NR_FILPS]; rfilp++) {
-       if (rfilp->filp_count < 1 || !(vp = rfilp->filp_vno)) continue;
-       if (major(vp->v_sdev) != maj) continue;
-       if (!S_ISCHR(vp->v_mode)) continue;
-
-       rfilp->filp_state |= FS_NEEDS_REOPEN;
-       needs_reopen = TRUE;
-  }
-
-  if (needs_reopen)
-       restart_reopen(maj);
-}
-
 /*===========================================================================*
  *                             opcl_reply                                   *
  *===========================================================================*/
@@ -1032,7 +963,6 @@ void cdev_reply(void)
   switch (call_nr) {
   case DEV_OPEN_REPL:
   case DEV_CLOSE_REPL: opcl_reply(&m_in);      break;
-  case DEV_REOPEN_REPL:        reopen_reply(&m_in);    break;
   case DEV_REVIVE:     task_reply(&m_in);      break;
   case DEV_SEL_REPL1:
        select_reply1(m_in.m_source, m_in.DEV_MINOR, m_in.DEV_SEL_OPS);
@@ -1070,157 +1000,3 @@ void bdev_reply(struct dmap *dp)
   wp->w_drv_sendrec = NULL;
   worker_signal(wp);
 }
-
-/*===========================================================================*
- *                             filp_gc_thread                               *
- *===========================================================================*/
-static void filp_gc_thread(void)
-{
-/* Filp garbage collection thread function. Since new filps may be invalidated
- * while the actual garbage collection procedure is running, we repeat the
- * procedure until it can not find any more work to do.
- */
-
-  while (do_filp_gc())
-       /* simply repeat */;
-}
-
-/*===========================================================================*
- *                             restart_reopen                               *
- *===========================================================================*/
-static void restart_reopen(devmajor_t maj)
-{
-  devmajor_t major_dev;
-  devminor_t minor_dev;
-  endpoint_t driver_e;
-  struct vnode *vp;
-  struct filp *rfilp;
-  struct fproc *rfp;
-  message m_out;
-  int n, r;
-
-  memset(&m_out, 0, sizeof(m_out));
-
-  if (maj < 0 || maj >= NR_DEVICES) panic("VFS: out-of-bound major");
-
-  for (rfilp = filp; rfilp < &filp[NR_FILPS]; rfilp++) {
-       if (rfilp->filp_count < 1 || !(vp = rfilp->filp_vno)) continue;
-       if (!(rfilp->filp_state & FS_NEEDS_REOPEN)) continue;
-       if (!S_ISCHR(vp->v_mode)) continue;
-
-       major_dev = major(vp->v_sdev);
-       minor_dev = minor(vp->v_sdev);
-       if (major_dev != maj) continue;
-
-       if (rfilp->filp_flags & O_REOPEN) {
-               /* Try to reopen a file upon driver restart */
-               r = dev_reopen(vp->v_sdev, rfilp-filp,
-                       rfilp->filp_mode & (R_BIT|W_BIT));
-
-               if (r == OK)
-                       return;
-
-               printf("VFS: file on dev %d/%d re-open failed: %d\n",
-                       major_dev, minor_dev, r);
-       }
-
-       /* File descriptor is to be closed when driver restarts. */
-       n = invalidate_filp(rfilp);
-       if (n != rfilp->filp_count) {
-               printf("VFS: warning: invalidate/count "
-                      "discrepancy (%d, %d)\n", n, rfilp->filp_count);
-       }
-       rfilp->filp_count = 0;
-
-       /* We have to clean up this filp and vnode, but can't do that yet as
-        * it's locked by a worker thread. Start a new job to garbage collect
-        * invalidated filps associated with this device driver. This thread
-        * is associated with a process that we know is idle otherwise: VFS.
-        * Be careful that we don't start two threads or lose work, though.
-        */
-       if (worker_can_start(fproc_addr(VFS_PROC_NR))) {
-               worker_start(fproc_addr(VFS_PROC_NR), filp_gc_thread,
-                       &m_out /*unused*/, FALSE /*use_spare*/);
-       }
-  }
-
-  /* Nothing more to re-open. Restart suspended processes */
-  driver_e = dmap[maj].dmap_driver;
-  for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
-       if(rfp->fp_pid == PID_FREE) continue;
-       if(rfp->fp_blocked_on == FP_BLOCKED_ON_OTHER &&
-          rfp->fp_task == driver_e && (rfp->fp_flags & FP_SUSP_REOPEN)) {
-               rfp->fp_flags &= ~FP_SUSP_REOPEN;
-               rfp->fp_blocked_on = FP_BLOCKED_ON_NONE;
-               reply(&m_out, rfp->fp_endpoint, ERESTART);
-       }
-  }
-}
-
-
-/*===========================================================================*
- *                             reopen_reply                                 *
- *===========================================================================*/
-static void reopen_reply(message *m_ptr)
-{
-  endpoint_t driver_e;
-  devmajor_t maj;
-  int filp_no, status;
-  struct filp *rfilp;
-  struct vnode *vp;
-  struct dmap *dp;
-
-  driver_e = m_ptr->m_source;
-  filp_no = m_ptr->REP_ENDPT;
-  status = m_ptr->REP_STATUS;
-
-  if (filp_no < 0 || filp_no >= NR_FILPS) {
-       printf("VFS: reopen_reply: bad filp number %d from driver %d\n",
-               filp_no, driver_e);
-       return;
-  }
-
-  rfilp = &filp[filp_no];
-  if (rfilp->filp_count < 1) {
-       printf("VFS: reopen_reply: filp number %d not inuse (from driver %d)\n",
-              filp_no, driver_e);
-       return;
-  }
-
-  vp = rfilp->filp_vno;
-  if (!vp) {
-       printf("VFS: reopen_reply: no vnode for filp number %d (from driver "
-               "%d)\n", filp_no, driver_e);
-       return;
-  }
-
-  if (!(rfilp->filp_state & FS_NEEDS_REOPEN)) {
-       printf("VFS: reopen_reply: bad state %d for filp number %d"
-              " (from driver %d)\n", rfilp->filp_state, filp_no, driver_e);
-       return;
-  }
-
-  if (!S_ISCHR(vp->v_mode)) {
-       printf("VFS: reopen_reply: bad mode 0%o for filp number %d"
-              " (from driver %d)\n", vp->v_mode, filp_no, driver_e);
-       return;
-  }
-
-  maj = major(vp->v_sdev);
-  dp = &dmap[maj];
-  if (dp->dmap_driver != driver_e) {
-       printf("VFS: reopen_reply: bad major %d for filp number %d "
-               "(from driver %d, current driver is %d)\n", maj, filp_no,
-               driver_e, dp->dmap_driver);
-       return;
-  }
-
-  if (status == OK) {
-       rfilp->filp_state &= ~FS_NEEDS_REOPEN;
-  } else {
-       printf("VFS: reopen_reply: should handle error status\n");
-       return;
-  }
-
-  restart_reopen(maj);
-}
index b96724c0443636be8c9670a1446554b58600cce3..54d071754e7c8aac19fb8b722a8dac160e32f54f 100644 (file)
@@ -359,7 +359,7 @@ void dmap_endpt_up(endpoint_t proc_e, int is_blk)
                                worker = worker_get(dp->dmap_servicing);
                                worker_stop(worker);
                        }
-                       cdev_up(major);
+                       invalidate_filp_by_char_major(major);
                }
        }
   }
index 51881b24be0d286af5b7cd2d8824637a5e010da8..d8e3745215b3dd7ca410428a6b8aa6281a2cb2cf 100644 (file)
@@ -325,7 +325,6 @@ int pm_exec(vir_bytes path, size_t path_len, vir_bytes frame, size_t frame_len,
                        newfilp->filp_count = 1;
                        newfilp->filp_vno = vp;
                        newfilp->filp_flags = O_RDONLY;
-                       FD_SET(newfd, &vmfp->fp_filp_inuse);
                        vmfp->fp_filp[newfd] = newfilp;
                        /* dup_vnode(vp); */
                        execi.vmfd = newfd;
index 022aa4652de4a064abea978da5200d8cdabe93f8..1bba747ab7d3778c348f30e50aa632cb6fedc6a1 100644 (file)
@@ -8,7 +8,6 @@
 EXTERN struct filp {
   mode_t filp_mode;            /* RW bits, telling how file is opened */
   int filp_flags;              /* flags from open and fcntl */
-  int filp_state;              /* state for crash recovery */
   int filp_count;              /* how many file descriptors share this slot?*/
   struct vnode *filp_vno;      /* vnode belonging to this file */
   off_t filp_pos;              /* file position */
@@ -29,11 +28,7 @@ EXTERN struct filp {
   int filp_pipe_select_ops;
 } filp[NR_FILPS];
 
-#define FILP_CLOSED    0       /* filp_mode: associated device closed */
-
-#define FS_NORMAL      000     /* file descriptor can be used normally */
-#define FS_NEEDS_REOPEN        001     /* file descriptor needs to be re-opened */
-#define FS_INVALIDATED 002     /* file was invalidated */
+#define FILP_CLOSED    0       /* filp_mode: associated device closed/gone */
 
 #define FSF_UPDATE     001     /* The driver should be informed about new
                                 * state.
index 865a66335f4b479e43396162607aafb1cfbefc62..571abaf2c1da3820b68b1719049555089754fede 100644 (file)
@@ -75,64 +75,6 @@ void check_filp_locks(void)
 #endif
 }
 
-/*===========================================================================*
- *                             do_filp_gc                                   *
- *===========================================================================*/
-int do_filp_gc(void)
-{
-/* Perform filp garbage collection. Return whether at least one invalidated
- * filp was found, in which case the entire procedure will be invoked again.
- */
-  struct filp *f;
-  struct vnode *vp;
-  int found = FALSE;
-
-  for (f = &filp[0]; f < &filp[NR_FILPS]; f++) {
-       if (!(f->filp_state & FS_INVALIDATED)) continue;
-
-       found = TRUE;
-
-       if (f->filp_mode == FILP_CLOSED || f->filp_vno == NULL) {
-               /* File was already closed before gc could kick in */
-               assert(f->filp_count <= 0);
-               f->filp_state &= ~FS_INVALIDATED;
-               f->filp_count = 0;
-               continue;
-       }
-
-       assert(f->filp_vno != NULL);
-       vp = f->filp_vno;
-
-       /* Synchronize with worker thread that might hold a lock on the vp */
-       lock_vnode(vp, VNODE_OPCL);
-       unlock_vnode(vp);
-
-       /* If garbage collection was invoked due to a failed device open
-        * request, then common_open has already cleaned up and we have
-        * nothing to do.
-        */
-       if (!(f->filp_state & FS_INVALIDATED)) {
-               continue;
-       }
-
-       /* If garbage collection was invoked due to a failed device close
-        * request, the close_filp has already cleaned up and we have nothing
-        * to do.
-        */
-       if (f->filp_mode != FILP_CLOSED) {
-               assert(f->filp_count == 0);
-               f->filp_count = 1;      /* So lock_filp and close_filp will do
-                                        * their job */
-               lock_filp(f, VNODE_READ);
-               close_filp(f);
-       }
-
-       f->filp_state &= ~FS_INVALIDATED;
-  }
-
-  return found;
-}
-
 /*===========================================================================*
  *                             init_filps                                   *
  *===========================================================================*/
@@ -163,7 +105,7 @@ int get_fd(struct fproc *rfp, int start, mode_t bits, int *k, struct filp **fpt)
 
   /* Search the fproc fp_filp table for a free file descriptor. */
   for (i = start; i < OPEN_MAX; i++) {
-       if (rfp->fp_filp[i] == NULL && !FD_ISSET(i, &rfp->fp_filp_inuse)) {
+       if (rfp->fp_filp[i] == NULL) {
                /* A file descriptor has been located. */
                *k = i;
                break;
@@ -186,7 +128,6 @@ int get_fd(struct fproc *rfp, int start, mode_t bits, int *k, struct filp **fpt)
                f->filp_select_ops = 0;
                f->filp_pipe_select_ops = 0;
                f->filp_flags = 0;
-               f->filp_state = FS_NORMAL;
                f->filp_select_flags = 0;
                f->filp_softlock = NULL;
                *fpt = f;
@@ -226,9 +167,9 @@ tll_access_t locktype;
   filp = NULL;
   if (fild < 0 || fild >= OPEN_MAX)
        err_code = EBADF;
-  else if (rfp->fp_filp[fild] == NULL && FD_ISSET(fild, &rfp->fp_filp_inuse))
-       err_code = EIO; /* The filedes is not there, but is not closed either.
-                        */
+  else if (locktype != VNODE_OPCL && rfp->fp_filp[fild] != NULL &&
+               rfp->fp_filp[fild]->filp_mode == FILP_CLOSED)
+       err_code = EIO; /* disallow all use except close(2) */
   else if ((filp = rfp->fp_filp[fild]) == NULL)
        err_code = EBADF;
   else
@@ -265,24 +206,11 @@ struct filp *find_filp(struct vnode *vp, mode_t bits)
 /*===========================================================================*
  *                             invalidate_filp                              *
  *===========================================================================*/
-int invalidate_filp(struct filp *rfilp)
+void invalidate_filp(struct filp *rfilp)
 {
-/* Invalidate filp. fp_filp_inuse is not cleared, so filp can't be reused
-   until it is closed first. */
-
-  int f, fd, n = 0;
-  for (f = 0; f < NR_PROCS; f++) {
-       if (fproc[f].fp_pid == PID_FREE) continue;
-       for (fd = 0; fd < OPEN_MAX; fd++) {
-               if(fproc[f].fp_filp[fd] && fproc[f].fp_filp[fd] == rfilp) {
-                       fproc[f].fp_filp[fd] = NULL;
-                       n++;
-               }
-       }
-  }
+/* Invalidate filp. */
 
-  rfilp->filp_state |= FS_INVALIDATED;
-  return(n);   /* Report back how often this filp has been invalidated. */
+  rfilp->filp_mode = FILP_CLOSED;
 }
 
 /*===========================================================================*
@@ -296,7 +224,7 @@ void invalidate_filp_by_char_major(int major)
        if (f->filp_count != 0 && f->filp_vno != NULL) {
                if (major(f->filp_vno->v_sdev) == major &&
                    S_ISCHR(f->filp_vno->v_mode)) {
-                       (void) invalidate_filp(f);
+                       invalidate_filp(f);
                }
        }
   }
@@ -312,7 +240,7 @@ void invalidate_filp_by_endpt(endpoint_t proc_e)
   for (f = &filp[0]; f < &filp[NR_FILPS]; f++) {
        if (f->filp_count != 0 && f->filp_vno != NULL) {
                if (f->filp_vno->v_fs_e == proc_e)
-                       (void) invalidate_filp(f);
+                       invalidate_filp(f);
        }
   }
 }
@@ -372,7 +300,7 @@ struct filp *filp;
   if (filp->filp_softlock != NULL)
        assert(filp->filp_softlock == fp);
 
-  if (filp->filp_count > 0 || filp->filp_state & FS_INVALIDATED) {
+  if (filp->filp_count > 0) {
        /* Only unlock vnode if filp is still in use */
 
        /* and if we don't hold a soft lock */
@@ -507,11 +435,8 @@ filp_id_t cfilp;
 
   /* Find an open slot in fp_filp */
   for (fd = 0; fd < OPEN_MAX; fd++) {
-       if (rfp->fp_filp[fd] == NULL &&
-           !FD_ISSET(fd, &rfp->fp_filp_inuse)) {
-
+       if (rfp->fp_filp[fd] == NULL) {
                /* Found a free slot, add descriptor */
-               FD_SET(fd, &rfp->fp_filp_inuse);
                rfp->fp_filp[fd] = cfilp;
                rfp->fp_filp[fd]->filp_count++;
                return(fd);
@@ -586,7 +511,6 @@ int fd;
   rfilp = (struct filp *) verify_fd(ep, fd);
   if (rfilp != NULL) {
        /* Found a valid descriptor, remove it */
-       FD_CLR(fd, &rfp->fp_filp_inuse);
        if (rfp->fp_filp[fd]->filp_count == 0) {
                unlock_filp(rfilp);
                printf("VFS: filp_count for slot %d fd %d already zero", slot,
@@ -653,15 +577,9 @@ struct filp *f;
                        }
                        unlock_bsf();
 
-                       /* Attempt to close only when feasible */
-                       if (!(f->filp_state & FS_INVALIDATED)) {
-                               (void) bdev_close(dev); /* Ignore errors */
-                       }
+                       (void) bdev_close(dev); /* Ignore errors */
                } else {
-                       /* Attempt to close only when feasible */
-                       if (!(f->filp_state & FS_INVALIDATED)) {
-                               (void) dev_close(dev);  /* Ignore errors */
-                       }
+                       (void) dev_close(dev);  /* Ignore errors */
                }
 
                f->filp_mode = FILP_CLOSED;
@@ -674,10 +592,7 @@ struct filp *f;
        release(vp, rw, susp_count);
   }
 
-  f->filp_count--;     /* If filp got invalidated at device closure, the
-                        * count might've become negative now */
-  if (f->filp_count == 0 ||
-      (f->filp_count < 0 && f->filp_state & FS_INVALIDATED)) {
+  if (--f->filp_count == 0) {
        if (S_ISFIFO(vp->v_mode)) {
                /* Last reader or writer is going. Tell PFS about latest
                 * pipe size.
index 444d9996826e0f78ab891c82b46d682793309fa5..097bcfaae4eeeb5329a34eade636c7541517a7f2 100644 (file)
@@ -20,8 +20,7 @@ EXTERN struct fproc {
   struct vnode *fp_wd;         /* working directory; NULL during reboot */
   struct vnode *fp_rd;         /* root directory; NULL during reboot */
 
-  struct filp *fp_filp[OPEN_MAX];/* the file descriptor table */
-  fd_set fp_filp_inuse;                /* which fd's are in use? */
+  struct filp *fp_filp[OPEN_MAX];/* the file descriptor table (free if NULL) */
   fd_set fp_cloexec_set;       /* bit map for POSIX Table 6-2 FD_CLOEXEC */
 
   dev_t fp_tty;                        /* major/minor of controlling tty */
@@ -59,16 +58,13 @@ EXTERN struct fproc {
 } fproc[NR_PROCS];
 
 /* fp_flags */
-#define FP_NOFLAGS     00
-#define FP_SUSP_REOPEN 01      /* Process is suspended until the reopens are
-                                * completed (after the restart of a driver).
-                                */
+#define FP_NOFLAGS      0000
+#define FP_SRV_PROC     0001   /* Set if process is a service */
 #define FP_REVIVED      0002   /* Indicates process is being revived */
 #define FP_SESLDR       0004   /* Set if process is session leader */
 #define FP_PENDING      0010   /* Set if process has pending work */
 #define FP_EXITING      0020   /* Set if process is exiting */
 #define FP_PM_WORK      0040   /* Set if process has a postponed PM request */
-#define FP_SRV_PROC     0100   /* Set if process is a service */
 
 /* Field values. */
 #define NOT_REVIVING       0xC0FFEEE   /* process is not being revived */
index 7e9087942984fb6601ce46970b87e14de93cccf8..56374d78c0d561c133234ba18761cbbd7bd85d86 100644 (file)
@@ -389,7 +389,8 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *info)
        /* Initialize process directories. mount_fs will set them to the
         * correct values.
         */
-       FD_ZERO(&(rfp->fp_filp_inuse));
+       for (i = 0; i < OPEN_MAX; i++)
+               rfp->fp_filp[i] = NULL;
        rfp->fp_rd = NULL;
        rfp->fp_wd = NULL;
   }
index e167c17a9d9d58cf2967e83993bde5d033930df7..449b366e6040b9347943411c662689232bdd6b0f 100644 (file)
@@ -121,7 +121,6 @@ int do_fcntl(message *UNUSED(m_out))
        else if ((r = get_fd(fp, fcntl_argx, 0, &new_fd, NULL)) == OK) {
                f->filp_count++;
                fp->fp_filp[new_fd] = f;
-               FD_SET(new_fd, &fp->fp_filp_inuse);
                r = new_fd;
        }
        break;
@@ -337,9 +336,6 @@ int dupvm(struct fproc *rfp, int pfd, int *vmfd, struct filp **newfilp)
        assert(f->filp_count > 0);
        vmf->fp_filp[procfd] = f;
 
-       /* mmap FD's are inuse */
-       FD_SET(procfd, &vmf->fp_filp_inuse);
-
        *newfilp = f;
 
        return OK;
index 6587c5371866be19a786103c66dff8f82998d42e..2beb489f6dbe37e9cd523b28de01870106135fe6 100644 (file)
@@ -127,7 +127,6 @@ int common_open(char path[PATH_MAX], int oflags, mode_t omode)
 
   /* Claim the file descriptor and filp slot and fill them in. */
   fp->fp_filp[scratch(fp).file.fd_nr] = filp;
-  FD_SET(scratch(fp).file.fd_nr, &fp->fp_filp_inuse);
   filp->filp_count = 1;
   filp->filp_vno = vp;
   filp->filp_flags = oflags;
@@ -267,10 +266,8 @@ int common_open(char path[PATH_MAX], int oflags, mode_t omode)
   if (r != OK) {
        if (r != SUSPEND) {
                fp->fp_filp[scratch(fp).file.fd_nr] = NULL;
-               FD_CLR(scratch(fp).file.fd_nr, &fp->fp_filp_inuse);
                filp->filp_count = 0;
                filp->filp_vno = NULL;
-               filp->filp_state &= ~FS_INVALIDATED; /* Prevent garbage col. */
                put_vnode(vp);
        }
   } else {
@@ -687,7 +684,6 @@ int fd_nr;
   close_filp(rfilp);
 
   FD_CLR(fd_nr, &rfp->fp_cloexec_set);
-  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) {
index 57c2378b8565c9c97e72a344b7b344fbca4bab8c..88da3ef7c5a953ccf2a31de000ce0165accddacd 100644 (file)
@@ -105,11 +105,9 @@ static int create_pipe(int fil_des[2], int flags)
        return(r);
   }
   rfp->fp_filp[fil_des[0]] = fil_ptr0;
-  FD_SET(fil_des[0], &rfp->fp_filp_inuse);
   fil_ptr0->filp_count = 1;            /* mark filp in use */
   if ((r = get_fd(fp, 0, W_BIT, &fil_des[1], &fil_ptr1)) != OK) {
        rfp->fp_filp[fil_des[0]] = NULL;
-       FD_CLR(fil_des[0], &rfp->fp_filp_inuse);
        fil_ptr0->filp_count = 0;       /* mark filp free */
        unlock_filp(fil_ptr0);
        unlock_vnode(vp);
@@ -117,7 +115,6 @@ static int create_pipe(int fil_des[2], int flags)
        return(r);
   }
   rfp->fp_filp[fil_des[1]] = fil_ptr1;
-  FD_SET(fil_des[1], &rfp->fp_filp_inuse);
   fil_ptr1->filp_count = 1;
 
   /* Create a named pipe inode on PipeFS */
@@ -126,10 +123,8 @@ static int create_pipe(int fil_des[2], int flags)
 
   if (r != OK) {
        rfp->fp_filp[fil_des[0]] = NULL;
-       FD_CLR(fil_des[0], &rfp->fp_filp_inuse);
        fil_ptr0->filp_count = 0;
        rfp->fp_filp[fil_des[1]] = NULL;
-       FD_CLR(fil_des[1], &rfp->fp_filp_inuse);
        fil_ptr1->filp_count = 0;
        unlock_filp(fil_ptr1);
        unlock_filp(fil_ptr0);
@@ -332,9 +327,6 @@ void suspend(int why)
   fp->fp_blocked_on = why;
   assert(fp->fp_grant == GRANT_INVALID || !GRANT_VALID(fp->fp_grant));
   fp->fp_block_callnr = job_call_nr;
-  fp->fp_flags &= ~FP_SUSP_REOPEN;             /* Clear this flag. The caller
-                                                * can set it when needed.
-                                                */
 }
 
 /*===========================================================================*
@@ -381,7 +373,7 @@ void unsuspend_by_endpt(endpoint_t proc_e)
   for (rp = &fproc[0]; rp < &fproc[NR_PROCS]; rp++) {
        if (rp->fp_pid == PID_FREE) continue;
        if (rp->fp_blocked_on == FP_BLOCKED_ON_OTHER && rp->fp_task == proc_e)
-               revive(rp->fp_endpoint, EAGAIN);
+               revive(rp->fp_endpoint, EIO);
   }
 
   /* Revive processes waiting in drivers on select()s with EAGAIN too */
@@ -436,8 +428,8 @@ int count;                  /* max number of processes to release */
                if (rp->fp_blocked_on == FP_BLOCKED_ON_POPEN ||
                    rp->fp_blocked_on == FP_BLOCKED_ON_LOCK ||
                    rp->fp_blocked_on == FP_BLOCKED_ON_OTHER) {
-                       if (!FD_ISSET(scratch(rp).file.fd_nr,
-                                                       &rp->fp_filp_inuse))
+                       f = rp->fp_filp[scratch(rp).file.fd_nr];
+                       if (f == NULL || f->filp_mode == FILP_CLOSED)
                                continue;
                        if (rp->fp_filp[scratch(rp).file.fd_nr]->filp_vno != vp)
                                continue;
@@ -570,15 +562,6 @@ void unpause(void)
                break;
 
        case FP_BLOCKED_ON_OTHER:/* process trying to do device I/O (e.g. tty)*/
-               if (fp->fp_flags & FP_SUSP_REOPEN) {
-                       /* Process is suspended while waiting for a reopen.
-                        * Just reply EINTR.
-                        */
-                       fp->fp_flags &= ~FP_SUSP_REOPEN;
-                       status = EINTR;
-                       break;
-               }
-
                fild = scratch(fp).file.fd_nr;
                if (fild < 0 || fild >= OPEN_MAX)
                        panic("file descriptor out-of-range");
index 9f6a38616c8f37e8663ca75d5a2f55232ccb5097..d989429e5c0054628ad9b9570f6611b81304daec 100644 (file)
@@ -30,14 +30,13 @@ void send_work(void);
 
 /* device.c */
 int dev_open(dev_t dev, int flags);
-int dev_reopen(dev_t dev, int filp_no, int flags);
 int dev_close(dev_t dev);
 void cdev_reply(void);
 int bdev_open(dev_t dev, int access);
 int bdev_close(dev_t dev);
 void bdev_reply(struct dmap *dp);
 int dev_io(int op, dev_t dev, endpoint_t proc_e, void *buf, off_t pos,
-       size_t bytes, int flags, int suspend_reopen);
+       size_t bytes, int flags);
 int gen_opcl(int op, dev_t dev, endpoint_t task_nr, int flags);
 int gen_io(endpoint_t drv_e, message *mess_ptr);
 int no_dev(int op, dev_t dev, endpoint_t proc, int flags);
@@ -51,7 +50,6 @@ int dev_select(dev_t dev, int ops);
 int dev_cancel(dev_t dev);
 void pm_setsid(endpoint_t proc_e);
 void bdev_up(int major);
-void cdev_up(int major);
 
 /* dmap.c */
 void lock_dmap(struct dmap *dp);
@@ -78,7 +76,6 @@ int pm_exec(vir_bytes path, size_t path_len, vir_bytes frame, size_t frame_len,
        vir_bytes *pc, vir_bytes *newsp, vir_bytes *ps_str, int flags);
 
 /* filedes.c */
-int do_filp_gc(void);
 void check_filp_locks(void);
 void check_filp_locks_by_me(void);
 void init_filps(void);
@@ -90,7 +87,7 @@ struct filp *get_filp2(struct fproc *rfp, int fild, tll_access_t locktype);
 void lock_filp(struct filp *filp, tll_access_t locktype);
 void unlock_filp(struct filp *filp);
 void unlock_filps(struct filp *filp1, struct filp *filp2);
-int invalidate_filp(struct filp *);
+void invalidate_filp(struct filp *);
 void invalidate_filp_by_endpt(endpoint_t proc_e);
 void invalidate_filp_by_char_major(int major);
 int do_verify_fd(message *m_out);
index fcd280aafe5386bd41cd24854418e8ea19104e67..1a43d4ad9b3789e3671fa00333f9b07507c62d68 100644 (file)
@@ -105,7 +105,7 @@ int actual_read_write_peek(struct fproc *rfp, int rw_flag, int io_fd,
 
   if (((f->filp_mode) & (ro ? R_BIT : W_BIT)) == 0) {
        unlock_filp(f);
-       return(f->filp_mode == FILP_CLOSED ? EIO : EBADF);
+       return(EBADF);
   }
   if (scratch(rfp).io.io_nbytes == 0) {
        unlock_filp(f);
@@ -160,7 +160,6 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f,
        r = rw_pipe(rw_flag, for_e, f, buf, size);
   } else if (S_ISCHR(vp->v_mode)) {    /* Character special files. */
        dev_t dev;
-       int suspend_reopen;
        int op = (rw_flag == READING ? DEV_READ_S : DEV_WRITE_S);
 
        if(rw_flag == PEEKING) {
@@ -171,11 +170,9 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f,
        if (vp->v_sdev == NO_DEV)
                panic("VFS: read_write tries to access char dev NO_DEV");
 
-       suspend_reopen = (f->filp_state & FS_NEEDS_REOPEN);
        dev = (dev_t) vp->v_sdev;
 
-       r = dev_io(op, dev, for_e, buf, position, size, f->filp_flags,
-                  suspend_reopen);
+       r = dev_io(op, dev, for_e, buf, position, size, f->filp_flags);
        if (r >= 0) {
                /* This should no longer happen: all calls are asynchronous. */
                printf("VFS: I/O to device %x succeeded immediately!?\n", dev);
index ace48a3979bf37e708d03971dc23e49f21993068..22f3c555a88cf45820d6b288af7b95b2582275ca 100644 (file)
@@ -752,7 +752,7 @@ void select_unsuspend_by_endpt(endpoint_t proc_e)
                major = major(f->filp_vno->v_sdev);
                if (dmap_driver_match(proc_e, major)) {
                        se->filps[fd] = NULL;
-                       se->error = EINTR;
+                       se->error = EIO;
                        select_cancel_filp(f);
                        wakehim = 1;
                }