diff options
| author | karthik-us <ksubrahm@redhat.com> | 2016-05-05 12:42:35 +0530 | 
|---|---|---|
| committer | Jeff Darcy <jdarcy@redhat.com> | 2016-05-31 08:55:57 -0700 | 
| commit | 03880f81dad9fd2a3a07c56a3cfbb994d44819b7 (patch) | |
| tree | 334f7f3752dee2163f2bf6bff8df2fa8b32588da | |
| parent | 1126ebcf667771267a47ea9749ed5f30a76d0d60 (diff) | |
features/worm: updating function names & unwinding FOPs with op_errno
- Added gf_worm prefix to some of the functions in worm-helper files so that
  they do not clash with other functions
- Made the functions in worm.c static
- Unwinding the FOPs with op_errno instead of using different unwind statements
- Removed the multiple goto labels (wind & unwind)
Change-Id: I3a2f114061aae4b422df54e91c4b3f702af5d0b0
BUG: 1333263
Signed-off-by: karthik-us <ksubrahm@redhat.com>
Reviewed-on: http://review.gluster.org/14222
Smoke: Gluster Build System <jenkins@build.gluster.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Joseph Fernandes
Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
| -rw-r--r-- | xlators/features/read-only/src/read-only.h | 1 | ||||
| -rw-r--r-- | xlators/features/read-only/src/worm-helper.c | 119 | ||||
| -rw-r--r-- | xlators/features/read-only/src/worm-helper.h | 19 | ||||
| -rw-r--r-- | xlators/features/read-only/src/worm.c | 372 | 
4 files changed, 251 insertions, 260 deletions
diff --git a/xlators/features/read-only/src/read-only.h b/xlators/features/read-only/src/read-only.h index 3178bb26715..d0263e74179 100644 --- a/xlators/features/read-only/src/read-only.h +++ b/xlators/features/read-only/src/read-only.h @@ -14,6 +14,7 @@  #include "read-only-mem-types.h"  #include "xlator.h" +  typedef struct {          uint8_t worm : 1;          uint8_t retain : 1; diff --git a/xlators/features/read-only/src/worm-helper.c b/xlators/features/read-only/src/worm-helper.c index b5b1c628d73..692899d9379 100644 --- a/xlators/features/read-only/src/worm-helper.c +++ b/xlators/features/read-only/src/worm-helper.c @@ -18,7 +18,7 @@   * the write protection bits for all the users of the file.   * Return true if all the write bits are disabled,false otherwise*/  gf_boolean_t -is_write_disabled (struct iatt *stbuf) +gf_worm_write_disabled (struct iatt *stbuf)  {          gf_boolean_t ret        =       _gf_false; @@ -113,7 +113,7 @@ worm_set_state (xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr,          if (ret)                  goto out; -        ret = set_xattr (this, retention_state, fop_with_fd, file_ptr); +        ret = gf_worm_set_xattr (this, retention_state, fop_with_fd, file_ptr);          if (ret) {                  gf_log (this->name, GF_LOG_ERROR, "Error setting xattr");                  goto out; @@ -153,7 +153,7 @@ worm_get_state (xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr,                  ret = -2;                  gf_log (this->name, GF_LOG_ERROR, "Empty val");          } -        deserialize_state (val, reten_state); +        gf_worm_deserialize_state (val, reten_state);  out:          if (dict)                  dict_unref (dict); @@ -165,44 +165,32 @@ out:   * Based on the retain value and the access time of the file, the transition   * from WORM/Retention to WORM is made.*/  void -state_lookup (xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr, -              worm_reten_state_t *reten_state) +gf_worm_state_lookup (xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr, +                      worm_reten_state_t *reten_state, struct iatt *stbuf)  {          int ret                                 =       -1; -        struct iatt stbuf                       =       {0,};          GF_VALIDATE_OR_GOTO ("worm", this, out);          GF_VALIDATE_OR_GOTO (this->name, file_ptr, out);          GF_VALIDATE_OR_GOTO (this->name, reten_state, out); +        GF_VALIDATE_OR_GOTO (this->name, stbuf, out); -        if (fop_with_fd) -                ret = syncop_fstat (this, (fd_t *)file_ptr, &stbuf, NULL, NULL); -        else -                ret = syncop_stat (this, (loc_t *)file_ptr, &stbuf, NULL, NULL); -        if (ret) { -                gf_log (this->name, GF_LOG_ERROR, "Stat lookup error: %s", -                        strerror (-ret)); -                        goto out; -        } -        if (time (NULL) < stbuf.ia_atime) -                goto out; - -        stbuf.ia_atime -= reten_state->ret_period; +        stbuf->ia_atime -= reten_state->ret_period;          reten_state->retain = 0;          reten_state->ret_period = 0;          reten_state->auto_commit_period = 0; -        ret = set_xattr (this, reten_state, fop_with_fd, file_ptr); +        ret = gf_worm_set_xattr (this, reten_state, fop_with_fd, file_ptr);          if (ret) {                  gf_log (this->name, GF_LOG_ERROR, "Error setting xattr");                  goto out;          }          if (fop_with_fd) -                ret = syncop_fsetattr (this, (fd_t *)file_ptr, &stbuf, +                ret = syncop_fsetattr (this, (fd_t *)file_ptr, stbuf,                                         GF_SET_ATTR_ATIME, NULL, NULL,                                         NULL, NULL);          else -                ret = syncop_setattr (this, (loc_t *)file_ptr, &stbuf, +                ret = syncop_setattr (this, (loc_t *)file_ptr, stbuf,                                        GF_SET_ATTR_ATIME, NULL, NULL,                                        NULL, NULL);          if (ret) @@ -216,7 +204,7 @@ out:  /*This function serializes and stores the WORM/Retention state of a file in an   * uint64_t variable by setting the bits using the bitwise operations.*/  void -serialize_state (worm_reten_state_t *reten_state, char *val) +gf_worm_serialize_state (worm_reten_state_t *reten_state, char *val)  {          uint32_t state     =       0; @@ -237,7 +225,8 @@ out:  /*This function deserializes the data stored in the xattr of the file and loads   * the value to the reten_state structure.*/ -void deserialize_state (char *val, worm_reten_state_t *reten_state) +void +gf_worm_deserialize_state (char *val, worm_reten_state_t *reten_state)  {          char *token     =       NULL;          uint32_t state  =       0; @@ -264,8 +253,8 @@ out:  /*Function to set the xattr for a file.   * If the xattr is already present then it will replace that.*/  int32_t -set_xattr (xlator_t *this, worm_reten_state_t *reten_state, -           gf_boolean_t fop_with_fd, void *file_ptr) +gf_worm_set_xattr (xlator_t *this, worm_reten_state_t *reten_state, +                   gf_boolean_t fop_with_fd, void *file_ptr)  {          char val[100]   =        "";          int ret         =        -1; @@ -275,7 +264,7 @@ set_xattr (xlator_t *this, worm_reten_state_t *reten_state,          GF_VALIDATE_OR_GOTO (this->name, reten_state, out);          GF_VALIDATE_OR_GOTO (this->name, file_ptr, out); -        serialize_state (reten_state, val); +        gf_worm_serialize_state (reten_state, val);          dict = dict_new ();          if (!dict) {                  gf_log (this->name, GF_LOG_ERROR, "Error creating the dict"); @@ -309,11 +298,11 @@ out:   * 1: If the FOP sholud block i.e., if the file is in WORM-Retained/WORM state.   * 2: Blocks the FOP if any operation fails while doing the state transition or   *    fails to get the state of the file.*/ -int32_t -state_transition (xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr, -                  glusterfs_fop_t op, int *ret_val) +int +gf_worm_state_transition (xlator_t *this, gf_boolean_t fop_with_fd, +                          void *file_ptr, glusterfs_fop_t op)  { -        int label                         =       -1; +        int op_errno                      =       EROFS;          int ret                           =       -1;          uint64_t com_period               =       0;          uint64_t ret_period               =       0; @@ -333,70 +322,74 @@ state_transition (xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr,                  ret = syncop_getxattr (this, (loc_t *)file_ptr, &dict,                                         "trusted.start_time", NULL, NULL);          if (ret < 0 || !dict) { -                ret = -2; -                label = 2; +                op_errno = ret; +                gf_msg (this->name, GF_LOG_ERROR, -ret, 0, +                        "Error getting xattr");                  goto out;          }          ret = dict_get_uint64 (dict, "trusted.start_time", &start_time);          if (ret) { -                label = 2; +                op_errno = ret; +                gf_msg (this->name, GF_LOG_ERROR, -ret, 0, +                        "Error getting start time"); +                goto out; +        } + +        com_period = priv->com_period; +        if (fop_with_fd) +                ret = syncop_fstat (this, (fd_t *)file_ptr, &stbuf, NULL, NULL); +        else +                ret = syncop_stat (this, (loc_t *)file_ptr, &stbuf, NULL, NULL); +        if (ret) { +                op_errno = ret; +                gf_msg (this->name, GF_LOG_ERROR, -ret, 0, +                        "Error getting file stat");                  goto out;          }          ret = worm_get_state (this, fop_with_fd, file_ptr, &reten_state);          if (ret == -2) { -                ret = -1; -                label = 2; +                op_errno = ret; +                gf_msg (this->name, GF_LOG_ERROR, -ret, 0, +                        "Error getting worm/retention state");                  goto out;          } -        com_period = priv->com_period; +          if (ret == -1 && (time (NULL) - start_time) >= com_period) { -                if (fop_with_fd) -                        ret = syncop_fstat (this, (fd_t *)file_ptr, &stbuf, -                                            NULL, NULL); -                else -                        ret = syncop_stat (this, (loc_t *)file_ptr, &stbuf, -                                           NULL, NULL); -                if (ret) { -                        label = 2; -                        goto out; -                }                  ret_period = priv->reten_period;                  if ((time (NULL) - stbuf.ia_mtime) >= ret_period) {                          ret = worm_set_state(this, fop_with_fd, file_ptr,                                               &reten_state, &stbuf);                          if (ret) { -                                label = 2; +                                op_errno = ret; +                                gf_msg (this->name, GF_LOG_ERROR, -ret, 0, +                                        "Error setting worm/retention state");                                  goto out;                          } -                        label = 1;                          goto out;                  } else { -                        label = 0; +                        op_errno = 0;                          goto out;                  }          } else if (ret == -1 && (time (NULL) - start_time)                     < com_period) { -                label = 0; +                op_errno = 0;                  goto out;          } else if (reten_state.retain && -                   (time (NULL) - start_time) >= -                    reten_state.auto_commit_period) { -                state_lookup (this, fop_with_fd, file_ptr, &reten_state); +                   ((time (NULL) >= stbuf.ia_atime))) { +                gf_worm_state_lookup (this, fop_with_fd, file_ptr, +                                      &reten_state, &stbuf); +        } +        if (reten_state.worm && !reten_state.retain && +                 op == GF_FOP_UNLINK) { +                op_errno = 0; +                goto out;          } -        if (reten_state.retain) -                label = 1; -        else if (reten_state.worm && !reten_state.retain && -                 op == GF_FOP_UNLINK) -                label = 0; -        else -                label = 1;  out:          if (dict)                  dict_unref (dict); -        *ret_val = ret; -        return label; +        return op_errno;  } diff --git a/xlators/features/read-only/src/worm-helper.h b/xlators/features/read-only/src/worm-helper.h index a06a1d38063..745df8294c3 100644 --- a/xlators/features/read-only/src/worm-helper.h +++ b/xlators/features/read-only/src/worm-helper.h @@ -8,7 +8,7 @@     cases as published by the Free Software Foundation.  */ -gf_boolean_t is_write_disabled (struct iatt *stbuf); +gf_boolean_t gf_worm_write_disabled (struct iatt *stbuf);  int32_t worm_init_state (xlator_t *this, gf_boolean_t fop_with_fd,                           void *file_ptr); @@ -20,17 +20,18 @@ int32_t worm_set_state (xlator_t *this, gf_boolean_t fop_with_fd,  int32_t worm_get_state (xlator_t *this, gf_boolean_t fop_with_fd,                          void *file_ptr, worm_reten_state_t *reten_state); -void state_lookup (xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr, -                   worm_reten_state_t *reten_state); +void gf_worm_state_lookup (xlator_t *this, gf_boolean_t fop_with_fd, +                           void *file_ptr, worm_reten_state_t *reten_state, +                           struct iatt *stbuf); -void serialize_state (worm_reten_state_t *reten_state, char *val); +void gf_worm_serialize_state (worm_reten_state_t *reten_state, char *val); -void deserialize_state (char *val, worm_reten_state_t *reten_state); +void gf_worm_deserialize_state (char *val, worm_reten_state_t *reten_state); -int32_t set_xattr (xlator_t *this, worm_reten_state_t *reten_state, -                   gf_boolean_t fop_with_fd, void *file_ptr); +int32_t gf_worm_set_xattr (xlator_t *this, worm_reten_state_t *reten_state, +                           gf_boolean_t fop_with_fd, void *file_ptr); -int32_t state_transition (xlator_t *this, gf_boolean_t fop_with_fd, -                          void *file_ptr, glusterfs_fop_t op, int *ret_val); +int gf_worm_state_transition (xlator_t *this, gf_boolean_t fop_with_fd, +                              void *file_ptr, glusterfs_fop_t op);  int32_t is_wormfile (xlator_t *this, gf_boolean_t fop_with_fd, void *file_ptr); diff --git a/xlators/features/read-only/src/worm.c b/xlators/features/read-only/src/worm.c index 8297e8d3b7a..ad06f46a4e4 100644 --- a/xlators/features/read-only/src/worm.c +++ b/xlators/features/read-only/src/worm.c @@ -30,7 +30,7 @@ mem_acct_init (xlator_t *this)  } -int32_t +static int32_t  worm_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,             fd_t *fd, dict_t *xdata)  { @@ -46,185 +46,150 @@ worm_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,  } -int32_t +static int32_t  worm_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,             dict_t *xdata)  { -        int ret                     =       -1; -        int label                   =       -1; +        int op_errno                =       EROFS;          read_only_priv_t *priv      =       NULL;          priv = this->private;          GF_ASSERT (priv);          if (is_readonly_or_worm_enabled (this)) -                goto unwind; -        if (!priv->worm_file) -                goto wind; +                goto out; +        if (!priv->worm_file) { +                op_errno = 0; +                goto out; +        }          gf_uuid_copy (oldloc->gfid, oldloc->inode->gfid); -        if (is_wormfile (this, _gf_false, oldloc)) -                goto wind; -        label = state_transition (this, _gf_false, oldloc, GF_FOP_LINK, &ret); -        if (label == 0) -                goto wind; -        if (label == 1) -                goto unwind; -        if (label == 2) +        if (is_wormfile (this, _gf_false, oldloc)) { +                op_errno = 0;                  goto out; +        } +        op_errno = gf_worm_state_transition (this, _gf_false, oldloc, +                                             GF_FOP_LINK); -unwind: -        STACK_UNWIND_STRICT (link, frame, -1, EROFS, NULL, NULL, NULL, NULL, -                             NULL); -        ret = 0; -        goto out; -wind: -        STACK_WIND_TAIL (frame, FIRST_CHILD(this), -                         FIRST_CHILD(this)->fops->link, -                         oldloc, newloc, xdata); -        ret = 0;  out: -        if (label == 2) -                STACK_UNWIND_STRICT (link, frame, -1, ret, NULL, NULL, +        if (op_errno) +                STACK_UNWIND_STRICT (link, frame, -1, op_errno, NULL, NULL,                                       NULL, NULL, NULL); -        return ret; +        else +                STACK_WIND_TAIL (frame, FIRST_CHILD(this), +                                 FIRST_CHILD(this)->fops->link, +                                 oldloc, newloc, xdata); +        return 0;  } -int32_t +static int32_t  worm_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,               dict_t *xdata)  { -        int ret                     =       -1; -        int label                   =       -1; +        int op_errno                =       EROFS;          read_only_priv_t *priv      =       NULL;          priv = this->private;          GF_ASSERT (priv); -        if (is_readonly_or_worm_enabled (this)) -                goto unwind; -        if (!priv->worm_file) -                goto wind; +        if (is_readonly_or_worm_enabled (this)) { +                goto out; +        } +        if (!priv->worm_file) { +                op_errno = 0; +                goto out; +        }          gf_uuid_copy (loc->gfid, loc->inode->gfid); -        if (is_wormfile (this, _gf_false, loc)) -                goto wind; -        label = state_transition (this, _gf_false, loc, GF_FOP_UNLINK, &ret); -        if (label == 0) -                goto wind; -        if (label == 1) -                goto unwind; -        if (label == 2) +        if (is_wormfile (this, _gf_false, loc)) { +                op_errno = 0;                  goto out; - -unwind: -        STACK_UNWIND_STRICT (unlink, frame, -1, EROFS, NULL, NULL, NULL); -        ret = 0; -        goto out; -wind: -        STACK_WIND_TAIL (frame, FIRST_CHILD(this), -                         FIRST_CHILD(this)->fops->unlink, -                         loc, flags, xdata); -        ret = 0; +        } +        op_errno = gf_worm_state_transition (this, _gf_false, loc, +                                             GF_FOP_UNLINK);  out: -        if (label == 2) -                STACK_UNWIND_STRICT (unlink, frame, -1, ret, -                                     NULL, NULL, NULL); -        return ret; +        if (op_errno) +                STACK_UNWIND_STRICT (unlink, frame, -1, op_errno, NULL, NULL, +                                     NULL); +        else +                STACK_WIND_TAIL (frame, FIRST_CHILD(this), +                                 FIRST_CHILD(this)->fops->unlink, +                                 loc, flags, xdata); +        return 0;  } -int32_t +static int32_t  worm_rename (call_frame_t *frame, xlator_t *this,               loc_t *oldloc, loc_t *newloc, dict_t *xdata)  { -        int ret                     =       -1; -        int label                   =       -1; +        int op_errno                =       EROFS;          read_only_priv_t *priv      =       NULL;          priv = this->private;          GF_ASSERT (priv);          if (is_readonly_or_worm_enabled (this)) -                goto unwind; -        if (!priv->worm_file) -                goto wind; +                goto out; +        if (!priv->worm_file) { +                op_errno = 0; +                goto out; +        }          gf_uuid_copy (oldloc->gfid, oldloc->inode->gfid); -        if (is_wormfile (this, _gf_false, oldloc)) -                goto wind; -        label = state_transition (this, _gf_false, oldloc, GF_FOP_RENAME, -                                  &ret); -        if (label == 0) -                goto wind; -        if (label == 1) -                goto unwind; -        if (label == 2) +        if (is_wormfile (this, _gf_false, oldloc)) { +                op_errno = 0;                  goto out; +        } +        op_errno = gf_worm_state_transition (this, _gf_false, oldloc, +                                           GF_FOP_RENAME); -unwind: -        STACK_UNWIND_STRICT (rename, frame, -1, EROFS, NULL, -                             NULL, NULL, NULL, NULL, NULL); -        ret = 0; -        goto out; -wind: -        STACK_WIND_TAIL (frame, FIRST_CHILD (this), -                         FIRST_CHILD (this)->fops->rename, -                         oldloc, newloc, xdata); -        ret = 0;  out: -        if (label == 2) -                STACK_UNWIND_STRICT (rename, frame, -1, ret, NULL, +        if (op_errno) +                STACK_UNWIND_STRICT (rename, frame, -1, op_errno, NULL,                                       NULL, NULL, NULL, NULL, NULL); -        return ret; +        else +                STACK_WIND_TAIL (frame, FIRST_CHILD (this), +                                 FIRST_CHILD (this)->fops->rename, +                                 oldloc, newloc, xdata); +        return 0;  } -int32_t +static int32_t  worm_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,                 dict_t *xdata)  { -        int ret                     =       -1; -        int label                   =       -1; +        int op_errno                =       EROFS;          read_only_priv_t *priv      =       NULL;          priv = this->private;          GF_ASSERT (priv);          if (is_readonly_or_worm_enabled (this)) -                goto unwind; -        if (!priv->worm_file) -                goto wind; - -        if (is_wormfile (this, _gf_false, loc)) -                goto wind; -        label = state_transition (this, _gf_false, loc, GF_FOP_TRUNCATE, -                                  &ret); -        if (label == 0) -                goto wind; -        if (label == 1) -                goto unwind; -        if (label == 2)                  goto out; +        if (!priv->worm_file) { +                op_errno = 0; +                goto out; +        } -unwind: -        STACK_UNWIND_STRICT (truncate, frame, -1, EROFS, -                                     NULL, NULL, NULL); -        ret = 0; -        goto out; +        if (is_wormfile (this, _gf_false, loc)) { +                op_errno = 0; +                goto out; +        } +        op_errno = gf_worm_state_transition (this, _gf_false, loc, +                                           GF_FOP_TRUNCATE); -wind: -        STACK_WIND_TAIL (frame, -                         FIRST_CHILD (this), -                         FIRST_CHILD (this)->fops->truncate, -                         loc, offset, xdata); -        ret = 0;  out: -        if (label == 2) -                STACK_UNWIND_STRICT (truncate, frame, -1, ret, -                                     NULL, NULL, NULL); -        return ret; +        if (op_errno) +                STACK_UNWIND_STRICT (truncate, frame, -1, op_errno, NULL, NULL, +                                     NULL); +        else +                STACK_WIND_TAIL (frame, FIRST_CHILD (this), +                                 FIRST_CHILD (this)->fops->truncate, +                                 loc, offset, xdata); +        return 0;  } -int32_t +static int32_t  worm_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,                struct iatt *stbuf, int32_t valid, dict_t *xdata)  { @@ -232,22 +197,29 @@ worm_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,          worm_reten_state_t reten_state  =       {0,};          struct iatt stpre               =       {0,};          read_only_priv_t *priv          =       NULL; +        int op_errno                    =       EROFS;          int ret                         =       -1;          priv = this->private;          GF_ASSERT (priv); -        if (!priv->worm_file) -                goto wind; +        if (!priv->worm_file) { +                op_errno = 0; +                goto out; +        } -        if (is_wormfile (this, _gf_false, loc)) -                goto wind; +        if (is_wormfile (this, _gf_false, loc)) { +                op_errno = 0; +                goto out; +        }          if (valid & GF_SET_ATTR_MODE) { -                rd_only = is_write_disabled (stbuf); -                if (!rd_only) -                        goto wind; +                rd_only = gf_worm_write_disabled (stbuf); +                if (!rd_only) { +                        op_errno = 0; +                        goto out; +                }                  ret = worm_set_state (this, _gf_false, loc, -                                      &reten_state, stbuf); +                                           &reten_state, stbuf);                  if (ret) {                          gf_log (this->name, GF_LOG_ERROR,                                  "Error setting worm state"); @@ -255,8 +227,10 @@ worm_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,                  }          } else if (valid & GF_SET_ATTR_ATIME) {                  ret = worm_get_state (this, _gf_false, loc, &reten_state); -                if (ret) -                        goto wind; +                if (ret) { +                        op_errno = 0; +                        goto out; +                }                  if (reten_state.retain) {                          ret = syncop_stat (this, loc, &stpre, NULL, NULL);                          if (ret) @@ -267,7 +241,7 @@ worm_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,                                                  "Cannot set atime less than "                                                  "the mtime for a WORM-Retained "                                                  "file"); -                                        goto unwind; +                                        goto out;                                  }                          } else {                                  if (stbuf->ia_atime < stpre.ia_atime) { @@ -275,27 +249,27 @@ worm_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,                                                  "Cannot decrease the atime of a"                                                  " WORM-Retained file in "                                                  "Enterprise mode"); -                                        goto unwind; +                                        goto out;                                  }                          }                          stbuf->ia_mtime = stpre.ia_mtime;                  }          } +        op_errno = 0; -wind: -        STACK_WIND_TAIL (frame, FIRST_CHILD (this), -                    FIRST_CHILD (this)->fops->setattr, -                    loc, stbuf, valid, xdata); -        ret = 0; -        goto out; -unwind: -        STACK_UNWIND_STRICT (setattr, frame, -1, EROFS, NULL, NULL, NULL);  out: -        return ret; +        if (op_errno) +                STACK_UNWIND_STRICT (setattr, frame, -1, EROFS, NULL, NULL, +                                     NULL); +        else +                STACK_WIND_TAIL (frame, FIRST_CHILD (this), +                                 FIRST_CHILD (this)->fops->setattr, +                                 loc, stbuf, valid, xdata); +        return 0;  } -int32_t +static int32_t  worm_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,                 struct iatt *stbuf, int32_t valid, dict_t *xdata)  { @@ -303,19 +277,26 @@ worm_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,          worm_reten_state_t reten_state  =       {0,};          struct iatt stpre               =       {0,};          read_only_priv_t *priv          =       NULL; +        int op_errno                    =       EROFS;          int ret                         =       -1;          priv = this->private;          GF_ASSERT (priv); -        if (!priv->worm_file) -                goto wind; +        if (!priv->worm_file) { +                op_errno = 0; +                goto out; +        } -        if (is_wormfile (this, _gf_true, fd)) -                goto wind; +        if (is_wormfile (this, _gf_true, fd)) { +                op_errno = 0; +                goto out; +        }          if (valid & GF_SET_ATTR_MODE) { -                rd_only = is_write_disabled (stbuf); -                if (!rd_only) -                        goto wind; +                rd_only = gf_worm_write_disabled (stbuf); +                if (!rd_only) { +                        op_errno = 0; +                        goto out; +                }                  ret = worm_set_state (this, _gf_true, fd,                                        &reten_state, stbuf); @@ -326,8 +307,10 @@ worm_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,                  }          } else if (valid & GF_SET_ATTR_ATIME) {                  ret = worm_get_state (this, _gf_true, fd, &reten_state); -                if (ret) -                        goto wind; +                if (ret) { +                        op_errno = 0; +                        goto out; +                }                  if (reten_state.retain) {                          ret = syncop_fstat (this, fd, &stpre, NULL, NULL);                          if (ret) @@ -338,7 +321,7 @@ worm_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,                                                  "Cannot set atime less than "                                                  "the mtime for a WORM-Retained "                                                  "file"); -                                        goto unwind; +                                        goto out;                                  }                          } else {                                  if (stbuf->ia_atime < stpre.ia_atime) { @@ -346,76 +329,77 @@ worm_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,                                                  "Cannot decrease the atime of a"                                                  " WORM-Retained file in "                                                  "Enterprise mode"); -                                        goto unwind; +                                        goto out;                                  }                          }                          stbuf->ia_mtime = stpre.ia_mtime;                  }          } +        op_errno = 0; -wind: -        STACK_WIND_TAIL (frame, FIRST_CHILD (this), -                    FIRST_CHILD (this)->fops->fsetattr, -                    fd, stbuf, valid, xdata); -        ret = 0; -        goto out; -unwind: -        STACK_UNWIND_STRICT (fsetattr, frame, -1, EROFS, NULL, NULL, NULL);  out: -        return ret; +        if (op_errno) +                STACK_UNWIND_STRICT (fsetattr, frame, -1, op_errno, NULL, NULL, +                                     NULL); +        else +                STACK_WIND_TAIL (frame, FIRST_CHILD (this), +                                 FIRST_CHILD (this)->fops->fsetattr, +                                 fd, stbuf, valid, xdata); +        return 0;  } -int32_t +static int32_t  worm_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,               struct iovec *vector, int32_t count, off_t offset, uint32_t flags,               struct iobref *iobref, dict_t *xdata)  {          worm_reten_state_t reten_state    =       {0,};          read_only_priv_t *priv            =       NULL; +        int op_errno                      =       EROFS;          int ret                           =       -1;          priv = this->private;          GF_ASSERT (priv); -        if (!priv->worm_file) -                goto wind; - -        if (is_wormfile (this, _gf_true, fd)) -                goto wind; +        if (!priv->worm_file) { +                op_errno = 0; +                goto out; +        } +        if (is_wormfile (this, _gf_true, fd)) { +                op_errno = 0; +                goto out; +        }          ret = worm_get_state (this, _gf_true, fd, &reten_state); +        if (ret) +                goto out;          if (!reten_state.worm) -                goto wind; - -        STACK_UNWIND_STRICT (writev, frame, -1, EROFS, NULL, NULL, NULL); -        goto out; - -wind: -        STACK_WIND_TAIL (frame, -                         FIRST_CHILD (this), -                         FIRST_CHILD (this)->fops->writev, -                         fd, vector, count, offset, flags, -                         iobref, xdata); -        ret = 0; +                op_errno = 0;  out: -        return ret; +        if (op_errno) +                STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL, +                                     NULL); +        else +                STACK_WIND_TAIL (frame, FIRST_CHILD (this), +                                 FIRST_CHILD (this)->fops->writev, +                                 fd, vector, count, offset, flags, iobref, +                                 xdata); +        return 0;  } - -int32_t -worm_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, -             mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) +static int32_t +worm_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                 int32_t op_ret, int32_t op_errno, fd_t *fd, +                 inode_t *inode, struct iatt *buf, +                 struct iatt *preparent, struct iatt *postparent, +                 dict_t *xdata)  { -        int ret                   =       -1; +        int ret                   =       0;          read_only_priv_t *priv    =       NULL;          dict_t *dict              =       NULL; -        STACK_WIND_TAIL (frame, FIRST_CHILD (this), -                         FIRST_CHILD(this)->fops->create, loc, flags, -                         mode, umask, fd, xdata);          priv = this->private;          GF_ASSERT (priv); -          if (priv->worm_file) {                  dict = dict_new ();                  if (!dict) { @@ -423,7 +407,6 @@ worm_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,                                  "dict");                          goto out;                  } -                GF_VALIDATE_OR_GOTO (this->name, dict, out);                  ret = dict_set_int8 (dict, "trusted.worm_file", 1);                  if (ret) {                          gf_log (this->name, GF_LOG_ERROR, "Error in setting " @@ -444,12 +427,25 @@ worm_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,          }  out: +        STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf, +                             preparent, postparent, xdata);          if (dict)                  dict_destroy (dict);          return ret;  } +static int32_t +worm_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, +             mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) +{ +        STACK_WIND (frame, worm_create_cbk,  FIRST_CHILD (this), +                    FIRST_CHILD(this)->fops->create, loc, flags, +                    mode, umask, fd, xdata); +        return 0; +} + +  int32_t  init (xlator_t *this)  {  | 
