summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPranith Kumar K <pkarampu@redhat.com>2015-02-05 21:23:37 +0530
committerVijay Bellur <vbellur@redhat.com>2015-02-06 14:04:32 -0800
commit2efb36047aa11838b2cde93a3e95741e7ba40bae (patch)
treeb5a06756058974d9d390b1781f8c920cf28859d4
parentf75bb4a9ca14b50c7f828ee3fe4ba73dd78f094c (diff)
syncop: Provide syncop_ftw and syncop_dir_scan utils
ftw provides file tree walk. dir_scan does just a readdir not readdirp. Also changed Afr's self-heal-daemon's crawling functions to use this. These utils will be used by ec in future to do proactive/full healing. Change-Id: I05715ddb789592c1b79a71e98f1e8cc29aac5c26 BUG: 1177601 Signed-off-by: Pranith Kumar K <pkarampu@redhat.com> Reviewed-on: http://review.gluster.org/9485 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Ravishankar N <ravishankar@redhat.com> Reviewed-by: Krutika Dhananjay <kdhananj@redhat.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
-rw-r--r--heal/src/glfs-heal.c36
-rw-r--r--libglusterfs/src/gf-dirent.c32
-rw-r--r--libglusterfs/src/gf-dirent.h2
-rw-r--r--libglusterfs/src/syncop.c166
-rw-r--r--libglusterfs/src/syncop.h12
-rw-r--r--tests/bugs/replicate/bug-1130892.t2
-rw-r--r--xlators/cluster/afr/src/afr-self-heald.c374
7 files changed, 322 insertions, 302 deletions
diff --git a/heal/src/glfs-heal.c b/heal/src/glfs-heal.c
index a6208fa052f..3ea3f430e3b 100644
--- a/heal/src/glfs-heal.c
+++ b/heal/src/glfs-heal.c
@@ -92,37 +92,6 @@ out:
return ret;
}
-int
-glfsh_get_index_dir_fd (xlator_t *xl, loc_t *loc, fd_t **fd)
-{
- int ret = -1;
-
- *fd = fd_create (loc->inode, GF_CLIENT_PID_GLFS_HEAL);
- if (!*fd) {
- printf ("fd_create failed: %s", strerror(errno));
- goto out;
- }
- ret = syncop_opendir (xl, loc, *fd);
- if (ret) {
- fd_unref(*fd);
-#ifdef GF_LINUX_HOST_OS /* See comment in afr_shd_index_opendir() */
- *fd = fd_anonymous (loc->inode);
- if (!*fd) {
- printf ("fd_anonymous failed: %s",
- strerror(errno));
- goto out;
- }
- ret = 0;
-#else
- printf ("opendir failed: %s", strerror(errno));
- goto out;
-#endif
- }
-
-out:
- return ret;
-}
-
static xlator_t*
_get_afr_ancestor (xlator_t *xl)
{
@@ -478,7 +447,7 @@ glfsh_print_pending_heals (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
goto out;
}
- ret = glfsh_get_index_dir_fd (xl, &dirloc, &fd);
+ ret = syncop_dirfd (xl, &dirloc, &fd, GF_CLIENT_PID_GLFS_HEAL);
if (ret)
goto out;
@@ -691,7 +660,8 @@ glfsh_heal_from_brick (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
else {
ret = glfsh_get_index_dir_loc (rootloc, client, &dirloc,
&op_errno);
- ret = glfsh_get_index_dir_fd (client, &dirloc, &fd);
+ ret = syncop_dirfd (client, &dirloc, &fd,
+ GF_CLIENT_PID_GLFS_HEAL);
if (ret)
goto out;
ret = glfsh_crawl_directory (fs, top_subvol, rootloc, client,
diff --git a/libglusterfs/src/gf-dirent.c b/libglusterfs/src/gf-dirent.c
index 3b42a0813d5..f6fd3ab54ee 100644
--- a/libglusterfs/src/gf-dirent.c
+++ b/libglusterfs/src/gf-dirent.c
@@ -67,6 +67,25 @@ gf_dirent_free (gf_dirent_t *entries)
}
}
+void
+gf_link_inode_from_dirent (xlator_t *this, inode_t *parent, gf_dirent_t *entry)
+{
+ inode_t *link_inode = NULL;
+ inode_t *tmp = NULL;
+
+ if (!entry->inode)
+ return;
+ link_inode = inode_link (entry->inode, parent,
+ entry->d_name, &entry->d_stat);
+ if (!link_inode)
+ return;
+
+ inode_lookup (link_inode);
+ tmp = entry->inode;
+ entry->inode = link_inode;
+ inode_unref (tmp);
+}
+
/* TODO: Currently, with this function, we will be breaking the
policy of 1-1 mapping of kernel nlookup refs with our inode_t's
nlookup count.
@@ -77,20 +96,9 @@ gf_link_inodes_from_dirent (xlator_t *this, inode_t *parent,
gf_dirent_t *entries)
{
gf_dirent_t *entry = NULL;
- inode_t *link_inode = NULL;
- inode_t *tmp = NULL;
list_for_each_entry (entry, &entries->list, list) {
- if (entry->inode) {
- link_inode = inode_link (entry->inode, parent,
- entry->d_name, &entry->d_stat);
- if (!link_inode)
- continue;
- inode_lookup (link_inode);
- tmp = entry->inode;
- entry->inode = link_inode;
- inode_unref (tmp);
- }
+ gf_link_inode_from_dirent (this, parent, entry);
}
return 0;
diff --git a/libglusterfs/src/gf-dirent.h b/libglusterfs/src/gf-dirent.h
index 588d522dbcf..4c1ff0b1684 100644
--- a/libglusterfs/src/gf-dirent.h
+++ b/libglusterfs/src/gf-dirent.h
@@ -55,4 +55,6 @@ void gf_dirent_free (gf_dirent_t *entries);
int gf_link_inodes_from_dirent (xlator_t *this, inode_t *parent,
gf_dirent_t *entries);
+void
+gf_link_inode_from_dirent (xlator_t *this, inode_t *parent, gf_dirent_t *entry);
#endif /* _GF_DIRENT_H */
diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c
index c2794732522..56042d6897e 100644
--- a/libglusterfs/src/syncop.c
+++ b/libglusterfs/src/syncop.c
@@ -2382,3 +2382,169 @@ syncop_inodelk (xlator_t *subvol, const char *volume, loc_t *loc, int32_t cmd,
return args.op_ret;
}
+
+int
+syncop_dirfd (xlator_t *subvol, loc_t *loc, fd_t **fd, int pid)
+{
+ int ret = 0;
+ fd_t *dirfd = NULL;
+
+ if (!fd)
+ return -EINVAL;
+
+ dirfd = fd_create (loc->inode, pid);
+ if (!dirfd) {
+ gf_log (subvol->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, dirfd);
+ if (ret) {
+ /*
+ * On Linux, if the brick was not updated, opendir will
+ * fail. We therefore use backward compatible code
+ * that violate the standards by reusing offsets
+ * in seekdir() from different DIR *, but it works on Linux.
+ *
+ * On other systems it never worked, hence we do not need
+ * to provide backward-compatibility.
+ */
+#ifdef GF_LINUX_HOST_OS
+ fd_unref (dirfd);
+ dirfd = fd_anonymous (loc->inode);
+ if (!dirfd) {
+ gf_log(subvol->name, GF_LOG_ERROR,
+ "fd_anonymous of %s failed: %s",
+ uuid_utoa (loc->gfid), strerror(errno));
+ ret = -errno;
+ goto out;
+ }
+ ret = 0;
+#else /* GF_LINUX_HOST_OS */
+ fd_unref (dirfd);
+ gf_log (subvol->name, GF_LOG_ERROR,
+ "opendir of %s failed: %s",
+ uuid_utoa (loc->gfid), strerror(errno));
+ goto out;
+#endif /* GF_LINUX_HOST_OS */
+ }
+out:
+ if (ret == 0)
+ *fd = dirfd;
+ return ret;
+}
+
+int
+syncop_ftw (xlator_t *subvol, loc_t *loc, int pid, void *data,
+ int (*fn) (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
+ void *data))
+{
+ loc_t child_loc = {0, };
+ fd_t *fd = NULL;
+ uint64_t offset = 0;
+ gf_dirent_t *entry = NULL;
+ int ret = 0;
+ gf_dirent_t entries;
+
+ ret = syncop_dirfd (subvol, loc, &fd, pid);
+ if (ret)
+ goto out;
+
+ INIT_LIST_HEAD (&entries.list);
+
+ while ((ret = syncop_readdirp (subvol, fd, 131072, offset, 0,
+ &entries))) {
+ if (ret < 0)
+ break;
+
+ if (ret > 0) {
+ /* If the entries are only '.', and '..' then ret
+ * value will be non-zero. so set it to zero here. */
+ ret = 0;
+ }
+ list_for_each_entry (entry, &entries.list, list) {
+ offset = entry->d_off;
+
+ if (!strcmp (entry->d_name, ".") ||
+ !strcmp (entry->d_name, ".."))
+ continue;
+
+ gf_link_inode_from_dirent (NULL, fd->inode, entry);
+
+ ret = fn (subvol, entry, loc, data);
+ if (ret)
+ break;
+
+ if (entry->d_stat.ia_type == IA_IFDIR) {
+ child_loc.inode = inode_ref (entry->inode);
+ uuid_copy (child_loc.gfid, entry->inode->gfid);
+ ret = syncop_ftw (subvol, &child_loc,
+ pid, data, fn);
+ loc_wipe (&child_loc);
+ if (ret)
+ break;
+ }
+ }
+
+ gf_dirent_free (&entries);
+ if (ret)
+ break;
+ }
+
+out:
+ if (fd)
+ fd_unref (fd);
+ return ret;
+}
+
+int
+syncop_dir_scan (xlator_t *subvol, loc_t *loc, int pid, void *data,
+ int (*fn) (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
+ void *data))
+{
+ fd_t *fd = NULL;
+ uint64_t offset = 0;
+ gf_dirent_t *entry = NULL;
+ int ret = 0;
+ gf_dirent_t entries;
+
+ ret = syncop_dirfd (subvol, loc, &fd, pid);
+ if (ret)
+ goto out;
+
+ INIT_LIST_HEAD (&entries.list);
+
+ while ((ret = syncop_readdir (subvol, fd, 131072, offset, &entries))) {
+ if (ret < 0)
+ break;
+
+ if (ret > 0) {
+ /* If the entries are only '.', and '..' then ret
+ * value will be non-zero. so set it to zero here. */
+ ret = 0;
+ }
+
+ list_for_each_entry (entry, &entries.list, list) {
+ offset = entry->d_off;
+
+ if (!strcmp (entry->d_name, ".") ||
+ !strcmp (entry->d_name, ".."))
+ continue;
+
+ ret = fn (subvol, entry, loc, data);
+ if (ret)
+ break;
+ }
+ gf_dirent_free (&entries);
+ if (ret)
+ break;
+ }
+
+out:
+ if (fd)
+ fd_unref (fd);
+ return ret;
+}
diff --git a/libglusterfs/src/syncop.h b/libglusterfs/src/syncop.h
index e95dd6fc33d..40ed0e865e3 100644
--- a/libglusterfs/src/syncop.h
+++ b/libglusterfs/src/syncop.h
@@ -427,4 +427,16 @@ int
syncop_inodelk (xlator_t *subvol, const char *volume, loc_t *loc, int32_t cmd,
struct gf_flock *lock, dict_t *xdata_req, dict_t **xdata_rsp);
+int
+syncop_ftw (xlator_t *subvol, loc_t *loc, int pid, void *data,
+ int (*fn) (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
+ void *data));
+
+int
+syncop_dir_scan (xlator_t *subvol, loc_t *loc, int pid, void *data,
+ int (*fn) (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
+ void *data));
+
+int
+syncop_dirfd (xlator_t *subvol, loc_t *loc, fd_t **fd, int pid);
#endif /* _SYNCOP_H */
diff --git a/tests/bugs/replicate/bug-1130892.t b/tests/bugs/replicate/bug-1130892.t
index 0840ffbb0b9..945ee4982fc 100644
--- a/tests/bugs/replicate/bug-1130892.t
+++ b/tests/bugs/replicate/bug-1130892.t
@@ -52,7 +52,9 @@ EXPECT_NOT "00000000" afr_get_specific_changelog_xattr $B0/${V0}-0/one trusted.a
EXPECT "00000000" afr_get_specific_changelog_xattr $B0/${V0}-0/one trusted.afr.$V0-client-1 metadata
TEST gluster volume set $V0 self-heal-daemon on
+
EXPECT_WITHIN $PROCESS_UP_TIMEOUT "Y" glustershd_up_status
+TEST $CLI volume heal $V0
EXPECT_WITHIN $HEAL_TIMEOUT "Y" is_dir_heal_done $B0/${V0}-0 $B0/${V0}-1 one
EXPECT_WITHIN $HEAL_TIMEOUT "Y" is_dir_heal_done $B0/${V0}-0 $B0/${V0}-1 one/two
EXPECT_WITHIN $HEAL_TIMEOUT "Y" is_file_heal_done $B0/${V0}-0 $B0/${V0}-1 one/two/three
diff --git a/xlators/cluster/afr/src/afr-self-heald.c b/xlators/cluster/afr/src/afr-self-heald.c
index 7426e9290a9..74998b97b63 100644
--- a/xlators/cluster/afr/src/afr-self-heald.c
+++ b/xlators/cluster/afr/src/afr-self-heald.c
@@ -216,21 +216,14 @@ out:
}
-fd_t *
-afr_shd_index_opendir (xlator_t *this, int child)
+inode_t*
+afr_shd_index_inode (xlator_t *this, xlator_t *subvol)
{
- fd_t *fd = NULL;
- afr_private_t *priv = NULL;
- xlator_t *subvol = NULL;
loc_t rootloc = {0, };
inode_t *inode = NULL;
int ret = 0;
dict_t *xattr = NULL;
void *index_gfid = NULL;
- loc_t loc = {0, };
-
- priv = this->private;
- subvol = priv->children[child];
rootloc.inode = inode_ref (this->itable->root);
uuid_copy (rootloc.gfid, rootloc.inode->gfid);
@@ -250,53 +243,15 @@ afr_shd_index_opendir (xlator_t *this, int child)
subvol->name, uuid_utoa (index_gfid));
inode = afr_shd_inode_find (this, subvol, index_gfid);
- if (!inode)
- goto out;
-
- fd = fd_create (inode, GF_CLIENT_PID_AFR_SELF_HEALD);
- if (!fd)
- goto out;
-
- uuid_copy (loc.gfid, index_gfid);
- loc.inode = inode;
-
- ret = syncop_opendir(this, &loc, fd);
- if (ret) {
- /*
- * On Linux, if the brick was not updated, opendir will
- * fail. We therefore use backward compatible code
- * that violate the standards by reusing offsets
- * in seekdir() from different DIR *, but it works on Linux.
- *
- * On other systems it never worked, hence we do not need
- * to provide backward-compatibility.
- */
-#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",
- uuid_utoa (index_gfid), subvol->name, strerror(errno));
- fd_unref (fd);
- fd = NULL;
- goto out;
-#endif /* GF_LINUX_HOST_OS */
- }
out:
loc_wipe (&rootloc);
- if (inode)
- inode_unref (inode);
-
if (xattr)
dict_unref (xattr);
- return fd;
-}
+ return inode;
+}
int
afr_shd_index_purge (xlator_t *subvol, inode_t *inode, char *name)
@@ -420,181 +375,95 @@ afr_shd_sweep_done (struct subvol_healer *healer)
GF_FREE (history);
}
-
int
-afr_shd_index_sweep (struct subvol_healer *healer)
+afr_shd_index_heal (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
+ void *data)
{
- xlator_t *this = NULL;
- int child = -1;
- fd_t *fd = NULL;
- xlator_t *subvol = NULL;
- afr_private_t *priv = NULL;
- uint64_t offset = 0;
- gf_dirent_t entries;
- gf_dirent_t *entry = NULL;
- uuid_t gfid;
- int ret = 0;
- int count = 0;
-
- this = healer->this;
- child = healer->subvol;
- priv = this->private;
- subvol = priv->children[child];
+ struct subvol_healer *healer = data;
+ afr_private_t *priv = NULL;
+ uuid_t gfid = {0};
+ int ret = 0;
- fd = afr_shd_index_opendir (this, child);
- if (!fd) {
- gf_log (this->name, GF_LOG_WARNING,
- "unable to opendir index-dir on %s", subvol->name);
- return -errno;
- }
-
- INIT_LIST_HEAD (&entries.list);
-
- while ((ret = syncop_readdir (subvol, fd, 131072, offset, &entries))) {
- if (ret > 0)
- ret = 0;
- list_for_each_entry (entry, &entries.list, list) {
- offset = entry->d_off;
+ priv = healer->this->private;
+ if (!priv->shd.enabled)
+ return -EBUSY;
- if (!priv->shd.enabled) {
- ret = -EBUSY;
- break;
- }
-
- if (!strcmp (entry->d_name, ".") ||
- !strcmp (entry->d_name, ".."))
- continue;
+ gf_log (healer->this->name, GF_LOG_DEBUG, "got entry: %s",
+ entry->d_name);
- gf_log (this->name, GF_LOG_DEBUG, "got entry: %s",
- entry->d_name);
-
- ret = uuid_parse (entry->d_name, gfid);
- if (ret)
- continue;
-
- ret = afr_shd_selfheal (healer, child, gfid);
- if (ret == 0)
- count++;
+ ret = uuid_parse (entry->d_name, gfid);
+ if (ret)
+ return 0;
- if (ret == -ENOENT || ret == -ESTALE) {
- afr_shd_index_purge (subvol, fd->inode,
- entry->d_name);
- ret = 0;
- }
- }
+ ret = afr_shd_selfheal (healer, healer->subvol, gfid);
- gf_dirent_free (&entries);
- if (ret)
- break;
- }
+ if (ret == -ENOENT || ret == -ESTALE)
+ afr_shd_index_purge (subvol, parent->inode, entry->d_name);
- if (fd) {
- if (fd->inode)
- inode_forget (fd->inode, 1);
- fd_unref (fd);
- }
-
- if (!ret)
- ret = count;
- return ret;
+ return 0;
}
-
int
-afr_shd_full_sweep (struct subvol_healer *healer, inode_t *inode)
+afr_shd_index_sweep (struct subvol_healer *healer)
{
- loc_t loc = {0, };
- fd_t *fd = NULL;
- xlator_t *this = NULL;
- xlator_t *subvol = NULL;
- afr_private_t *priv = NULL;
- uint64_t offset = 0;
- gf_dirent_t entries;
- gf_dirent_t *entry = NULL;
- int ret = 0;
+ loc_t loc = {0};
+ afr_private_t *priv = NULL;
+ int ret = 0;
+ xlator_t *subvol = NULL;
- this = healer->this;
- priv = this->private;
+ priv = healer->this->private;
subvol = priv->children[healer->subvol];
- 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 */
+ loc.inode = afr_shd_index_inode (healer->this, subvol);
+ if (!loc.inode) {
+ gf_log (healer->this->name, GF_LOG_WARNING,
+ "unable to get index-dir on %s", subvol->name);
+ return -errno;
}
- INIT_LIST_HEAD (&entries.list);
+ ret = syncop_dir_scan (subvol, &loc, GF_CLIENT_PID_AFR_SELF_HEALD,
+ healer, afr_shd_index_heal);
- while ((ret = syncop_readdirp (subvol, fd, 131072, offset, 0, &entries))) {
- if (ret < 0)
- break;
+ inode_forget (loc.inode, 1);
+ loc_wipe (&loc);
- ret = gf_link_inodes_from_dirent (this, fd->inode, &entries);
- if (ret)
- break;
+ if (ret == 0)
+ ret = healer->crawl_event.healed_count;
- list_for_each_entry (entry, &entries.list, list) {
- offset = entry->d_off;
-
- if (!priv->shd.enabled) {
- ret = -EBUSY;
- break;
- }
+ return ret;
+}
- if (!strcmp (entry->d_name, ".") ||
- !strcmp (entry->d_name, ".."))
- continue;
+int
+afr_shd_full_heal (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
+ void *data)
+{
+ struct subvol_healer *healer = data;
+ xlator_t *this = healer->this;
+ afr_private_t *priv = NULL;
- afr_shd_selfheal_name (healer, healer->subvol,
- inode->gfid, entry->d_name);
+ priv = this->private;
+ if (!priv->shd.enabled)
+ return -EBUSY;
- afr_shd_selfheal (healer, healer->subvol,
- entry->d_stat.ia_gfid);
+ afr_shd_selfheal_name (healer, healer->subvol,
+ parent->inode->gfid, entry->d_name);
- if (entry->d_stat.ia_type == IA_IFDIR) {
- ret = afr_shd_full_sweep (healer, entry->inode);
- if (ret)
- break;
- }
- }
+ afr_shd_selfheal (healer, healer->subvol, entry->d_stat.ia_gfid);
- gf_dirent_free (&entries);
- if (ret)
- break;
- }
+ return 0;
+}
-out:
- loc_wipe (&loc);
- if (fd)
- fd_unref (fd);
- return ret;
+int
+afr_shd_full_sweep (struct subvol_healer *healer, inode_t *inode)
+{
+ afr_private_t *priv = NULL;
+ loc_t loc = {0};
+
+ priv = healer->this->private;
+ loc.inode = inode;
+ return syncop_ftw (priv->children[healer->subvol], &loc,
+ GF_CLIENT_PID_AFR_SELF_HEALD, healer,
+ afr_shd_full_heal);
}
@@ -974,78 +843,69 @@ out:
return ret;
}
-
int
-afr_shd_gather_index_entries (xlator_t *this, int child, dict_t *output)
+afr_shd_gather_entry (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
+ void *data)
{
- fd_t *fd = NULL;
- xlator_t *subvol = NULL;
- afr_private_t *priv = NULL;
- uint64_t offset = 0;
- gf_dirent_t entries;
- gf_dirent_t *entry = NULL;
- uuid_t gfid;
- int ret = 0;
- int count = 0;
- char *path = NULL;
+ dict_t *output = data;
+ xlator_t *this = NULL;
+ afr_private_t *priv = NULL;
+ char *path = NULL;
+ int ret = 0;
+ int child = 0;
+ uuid_t gfid = {0};
- priv = this->private;
- subvol = priv->children[child];
-
- fd = afr_shd_index_opendir (this, child);
- if (!fd) {
- gf_log (this->name, GF_LOG_WARNING,
- "unable to opendir index-dir on %s", subvol->name);
- return -errno;
- }
+ this = THIS;
+ priv = this->private;
- INIT_LIST_HEAD (&entries.list);
+ gf_log (this->name, GF_LOG_DEBUG, "got entry: %s",
+ entry->d_name);
- while ((ret = syncop_readdir (subvol, fd, 131072, offset, &entries))) {
- if (ret > 0)
- ret = 0;
- list_for_each_entry (entry, &entries.list, list) {
- offset = entry->d_off;
-
- if (!strcmp (entry->d_name, ".") ||
- !strcmp (entry->d_name, ".."))
- continue;
+ ret = uuid_parse (entry->d_name, gfid);
+ if (ret)
+ return 0;
- gf_log (this->name, GF_LOG_DEBUG, "got entry: %s",
- entry->d_name);
+ for (child = 0; child < priv->child_count; child++)
+ if (priv->children[child] == subvol)
+ break;
- ret = uuid_parse (entry->d_name, gfid);
- if (ret)
- continue;
+ if (child == priv->child_count)
+ return 0;
- path = NULL;
- ret = afr_shd_gfid_to_path (this, subvol, gfid, &path);
-
- if (ret == -ENOENT || ret == -ESTALE) {
- afr_shd_index_purge (subvol, fd->inode,
- entry->d_name);
- ret = 0;
- continue;
- }
+ ret = afr_shd_gfid_to_path (this, subvol, gfid, &path);
- ret = afr_shd_dict_add_path (this, output, child, path,
- NULL);
- }
+ if (ret == -ENOENT || ret == -ESTALE) {
+ afr_shd_index_purge (subvol, parent->inode, entry->d_name);
+ } else if (ret == 0) {
+ ret = afr_shd_dict_add_path (this, output, child, path, NULL);
+ }
- gf_dirent_free (&entries);
- if (ret)
- break;
- }
+ return 0;
+}
- if (fd) {
- if (fd->inode)
- inode_forget (fd->inode, 1);
- fd_unref (fd);
+int
+afr_shd_gather_index_entries (xlator_t *this, int child, dict_t *output)
+{
+ loc_t loc = {0};
+ afr_private_t *priv = NULL;
+ xlator_t *subvol = NULL;
+ int ret = 0;
+
+ priv = this->private;
+ subvol = priv->children[child];
+
+ loc.inode = afr_shd_index_inode (this, subvol);
+ if (!loc.inode) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "unable to get index-dir on %s", subvol->name);
+ return -errno;
}
- if (!ret)
- ret = count;
- return ret;
+ ret = syncop_dir_scan (subvol, &loc, GF_CLIENT_PID_AFR_SELF_HEALD,
+ output, afr_shd_gather_entry);
+ inode_forget (loc.inode, 1);
+ loc_wipe (&loc);
+ return ret;
}