]> Zhao Yanbai Git Server - minix.git/commitdiff
VFS: update filp_pos on chardev I/O (workaround) 60/960/2
authorDavid van Moolenbroek <david@minix3.org>
Mon, 2 Sep 2013 15:34:44 +0000 (17:34 +0200)
committerLionel Sambuc <lionel@minix3.org>
Tue, 18 Feb 2014 10:25:03 +0000 (11:25 +0100)
Previously, reading from or writing to a character device would not
update the file position on the corresponding filp object.  Performing
this update correctly is not trivial: during and after the I/O
operation, the filp object must not be locked.  Ideally, read/write
requests on a filp that is already involved in a read/write operation,
should be queued.  For now, we optimistically update the file position
at the start of the I/O; this works under the assumptions listed in
the corresponding comment.

Change-Id: I172a61781850423709924390ae3df1f2d1f94707

servers/vfs/read.c

index fd3f9fcb65e0a574f5909df0d1c3a733d5046f90..fcd280aafe5386bd41cd24854418e8ea19104e67 100644 (file)
@@ -177,9 +177,31 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f,
        r = dev_io(op, dev, for_e, buf, position, size, f->filp_flags,
                   suspend_reopen);
        if (r >= 0) {
+               /* This should no longer happen: all calls are asynchronous. */
+               printf("VFS: I/O to device %x succeeded immediately!?\n", dev);
                cum_io = r;
-               position += cum_io;
+               position += r;
                r = OK;
+       } else if (r == SUSPEND) {
+               /* FIXME: multiple read/write operations on a single filp
+                * should be serialized. They currently aren't; in order to
+                * achieve a similar effect, we optimistically advance the file
+                * position here. This works under the following assumptions:
+                * - character drivers that use the seek position at all,
+                *   expose a view of a statically-sized range of bytes, i.e.,
+                *   they are basically byte-granular block devices;
+                * - if short I/O or an error is returned, all subsequent calls
+                *   will return (respectively) EOF and an error;
+                * - the application never checks its own file seek position,
+                *   or does not care that it may end up having seeked beyond
+                *   the number of bytes it has actually read;
+                * - communication to the character driver is FIFO (this one
+                *   is actually true! whew).
+                * Many improvements are possible here, but in the end,
+                * anything short of queuing concurrent operations will be
+                * suboptimal - so we settle for this hack for now.
+                */
+               position += size;
        }
   } else if (S_ISBLK(vp->v_mode)) {    /* Block special files. */
        if (vp->v_sdev == NO_DEV)