summaryrefslogtreecommitdiffstats
path: root/xlators/features/bit-rot/src/stub
diff options
context:
space:
mode:
authorVenky Shankar <vshankar@redhat.com>2015-03-31 15:48:18 +0530
committerVijay Bellur <vbellur@redhat.com>2015-04-08 07:01:32 +0000
commitf0cd1d73c63001740cd7691a77df7631c9b8e8dc (patch)
tree336a8ee694dc71a2fde6927d8a40682bef6368ef /xlators/features/bit-rot/src/stub
parent7fb55dbdabf73f9169b0f3021a42fa120d64b373 (diff)
bitrot/scrub: Scrubber fixes
This patch fixes a handful of problem with scrubber which are detailed below. Scrubber used to skip objects for verification due to missing fd iterface to fetch versioning extended attributes. Similar to the inode interface, an fd based interface in POSIX is now introduced. Moreover, this patch also fixes potential false reporting by scrubber due to: An object gets dirtied and signed when scrubber is busy calculatingobject checksum. This is fixed by caching the signed version when an object is first inspected for stalenes, i.e., during pre-compute stage. This version is used to verify checksum in the post-compute stage when the signatures are compared for possible corruption. Side effect of _not_ sending signature length during signing resulted in "truncated" signature to be set for an object. Now, at the time of signing, the signature length is sent and is used in place of invoking strlen() to get signature length (which could have possible 00s). The signature length itself is not persisted in the signature xattr, but is calculated on-the-fly by substracting the xattr length by the "structure" header size. Some of the log entries are made more meaningful (as and aid for debugging). Change-Id: I938bee5aea6688d5d99eb2640053613af86d6269 BUG: 1207624 Signed-off-by: Venky Shankar <vshankar@redhat.com> Reviewed-on: http://review.gluster.org/10118 Reviewed-by: Raghavendra Bhat <raghavendra@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'xlators/features/bit-rot/src/stub')
-rw-r--r--xlators/features/bit-rot/src/stub/bit-rot-common.h6
-rw-r--r--xlators/features/bit-rot/src/stub/bit-rot-stub.c27
-rw-r--r--xlators/features/bit-rot/src/stub/bit-rot-stub.h1
3 files changed, 27 insertions, 7 deletions
diff --git a/xlators/features/bit-rot/src/stub/bit-rot-common.h b/xlators/features/bit-rot/src/stub/bit-rot-common.h
index fdf23142768..699323170d3 100644
--- a/xlators/features/bit-rot/src/stub/bit-rot-common.h
+++ b/xlators/features/bit-rot/src/stub/bit-rot-common.h
@@ -76,6 +76,7 @@ typedef struct br_isignature_in {
unsigned long signedversion; /* version against which the
object was signed */
+ size_t signaturelen; /* signature length */
char signature[0]; /* object signature */
} br_isignature_t;
@@ -86,11 +87,14 @@ typedef struct br_isignature_in {
typedef struct br_isignature_out {
char stale; /* stale signature? */
+ unsigned long version; /* current signed version */
+
uint32_t time[2]; /* time when the object
got dirtied */
int8_t signaturetype; /* hash type */
- char signature[0]; /* signature (hash) */
+ size_t signaturelen; /* signature length */
+ char signature[0]; /* signature (hash) */
} br_isignature_out_t;
typedef struct br_stub_init {
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 f8c8f59c1f8..0db500659b5 100644
--- a/xlators/features/bit-rot/src/stub/bit-rot-stub.c
+++ b/xlators/features/bit-rot/src/stub/bit-rot-stub.c
@@ -566,7 +566,7 @@ br_stub_prepare_signature (xlator_t *this, dict_t *dict,
if (!br_is_signature_type_valid (sign->signaturetype))
goto error_return;
- signaturelen = strlen (sign->signature);
+ signaturelen = sign->signaturelen;
ret = br_stub_alloc_versions (NULL, &sbuf, signaturelen);
if (ret)
goto error_return;
@@ -657,8 +657,8 @@ br_stub_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, dict_t *xattr, dict_t *xdata)
{
int32_t ret = 0;
- ssize_t totallen = 0;
- ssize_t signaturelen = 0;
+ size_t totallen = 0;
+ size_t signaturelen = 0;
br_version_t *obuf = NULL;
br_signature_t *sbuf = NULL;
br_isignature_out_t *sign = NULL;
@@ -681,8 +681,21 @@ br_stub_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|| (status == BR_VXATTR_STATUS_UNSIGNED))
goto delkeys;
- signaturelen = strlen (sbuf->signature);
- totallen = signaturelen + sizeof (br_isignature_out_t);
+ /**
+ * okay.. we have enough information to satisfy the request,
+ * namely: version and signing extended attribute. what's
+ * pending is the signature length -- that's figured out
+ * indirectly via the size of the _whole_ xattr and the
+ * on-disk signing xattr header size.
+ */
+ op_errno = EINVAL;
+ ret = dict_get_uint32 (xattr, BITROT_SIGNING_XATTR_SIZE_KEY,
+ (uint32_t *)&signaturelen);
+ if (ret)
+ goto delkeys;
+
+ signaturelen -= sizeof (br_signature_t);
+ totallen = sizeof (br_isignature_out_t) + signaturelen;
op_errno = ENOMEM;
sign = GF_CALLOC (1, totallen, gf_br_stub_mt_signature_t);
@@ -692,10 +705,12 @@ br_stub_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
sign->time[0] = obuf->timebuf[0];
sign->time[1] = obuf->timebuf[1];
- /* Object's dirty state */
+ /* Object's dirty state & current signed version */
+ sign->version = sbuf->signedversion;
sign->stale = (obuf->ongoingversion != sbuf->signedversion) ? 1 : 0;
/* Object's signature */
+ sign->signaturelen = signaturelen;
sign->signaturetype = sbuf->signaturetype;
(void) memcpy (sign->signature, sbuf->signature, signaturelen);
diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub.h b/xlators/features/bit-rot/src/stub/bit-rot-stub.h
index d565112b1ad..5db0e321c20 100644
--- a/xlators/features/bit-rot/src/stub/bit-rot-stub.h
+++ b/xlators/features/bit-rot/src/stub/bit-rot-stub.h
@@ -263,6 +263,7 @@ br_stub_remove_vxattrs (dict_t *xattr)
if (xattr) {
dict_del (xattr, BITROT_CURRENT_VERSION_KEY);
dict_del (xattr, BITROT_SIGNING_VERSION_KEY);
+ dict_del (xattr, BITROT_SIGNING_XATTR_SIZE_KEY);
}
}