From: David van Moolenbroek Date: Mon, 2 Sep 2013 15:34:44 +0000 (+0200) Subject: VFS: update filp_pos on chardev I/O (workaround) X-Git-Tag: v3.3.0~598 X-Git-Url: http://zhaoyanbai.com/repos/COPYRIGHT?a=commitdiff_plain;h=refs%2Fchanges%2F60%2F960%2F2;p=minix.git VFS: update filp_pos on chardev I/O (workaround) 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 --- diff --git a/servers/vfs/read.c b/servers/vfs/read.c index fd3f9fcb6..fcd280aaf 100644 --- a/servers/vfs/read.c +++ b/servers/vfs/read.c @@ -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)