diff options
| author | Krishnan Parthasarathi <kp@gluster.com> | 2011-11-16 16:23:48 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vijay@gluster.com> | 2012-02-14 02:48:59 -0800 | 
| commit | b27512e006ae55777f481937d321f60fa195c48d (patch) | |
| tree | d84c8cf1e5d34849da39ef9f936553d05fae1a2c /xlators/cluster/afr/src | |
| parent | 58a538e99806ae84ec4d4bf03aa726302e16d07b (diff) | |
locks: Added a getxattr interface to clear locks on a given inode.
getxattr returns a summary of no. of inodelks/entrylks cleared.
cmd_structure: trusted.glusterfs.clrlk.t<type>.k<kind>[.{range|basename}]
where,
type = "inode"| "entry"| "posix"
kind = "granted"| "blocked" | "all"
range = off,a-b, where a, b = 'start', 'len' from offset 'off'
Change-Id: I8a771530531030a9d4268643bc6823786ccb51f2
BUG: 789858
Signed-off-by: Krishnan Parthasarathi <kp@gluster.com>
Reviewed-on: http://review.gluster.com/2551
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vijay@gluster.com>
Diffstat (limited to 'xlators/cluster/afr/src')
| -rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 24 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-inode-read.c | 178 | 
2 files changed, 172 insertions, 30 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index b0f7b38f3..a5dee65f6 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -808,7 +808,6 @@ afr_local_transaction_cleanup (afr_local_t *local, xlator_t *this)          GF_FREE (local->transaction.pre_op);          GF_FREE (local->transaction.child_errno); -        GF_FREE (local->child_errno);          GF_FREE (local->transaction.eager_lock);          GF_FREE (local->transaction.basename); @@ -845,6 +844,9 @@ afr_local_cleanup (afr_local_t *local, xlator_t *this)          if (local->child_up)                  GF_FREE (local->child_up); +        if (local->child_errno) +                GF_FREE (local->child_errno); +          if (local->fresh_children)                  GF_FREE (local->fresh_children); @@ -3592,8 +3594,8 @@ afr_local_init (afr_local_t *local, afr_private_t *priv, int32_t *op_errno)          local->op_ret = -1;          local->op_errno = EUCLEAN; -        local->child_up = GF_CALLOC (sizeof (*local->child_up), -                                     priv->child_count, +        local->child_up = GF_CALLOC (priv->child_count, +                                     sizeof (*local->child_up),                                       gf_afr_mt_char);          if (!local->child_up) {                  if (op_errno) @@ -3611,6 +3613,16 @@ afr_local_init (afr_local_t *local, afr_private_t *priv, int32_t *op_errno)                          *op_errno = ENOTCONN;                  goto out;          } + +        local->child_errno = GF_CALLOC (priv->child_count, +                                        sizeof (*local->child_errno), +                                        gf_afr_mt_int32_t); +        if (!local->child_errno) { +                if (op_errno) +                        *op_errno = ENOMEM; +                goto out; +        } +          ret = 0;  out:          return ret; @@ -3711,12 +3723,6 @@ afr_transaction_local_init (afr_local_t *local, xlator_t *this)          local->first_up_child = afr_first_up_child (local->child_up,                                                      priv->child_count); -        local->child_errno = GF_CALLOC (sizeof (*local->child_errno), -                                        priv->child_count, -                                        gf_afr_mt_int32_t); -        if (!local->child_errno) -                goto out; -          local->transaction.eager_lock =                  GF_CALLOC (sizeof (*local->transaction.eager_lock),                             priv->child_count, diff --git a/xlators/cluster/afr/src/afr-inode-read.c b/xlators/cluster/afr/src/afr-inode-read.c index 0ef0f4f86..ec0acbd3b 100644 --- a/xlators/cluster/afr/src/afr-inode-read.c +++ b/xlators/cluster/afr/src/afr-inode-read.c @@ -632,6 +632,101 @@ afr_getxattr_unwind (call_frame_t *frame,  }  int32_t +afr_getxattr_clrlk_cbk (call_frame_t *frame, void *cookie, +                        xlator_t *this, int32_t op_ret, int32_t op_errno, +                        dict_t *dict) +{ +        afr_local_t     *local                  = NULL; +        afr_private_t   *priv                   = NULL; +        xlator_t        **children              = NULL; +        dict_t          *xattr                  = NULL; +        char            *tmp_report             = NULL; +        char            lk_summary[1024]        = {0,}; +        int             serz_len                = 0; +        int32_t         callcnt                 = 0; +        long int        cky                     = 0; +        int             ret                     = 0; + +        priv     = this->private; +        children = priv->children; + +        local = frame->local; +        cky = (long) cookie; + +        LOCK (&frame->lock); +        { +                callcnt = --local->call_count; + +                if (!local->dict) +                        local->dict = dict_new (); +                if (local->dict) { +                        ret = dict_get_str (dict, local->cont.getxattr.name, +                                            &tmp_report); +                        if (ret) +                                goto unlock; +                        ret = dict_set_str (local->dict, +                                            children[cky]->name, +                                            tmp_report); +                        if (ret) +                                goto unlock; +                } +                if (op_ret == -1) +                        local->child_errno[cky] = op_errno; +        } +unlock: +        UNLOCK (&frame->lock); + +        if (!callcnt) { +                xattr = dict_new (); +                if (!xattr) { +                        op_ret = -1; +                        op_errno = ENOMEM; +                        goto unwind; +                } +                ret = dict_serialize_value_with_delim (local->dict, +                                                       lk_summary, +                                                       &serz_len, '\n'); +                if (ret) { +                        op_ret = -1; +                        op_errno = ENOMEM; +                        gf_log (this->name, GF_LOG_ERROR, +                                "Error serializing dictionary"); +                        goto unwind; +                } +                if (serz_len == -1) +                        snprintf (lk_summary, sizeof (lk_summary), +                                  "No locks cleared."); +                ret = dict_set_dynstr (xattr, local->cont.getxattr.name, +                                       gf_strdup (lk_summary)); +                if (ret) { +                        op_ret = -1; +                        op_errno = ENOMEM; +                        gf_log (this->name, GF_LOG_ERROR, +                                "Error setting dictionary"); +                        goto unwind; +                } + +        unwind: +                // Updating child_errno with more recent 'events' +                local->child_errno[cky] = op_errno; +                op_errno = afr_resultant_errno_get (NULL, local->child_errno, +                                                    priv->child_count); +                AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, xattr); + +                if (local->dict) +                        dict_unref (local->dict); + +                if (local->child_errno) +                        GF_FREE (local->child_errno); + +                if (xattr) +                        dict_unref (xattr); +        } + +        return ret; +} + +int32_t  afr_getxattr_pathinfo_cbk (call_frame_t *frame, void *cookie,                             xlator_t *this, int32_t op_ret, int32_t op_errno,                             dict_t *dict) @@ -735,20 +830,69 @@ afr_getxattr_pathinfo_cbk (call_frame_t *frame, void *cookie,          return ret;  } +static gf_boolean_t +afr_is_special_xattr (const char *name, fop_getxattr_cbk_t *cbk) +{ +        gf_boolean_t    is_spl = _gf_true; + +        GF_ASSERT (cbk); +        if (!cbk) { +                is_spl = _gf_false; +                goto out; +        } + +        if (!strcmp (name, GF_XATTR_PATHINFO_KEY)) +                *cbk = afr_getxattr_pathinfo_cbk; + +        else if (!strcmp (name, GF_XATTR_CLRLK_CMD)) +                *cbk = afr_getxattr_clrlk_cbk; +        else +                is_spl = _gf_false; + +out: +        return is_spl; +} + +static void +afr_getxattr_frm_all_children (xlator_t *this, call_frame_t *frame, +                               const char *name, loc_t *loc, +                               fop_getxattr_cbk_t cbk) +{ +        afr_private_t   *priv           = NULL; +        afr_local_t     *local          = NULL; +        xlator_t        **children      = NULL; +        int             i               = 0; + +        priv     = this->private; +        children = priv->children; + +        local = frame->local; +        local->call_count = priv->child_count; + +        for (i = 0; i < priv->child_count; i++) { +                STACK_WIND_COOKIE (frame, cbk, +                                   (void *) (long) i, +                                   children[i], children[i]->fops->getxattr, +                                   loc, name); +        } +        return; +} +  int32_t  afr_getxattr (call_frame_t *frame, xlator_t *this,                loc_t *loc, const char *name)  { -        afr_private_t   *priv         = NULL; -        xlator_t        **children    = NULL; -        int             call_child    = 0; -        afr_local_t     *local        = NULL; -        xlator_list_t   *trav         = NULL; -        xlator_t        **sub_volumes = NULL; -        int             i             = 0; -        int32_t         op_errno      = 0; -        int32_t         read_child    = -1; -        int             ret           = -1; +        afr_private_t           *priv         = NULL; +        xlator_t                **children    = NULL; +        int                     call_child    = 0; +        afr_local_t             *local        = NULL; +        xlator_list_t           *trav         = NULL; +        xlator_t                **sub_volumes = NULL; +        int                     i             = 0; +        int32_t                 op_errno      = 0; +        int32_t                 read_child    = -1; +        int                     ret           = -1; +        fop_getxattr_cbk_t      cbk           = NULL;          VALIDATE_OR_GOTO (frame, out); @@ -814,17 +958,9 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,                   * if we are doing getxattr with pathinfo as the key then we                   * collect information from all childs                   */ -                if (strncmp (name, GF_XATTR_PATHINFO_KEY, -                             strlen (GF_XATTR_PATHINFO_KEY)) == 0) { - -                        local->call_count = priv->child_count; -                        for (i = 0; i < priv->child_count; i++) { -                                STACK_WIND_COOKIE (frame, afr_getxattr_pathinfo_cbk, -                                                   (void *) (long) i, -                                                   children[i], children[i]->fops->getxattr, -                                                   loc, name); -                        } - +                if (afr_is_special_xattr (name, &cbk)) { +                        afr_getxattr_frm_all_children (this, frame, name, +                                                       loc, cbk);                          return 0;                  }  | 
