diff options
Diffstat (limited to 'xlators/features/bit-rot/src/stub/bit-rot-stub.c')
| -rw-r--r-- | xlators/features/bit-rot/src/stub/bit-rot-stub.c | 77 | 
1 files changed, 72 insertions, 5 deletions
diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub.c b/xlators/features/bit-rot/src/stub/bit-rot-stub.c index f30b5a74307..9439f0cdfe7 100644 --- a/xlators/features/bit-rot/src/stub/bit-rot-stub.c +++ b/xlators/features/bit-rot/src/stub/bit-rot-stub.c @@ -452,6 +452,40 @@ br_stub_mark_inode_modified (xlator_t *this, br_stub_local_t *local)  }  /** + * The possible return values from br_stub_is_bad_object () are: + * 1) 0  => as per the inode context object is not bad + * 2) -1 => Failed to get the inode context itself + * 3) -2 => As per the inode context object is bad + * Both -ve values means the fop which called this function is failed + * and error is returned upwards. + */ +static int +br_stub_check_bad_object (xlator_t *this, inode_t *inode, int32_t *op_ret, +                           int32_t *op_errno) +{ +        int ret = -1; + +        ret = br_stub_is_bad_object (this, inode); +        if (ret == -2) { +                gf_msg (this->name, GF_LOG_ERROR, 0, BRS_MSG_BAD_OBJECT_ACCESS, +                        "%s is a bad object. Returning", +                        uuid_utoa (inode->gfid)); +                *op_ret = -1; +                *op_errno = EIO; +        } + +        if (ret == -1) { +                gf_msg (this->name, GF_LOG_ERROR, 0, +                        BRS_MSG_GET_INODE_CONTEXT_FAILED, "could not get inode" +                        " context for %s", uuid_utoa (inode->gfid)); +                *op_ret = -1; +                *op_errno = EINVAL; +        } + +        return ret; +} + +/**   * callback for inode/fd versioning   */  int @@ -1095,6 +1129,12 @@ br_stub_fsetxattr (call_frame_t *frame, xlator_t *this,                  goto done;          } +        if (dict_get (dict, GLUSTERFS_GET_OBJECT_SIGNATURE)) { +                br_stub_handle_internal_xattr (frame, this, fd, +                                               GLUSTERFS_GET_OBJECT_SIGNATURE); +                goto done; +        } +          /* object reopen request */          ret = dict_get_uint32 (dict, BR_REOPEN_SIGN_HINT_KEY, &val);          if (!ret) { @@ -1135,6 +1175,7 @@ br_stub_setxattr (call_frame_t *frame, xlator_t *this,          char    *format                    = "(%s:%s)";          if (dict_get (dict, GLUSTERFS_SET_OBJECT_SIGNATURE) || +            dict_get (dict, GLUSTERFS_GET_OBJECT_SIGNATURE) ||              dict_get (dict, BR_REOPEN_SIGN_HINT_KEY) ||              dict_get (dict, BITROT_OBJECT_BAD_KEY) ||              dict_get (dict, BITROT_SIGNING_VERSION_KEY) || @@ -1579,13 +1620,16 @@ br_stub_readv (call_frame_t *frame, xlator_t *this,  {          int32_t              op_ret   = -1;          int32_t              op_errno = EINVAL; +        int32_t              ret      = -1;          GF_VALIDATE_OR_GOTO ("bit-rot-stub", this, unwind);          GF_VALIDATE_OR_GOTO (this->name, frame, unwind);          GF_VALIDATE_OR_GOTO (this->name, fd, unwind);          GF_VALIDATE_OR_GOTO (this->name, fd->inode, unwind); -        BR_STUB_HANDLE_BAD_OBJECT (this, fd->inode, op_ret, op_errno, unwind); +        ret = br_stub_check_bad_object (this, fd->inode, &op_ret, &op_errno); +        if (ret) +                goto unwind;          STACK_WIND_TAIL (frame, FIRST_CHILD(this),                           FIRST_CHILD(this)->fops->readv, fd, size, offset, @@ -1679,7 +1723,9 @@ br_stub_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,          if (ret)                  goto unwind; -        BR_STUB_HANDLE_BAD_OBJECT (this, fd->inode, op_ret, op_errno, unwind); +        ret = br_stub_check_bad_object (this, fd->inode, &op_ret, &op_errno); +        if (ret) +                goto unwind;          /**           * The inode is not dirty and also witnessed atleast one successful @@ -1800,7 +1846,9 @@ br_stub_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd,          if (ret)                  goto unwind; -        BR_STUB_HANDLE_BAD_OBJECT (this, fd->inode, op_ret, op_errno, unwind); +        ret = br_stub_check_bad_object (this, fd->inode, &op_ret, &op_errno); +        if (ret) +                goto unwind;          if (!inc_version && modified)                  goto wind; @@ -1932,7 +1980,9 @@ br_stub_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,          if (ret)                  goto cleanup_fd; -        BR_STUB_HANDLE_BAD_OBJECT (this, fd->inode, op_ret, op_errno, unwind); +        ret = br_stub_check_bad_object (this, fd->inode, &op_ret, &op_errno); +        if (ret) +                goto unwind;          if (!inc_version && modified)                  goto wind; @@ -2026,7 +2076,9 @@ br_stub_open (call_frame_t *frame, xlator_t *this,          ctx = (br_stub_inode_ctx_t *)(long)ctx_addr; -        BR_STUB_HANDLE_BAD_OBJECT (this, loc->inode, op_ret, op_errno, unwind); +        ret = br_stub_check_bad_object (this, fd->inode, &op_ret, &op_errno); +        if (ret) +                goto unwind;          if (frame->root->pid == GF_CLIENT_PID_SCRUB)                  goto wind; @@ -2208,6 +2260,13 @@ unwind:   * calls can be avoided and bad objects can be caught instantly. Fetching the   * xattr is needed only in lookups when there is a brick restart or inode   * forget. + * + * If the dict (@xattr) is NULL, then how should that be handled? Fail the + * lookup operation? Or let it continue with version being initialized to + * BITROT_DEFAULT_CURRENT_VERSION. But what if the version was different + * on disk (and also a right signature was there), but posix failed to + * successfully allocate the dict? Posix does not treat call back xdata + * creattion failure as the lookup failure.   */  static inline int32_t  br_stub_lookup_version (xlator_t *this, @@ -2232,6 +2291,14 @@ br_stub_lookup_version (xlator_t *this,                     || (status == BR_VXATTR_STATUS_UNSIGNED))                          ? obuf->ongoingversion : BITROT_DEFAULT_CURRENT_VERSION; +        /** +         * If signature is there, but version is not therem then that status is +         * is treated as INVALID. So in that case, we should not initialize the +         * inode context with wrong version names etc. +         */ +        if (status == BR_VXATTR_STATUS_INVALID) +                return -1; +          return br_stub_init_inode_versions (this, NULL, inode, version,                                              _gf_true, bad_object);  }  | 
