diff options
-rw-r--r-- | xlators/cluster/afr/src/afr-self-heald.c | 46 | ||||
-rw-r--r-- | xlators/features/index/src/index.c | 42 | ||||
-rw-r--r-- | xlators/features/index/src/index.h | 1 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.c | 26 |
4 files changed, 87 insertions, 28 deletions
diff --git a/xlators/cluster/afr/src/afr-self-heald.c b/xlators/cluster/afr/src/afr-self-heald.c index 10e19964ed9..6ce52aad1c4 100644 --- a/xlators/cluster/afr/src/afr-self-heald.c +++ b/xlators/cluster/afr/src/afr-self-heald.c @@ -276,6 +276,8 @@ afr_shd_index_opendir (xlator_t *this, int child) #ifdef GF_LINUX_HOST_OS fd_unref (fd); fd = fd_anonymous (inode); + if (!fd) + goto out; #else /* GF_LINUX_HOST_OS */ gf_log(this->name, GF_LOG_ERROR, "opendir of %s for %s failed: %s", @@ -429,7 +431,7 @@ afr_shd_index_sweep (struct subvol_healer *healer) fd_t *fd = NULL; xlator_t *subvol = NULL; afr_private_t *priv = NULL; - off_t offset = 0; + uint64_t offset = 0; gf_dirent_t entries; gf_dirent_t *entry = NULL; uuid_t gfid; @@ -503,11 +505,12 @@ afr_shd_index_sweep (struct subvol_healer *healer) int afr_shd_full_sweep (struct subvol_healer *healer, inode_t *inode) { + loc_t loc = {0, }; fd_t *fd = NULL; xlator_t *this = NULL; xlator_t *subvol = NULL; afr_private_t *priv = NULL; - off_t offset = 0; + uint64_t offset = 0; gf_dirent_t entries; gf_dirent_t *entry = NULL; int ret = 0; @@ -516,9 +519,38 @@ afr_shd_full_sweep (struct subvol_healer *healer, inode_t *inode) priv = this->private; subvol = priv->children[healer->subvol]; - fd = fd_anonymous (inode); - if (!fd) - return -errno; + uuid_copy (loc.gfid, inode->gfid); + loc.inode = inode_ref(inode); + + fd = fd_create (inode, GF_CLIENT_PID_AFR_SELF_HEALD); + if (!fd) { + gf_log(this->name, GF_LOG_ERROR, + "fd_create of %s failed: %s", + uuid_utoa (loc.gfid), strerror(errno)); + ret = -errno; + goto out; + } + + ret = syncop_opendir (subvol, &loc, fd); + if (ret) { +#ifdef GF_LINUX_HOST_OS /* See comment in afr_shd_index_opendir() */ + fd_unref(fd); + fd = fd_anonymous (inode); + if (!fd) { + gf_log(this->name, GF_LOG_ERROR, + "fd_anonymous of %s failed: %s", + uuid_utoa (loc.gfid), strerror(errno)); + ret = -errno; + goto out; + } +#else /* GF_LINUX_HOST_OS */ + gf_log(this->name, GF_LOG_ERROR, + "opendir of %s failed: %s", + uuid_utoa (loc.gfid), strerror(errno)); + ret = -errno; + goto out; +#endif /* GF_LINUX_HOST_OS */ + } INIT_LIST_HEAD (&entries.list); @@ -560,6 +592,8 @@ afr_shd_full_sweep (struct subvol_healer *healer, inode_t *inode) break; } +out: + loc_wipe (&loc); if (fd) fd_unref (fd); return ret; @@ -949,7 +983,7 @@ afr_shd_gather_index_entries (xlator_t *this, int child, dict_t *output) fd_t *fd = NULL; xlator_t *subvol = NULL; afr_private_t *priv = NULL; - off_t offset = 0; + uint64_t offset = 0; gf_dirent_t entries; gf_dirent_t *entry = NULL; uuid_t gfid; diff --git a/xlators/features/index/src/index.c b/xlators/features/index/src/index.c index c342da8274c..50e2e0ab54d 100644 --- a/xlators/features/index/src/index.c +++ b/xlators/features/index/src/index.c @@ -268,10 +268,11 @@ check_delete_stale_index_file (xlator_t *this, char *filename) } static int -index_fill_readdir (fd_t *fd, DIR *dir, off_t off, +index_fill_readdir (fd_t *fd, index_fd_ctx_t *fctx, DIR *dir, off_t off, size_t size, gf_dirent_t *entries) { off_t in_case = -1; + off_t last_off = 0; size_t filled = 0; int count = 0; char entrybuf[sizeof(struct dirent) + 256 + 8]; @@ -286,11 +287,11 @@ index_fill_readdir (fd_t *fd, DIR *dir, off_t off, } else { seekdir (dir, off); #ifndef GF_LINUX_HOST_OS - if (telldir(dir) != off) { + if ((u_long)telldir(dir) != off && off != fctx->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; @@ -299,7 +300,7 @@ index_fill_readdir (fd_t *fd, DIR *dir, off_t off, } while (filled <= size) { - in_case = telldir (dir); + in_case = (u_long)telldir (dir); if (in_case == -1) { gf_log (THIS->name, GF_LOG_ERROR, @@ -335,12 +336,13 @@ index_fill_readdir (fd_t *fd, DIR *dir, off_t off, if (this_size + filled > size) { seekdir (dir, in_case); #ifndef GF_LINUX_HOST_OS - if (telldir(dir) != in_case) { + if ((u_long)telldir(dir) != in_case && + in_case != fctx->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; @@ -357,7 +359,14 @@ index_fill_readdir (fd_t *fd, DIR *dir, off_t off, 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; list_add_tail (&this_entry->list, &entries->list); @@ -366,9 +375,12 @@ index_fill_readdir (fd_t *fd, DIR *dir, off_t off, count ++; } - if ((!readdir (dir) && (errno == 0))) + if ((!readdir (dir) && (errno == 0))) { /* Indicate EOF */ errno = ENOENT; + /* Remember EOF offset for later detection */ + fctx->dir_eof = last_off; + } out: return count; } @@ -581,6 +593,7 @@ __index_fd_ctx_get (fd_t *fd, xlator_t *this, index_fd_ctx_t **ctx) fctx = NULL; goto out; } + fctx->dir_eof = -1; ret = __fd_ctx_set (fd, this, (uint64_t)(long)fctx); if (ret) { @@ -949,7 +962,7 @@ index_readdir_wrapper (call_frame_t *frame, xlator_t *this, goto done; } - count = index_fill_readdir (fd, dir, off, size, &entries); + count = index_fill_readdir (fd, fctx, dir, off, size, &entries); /* pick ENOENT to indicate EOF */ op_errno = errno; @@ -1270,8 +1283,11 @@ index_releasedir (xlator_t *this, fd_t *fd) goto out; fctx = (index_fd_ctx_t*) (long) ctx; - if (fctx->dir) - closedir (fctx->dir); + if (fctx->dir) { + ret = closedir (fctx->dir); + if (ret) + gf_log (this->name, GF_LOG_ERROR, "closedir error: %s", strerror (errno)); + } GF_FREE (fctx); out: diff --git a/xlators/features/index/src/index.h b/xlators/features/index/src/index.h index 661dcdbc417..206d280e519 100644 --- a/xlators/features/index/src/index.h +++ b/xlators/features/index/src/index.h @@ -34,6 +34,7 @@ typedef struct index_inode_ctx { typedef struct index_fd_ctx { DIR *dir; + off_t dir_eof; } index_fd_ctx_t; typedef struct index_priv { diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index d8599881fb7..c1730e8d337 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -4853,6 +4853,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]; @@ -4888,11 +4889,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; @@ -4901,7 +4902,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, @@ -4961,13 +4962,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; @@ -4984,7 +4985,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; @@ -4998,7 +5006,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; |