diff options
| -rw-r--r-- | xlators/storage/posix/src/posix.c | 21 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix.h | 1 | 
2 files changed, 19 insertions, 3 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index a0027055fad..3e3d14fc793 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); @@ -4844,12 +4845,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 */ @@ -4863,7 +4874,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 " @@ -4936,7 +4947,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 " @@ -4968,9 +4980,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 */  };  | 
