diff options
Diffstat (limited to 'xlators/features')
-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) { |