diff options
Diffstat (limited to 'xlators/storage/posix/src/posix.c')
-rw-r--r-- | xlators/storage/posix/src/posix.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index a3aa57a0153..638e0f59202 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -4857,6 +4857,7 @@ posix_fill_readdir (fd_t *fd, DIR *dir, off_t off, size_t size, gf_dirent_t *entries, xlator_t *this, int32_t skip_dirs) { off_t in_case = -1; + off_t last_off = 0; size_t filled = 0; int count = 0; char entrybuf[sizeof(struct dirent) + 256 + 8]; @@ -4892,11 +4893,11 @@ 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) != (long)off && off != pfd->dir_eof) { + if ((u_long)telldir(dir) != off && off != pfd->dir_eof) { gf_log (THIS->name, GF_LOG_ERROR, - "seekdir(%ld) failed on dir=%p: " + "seekdir(0x%llx) failed on dir=%p: " "Invalid argument (offset reused from " - "another DIR * structure?)", (long)off, dir); + "another DIR * structure?)", off, dir); errno = EINVAL; count = -1; goto out; @@ -4905,7 +4906,7 @@ posix_fill_readdir (fd_t *fd, DIR *dir, off_t off, size_t size, } while (filled <= size) { - in_case = telldir (dir); + in_case = (u_long)telldir (dir); if (in_case == -1) { gf_log (THIS->name, GF_LOG_ERROR, @@ -4965,13 +4966,13 @@ 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) != (long)in_case && + if ((u_long)telldir(dir) != in_case && in_case != pfd->dir_eof) { gf_log (THIS->name, GF_LOG_ERROR, - "seekdir(%ld) failed on dir=%p: " + "seekdir(0x%llx) failed on dir=%p: " "Invalid argument (offset reused from " "another DIR * structure?)", - (long)in_case, dir); + in_case, dir); errno = EINVAL; count = -1; goto out; @@ -4988,7 +4989,14 @@ posix_fill_readdir (fd_t *fd, DIR *dir, off_t off, size_t size, entry->d_name, strerror (errno)); goto out; } - this_entry->d_off = telldir (dir); + /* + * we store the offset of next entry here, which is + * probably not intended, but code using syncop_readdir() + * (glfs-heal.c, afr-self-heald.c, pump.c) rely on it + * for directory read resumption. + */ + last_off = (u_long)telldir(dir); + this_entry->d_off = last_off; this_entry->d_ino = entry->d_ino; this_entry->d_type = entry->d_type; @@ -5002,7 +5010,7 @@ posix_fill_readdir (fd_t *fd, DIR *dir, off_t off, size_t size, /* Indicate EOF */ errno = ENOENT; /* Remember EOF offset for later detection */ - pfd->dir_eof = telldir (dir); + pfd->dir_eof = (u_long)last_off; } out: return count; |