From 9d0dbd3eb4279a4d8dc5a2e8adae31132c7d489a Mon Sep 17 00:00:00 2001
From: Wenguang Wang <wenguangw@vmware.com>
Date: Mon, 2 Mar 2020 10:41:13 -0800
Subject: [PATCH 02/10] p9fs_dir_readdir offset support
In the linux 9p client fs module, in readdir implementation, we do not check
for current offset position (which could have been changed by a seek call), and
keep returning (now incorrect) data from the already read and remaining buffer.
---
fs/9p/vfs_dir.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
index 3bb95adc9..cf44b0690 100644
--- a/fs/9p/vfs_dir.c
+++ b/fs/9p/vfs_dir.c
@@ -29,6 +29,7 @@
* struct p9_rdir - readdir accounting
* @head: start offset of current dirread buffer
* @tail: end offset of current dirread buffer
+ * @pos: expected dir offset to read the dirread buffer @head
* @buf: dirread buffer
*
* private structure for keeping track of readdir
@@ -38,6 +39,7 @@
struct p9_rdir {
int head;
int tail;
+ off_t pos;
uint8_t buf[];
};
@@ -105,7 +107,7 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
kvec.iov_len = buflen;
while (1) {
- if (rdir->tail == rdir->head) {
+ if (rdir->tail == rdir->head || rdir->pos != ctx->pos) {
struct iov_iter to;
int n;
@@ -135,6 +137,7 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
return 0;
rdir->head += err;
+ rdir->pos += err;
ctx->pos += err;
}
}
@@ -164,7 +167,7 @@ static int v9fs_dir_readdir_dotl(struct file *file, struct dir_context *ctx)
return -ENOMEM;
while (1) {
- if (rdir->tail == rdir->head) {
+ if (rdir->tail == rdir->head || rdir->pos != ctx->pos) {
err = p9_client_readdir(fid, rdir->buf, buflen,
ctx->pos);
if (err <= 0)
@@ -191,6 +194,7 @@ static int v9fs_dir_readdir_dotl(struct file *file, struct dir_context *ctx)
return 0;
ctx->pos = curdirent.d_off;
+ rdir->pos = curdirent.d_off;
rdir->head += err;
}
}
--
2.39.0