diff options
| author | Krutika Dhananjay <kdhananj@redhat.com> | 2016-06-22 14:52:58 +0530 | 
|---|---|---|
| committer | Pranith Kumar Karampuri <pkarampu@redhat.com> | 2016-06-28 01:13:57 -0700 | 
| commit | 2ca5388692e70e079c99771d8c66a06bd90d5268 (patch) | |
| tree | da9ff1435f6ba04267537d25bebaa9f0a4f01f21 /xlators/features/index | |
| parent | 888de8851e718d8e3117e47fa35cfc075b998f62 (diff) | |
features/index: Delete parent dir indices when heal on it is complete
In this patch, the state information about whether a directory
gfid index is present or not is stored in the inode ctx with
values IN and NOTIN. This saves index xl the need to perform
stat() everytime an index_entry_create() is called.
When a brick is restarted these in-memory inode ctx records will
be gone. So when granular entry heal happens after a brick is restarted,
and a post-op is done on the parent, if the state gotten from inode ctx
is UNKNOWN, then index xl does a stat to initialize the state as IN or
NOTIN. Note that this is a one-time operation for the lifetime of the
brick. Such a change also helps avoid calling index_del() in
xattrop_index_action() periodically even when granular self-heal is
disabled or when the volume type is disperse.
Change-Id: Ib92c17350e6531b91ab81477410fe1e7a5856207
BUG: 1331323
Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com>
Reviewed-on: http://review.gluster.org/14781
Smoke: Gluster Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Diffstat (limited to 'xlators/features/index')
| -rw-r--r-- | xlators/features/index/src/index.c | 123 | 
1 files changed, 89 insertions, 34 deletions
diff --git a/xlators/features/index/src/index.c b/xlators/features/index/src/index.c index b6bd5e87b73..cd40f2587b2 100644 --- a/xlators/features/index/src/index.c +++ b/xlators/features/index/src/index.c @@ -652,14 +652,19 @@ index_del (xlator_t *this, uuid_t gfid, const char *subdir, int type)                                         out, op_errno, EINVAL);          make_gfid_path (priv->index_basepath, subdir, gfid,                          gfid_path, sizeof (gfid_path)); -        ret = sys_unlink (gfid_path); + +        if ((strcmp (subdir, ENTRY_CHANGES_SUBDIR)) == 0) +                ret = sys_rmdir (gfid_path); +        else +                ret = sys_unlink (gfid_path); +          if (ret && (errno != ENOENT)) { -                gf_log (this->name, GF_LOG_ERROR, -                        "%s: failed to delete from index (%s)", -                        gfid_path, strerror (errno)); +                gf_log (this->name, GF_LOG_ERROR, "%s: failed to delete" +                        " from index (%s)", gfid_path, strerror (errno));                  ret = -errno;                  goto out;          } +          index_dec_link_count (priv, type);          ret = 0;  out: @@ -758,37 +763,47 @@ _check_key_is_zero_filled (dict_t *d, char *k, data_t *v,  }  int -index_entry_create (xlator_t *this, uuid_t gfid, char *filename) -{ -        char entry_base_index_path[PATH_MAX] = {0}; -        char pgfid_path[PATH_MAX] = {0}; -        char entry_path[PATH_MAX] = {0}; -        struct stat st = {0}; -        uuid_t index = {0}; -        index_priv_t *priv = NULL; -        int ret = -1; -        int op_errno = 0; -        int fd = 0; +index_entry_create (xlator_t *this, inode_t *inode, char *filename) +{ +        int                 fd                              = 0; +        int                 ret                             = -1; +        int                 op_errno                        = 0; +        char               *subdir                          = NULL; +        char                pgfid_path[PATH_MAX]            = {0}; +        char                entry_path[PATH_MAX]            = {0}; +        char                entry_base_index_path[PATH_MAX] = {0}; +        uuid_t              index                           = {0}; +        struct stat         st                              = {0}; +        index_priv_t       *priv                            = NULL; +        index_inode_ctx_t  *ctx                             = NULL; -        GF_ASSERT_AND_GOTO_WITH_ERROR (this->name, !gf_uuid_is_null (gfid), -                                       out, op_errno, EINVAL); +        priv = this->private; + +        GF_ASSERT_AND_GOTO_WITH_ERROR (this->name, +                                       !gf_uuid_is_null (inode->gfid), out, +                                       op_errno, EINVAL);          GF_ASSERT_AND_GOTO_WITH_ERROR (this->name, filename, out, op_errno,                                         EINVAL); -        priv = this->private; -        make_gfid_path (priv->index_basepath, ENTRY_CHANGES_SUBDIR, gfid, -                        pgfid_path, sizeof (pgfid_path)); +        ret = index_inode_ctx_get (inode, this, &ctx); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, "Not able to get inode ctx " +                        "for %s", uuid_utoa (inode->gfid)); +                op_errno = ENOMEM; +                goto out; +        } -        ret = stat (pgfid_path, &st); -        if (ret != 0) { -                op_errno = errno; -                if (op_errno != ENOENT) -                        goto out; +        make_gfid_path (priv->index_basepath, ENTRY_CHANGES_SUBDIR, +                        inode->gfid, pgfid_path, sizeof (pgfid_path)); +        subdir = index_get_subdir_from_type (ENTRY_CHANGES); + +        if (ctx->state[ENTRY_CHANGES] != IN) {                  ret = sys_mkdir (pgfid_path, 0600);                  if (ret != 0 && errno != EEXIST) {                          op_errno = errno;                          goto out;                  } +                ctx->state[ENTRY_CHANGES] = IN;          }          op_errno = 0; @@ -810,22 +825,25 @@ out:  int  index_entry_delete (xlator_t *this, uuid_t pgfid, char *filename)  { -        char entry_base_index_path[PATH_MAX] = {0}; -        char pgfid_path[PATH_MAX] = {0}; -        char entry_path[PATH_MAX] = {0}; -        index_priv_t *priv = NULL; -        int op_errno = 0; -        int ret = 0; +        int                 ret                             = 0; +        int                 op_errno                        = 0; +        char                entry_base_index_path[PATH_MAX] = {0}; +        char                pgfid_path[PATH_MAX]            = {0}; +        char                entry_path[PATH_MAX]            = {0}; +        index_priv_t       *priv                            = NULL; + +        priv = this->private;          GF_ASSERT_AND_GOTO_WITH_ERROR (this->name, !gf_uuid_is_null (pgfid),                                         out, op_errno, EINVAL);          GF_ASSERT_AND_GOTO_WITH_ERROR (this->name, filename, out, op_errno,                                         EINVAL); -        priv = this->private; +          make_gfid_path (priv->index_basepath, ENTRY_CHANGES_SUBDIR, pgfid,                          pgfid_path, sizeof (pgfid_path));          snprintf (entry_path, sizeof(entry_path), "%s/%s", pgfid_path,                    filename); +          ret = sys_unlink (entry_path);          if (ret && (errno != ENOENT)) {                  op_errno = errno; @@ -836,7 +854,6 @@ index_entry_delete (xlator_t *this, uuid_t pgfid, char *filename)  out:          return -op_errno; -  }  int @@ -853,7 +870,7 @@ index_entry_action (xlator_t *this, inode_t *inode, dict_t *xdata, char *key)          }          if (strcmp (key, GF_XATTROP_ENTRY_IN_KEY) == 0) -                ret = index_entry_create (this, inode->gfid, filename); +                ret = index_entry_create (this, inode, filename);          else if (strcmp (key, GF_XATTROP_ENTRY_OUT_KEY) == 0)                  ret = index_entry_delete (this, inode->gfid, filename); @@ -896,6 +913,29 @@ out:          return;  } +static void +index_init_state (xlator_t *this, inode_t *inode, index_inode_ctx_t *ctx, +                  char *subdir) +{ +        int                 ret                             = -1; +        char                pgfid_path[PATH_MAX]            = {0}; +        struct stat         st                              = {0}; +        index_priv_t       *priv                            = NULL; + +        priv = this->private; + +        make_gfid_path (priv->index_basepath, subdir, inode->gfid, pgfid_path, +                        sizeof (pgfid_path)); + +        ret = sys_stat (pgfid_path, &st); +        if (ret == 0) +                ctx->state[ENTRY_CHANGES] = IN; +        else if (ret != 0 && errno == ENOENT) +                ctx->state[ENTRY_CHANGES] = NOTIN; + +        return; +} +  void  xattrop_index_action (xlator_t *this, index_local_t *local, dict_t *xattr,                        dict_match_t match, void *match_data) @@ -903,9 +943,11 @@ xattrop_index_action (xlator_t *this, index_local_t *local, dict_t *xattr,          int              i                       = 0;          int            ret                       = 0;          int            zfilled[XATTROP_TYPE_END] = {0,}; +        char          *subdir                    = NULL;          dict_t        *req_xdata                 = NULL;          inode_t       *inode                     = NULL;          gf_boolean_t   zero_xattr                = _gf_true; +        index_inode_ctx_t *ctx                   = NULL;          inode = local->inode;          req_xdata = local->xdata; @@ -918,6 +960,19 @@ xattrop_index_action (xlator_t *this, index_local_t *local, dict_t *xattr,          if (req_xdata)                  ret = index_entry_action (this, inode, req_xdata,                                            GF_XATTROP_ENTRY_OUT_KEY); + +        if (zfilled[XATTROP] == 1) { +                subdir = index_get_subdir_from_type (ENTRY_CHANGES); +                ret = index_inode_ctx_get (inode, this, &ctx); +                if (ctx->state[ENTRY_CHANGES] == UNKNOWN) +                        index_init_state (this, inode, ctx, subdir); +                if (ctx->state[ENTRY_CHANGES] == IN) { +                        ret = index_del (this, inode->gfid, subdir, +                                         ENTRY_CHANGES); +                        ctx->state[ENTRY_CHANGES] = NOTIN; +                } +        } +          return;  }  | 
