summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xlators/storage/posix/src/posix.c21
-rw-r--r--xlators/storage/posix/src/posix.h1
2 files changed, 19 insertions, 3 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index 6b12d39df79..9f7fa0313cd 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -933,6 +933,7 @@ posix_opendir (call_frame_t *frame, xlator_t *this,
}
pfd->dir = dir;
+ pfd->dir_eof = -1;
pfd->fd = dirfd (dir);
op_ret = fd_ctx_set (fd, this, (uint64_t)(long)pfd);
@@ -4845,12 +4846,22 @@ posix_fill_readdir (fd_t *fd, DIR *dir, off_t off, size_t size,
struct dirent *entry = NULL;
int32_t this_size = -1;
gf_dirent_t *this_entry = NULL;
+ struct posix_fd *pfd = NULL;
uuid_t rootgfid = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
struct stat stbuf = {0,};
char *hpath = NULL;
int len = 0;
int ret = 0;
+ ret = posix_fd_ctx_get (fd, this, &pfd);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "pfd is NULL, fd=%p", fd);
+ count = -1;
+ errno = -ret;
+ goto out;
+ }
+
if (skip_dirs) {
len = posix_handle_path (this, fd->inode->gfid, NULL, NULL, 0);
hpath = alloca (len + 256); /* NAME_MAX */
@@ -4864,7 +4875,7 @@ posix_fill_readdir (fd_t *fd, DIR *dir, off_t off, size_t size,
} else {
seekdir (dir, off);
#ifndef GF_LINUX_HOST_OS
- if (telldir(dir) != off) {
+ if (telldir(dir) != (long)off && off != pfd->dir_eof) {
gf_log (THIS->name, GF_LOG_ERROR,
"seekdir(%ld) failed on dir=%p: "
"Invalid argument (offset reused from "
@@ -4937,7 +4948,8 @@ posix_fill_readdir (fd_t *fd, DIR *dir, off_t off, size_t size,
if (this_size + filled > size) {
seekdir (dir, in_case);
#ifndef GF_LINUX_HOST_OS
- if (telldir(dir) != in_case) {
+ if (telldir(dir) != (long)in_case &&
+ in_case != pfd->dir_eof) {
gf_log (THIS->name, GF_LOG_ERROR,
"seekdir(%ld) failed on dir=%p: "
"Invalid argument (offset reused from "
@@ -4969,9 +4981,12 @@ posix_fill_readdir (fd_t *fd, DIR *dir, off_t off, size_t size,
count ++;
}
- if ((!readdir (dir) && (errno == 0)))
+ if ((!readdir (dir) && (errno == 0))) {
/* Indicate EOF */
errno = ENOENT;
+ /* Remember EOF offset for later detection */
+ pfd->dir_eof = telldir (dir);
+ }
out:
return count;
}
diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h
index 5bb5e873c82..870315d0ea2 100644
--- a/xlators/storage/posix/src/posix.h
+++ b/xlators/storage/posix/src/posix.h
@@ -68,6 +68,7 @@ struct posix_fd {
int fd; /* fd returned by the kernel */
int32_t flags; /* flags for open/creat */
DIR * dir; /* handle returned by the kernel */
+ off_t dir_eof; /* offset at dir EOF */
int odirect;
struct list_head list; /* to add to the janitor list */
};