From e28f7b749e2e8895be9c177c633e4c1ac7067c7f Mon Sep 17 00:00:00 2001 From: chz Date: Mon, 21 Nov 2016 23:21:08 -0800 Subject: [PATCH] use read() for sequential reads on fd Some special files will complain when accessed with pread (e.g., relayfs will give "illegal seek"). To avoid these errors, ioctx uses read() instead of pread() when sequentially reading from a file. --- diod/ioctx.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/diod/ioctx.c b/diod/ioctx.c index aabf3677..3b8d1971 100644 --- a/diod/ioctx.c +++ b/diod/ioctx.c @@ -66,6 +66,7 @@ struct ioctx_struct { pthread_mutex_t lock; int refcount; int fd; + off_t off; DIR *dir; int lock_type; Npqid qid; @@ -181,6 +182,7 @@ _ioctx_create_open (Npuser *user, Path path, int flags, u32 mode) ioctx->refcount = 1; ioctx->lock_type = LOCK_UN; ioctx->dir = NULL; + ioctx->off = 0; ioctx->open_flags = flags; ioctx->user = user; np_user_incref (user); @@ -266,7 +268,27 @@ ioctx_open (Npfid *fid, u32 flags, u32 mode) int ioctx_pread (IOCtx ioctx, void *buf, size_t count, off_t offset) { - return pread (ioctx->fd, buf, count, offset); + ssize_t ret; + int has_read = 0; + + // claim read() if fd is at this offset + xpthread_mutex_lock (&ioctx->lock); + if (ioctx->off != -1 && ioctx->off == offset) { + ioctx->off = -1; + has_read = 1; + } + xpthread_mutex_unlock (&ioctx->lock); + + if (!has_read) { + return pread (ioctx->fd, buf, count, offset); + } + ret = read (ioctx->fd, buf, count); + + // next read() operation will follow the end of this one + xpthread_mutex_lock (&ioctx->lock); + ioctx->off = (ret < 0) ? offset : offset + ret; + xpthread_mutex_unlock (&ioctx->lock); + return ret; } int