summaryrefslogtreecommitdiffstats
path: root/xlators/features/bit-rot/src/stub/bit-rot-stub.c
diff options
context:
space:
mode:
authorRaghavendra Bhat <raghavendra@redhat.com>2015-06-27 13:17:32 +0530
committerVenky Shankar <vshankar@redhat.com>2015-08-11 21:17:39 -0700
commit7b44b6c16fb538e5f15a255182de4dee781994a0 (patch)
tree19207dfd0469c37a43f1ac9e50d31febbcabcbe8 /xlators/features/bit-rot/src/stub/bit-rot-stub.c
parent8d7a4f6b0aa8e63e1a0802e22bcebe96e4e7490f (diff)
features/bit-rot-stub: fail the fop if inode context get fails
In stub, for fops like readv, writev etc, if the the object is bad, then the fop is denied. But for checking if the object is bad inode context should be checked. Now, if the inode context is not there, then the fop is allowed to continue. This patch fixes it and the fop is unwound with an error, if the inode context is not found. Change-Id: I5ea4d4fc1a91387f7f9d13ca8cb43c88429f02b0 BUG: 1243391 Signed-off-by: Raghavendra Bhat <raghavendra@redhat.com> Reviewed-on: http://review.gluster.org/11449 Tested-by: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Venky Shankar <vshankar@redhat.com>
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.c77
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 f30b5a7..9439f0c 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);
}