diff options
| -rw-r--r-- | heal/src/glfs-heal.c | 343 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 100 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-common.c | 19 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-data.c | 8 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-entry.c | 11 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-metadata.c | 7 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-name.c | 3 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal.h | 12 | ||||
| -rw-r--r-- | xlators/features/index/src/index.c | 5 | 
9 files changed, 340 insertions, 168 deletions
diff --git a/heal/src/glfs-heal.c b/heal/src/glfs-heal.c index 2f120c9bd3d..ce9ffbbc70b 100644 --- a/heal/src/glfs-heal.c +++ b/heal/src/glfs-heal.c @@ -26,7 +26,8 @@                    "source-brick <HOSTNAME:BRICKNAME> [<FILE>] | "\                    "split-brain-info]\n" -typedef void    (*print_status) (dict_t *, char *, uuid_t, uint64_t *); +typedef void    (*print_status) (dict_t *, char *, uuid_t, uint64_t *, +                 gf_boolean_t flag);  int glfsh_heal_splitbrain_file (glfs_t *fs, xlator_t *top_subvol,                                  loc_t *rootloc, char *file, dict_t *xattr_req); @@ -49,9 +50,30 @@ out:  } +void +glfsh_print_heal_op_status (int ret, uint64_t num_entries, +                            gf_xl_afr_op_t heal_op) +{ + +        if (ret < 0) { +                printf ("Failed to process entries completely. " +                         "Number of entries so far: %"PRIu64"\n", num_entries); +        } else { +                if (heal_op == GF_SHD_OP_INDEX_SUMMARY) +                        printf ("Number of entries: %"PRIu64"\n", num_entries); +                else if (heal_op == GF_SHD_OP_SPLIT_BRAIN_FILES) +                        printf ("Number of entries in split-brain: %"PRIu64"\n" +                                , num_entries); +                else if (heal_op == GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) +                        printf ("Number of healed entries: %"PRIu64"\n", +                                num_entries); +        } +        return; +} +  int  glfsh_get_index_dir_loc (loc_t *rootloc, xlator_t *xl, loc_t *dirloc, -                         int32_t *op_errno) +                         int32_t *op_errno, char *vgfid)  {          void      *index_gfid = NULL;          int       ret = 0; @@ -59,14 +81,13 @@ glfsh_get_index_dir_loc (loc_t *rootloc, xlator_t *xl, loc_t *dirloc,          struct iatt   iattr = {0};          struct iatt   parent = {0}; -        ret = syncop_getxattr (xl, rootloc, &xattr, GF_XATTROP_INDEX_GFID, -                               NULL, NULL); +        ret = syncop_getxattr (xl, rootloc, &xattr, vgfid, NULL, NULL);          if (ret < 0) {                  *op_errno = -ret;                  goto out;          } -        ret = dict_get_ptr (xattr, GF_XATTROP_INDEX_GFID, &index_gfid); +        ret = dict_get_ptr (xattr, vgfid, &index_gfid);          if (ret < 0) {                  *op_errno = EINVAL;                  goto out; @@ -137,53 +158,105 @@ glfsh_index_purge (xlator_t *subvol, inode_t *inode, char *name)  void  glfsh_print_spb_status (dict_t *dict, char *path, uuid_t gfid, -                        uint64_t *num_entries) +                        uint64_t *num_entries, gf_boolean_t flag)  { -       char *value  = NULL; -       int   ret    = 0; +        int   ret    = 0; +        gf_boolean_t    pending         = _gf_false; +        gf_boolean_t    split_b         = _gf_false; +        char            *value          = NULL; -       ret = dict_get_str (dict, "heal-info", &value); -       if (ret) -               return; +        ret = dict_get_str (dict, "heal-info", &value); +        if (ret) +                return; -       if (!strcmp (value, "split-brain")) { -                (*num_entries)++; -                printf ("%s\n", +        if (!strcmp (value, "split-brain")) { +                split_b = _gf_true; +        } else if (!strcmp (value, "split-brain-pending")) { +                split_b = _gf_true; +                pending = _gf_true; +        } +        /* Consider the entry only iff : +         * 1) The dir being processed is not indices/dirty, indicated by +         *    flag == _gf_false +         * 2) The dir being processed is indices/dirty but the entry also +         *    exists in indices/xattrop dir and has already been processed. +         */ +        if (split_b) { +                if (!flag || (flag && !pending)) { +                        (*num_entries)++; +                        printf ("%s\n",                          path ? path : uuid_utoa (gfid)); -       } -       return; +                } +        } +        return;  }  void  glfsh_print_heal_status (dict_t *dict, char *path, uuid_t gfid, -                         uint64_t *num_entries) +                         uint64_t *num_entries, gf_boolean_t ignore_dirty)  { -       char *value  = NULL; -       int   ret    = 0; -       char *status = NULL; - -       ret = dict_get_str (dict, "heal-info", &value); -       if (ret || (!strcmp (value, "no-heal"))) -               return; - -       (*num_entries)++; -       if (!strcmp (value, "heal")) { -               ret = gf_asprintf (&status, " "); -       } else if (!strcmp (value, "possibly-healing")) { -               ret = gf_asprintf (&status, " - Possibly undergoing heal\n"); -       } else if (!strcmp (value, "split-brain")) { -               ret = gf_asprintf (&status, " - Is in split-brain\n"); -       } -       if (ret == -1) -               status = NULL; - -       printf ("%s%s\n", -               path ? path : uuid_utoa (gfid), -               status); - -       if (status) -               GF_FREE (status); -       return; +        int             ret             = 0; +        gf_boolean_t    pending         = _gf_false; +        char            *status         = NULL; +        char            *value          = NULL; + +        ret = dict_get_str (dict, "heal-info", &value); +        if (ret || (!strcmp (value, "no-heal"))) +                return; + +        if (!strcmp (value, "heal")) { +                ret = gf_asprintf (&status, " "); +                if (ret < 0) +                        goto out; +        } else if (!strcmp (value, "possibly-healing")) { +                ret = gf_asprintf (&status, +                                   " - Possibly undergoing heal\n"); +                if (ret < 0) +                        goto out; +        } else if (!strcmp (value, "split-brain")) { +                ret = gf_asprintf (&status, " - Is in split-brain\n"); +                if (ret < 0) +                        goto out; +        } else if (!strcmp (value, "heal-pending")) { +                pending = _gf_true; +                ret = gf_asprintf (&status, " "); +                if (ret < 0) +                        goto out; +        } else if (!strcmp (value, "split-brain-pending")) { +                pending = _gf_true; +                ret = gf_asprintf (&status, " - Is in split-brain\n"); +                if (ret < 0) +                        goto out; +        } else if (!strcmp (value, "possibly-healing-pending")) { +                pending = _gf_true; +                ret = gf_asprintf (&status, +                                   " - Possibly undergoing heal\n"); +                if (ret < 0) +                        goto out; +        } +out: +        /* If ignore_dirty is set, it means indices/dirty directory is +         * being processed. Ignore the entry if it also exists in +         * indices/xattrop. +         * Boolean pending is set to true if the entry also exists in +         * indices/xattrop directory. +         */ +        if (ignore_dirty) { +                if (pending) { +                        GF_FREE (status); +                        status = NULL; +                        return; +                } +        } +        if (ret == -1) +                status = NULL; + +        (*num_entries)++; +        printf ("%s%s\n", +                path ? path : uuid_utoa (gfid), status ? status : ""); + +        GF_FREE (status); +        return;  }  static int @@ -216,7 +289,8 @@ glfsh_heal_entries (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,  static int  glfsh_process_entries (xlator_t *xl, fd_t *fd, gf_dirent_t *entries,                         uint64_t *offset, uint64_t *num_entries, -                       print_status glfsh_print_status) +                       print_status glfsh_print_status, +                       gf_boolean_t ignore_dirty)  {          gf_dirent_t      *entry = NULL;          gf_dirent_t      *tmp = NULL; @@ -258,7 +332,7 @@ glfsh_process_entries (xlator_t *xl, fd_t *fd, gf_dirent_t *entries,                  }                  if (dict)                          glfsh_print_status (dict, path, gfid, -                                            num_entries); +                                            num_entries, ignore_dirty);          }          ret = 0;          GF_FREE (path); @@ -272,13 +346,13 @@ glfsh_process_entries (xlator_t *xl, fd_t *fd, gf_dirent_t *entries,  static int  glfsh_crawl_directory (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,                         xlator_t *readdir_xl, fd_t *fd, loc_t *loc, -                       dict_t *xattr_req) +                       dict_t *xattr_req, uint64_t *num_entries, +                       gf_boolean_t ignore)  {          uint64_t        offset = 0;          gf_dirent_t     entries;          int             ret = 0;          gf_boolean_t    free_entries = _gf_false; -        uint64_t        num_entries = 0;          int             heal_op = -1;          INIT_LIST_HEAD (&entries.list); @@ -300,21 +374,23 @@ glfsh_crawl_directory (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,                  if (heal_op == GF_SHD_OP_INDEX_SUMMARY) {                          ret = glfsh_process_entries (readdir_xl, fd,                                                       &entries, &offset, -                                                     &num_entries, -                                                     glfsh_print_heal_status); +                                                     num_entries, +                                                     glfsh_print_heal_status, +                                                     ignore);                          if (ret < 0)                                  goto out;                  } else if (heal_op == GF_SHD_OP_SPLIT_BRAIN_FILES) {                          ret = glfsh_process_entries (readdir_xl, fd,                                                       &entries, &offset, -                                                     &num_entries, -                                                     glfsh_print_spb_status); +                                                     num_entries, +                                                     glfsh_print_spb_status, +                                                     ignore);                          if (ret < 0)                                  goto out;                  } else if (heal_op == GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) {                          ret = glfsh_heal_entries (fs, top_subvol, rootloc,                                                    &entries, &offset, -                                                  &num_entries, xattr_req); +                                                  num_entries, xattr_req);                  }                  gf_dirent_free (&entries);                  free_entries = _gf_false; @@ -323,19 +399,6 @@ glfsh_crawl_directory (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,  out:          if (free_entries)                  gf_dirent_free (&entries); -        if (ret < 0) { -                printf ("Failed to complete gathering info. " -                         "Number of entries so far: %"PRIu64"\n", num_entries); -        } else { -                if (heal_op == GF_SHD_OP_INDEX_SUMMARY) -                        printf ("Number of entries: %"PRIu64"\n", num_entries); -                else if (heal_op == GF_SHD_OP_SPLIT_BRAIN_FILES) -                        printf ("Number of entries in split-brain: %"PRIu64"\n" -                                , num_entries); -                else if (heal_op == GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) -                        printf ("Number of healed entries: %"PRIu64"\n", -                                num_entries); -        }          return ret;  } @@ -361,14 +424,53 @@ out:          return ret;  } -void -glfsh_print_pending_heals (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc, -                           xlator_t *xl, gf_xl_afr_op_t heal_op) +int +glfsh_print_pending_heals_type (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc, +                                xlator_t *xl, gf_xl_afr_op_t heal_op, +                                dict_t *xattr_req, char *vgfid, +                                uint64_t *num_entries)  {          int ret = 0;          loc_t   dirloc = {0};          fd_t    *fd = NULL;          int32_t op_errno = 0; +        gf_boolean_t ignore = _gf_false; + +        if (!strcmp(vgfid, GF_XATTROP_DIRTY_GFID)) +                ignore = _gf_true; + +        ret = glfsh_get_index_dir_loc (rootloc, xl, &dirloc, &op_errno, +                                       vgfid); +        if (ret < 0) { +                if (op_errno == ESTALE || op_errno == ENOENT) { +                        ret = 0; +                } else { +                        printf ("Status: %s\n", strerror (op_errno)); +                        ret = -op_errno; +                } +                goto out; +        } + +        ret = syncop_dirfd (xl, &dirloc, &fd, GF_CLIENT_PID_GLFS_HEAL); +        if (ret) +                goto out; + +        ret = glfsh_crawl_directory (fs, top_subvol, rootloc, xl, fd, &dirloc, +                                     xattr_req, num_entries, ignore); +        if (fd) +                fd_unref (fd); +out: +        loc_wipe (&dirloc); +        return ret; +} + +void +glfsh_print_pending_heals (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc, +                           xlator_t *xl, gf_xl_afr_op_t heal_op) +{ +        int ret = 0; +        uint64_t count = 0, total = 0; +          dict_t *xattr_req = NULL;          xattr_req = dict_new(); @@ -378,38 +480,31 @@ glfsh_print_pending_heals (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,          ret = dict_set_int32 (xattr_req, "heal-op", heal_op);          if (ret)                  goto out; +          ret = glfsh_print_brick_from_xl (xl);          if (ret < 0)                  goto out; -        ret = glfsh_get_index_dir_loc (rootloc, xl, &dirloc, &op_errno); -        if (ret < 0) { -                if (op_errno == ESTALE || op_errno == ENOENT) -                        printf ("Number of entries: 0\n"); -                else -                        printf ("Status: %s\n", strerror (op_errno)); -                goto out; -        } - -        ret = syncop_dirfd (xl, &dirloc, &fd, GF_CLIENT_PID_GLFS_HEAL); -        if (ret) +        ret = glfsh_print_pending_heals_type (fs, top_subvol, rootloc, xl, +                                              heal_op, xattr_req, +                                              GF_XATTROP_INDEX_GFID, &count); +        total += count; +        count = 0; +        if (ret == -ENOTCONN)                  goto out; -        ret = glfsh_crawl_directory (fs, top_subvol, rootloc, xl, fd, &dirloc, -                                     xattr_req); -        if (fd) -                fd_unref (fd); -        if (xattr_req) -                dict_unref (xattr_req); -        if (ret < 0) { -                if (heal_op == GF_SHD_OP_INDEX_SUMMARY) -                        printf ("Failed to find entries with pending" -                                " self-heal\n"); -                if (heal_op == GF_SHD_OP_SPLIT_BRAIN_FILES) -                        printf ("Failed to find entries in split-brain\n"); +        if (!strcmp (xl->type, "cluster/replicate")) { +                ret = glfsh_print_pending_heals_type (fs, top_subvol, +                                                      rootloc, xl, +                                                      heal_op, xattr_req, +                                                      GF_XATTROP_DIRTY_GFID, +                                                      &count); +                total += count;          }  out: -        loc_wipe (&dirloc); +        if (xattr_req) +                dict_unref (xattr_req); +        glfsh_print_heal_op_status (ret, total, heal_op);          return;  } @@ -598,15 +693,43 @@ out:  }  int +glfsh_heal_from_brick_type (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc, +                            char *hostname, char *brickpath, xlator_t *client, +                            dict_t *xattr_req, char *vgfid, +                            uint64_t *num_entries) +{ +        fd_t     *fd        = NULL; +        loc_t     dirloc    = {0}; +        int32_t   op_errno  = 0; +        int       ret       = -1; + +        ret = glfsh_get_index_dir_loc (rootloc, client, &dirloc, +                                       &op_errno, vgfid); +        if (ret < 0) +                goto out; + +        ret = syncop_dirfd (client, &dirloc, &fd, +                            GF_CLIENT_PID_GLFS_HEAL); +        if (ret) +                goto out; +        ret = glfsh_crawl_directory (fs, top_subvol, rootloc, client, +                                     fd, &dirloc, xattr_req, num_entries, +                                     _gf_false); +        if (fd) +                fd_unref (fd); +out: +        loc_wipe (&dirloc); +        return ret; +} + +int  glfsh_heal_from_brick (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,                        char *hostname, char *brickpath, char *file)  {          int       ret       = -1; +        uint64_t   count     = 0, total = 0;          dict_t   *xattr_req = NULL;          xlator_t *client    = NULL; -        fd_t     *fd        = NULL; -        loc_t     dirloc    = {0}; -        int32_t   op_errno  = 0;          xattr_req = dict_new();          if (!xattr_req) @@ -627,23 +750,31 @@ glfsh_heal_from_brick (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,                  goto out;          if (file)                  ret = glfsh_heal_splitbrain_file (fs, top_subvol, rootloc, file, -                                                 xattr_req); +                                                  xattr_req);          else { -                ret = glfsh_get_index_dir_loc (rootloc, client, &dirloc, -                                               &op_errno); -                ret = syncop_dirfd (client, &dirloc, &fd, -                                    GF_CLIENT_PID_GLFS_HEAL); -                if (ret) +                ret = glfsh_heal_from_brick_type (fs, top_subvol, rootloc, +                                                  hostname, brickpath, +                                                  client, xattr_req, +                                                  GF_XATTROP_INDEX_GFID, +                                                  &count); +                total += count; +                count = 0; +                ret = glfsh_heal_from_brick_type (fs, top_subvol, rootloc, +                                                  hostname, brickpath, +                                                  client, xattr_req, +                                                  GF_XATTROP_DIRTY_GFID, +                                                  &count); +                total += count; +                if (ret < 0)                          goto out; -                ret = glfsh_crawl_directory (fs, top_subvol, rootloc, client, -                                             fd, &dirloc, xattr_req); -                if (fd) -                        fd_unref (fd);          }  out:          if (xattr_req)                  dict_unref (xattr_req); -        loc_wipe (&dirloc); +        if (!file) +                glfsh_print_heal_op_status (ret, total, +                                            GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK); +          return ret;  } diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 932a26117a6..2be75b0b471 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -1250,7 +1250,6 @@ afr_replies_wipe (struct afr_reply *replies, int count)                          replies[i].xattr = NULL;                  }          } -	memset (&replies->need_heal, 0, sizeof (replies->need_heal));  }  void @@ -4385,7 +4384,8 @@ out:  int  afr_selfheal_locked_metadata_inspect (call_frame_t *frame, xlator_t *this, -                                      inode_t *inode, gf_boolean_t *msh) +                                      inode_t *inode, gf_boolean_t *msh, +                                      gf_boolean_t *pending)  {          int ret = -1;          unsigned char *locked_on = NULL; @@ -4416,7 +4416,8 @@ afr_selfheal_locked_metadata_inspect (call_frame_t *frame, xlator_t *this,                  ret = __afr_selfheal_metadata_prepare (frame, this, inode,                                                         locked_on, sources,                                                         sinks, healed_sinks, -                                                       locked_replies); +                                                       locked_replies, +                                                       pending);                  *msh = afr_decide_heal_info (priv, sources, ret);          }          afr_selfheal_uninodelk (frame, this, inode, this->name, @@ -4429,7 +4430,8 @@ out:  int  afr_selfheal_locked_data_inspect (call_frame_t *frame, xlator_t *this, -                                  inode_t *inode, gf_boolean_t *dsh) +                                  inode_t *inode, gf_boolean_t *dsh, +                                  gf_boolean_t *pflag)  {          int ret = -1;          afr_private_t   *priv = NULL; @@ -4471,7 +4473,8 @@ afr_selfheal_locked_data_inspect (call_frame_t *frame, xlator_t *this,                          ret = __afr_selfheal_data_prepare (frame, this, inode,                                                             data_lock, sources,                                                             sinks, healed_sinks, -                                                           locked_replies); +                                                           locked_replies, +                                                           pflag);                          *dsh = afr_decide_heal_info (priv, sources, ret);                  }                  afr_selfheal_uninodelk (frame, this, inode, this->name, 0, 0, @@ -4489,7 +4492,7 @@ out:  int  afr_selfheal_locked_entry_inspect (call_frame_t *frame, xlator_t *this,                                     inode_t *inode, -                                   gf_boolean_t *esh) +                                   gf_boolean_t *esh, gf_boolean_t *pflag)  {          int ret = -1;          int source = -1; @@ -4534,7 +4537,7 @@ afr_selfheal_locked_entry_inspect (call_frame_t *frame, xlator_t *this,                                                              data_lock, sources,                                                              sinks, healed_sinks,                                                              locked_replies, -                                                            &source); +                                                            &source, pflag);                          if ((ret == 0) && source < 0)                                  ret = -EIO;                          *esh = afr_decide_heal_info (priv, sources, ret); @@ -4556,7 +4559,8 @@ afr_selfheal_locked_inspect (call_frame_t *frame, xlator_t *this, uuid_t gfid,                               inode_t **inode,                               gf_boolean_t *entry_selfheal,                               gf_boolean_t *data_selfheal, -                             gf_boolean_t *metadata_selfheal) +                             gf_boolean_t *metadata_selfheal, +                             gf_boolean_t *pending)  {          int ret             = -1; @@ -4573,21 +4577,22 @@ afr_selfheal_locked_inspect (call_frame_t *frame, xlator_t *this, uuid_t gfid,          if (msh) {                  ret = afr_selfheal_locked_metadata_inspect (frame, this, -                                                            *inode, &msh); +                                                            *inode, &msh, +                                                            pending);                  if (ret == -EIO)                          goto out;          }          if (dsh) {                  ret = afr_selfheal_locked_data_inspect (frame, this, *inode, -                                                        &dsh); +                                                        &dsh, pending);                  if (ret == -EIO || (ret == -EAGAIN))                          goto out;          }          if (esh) {                  ret = afr_selfheal_locked_entry_inspect (frame, this, *inode, -                                                         &esh); +                                                         &esh, pending);          }  out: @@ -4609,28 +4614,12 @@ afr_set_heal_info (char *status)                  goto out;          } -        if (!strcmp (status, "heal")) { -                ret = dict_set_str (dict, "heal-info", "heal"); -                if (ret) -                        gf_msg ("", GF_LOG_WARNING, -ret, -                                AFR_MSG_DICT_SET_FAILED, -                                "Failed to set heal-info key to " -                                "heal"); -        } else if (!strcmp (status, "split-brain")) { -                ret = dict_set_str (dict, "heal-info", "split-brain"); -                if (ret) -                        gf_msg ("", GF_LOG_WARNING, -ret, -                                AFR_MSG_DICT_SET_FAILED, -                                "Failed to set heal-info key to " -                                "split-brain"); -        } else if (!strcmp (status, "possibly-healing")) { -                ret = dict_set_str (dict, "heal-info", "possibly-healing"); -                if (ret) -                        gf_msg ("", GF_LOG_WARNING, -ret, -                                AFR_MSG_DICT_SET_FAILED, -                                "Failed to set heal-info key to " -                                "possibly-healing"); -        } +        ret = dict_set_str (dict, "heal-info", status); +        if (ret) +                gf_msg ("", GF_LOG_WARNING, -ret, +                        AFR_MSG_DICT_SET_FAILED, +                        "Failed to set heal-info key to " +                        "%s", status);  out:          return dict;  } @@ -4641,14 +4630,19 @@ afr_get_heal_info (call_frame_t *frame, xlator_t *this, loc_t *loc)          gf_boolean_t    data_selfheal     = _gf_false;          gf_boolean_t    metadata_selfheal = _gf_false;          gf_boolean_t    entry_selfheal    = _gf_false; +        gf_boolean_t    pending           = _gf_false;          dict_t         *dict              = NULL;          int             ret               = -1;          int             op_errno          = 0; +        int             size              = 0;          inode_t        *inode             = NULL; +        char           *substr            = NULL; +        char           *status            = NULL;          ret = afr_selfheal_locked_inspect (frame, this, loc->gfid, &inode,                                             &entry_selfheal, -                                           &data_selfheal, &metadata_selfheal); +                                           &data_selfheal, &metadata_selfheal, +                                           &pending);          if (ret == -ENOMEM) {                  op_errno = -ret; @@ -4656,10 +4650,27 @@ afr_get_heal_info (call_frame_t *frame, xlator_t *this, loc_t *loc)                  goto out;          } +        if (pending) { +                size = strlen ("-pending") + 1; +                gf_asprintf (&substr, "-pending"); +                if (!substr) +                        goto out; +        } +          if (ret == -EIO) { -                dict = afr_set_heal_info ("split-brain"); +                size += strlen ("split-brain") + 1; +                ret = gf_asprintf (&status, "split-brain%s", +                                   substr? substr : ""); +                if (ret < 0) +                        goto out; +                dict = afr_set_heal_info (status);          } else if (ret == -EAGAIN) { -                dict = afr_set_heal_info ("possibly-healing"); +                size += strlen ("possibly-healing") + 1; +                ret = gf_asprintf (&status, "possibly-healing%s", +                                   substr? substr : ""); +                if (ret < 0) +                        goto out; +                dict = afr_set_heal_info (status);          } else if (ret >= 0) {                  /* value of ret = source index                   * so ret >= 0 and at least one of the 3 booleans set to @@ -4669,7 +4680,12 @@ afr_get_heal_info (call_frame_t *frame, xlator_t *this, loc_t *loc)                      !metadata_selfheal) {                          dict = afr_set_heal_info ("no-heal");                  } else { -                        dict = afr_set_heal_info ("heal"); +                        size += strlen ("heal") + 1; +                        ret = gf_asprintf (&status, "heal%s", +                                           substr? substr : ""); +                        if (ret < 0) +                                goto out; +                        dict = afr_set_heal_info (status);                  }          } else if (ret < 0) {                  /* Apart from above checked -ve ret values, there are @@ -4681,7 +4697,12 @@ afr_get_heal_info (call_frame_t *frame, xlator_t *this, loc_t *loc)                   */                  if (data_selfheal || entry_selfheal ||                      metadata_selfheal) { -                        dict = afr_set_heal_info ("heal"); +                        size += strlen ("heal") + 1; +                        ret = gf_asprintf (&status, "heal%s", +                                           substr? substr : ""); +                        if (ret < 0) +                                goto out; +                        dict = afr_set_heal_info (status);                  }          }          ret = 0; @@ -4694,6 +4715,7 @@ out:                  inode_forget (inode, 1);                  inode_unref (inode);          } +        GF_FREE (substr);          return ret;  } @@ -4718,7 +4740,7 @@ _afr_is_split_brain (call_frame_t *frame, xlator_t *this,          ret = afr_selfheal_find_direction (frame, this, replies,  					   type, priv->child_up, sources, -                                           sinks, witness); +                                           sinks, witness, NULL);          if (ret)                  return ret; diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c index bd234af789e..49c6bd0cc98 100644 --- a/xlators/cluster/afr/src/afr-self-heal-common.c +++ b/xlators/cluster/afr/src/afr-self-heal-common.c @@ -528,7 +528,8 @@ afr_selfheal_find_direction (call_frame_t *frame, xlator_t *this,                               struct afr_reply *replies,                               afr_transaction_type type,                               unsigned char *locked_on, unsigned char *sources, -                             unsigned char *sinks, uint64_t *witness) +                             unsigned char *sinks, uint64_t *witness, +                             gf_boolean_t *pflag)  {          afr_private_t *priv = NULL;          int i = 0; @@ -548,15 +549,25 @@ afr_selfheal_find_direction (call_frame_t *frame, xlator_t *this,  	matrix = ALLOC_MATRIX(priv->child_count, int);          memset (witness, 0, sizeof (*witness) * priv->child_count); +	/* First construct the pending matrix for further analysis */ +	afr_selfheal_extract_xattr (this, replies, type, dirty, matrix); + +        if (pflag) { +                for (i = 0; i < priv->child_count; i++) { +                        for (j = 0; j < priv->child_count; j++) +                                if (matrix[i][j]) +                                        *pflag = _gf_true; +                        if (*pflag) +                                break; +                } +        } +          if (afr_success_count (replies,                                 priv->child_count) < AFR_SH_MIN_PARTICIPANTS) {                  /* Treat this just like locks not being acquired */                  return -ENOTCONN;          } -	/* First construct the pending matrix for further analysis */ -	afr_selfheal_extract_xattr (this, replies, type, dirty, matrix); -          /* short list all self-accused */          for (i = 0; i < priv->child_count; i++) {                  if (matrix[i][i]) diff --git a/xlators/cluster/afr/src/afr-self-heal-data.c b/xlators/cluster/afr/src/afr-self-heal-data.c index 2789754c2e8..b40fa7dc6cc 100644 --- a/xlators/cluster/afr/src/afr-self-heal-data.c +++ b/xlators/cluster/afr/src/afr-self-heal-data.c @@ -617,7 +617,7 @@ __afr_selfheal_data_prepare (call_frame_t *frame, xlator_t *this,                               inode_t *inode, unsigned char *locked_on,                               unsigned char *sources, unsigned char *sinks,                               unsigned char *healed_sinks, -			     struct afr_reply *replies) +			     struct afr_reply *replies, gf_boolean_t *pflag)  {  	int ret = -1;  	int source = -1; @@ -635,7 +635,8 @@ __afr_selfheal_data_prepare (call_frame_t *frame, xlator_t *this,          witness = alloca0(priv->child_count * sizeof (*witness));  	ret = afr_selfheal_find_direction (frame, this, replies,  					   AFR_DATA_TRANSACTION, -					   locked_on, sources, sinks, witness); +					   locked_on, sources, sinks, witness, +                                           pflag);  	if (ret)  		return ret; @@ -699,7 +700,8 @@ __afr_selfheal_data (call_frame_t *frame, xlator_t *this, fd_t *fd,  		ret = __afr_selfheal_data_prepare (frame, this, fd->inode,                                                     data_lock, sources, sinks,                                                     healed_sinks, -						   locked_replies); +						   locked_replies, +                                                   NULL);  		if (ret < 0)  			goto unlock; diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c index 434b0481f0d..42a6c0453b1 100644 --- a/xlators/cluster/afr/src/afr-self-heal-entry.c +++ b/xlators/cluster/afr/src/afr-self-heal-entry.c @@ -388,7 +388,8 @@ __afr_selfheal_entry_prepare (call_frame_t *frame, xlator_t *this,                                inode_t *inode, unsigned char *locked_on,                                unsigned char *sources, unsigned char *sinks,                                unsigned char *healed_sinks, -			      struct afr_reply *replies, int *source_p) +			      struct afr_reply *replies, int *source_p, +                              gf_boolean_t *pflag)  {  	int ret = -1;  	int source = -1; @@ -405,7 +406,8 @@ __afr_selfheal_entry_prepare (call_frame_t *frame, xlator_t *this,          witness = alloca0 (sizeof (*witness) * priv->child_count);  	ret = afr_selfheal_find_direction (frame, this, replies,  					   AFR_ENTRY_TRANSACTION, -					   locked_on, sources, sinks, witness); +					   locked_on, sources, sinks, witness, +                                           pflag);  	if (ret)  		return ret; @@ -475,7 +477,7 @@ afr_selfheal_entry_dirent (call_frame_t *frame, xlator_t *this,                                                      locked_on,                                                      sources, sinks,                                                      healed_sinks, par_replies, -                                                    &source); +                                                    &source, NULL);                  if (ret < 0)                          goto unlock; @@ -649,7 +651,8 @@ __afr_selfheal_entry (call_frame_t *frame, xlator_t *this, fd_t *fd,  		ret = __afr_selfheal_entry_prepare (frame, this, fd->inode,                                                      data_lock, sources, sinks,                                                      healed_sinks, -						    locked_replies, &source); +						    locked_replies, &source, +                                                    NULL);                  if (AFR_COUNT(healed_sinks, priv->child_count) == 0) {                          did_sh = _gf_false;                          goto unlock; diff --git a/xlators/cluster/afr/src/afr-self-heal-metadata.c b/xlators/cluster/afr/src/afr-self-heal-metadata.c index 53133705adc..24b139ad216 100644 --- a/xlators/cluster/afr/src/afr-self-heal-metadata.c +++ b/xlators/cluster/afr/src/afr-self-heal-metadata.c @@ -307,7 +307,7 @@ int  __afr_selfheal_metadata_prepare (call_frame_t *frame, xlator_t *this, inode_t *inode,  				 unsigned char *locked_on, unsigned char *sources,  				 unsigned char *sinks, unsigned char *healed_sinks, -				 struct afr_reply *replies) +				 struct afr_reply *replies, gf_boolean_t *pflag)  {  	int ret = -1;  	int source = -1; @@ -325,7 +325,8 @@ __afr_selfheal_metadata_prepare (call_frame_t *frame, xlator_t *this, inode_t *i          witness = alloca0 (sizeof (*witness) * priv->child_count);          ret = afr_selfheal_find_direction (frame, this, replies,  					   AFR_METADATA_TRANSACTION, -					   locked_on, sources, sinks, witness); +					   locked_on, sources, sinks, witness, +                                           pflag);  	if (ret)  		return ret; @@ -400,7 +401,7 @@ afr_selfheal_metadata (call_frame_t *frame, xlator_t *this, inode_t *inode)  		ret = __afr_selfheal_metadata_prepare (frame, this, inode,                                                         data_lock, sources,                                                         sinks, healed_sinks, -						       locked_replies); +						       locked_replies, NULL);  		if (ret < 0)  			goto unlock; diff --git a/xlators/cluster/afr/src/afr-self-heal-name.c b/xlators/cluster/afr/src/afr-self-heal-name.c index 0d2fe6701bd..b57acbe99e0 100644 --- a/xlators/cluster/afr/src/afr-self-heal-name.c +++ b/xlators/cluster/afr/src/afr-self-heal-name.c @@ -514,7 +514,8 @@ __afr_selfheal_name_prepare (call_frame_t *frame, xlator_t *this, inode_t *paren          witness = alloca0 (sizeof (*witness) * priv->child_count);  	ret = afr_selfheal_find_direction (frame, this, replies,  					   AFR_ENTRY_TRANSACTION, -					   locked_on, sources, sinks, witness); +					   locked_on, sources, sinks, witness, +                                           NULL);  	if (ret)  		goto out; diff --git a/xlators/cluster/afr/src/afr-self-heal.h b/xlators/cluster/afr/src/afr-self-heal.h index a707e20e222..74e852aa038 100644 --- a/xlators/cluster/afr/src/afr-self-heal.h +++ b/xlators/cluster/afr/src/afr-self-heal.h @@ -140,7 +140,8 @@ afr_selfheal_find_direction (call_frame_t *frame, xlator_t *this,                               struct afr_reply *replies,                               afr_transaction_type type,                               unsigned char *locked_on, unsigned char *sources, -                             unsigned char *sinks, uint64_t *witness); +                             unsigned char *sinks, uint64_t *witness, +                             gf_boolean_t *flag);  int  afr_selfheal_fill_matrix (xlator_t *this, int **matrix, int subvol, int idx,                            dict_t *xdata); @@ -225,7 +226,8 @@ __afr_selfheal_data_prepare (call_frame_t *frame, xlator_t *this,                               inode_t *inode, unsigned char *locked_on,                               unsigned char *sources,                               unsigned char *sinks, unsigned char *healed_sinks, -                             struct afr_reply *replies); +                             struct afr_reply *replies, +                             gf_boolean_t *flag);  int  __afr_selfheal_metadata_prepare (call_frame_t *frame, xlator_t *this, @@ -233,14 +235,16 @@ __afr_selfheal_metadata_prepare (call_frame_t *frame, xlator_t *this,                                   unsigned char *sources,                                   unsigned char *sinks,                                   unsigned char *healed_sinks, -                                 struct afr_reply *replies); +                                 struct afr_reply *replies, +                                 gf_boolean_t *flag);  int  __afr_selfheal_entry_prepare (call_frame_t *frame, xlator_t *this,                                inode_t *inode, unsigned char *locked_on,                                unsigned char *sources,                                unsigned char *sinks,                                unsigned char *healed_sinks, -                              struct afr_reply *replies, int *source_p); +                              struct afr_reply *replies, int *source_p, +                              gf_boolean_t *flag);  int  afr_selfheal_unlocked_inspect (call_frame_t *frame, xlator_t *this, diff --git a/xlators/features/index/src/index.c b/xlators/features/index/src/index.c index 1d64ef2bf6e..f08cdb1d200 100644 --- a/xlators/features/index/src/index.c +++ b/xlators/features/index/src/index.c @@ -1330,7 +1330,7 @@ index_fetch_link_count (xlator_t *this, index_xattrop_type_t type)                  } else if (!strcmp (entry->d_name, ".") ||  		           !strcmp (entry->d_name, "..")) {  			continue; -                } else if (!strncmp (entry->d_name, subdir, strlen (subdir))) { +                } else {                          make_file_path (priv->index_basepath, subdir,                                          entry->d_name, index_path,                                          sizeof (index_path)); @@ -1345,9 +1345,6 @@ index_fetch_link_count (xlator_t *this, index_xattrop_type_t type)                                  else                                          break;                          } -                } else { -                        count = 1; -                        goto out;                  }  	}  out:  | 
