diff options
| author | shishir gowda <shishirng@gluster.com> | 2011-10-21 12:17:04 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vijay@gluster.com> | 2011-10-21 00:19:59 -0700 | 
| commit | b3d696f78b16f246bd34f87aafb52317033408cc (patch) | |
| tree | de7c6e86ac2faed92552a760fd5894a7f93102b6 | |
| parent | bdf20a205a4d67d5f6d3ac6010a34291c2822a80 (diff) | |
Stripe mknod: Always call mknod if REGULAR file on first child.
This prevents a possible race between mknod(REGULUAR files) and remove.
mknod first creates on the first_child, and only if successful, on other
subvolumes.
Change-Id: I0ddaeb92c1884c771c966bb151db052ab5735367
BUG: 3727
Reviewed-on: http://review.gluster.com/608
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Amar Tumballi <amar@gluster.com>
| -rw-r--r-- | xlators/cluster/stripe/src/stripe.c | 183 | ||||
| -rw-r--r-- | xlators/cluster/stripe/src/stripe.h | 1 | 
2 files changed, 138 insertions, 46 deletions
diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c index 206b1e1327c..bef1eb7495d 100644 --- a/xlators/cluster/stripe/src/stripe.c +++ b/xlators/cluster/stripe/src/stripe.c @@ -1467,7 +1467,7 @@ stripe_mknod_ifreg_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          }          prev  = cookie; -	priv  = this->private; +        priv  = this->private;          local = frame->local;          LOCK (&frame->lock); @@ -1483,16 +1483,9 @@ stripe_mknod_ifreg_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                                  local->failed = 1;                          local->op_errno = op_errno;                  } -                  if (op_ret >= 0) {                          local->op_ret = op_ret; -                        if (FIRST_CHILD(this) == prev->this) { -                                local->stbuf      = *buf; -                                local->preparent  = *preparent; -                                local->postparent = *postparent; -                        } -                          /* Can be used as a mechanism to understand if mknod                             was successful in at least one place */                          if (uuid_is_null (local->ia_gfid)) @@ -1554,6 +1547,111 @@ out:  int32_t +stripe_mknod_first_ifreg_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                        int32_t op_ret, int32_t op_errno, inode_t *inode, +                        struct iatt *buf, struct iatt *preparent, +                        struct iatt *postparent) +{ +        stripe_local_t   *local = NULL; +        stripe_private_t *priv = NULL; +        call_frame_t     *prev = NULL; +        xlator_list_t    *trav = NULL; +        int               i    = 1; +        char              size_key[256]  = {0,}; +        char              index_key[256] = {0,}; +        char              count_key[256] = {0,}; +        dict_t           *dict           = NULL; +        int               ret            = 0; +        int               need_unref     = 0; + +        if (!this || !frame || !frame->local || !cookie) { +                gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref"); +                goto out; +        } + +        prev  = cookie; +        priv  = this->private; +        local = frame->local; +        trav = this->children; + +        local->call_count--; + +        if (op_ret == -1) { +                gf_log (this->name, GF_LOG_DEBUG, "%s returned error %s", +                        prev->this->name, strerror (op_errno)); +                local->failed = 1; +                local->op_errno = op_errno; +                goto out; +        } + +        local->op_ret = op_ret; + +        local->stbuf      = *buf; +        local->preparent  = *preparent; +        local->postparent = *postparent; + +        if (uuid_is_null (local->ia_gfid)) +                uuid_copy (local->ia_gfid, buf->ia_gfid); +        local->preparent.ia_blocks  = local->preparent_blocks; +        local->preparent.ia_size    = local->preparent_size; +        local->postparent.ia_blocks = local->postparent_blocks; +        local->postparent.ia_size   = local->postparent_size; +        local->stbuf.ia_size        = local->stbuf_size; +        local->stbuf.ia_blocks      = local->stbuf_blocks; + +        sprintf (size_key, "trusted.%s.stripe-size", this->name); +        sprintf (count_key, "trusted.%s.stripe-count", this->name); +        sprintf (index_key, "trusted.%s.stripe-index", this->name); + +        trav = trav->next; +        while (trav) { +                if (priv->xattr_supported) { +                        dict = dict_new (); +                        if (!dict) { +                                gf_log (this->name, GF_LOG_ERROR, +                                        "failed to allocate dict %s", local->loc.path); +                        } +                        need_unref = 1; + +                        dict_copy (local->xattr, dict); + +                        ret = dict_set_int64 (dict, size_key, local->stripe_size); +                        if (ret) +                                gf_log (this->name, GF_LOG_ERROR, +                                        "%s: set stripe-size failed", local->loc.path); +                        ret = dict_set_int32 (dict, count_key, priv->child_count); + +                        if (ret) +                                gf_log (this->name, GF_LOG_ERROR, +                                        "%s: set child_count failed", local->loc.path); +                        ret = dict_set_int32 (dict, index_key, i); +                        if (ret) +                                gf_log (this->name, GF_LOG_ERROR, +                                        "%s: set stripe-index failed", local->loc.path); +                } else { +                        dict = local->xattr; +                } + +                STACK_WIND (frame, stripe_mknod_ifreg_cbk, +                            trav->xlator, trav->xlator->fops->mknod, +                            &local->loc, local->mode, local->rdev, dict); +                trav = trav->next; +                i++; + +                if (dict && need_unref) +                        dict_unref (dict); +        } + +        return 0; + +out: + +       STRIPE_STACK_UNWIND (mknod, frame, op_ret, op_errno, NULL, NULL, NULL, NULL); +       return 0; +} + + +int32_t  stripe_single_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                           int32_t op_ret, int32_t op_errno, inode_t *inode,                           struct iatt *buf, struct iatt *preparent, @@ -1571,7 +1669,6 @@ stripe_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,  {          stripe_private_t *priv           = NULL;          stripe_local_t   *local          = NULL; -        xlator_list_t    *trav           = NULL;          int32_t           op_errno       = EINVAL;          int32_t           i              = 0;          char              size_key[256]  = {0,}; @@ -1588,7 +1685,6 @@ stripe_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,          VALIDATE_OR_GOTO (loc->inode, err);          priv = this->private; -        trav = this->children;          if (priv->first_child_down) {                  op_errno = ENOTCONN; @@ -1621,6 +1717,9 @@ stripe_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,                  frame->local = local;                  local->inode = inode_ref (loc->inode);                  loc_copy (&local->loc, loc); +                local->xattr = dict_copy_with_ref (params, NULL); +                local->mode = mode; +                local->rdev = rdev;                  /* Everytime in stripe lookup, all child nodes should                     be looked up */ @@ -1635,48 +1734,40 @@ stripe_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,                  sprintf (index_key,                           "trusted.%s.stripe-index", this->name); -                while (trav) { -                        if (priv->xattr_supported) { -                                dict = dict_new (); -                                if (!dict) { -                                        gf_log (this->name, GF_LOG_ERROR, -                                                "failed to allocate dict %s", loc->path); -                                } -                                need_unref = 1; +                if (priv->xattr_supported) { +                        dict = dict_new (); +                        if (!dict) { +                                gf_log (this->name, GF_LOG_ERROR, +                                        "failed to allocate dict %s", loc->path); +                        } +                        need_unref = 1; -                                dict_copy (params, dict); +                        dict_copy (params, dict); -                                ret = dict_set_int64 (dict, size_key, -                                                      local->stripe_size); -                                if (ret) -                                        gf_log (this->name, GF_LOG_ERROR, -                                                "%s: set stripe-size failed", loc->path); -                                ret = dict_set_int32 (dict, count_key, -                                                      priv->child_count); -                                if (ret) -                                        gf_log (this->name, GF_LOG_ERROR, -                                                "%s: set child_count failed", -                                                loc->path); -                                ret = dict_set_int32 (dict, index_key, i); -                                if (ret) -                                        gf_log (this->name, GF_LOG_ERROR, -                                                "%s: set stripe-index failed", -                                                loc->path); -                        } else { -                                dict = params; -                        } +                        ret = dict_set_int64 (dict, size_key, +                                              local->stripe_size); +                        if (ret) +                                gf_log (this->name, GF_LOG_ERROR, +                                        "%s: set stripe-size failed", loc->path); +                        ret = dict_set_int32 (dict, count_key, +                                               priv->child_count); +                        if (ret) +                                gf_log (this->name, GF_LOG_ERROR, +                                        "%s: set child_count failed", loc->path); +                        ret = dict_set_int32 (dict, index_key, i); +                        if (ret) +                                gf_log (this->name, GF_LOG_ERROR, +                                        "%s: set stripe-index failed", loc->path); +                } else { +                        dict = params; +                } -                        STACK_WIND (frame, stripe_mknod_ifreg_cbk, -                                    trav->xlator, trav->xlator->fops->mknod, -                                    loc, mode, rdev, dict); -                        trav = trav->next; -                        i++; +                STACK_WIND (frame, stripe_mknod_first_ifreg_cbk, +                            FIRST_CHILD (this), FIRST_CHILD (this)->fops->mknod, +                            loc, mode, rdev, dict);                          if (dict && need_unref)                                  dict_unref (dict); -                } - -                /* This case is handled, no need to continue further. */                  return 0;          } diff --git a/xlators/cluster/stripe/src/stripe.h b/xlators/cluster/stripe/src/stripe.h index a6dece906ea..3ab67d62135 100644 --- a/xlators/cluster/stripe/src/stripe.h +++ b/xlators/cluster/stripe/src/stripe.h @@ -171,6 +171,7 @@ struct stripe_local {          loc_t                loc2;          mode_t               mode; +        dev_t                rdev;          /* For File I/O fops */          dict_t              *dict;  | 
