summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libglusterfs/src/dict.c22
-rw-r--r--libglusterfs/src/dict.h1
-rw-r--r--xlators/cluster/afr/src/pump.c121
3 files changed, 101 insertions, 43 deletions
diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c
index 7fbacf7c3..cfa1b8317 100644
--- a/libglusterfs/src/dict.c
+++ b/libglusterfs/src/dict.c
@@ -1247,6 +1247,28 @@ fail:
return new;
}
+static void
+_remove (dict_t *dict,
+ char *key,
+ data_t *value,
+ void *unused)
+{
+ dict_del ((dict_t *)dict, key);
+}
+
+int
+dict_reset (dict_t *dict)
+{
+ int32_t ret = -1;
+ if (!dict) {
+ gf_log_callingfn ("dict", GF_LOG_WARNING, "dict is NULL");
+ goto out;
+ }
+ dict_foreach (dict, _remove, NULL);
+ ret = 0;
+out:
+ return ret;
+}
/*
* !!!!!!! CLEANED UP CODE !!!!!!!
*/
diff --git a/libglusterfs/src/dict.h b/libglusterfs/src/dict.h
index 0d404997e..76a085ee7 100644
--- a/libglusterfs/src/dict.h
+++ b/libglusterfs/src/dict.h
@@ -73,6 +73,7 @@ void data_destroy (data_t *data);
int32_t dict_set (dict_t *this, char *key, data_t *value);
data_t *dict_get (dict_t *this, char *key);
void dict_del (dict_t *this, char *key);
+int dict_reset (dict_t *dict);
int32_t dict_serialized_length (dict_t *dict);
int32_t dict_serialize (dict_t *dict, char *buf);
diff --git a/xlators/cluster/afr/src/pump.c b/xlators/cluster/afr/src/pump.c
index b756e1664..0eb57ac24 100644
--- a/xlators/cluster/afr/src/pump.c
+++ b/xlators/cluster/afr/src/pump.c
@@ -335,24 +335,62 @@ pump_save_file_stats (xlator_t *this, const char *path)
return 0;
}
-static int
-gf_pump_traverse_directory (loc_t *loc, uuid_t gfid)
+static void
+_generate_gfid_on_empty (uuid_t gfid)
{
- xlator_t *this = NULL;
- afr_private_t *priv = NULL;
- fd_t *fd = NULL;
+ if (uuid_is_null (gfid))
+ uuid_generate (gfid);
+}
- off_t offset = 0;
- loc_t entry_loc;
- gf_dirent_t *entry = NULL;
- gf_dirent_t *tmp = NULL;
- gf_dirent_t entries;
+static void
+_empty_gfid_on_set (uuid_t gfid, int lookup_status, struct iatt *iatt)
+{
+ if (lookup_status || !uuid_compare (gfid, iatt->ia_gfid))
+ uuid_clear (gfid);
+}
- struct iatt iatt, parent;
- dict_t *xattr_rsp;
+static void
+_fill_loc_info (loc_t *loc, struct iatt *iatt, struct iatt *parent)
+{
+ afr_update_loc_gfids (loc, iatt, parent);
+ uuid_copy (loc->inode->gfid, iatt->ia_gfid);
+ loc->ino = iatt->ia_ino;
+ loc->inode->ino = iatt->ia_ino;
+}
- int ret = 0;
- gf_boolean_t is_directory_empty = _gf_true;
+static void
+_wipe_loc (loc_t *loc)
+{
+ loc_wipe (loc);
+ uuid_clear (loc->gfid);
+ uuid_clear (loc->pargfid);
+ loc->ino = 0;
+}
+
+static int
+gf_pump_traverse_directory (loc_t *loc, uuid_t gfid)
+{
+ xlator_t *this = NULL;
+ afr_private_t *priv = NULL;
+ fd_t *fd = NULL;
+ off_t offset = 0;
+ loc_t entry_loc = {0};
+ gf_dirent_t *entry = NULL;
+ gf_dirent_t *tmp = NULL;
+ gf_dirent_t entries;
+ struct iatt iatt = {0};
+ struct iatt parent = {0};
+ dict_t *xattr_rsp = NULL;
+ int ret = 0;
+ gf_boolean_t is_directory_empty = _gf_true;
+ dict_t *xattr_req = NULL;
+ gf_boolean_t free_entries = _gf_false;
+
+ xattr_req = dict_new ();
+ if (!xattr_req) {
+ ret = -1;
+ goto out;
+ }
INIT_LIST_HEAD (&entries.list);
this = THIS;
@@ -379,6 +417,7 @@ gf_pump_traverse_directory (loc_t *loc, uuid_t gfid)
loc->path, ret);
while (syncop_readdirp (this, fd, 131072, offset, &entries)) {
+ free_entries = _gf_true;
if (list_empty (&entries.list)) {
gf_log (this->name, GF_LOG_TRACE,
@@ -390,45 +429,39 @@ gf_pump_traverse_directory (loc_t *loc, uuid_t gfid)
gf_log (this->name, GF_LOG_DEBUG,
"found readdir entry=%s", entry->d_name);
+ _wipe_loc (&entry_loc);
ret = afr_build_child_loc (this, &entry_loc,
loc, entry->d_name);
if (ret)
goto out;
if (!IS_ENTRY_CWD (entry->d_name) &&
- !IS_ENTRY_PARENT (entry->d_name)) {
+ !IS_ENTRY_PARENT (entry->d_name)) {
is_directory_empty = _gf_false;
- ret = syncop_lookup (this, &entry_loc, NULL,
- &iatt, &xattr_rsp, &parent);
- if (ret)
- continue;
-
- entry_loc.ino = iatt.ia_ino;
- entry_loc.inode->ino = iatt.ia_ino;
-
- if (uuid_is_null (iatt.ia_gfid)) {
- uuid_generate (gfid);
- uuid_copy (entry_loc.inode->gfid,
- gfid);
- } else {
- uuid_copy (entry_loc.inode->gfid,
- iatt.ia_gfid);
- }
gf_log (this->name, GF_LOG_DEBUG,
"lookup %s => %"PRId64,
entry_loc.path,
iatt.ia_ino);
- ret = syncop_lookup (this, &entry_loc, NULL,
+ _generate_gfid_on_empty (gfid);
+ ret = dict_reset (xattr_req);
+ if (ret)
+ goto out;
+ ret = afr_set_dict_gfid (xattr_req, gfid);
+ if (ret)
+ goto out;
+ ret = syncop_lookup (this, &entry_loc, xattr_req,
&iatt, &xattr_rsp, &parent);
-
- gf_log (this->name, GF_LOG_DEBUG,
- "second lookup ret=%d: %s => %"PRId64,
- ret,
- entry_loc.path,
- iatt.ia_ino);
+ _empty_gfid_on_set (gfid, ret, &iatt);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: lookup failed",
+ entry_loc.path);
+ continue;
+ }
+ _fill_loc_info (&entry_loc, &iatt, &parent);
pump_update_resume_state (this, entry_loc.path);
@@ -442,10 +475,6 @@ gf_pump_traverse_directory (loc_t *loc, uuid_t gfid)
goto out;
}
- gf_log (this->name, GF_LOG_TRACE,
- "type of file=%d, IFDIR=%d",
- iatt.ia_type, IA_IFDIR);
-
if (IA_ISDIR (iatt.ia_type)) {
if (is_pump_traversal_allowed (this, entry_loc.path)) {
gf_log (this->name, GF_LOG_TRACE,
@@ -456,10 +485,10 @@ gf_pump_traverse_directory (loc_t *loc, uuid_t gfid)
}
}
offset = entry->d_off;
- loc_wipe (&entry_loc);
}
gf_dirent_free (&entries);
+ free_entries = _gf_false;
gf_log (this->name, GF_LOG_TRACE,
"offset incremented to %d",
(int32_t ) offset);
@@ -473,6 +502,12 @@ gf_pump_traverse_directory (loc_t *loc, uuid_t gfid)
}
out:
+ if (xattr_req)
+ dict_unref (xattr_req);
+ if (entry_loc.path)
+ loc_wipe (&entry_loc);
+ if (free_entries)
+ gf_dirent_free (&entries);
return 0;
}