diff options
author | Venky Shankar <vshankar@redhat.com> | 2015-03-31 15:48:18 +0530 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2015-04-08 07:01:32 +0000 |
commit | f0cd1d73c63001740cd7691a77df7631c9b8e8dc (patch) | |
tree | 336a8ee694dc71a2fde6927d8a40682bef6368ef /xlators/storage/posix/src | |
parent | 7fb55dbdabf73f9169b0f3021a42fa120d64b373 (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/storage/posix/src')
-rw-r--r-- | xlators/storage/posix/src/posix-helpers.c | 94 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.c | 11 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.h | 3 |
3 files changed, 102 insertions, 6 deletions
diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index 5b7236b193f..1b7d9118072 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -1856,8 +1856,12 @@ posix_fsyncer (void *d) } } +/** + * TODO: move fd/inode interfaces into a single routine.. + */ static int32_t -posix_fetch_signature_xattr (char *real_path, const char *key, dict_t *xattr) +posix_fetch_signature_xattr (char *real_path, + const char *key, dict_t *xattr, size_t *xsize) { int32_t ret = 0; char *memptr = NULL; @@ -1880,6 +1884,45 @@ posix_fetch_signature_xattr (char *real_path, const char *key, dict_t *xattr) if (ret) goto freemem; + if (xsize) + *xsize = xattrsize; + + return 0; + + freemem: + GF_FREE (memptr); + error_return: + return -1; +} + +static int32_t +posix_fd_fetch_signature_xattr (int fd, + const char *key, dict_t *xattr, size_t *xsize) +{ + int32_t ret = 0; + char *memptr = NULL; + ssize_t xattrsize = 0; + + xattrsize = sys_fgetxattr (fd, key, NULL, 0); + if ((xattrsize == -1) && ((errno == ENOATTR) || (errno == ENODATA))) + return 0; + if (xattrsize == -1) + goto error_return; + + memptr = GF_CALLOC (xattrsize + 1, sizeof (char), gf_posix_mt_char); + if (!memptr) + goto error_return; + ret = sys_fgetxattr (fd, key, memptr, xattrsize); + if (ret == -1) + goto freemem; + + ret = dict_set_dynptr (xattr, (char *)key, memptr, xattrsize); + if (ret) + goto freemem; + + if (xsize) + *xsize = xattrsize; + return 0; freemem: @@ -1898,21 +1941,60 @@ int32_t posix_get_objectsignature (char *real_path, dict_t *xattr) { int32_t ret = 0; + size_t signsize = 0; ret = posix_fetch_signature_xattr - (real_path, BITROT_CURRENT_VERSION_KEY, xattr); + (real_path, BITROT_CURRENT_VERSION_KEY, xattr, NULL); if (ret) goto error_return; ret = posix_fetch_signature_xattr - (real_path, BITROT_SIGNING_VERSION_KEY, xattr); + (real_path, BITROT_SIGNING_VERSION_KEY, xattr, &signsize); if (ret) - goto delkey; + goto delkey1; + + ret = dict_set_uint32 + (xattr, BITROT_SIGNING_XATTR_SIZE_KEY, (uint32_t) signsize); + if (ret) + goto delkey2; return 0; - delkey: + delkey2: + dict_del (xattr, BITROT_SIGNING_VERSION_KEY); + delkey1: dict_del (xattr, BITROT_CURRENT_VERSION_KEY); error_return: - return -1; + return -EINVAL; +} + +int32_t +posix_fdget_objectsignature (int fd, dict_t *xattr) +{ + int32_t ret = 0; + size_t signsize = 0; + + ret = posix_fd_fetch_signature_xattr + (fd, BITROT_CURRENT_VERSION_KEY, xattr, NULL); + if (ret) + goto error_return; + + ret = posix_fd_fetch_signature_xattr + (fd, BITROT_SIGNING_VERSION_KEY, xattr, &signsize); + if (ret) + goto delkey1; + + ret = dict_set_uint32 + (xattr, BITROT_SIGNING_XATTR_SIZE_KEY, (uint32_t) signsize); + if (ret) + goto delkey2; + + return 0; + + delkey2: + dict_del (xattr, BITROT_SIGNING_VERSION_KEY); + delkey1: + dict_del (xattr, BITROT_CURRENT_VERSION_KEY); + error_return: + return -EINVAL; } diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index cd93760faa4..da8e58efd8c 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -4134,6 +4134,17 @@ posix_fgetxattr (call_frame_t *frame, xlator_t *this, goto done; } + if (strncmp (name, GLUSTERFS_GET_OBJECT_SIGNATURE, + strlen (GLUSTERFS_GET_OBJECT_SIGNATURE)) == 0) { + op_ret = posix_fdget_objectsignature (_fd, dict); + if (op_ret < 0) { + op_errno = -op_ret; + op_ret = -1; + } + + goto done; + } + if (name) { strcpy (key, name); #ifdef GF_DARWIN_HOST_OS diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index 452248dd794..9fdc6ee44db 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -245,4 +245,7 @@ posix_pacl_get (const char *path, const char *key, char **acl_s); int32_t posix_get_objectsignature (char *, dict_t *); +int32_t +posix_fdget_objectsignature (int, dict_t *); + #endif /* _POSIX_H */ |