diff options
| author | Pranith Kumar K <pkarampu@redhat.com> | 2015-02-05 21:23:37 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vbellur@redhat.com> | 2015-02-06 14:04:32 -0800 | 
| commit | 2efb36047aa11838b2cde93a3e95741e7ba40bae (patch) | |
| tree | b5a06756058974d9d390b1781f8c920cf28859d4 | |
| parent | f75bb4a9ca14b50c7f828ee3fe4ba73dd78f094c (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.c | 36 | ||||
| -rw-r--r-- | libglusterfs/src/gf-dirent.c | 32 | ||||
| -rw-r--r-- | libglusterfs/src/gf-dirent.h | 2 | ||||
| -rw-r--r-- | libglusterfs/src/syncop.c | 166 | ||||
| -rw-r--r-- | libglusterfs/src/syncop.h | 12 | ||||
| -rw-r--r-- | tests/bugs/replicate/bug-1130892.t | 2 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heald.c | 374 | 
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;  }  | 
