From 8c8e5b25779f68c646ec00003a7bb2101e55cbc0 Mon Sep 17 00:00:00 2001 From: Pavan Sondur Date: Tue, 7 Sep 2010 10:40:57 +0000 Subject: cluster/afr: Various self heal fixes wrt gfid. Signed-off-by: Pavan Vilas Sondur Signed-off-by: Vijay Bellur BUG: 971 (dynamic volume management) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=971 --- xlators/cluster/afr/src/afr-common.c | 14 +++++ xlators/cluster/afr/src/afr-self-heal-common.c | 58 ++++++++++++++++-- xlators/cluster/afr/src/afr-self-heal-entry.c | 81 +++++++++++++++++++++++--- xlators/cluster/afr/src/afr.h | 3 + xlators/cluster/afr/src/pump.c | 2 + xlators/protocol/server/src/server3_1-fops.c | 3 + 6 files changed, 148 insertions(+), 13 deletions(-) diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index d536b45547a..cb01f0b9c32 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -60,6 +60,20 @@ #define AFR_ICTX_SPLIT_BRAIN_MASK 0x0000000100000000ULL #define AFR_ICTX_READ_CHILD_MASK 0x00000000FFFFFFFFULL +int32_t +afr_set_dict_gfid (dict_t *dict, uuid_t gfid) +{ + int ret = 0; + + GF_ASSERT (gfid); + + ret = dict_set_static_bin (dict, "gfid-req", gfid, 16); + if (ret) + gf_log (THIS->name, GF_LOG_DEBUG, "gfid set failed"); + + return ret; +} + uint64_t afr_is_split_brain (xlator_t *this, inode_t *inode) { diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c index 0e25be6944f..19ad4a849d3 100644 --- a/xlators/cluster/afr/src/afr-self-heal-common.c +++ b/xlators/cluster/afr/src/afr-self-heal-common.c @@ -984,11 +984,12 @@ sh_missing_entries_mknod (call_frame_t *frame, xlator_t *this) afr_self_heal_t *sh = NULL; afr_private_t *priv = NULL; int i = 0; + int ret = 0; int enoent_count = 0; int call_count = 0; mode_t st_mode = 0; dev_t ia_dev = 0; - + dict_t *dict = NULL; local = frame->local; sh = &local->self_heal; @@ -1009,6 +1010,14 @@ sh_missing_entries_mknod (call_frame_t *frame, xlator_t *this) "mknod %s mode 0%o on %d subvolumes", local->loc.path, st_mode, enoent_count); + dict = dict_new (); + if (!dict) + gf_log (this->name, GF_LOG_ERROR, "out of memory"); + + ret = afr_set_dict_gfid (dict, sh->buf[sh->source].ia_gfid); + if (ret) + gf_log (this->name, GF_LOG_DEBUG, "gfid set failed"); + for (i = 0; i < priv->child_count; i++) { if (sh->child_errno[i] == ENOENT) { STACK_WIND_COOKIE (frame, @@ -1016,12 +1025,15 @@ sh_missing_entries_mknod (call_frame_t *frame, xlator_t *this) (void *) (long) i, priv->children[i], priv->children[i]->fops->mknod, - &local->loc, st_mode, ia_dev, NULL); + &local->loc, st_mode, ia_dev, dict); if (!--call_count) break; } } + if (dict) + dict_unref (dict); + return 0; } @@ -1032,7 +1044,9 @@ sh_missing_entries_mkdir (call_frame_t *frame, xlator_t *this) afr_local_t *local = NULL; afr_self_heal_t *sh = NULL; afr_private_t *priv = NULL; + dict_t *dict = NULL; int i = 0; + int ret = 0; int enoent_count = 0; int call_count = 0; mode_t st_mode = 0; @@ -1052,6 +1066,20 @@ sh_missing_entries_mkdir (call_frame_t *frame, xlator_t *this) st_mode = st_mode_from_ia (sh->buf[sh->source].ia_prot, sh->buf[sh->source].ia_type); + dict = dict_new (); + if (!dict) { + gf_log (this->name, GF_LOG_ERROR, + "Out of memory"); + sh_missing_entries_finish (frame, this); + return 0; + } + + ret = afr_set_dict_gfid (dict, sh->buf[sh->source].ia_gfid); + if (ret) + gf_log (this->name, GF_LOG_DEBUG, + "inode gfid set failed"); + + gf_log (this->name, GF_LOG_TRACE, "mkdir %s mode 0%o on %d subvolumes", local->loc.path, st_mode, enoent_count); @@ -1070,25 +1098,30 @@ sh_missing_entries_mkdir (call_frame_t *frame, xlator_t *this) (void *) (long) i, priv->children[i], priv->children[i]->fops->mkdir, - &local->loc, st_mode, NULL); + &local->loc, st_mode, dict); if (!--call_count) break; } } } + if (dict) + dict_unref (dict); + return 0; } static int sh_missing_entries_symlink (call_frame_t *frame, xlator_t *this, - const char *link) + const char *link, struct iatt *buf) { afr_local_t *local = NULL; afr_self_heal_t *sh = NULL; afr_private_t *priv = NULL; + dict_t *dict = NULL; int i = 0; + int ret = 0; int enoent_count = 0; int call_count = 0; @@ -1104,6 +1137,19 @@ sh_missing_entries_symlink (call_frame_t *frame, xlator_t *this, call_count = enoent_count; local->call_count = call_count; + dict = dict_new (); + if (!dict) { + gf_log (this->name, GF_LOG_ERROR, + "Out of memory"); + sh_missing_entries_finish (frame, this); + return 0; + } + + ret = afr_set_dict_gfid (dict, buf->ia_gfid); + if (ret) + gf_log (this->name, GF_LOG_DEBUG, + "dict gfid set failed"); + gf_log (this->name, GF_LOG_TRACE, "symlink %s -> %s on %d subvolumes", local->loc.path, link, enoent_count); @@ -1115,7 +1161,7 @@ sh_missing_entries_symlink (call_frame_t *frame, xlator_t *this, (void *) (long) i, priv->children[i], priv->children[i]->fops->symlink, - link, &local->loc, NULL); + link, &local->loc, dict); if (!--call_count) break; } @@ -1132,7 +1178,7 @@ sh_missing_entries_readlink_cbk (call_frame_t *frame, void *cookie, const char *link, struct iatt *sbuf) { if (op_ret > 0) - sh_missing_entries_symlink (frame, this, link); + sh_missing_entries_symlink (frame, this, link, sbuf); else sh_missing_entries_finish (frame, this); diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c index af6c0c68916..dcb4f0cd1ca 100644 --- a/xlators/cluster/afr/src/afr-self-heal-entry.c +++ b/xlators/cluster/afr/src/afr-self-heal-entry.c @@ -553,8 +553,10 @@ afr_sh_entry_expunge_lookup_trash_cbk (call_frame_t *expunge_frame, void *cookie afr_local_t *expunge_local = NULL; afr_self_heal_t *expunge_sh = NULL; call_frame_t *frame = NULL; + dict_t *dict = NULL; int active_src = (long) cookie; + int ret = 0; inode_t *trash_inode; loc_t trash_loc; @@ -567,6 +569,18 @@ afr_sh_entry_expunge_lookup_trash_cbk (call_frame_t *expunge_frame, void *cookie if ((op_ret != 0) && (op_errno == ENOENT)) { init_trash_loc (&trash_loc, expunge_local->loc.inode->table); + dict = dict_new (); + if (!dict) { + gf_log (this->name, GF_LOG_ERROR, + "Out of memory"); + goto out; + } + + ret = afr_set_dict_gfid (dict, buf->ia_gfid); + if (ret) + gf_log (this->name, GF_LOG_DEBUG, "gfid set failed"); + + gf_log (this->name, GF_LOG_TRACE, "creating directory " GF_REPLICATE_TRASH_DIR " on subvolume %s", priv->children[active_src]->name); @@ -575,9 +589,11 @@ afr_sh_entry_expunge_lookup_trash_cbk (call_frame_t *expunge_frame, void *cookie (void *) (long) active_src, priv->children[active_src], priv->children[active_src]->fops->mkdir, - &trash_loc, 0777, NULL); + &trash_loc, 0777, dict); loc_wipe (&trash_loc); + if (dict) + dict_unref (dict); return 0; } @@ -1273,6 +1289,9 @@ afr_sh_entry_impunge_mknod (call_frame_t *impunge_frame, xlator_t *this, { afr_private_t *priv = NULL; afr_local_t *impunge_local = NULL; + dict_t *dict = NULL; + + int ret = 0; priv = this->private; impunge_local = impunge_frame->local; @@ -1282,13 +1301,24 @@ afr_sh_entry_impunge_mknod (call_frame_t *impunge_frame, xlator_t *this, impunge_local->loc.path, priv->children[child_index]->name); + dict = dict_new (); + if (!dict) + gf_log (this->name, GF_LOG_ERROR, "Out of memory"); + + ret = afr_set_dict_gfid (dict, stbuf->ia_gfid); + if (ret) + gf_log (this->name, GF_LOG_DEBUG, "gfid set failed"); + STACK_WIND_COOKIE (impunge_frame, afr_sh_entry_impunge_newfile_cbk, (void *) (long) child_index, priv->children[child_index], priv->children[child_index]->fops->mknod, &impunge_local->loc, st_mode_from_ia (stbuf->ia_prot, stbuf->ia_type), - stbuf->ia_rdev, NULL); + stbuf->ia_rdev, dict); + + if (dict) + dict_unref (dict); return 0; } @@ -1301,10 +1331,24 @@ afr_sh_entry_impunge_mkdir (call_frame_t *impunge_frame, xlator_t *this, { afr_private_t *priv = NULL; afr_local_t *impunge_local = NULL; + dict_t *dict = NULL; + + int ret = 0; priv = this->private; impunge_local = impunge_frame->local; + dict = dict_new (); + if (!dict) { + gf_log (this->name, GF_LOG_ERROR, + "Out of memory"); + return 0; + } + + ret = afr_set_dict_gfid (dict, stbuf->ia_gfid); + if (ret) + gf_log (this->name, GF_LOG_DEBUG, "gfid set failed"); + gf_log (this->name, GF_LOG_DEBUG, "creating missing directory %s on %s", impunge_local->loc.path, @@ -1316,7 +1360,10 @@ afr_sh_entry_impunge_mkdir (call_frame_t *impunge_frame, xlator_t *this, priv->children[child_index]->fops->mkdir, &impunge_local->loc, st_mode_from_ia (stbuf->ia_prot, stbuf->ia_type), - NULL); + dict); + + if (dict) + dict_unref (dict); return 0; } @@ -1326,12 +1373,30 @@ int afr_sh_entry_impunge_symlink (call_frame_t *impunge_frame, xlator_t *this, int child_index, const char *linkname) { - afr_private_t *priv = NULL; + afr_private_t *priv = NULL; afr_local_t *impunge_local = NULL; + dict_t *dict = NULL; + struct iatt *buf = NULL; + + int ret = 0; priv = this->private; impunge_local = impunge_frame->local; + buf = &impunge_local->cont.symlink.buf; + + dict = dict_new (); + if (!dict) { + gf_log (this->name, GF_LOG_ERROR, + "Out of memory"); + afr_sh_entry_impunge_entry_done (impunge_frame, this, 0); + } + + ret = afr_set_dict_gfid (dict, buf->ia_gfid); + if (ret) + gf_log (this->name, GF_LOG_DEBUG, + "dict set gfid failed"); + gf_log (this->name, GF_LOG_DEBUG, "creating missing symlink %s -> %s on %s", impunge_local->loc.path, linkname, @@ -1341,7 +1406,10 @@ afr_sh_entry_impunge_symlink (call_frame_t *impunge_frame, xlator_t *this, (void *) (long) child_index, priv->children[child_index], priv->children[child_index]->fops->symlink, - linkname, &impunge_local->loc, NULL); + linkname, &impunge_local->loc, dict); + + if (dict) + dict_unref (dict); return 0; } @@ -1474,7 +1542,6 @@ afr_sh_entry_impunge_readlink_sink_cbk (call_frame_t *impunge_frame, void *cooki /* * Hah! Sneaky wolf in sheep's clothing! */ - afr_sh_entry_impunge_symlink_unlink (impunge_frame, this, child_index); return 0; @@ -1552,7 +1619,6 @@ afr_sh_entry_impunge_readlink_cbk (call_frame_t *impunge_frame, void *cookie, } impunge_sh->linkname = gf_strdup (linkname); - afr_sh_entry_impunge_readlink_sink (impunge_frame, this, child_index); return 0; @@ -1586,6 +1652,7 @@ afr_sh_entry_impunge_readlink (call_frame_t *impunge_frame, xlator_t *this, impunge_local = impunge_frame->local; impunge_sh = &impunge_local->self_heal; active_src = impunge_sh->active_source; + impunge_local->cont.symlink.buf = *stbuf; STACK_WIND_COOKIE (impunge_frame, afr_sh_entry_impunge_readlink_cbk, (void *) (long) child_index, diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index af3e7f204a2..7ce4b0cea65 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -650,6 +650,9 @@ typedef struct { /* have we tried all children? */ #define all_tried(i, count) ((i) == (count) - 1) +int32_t +afr_set_dict_gfid (dict_t *dict, uuid_t gfid); + int pump_command_reply (call_frame_t *frame, xlator_t *this); diff --git a/xlators/cluster/afr/src/pump.c b/xlators/cluster/afr/src/pump.c index 5b31d389b28..5e2c2d43aca 100644 --- a/xlators/cluster/afr/src/pump.c +++ b/xlators/cluster/afr/src/pump.c @@ -528,6 +528,8 @@ build_root_loc (inode_t *inode, loc_t *loc) loc->inode = inode; loc->ino = 1; loc->inode->ino = 1; + memset (loc->inode->gfid, 0, 16); + loc->inode->gfid[15] = 1; } diff --git a/xlators/protocol/server/src/server3_1-fops.c b/xlators/protocol/server/src/server3_1-fops.c index c370dbe8afe..6c63ef6faac 100644 --- a/xlators/protocol/server/src/server3_1-fops.c +++ b/xlators/protocol/server/src/server3_1-fops.c @@ -1444,6 +1444,9 @@ server_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, op_ret, strerror (op_errno)); } + if (!rsp.path) + rsp.path = ""; + server_submit_reply (frame, req, &rsp, NULL, 0, NULL, xdr_serialize_readlink_rsp); -- cgit