diff options
-rw-r--r-- | libglusterfs/src/dict.c | 22 | ||||
-rw-r--r-- | libglusterfs/src/dict.h | 1 | ||||
-rw-r--r-- | xlators/cluster/afr/src/pump.c | 121 |
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; } |