summaryrefslogtreecommitdiffstats
path: root/xlators/storage/posix
diff options
context:
space:
mode:
authorVenky Shankar <vshankar@redhat.com>2015-03-30 21:46:25 +0530
committerVijay Bellur <vbellur@redhat.com>2015-04-08 06:43:09 +0000
commit2dfc36811337666c26e42c13f19eb59a7cef674f (patch)
treeb288162775cec05b3c4711ed10d0fd6b1f88cb6c /xlators/storage/posix
parent6a465e6e7e46940e00a387089cc995464975b53d (diff)
features/bitrot-stub: Enhancement to versioning protocol
.. and potential bug fixes / memleak. While assigning initial version to an object, both extended attributes (namely, ongoing version and the default signing version) were persisted. This is optimized to just persist the ongoing version along with safe handling of xattr request(s) in it's absence. This is better than the earlier approach as the two xattr sets were not atomic anyway (allowing a request to sneak in between between two set operations). This also allows to perform sanity checks on objects during lookup()/getxattr(): objects with missing ongoing version but presence of signature are possible candidates of tampering (and catching implementation bugs). There were couple of instances in the code where versioning xattrs were incorrectly removed before in-memory versions were initialized, which have been fixed with this patch. A memory leak in the IPC code path is also fixed. Change-Id: I01c690ccfe7156a883582275f40f79a7c10c0900 BUG: 1207054 Signed-off-by: Venky Shankar <vshankar@redhat.com> Reviewed-on: http://review.gluster.org/10117 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')
-rw-r--r--xlators/storage/posix/src/posix-helpers.c87
1 files changed, 39 insertions, 48 deletions
diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c
index 0638f845e9d..5b7236b193f 100644
--- a/xlators/storage/posix/src/posix-helpers.c
+++ b/xlators/storage/posix/src/posix-helpers.c
@@ -1856,72 +1856,63 @@ posix_fsyncer (void *d)
}
}
-/**
- * fetch on-disk ongoing version and object signature extended
- * attribute.
- */
-int32_t
-posix_get_objectsignature (char *real_path, dict_t *xattr)
+static int32_t
+posix_fetch_signature_xattr (char *real_path, const char *key, dict_t *xattr)
{
- int32_t op_ret = 0;
+ int32_t ret = 0;
char *memptr = NULL;
ssize_t xattrsize = 0;
- ssize_t allocsize = 0;
- op_ret = -EINVAL;
- xattrsize = sys_lgetxattr (real_path,
- BITROT_CURRENT_VERSION_KEY, NULL, 0);
- if (xattrsize == -1)
- goto error_return;
- allocsize += xattrsize;
-
- xattrsize = sys_lgetxattr (real_path,
- BITROT_SIGNING_VERSION_KEY, NULL, 0);
+ xattrsize = sys_lgetxattr (real_path, key, NULL, 0);
+ if ((xattrsize == -1) && ((errno == ENOATTR) || (errno == ENODATA)))
+ return 0;
if (xattrsize == -1)
goto error_return;
- allocsize += xattrsize;
- op_ret = -ENOMEM;
- /* bulk alloc */
- memptr = GF_CALLOC (allocsize + 2, sizeof (char), gf_posix_mt_char);
+ memptr = GF_CALLOC (xattrsize + 1, sizeof (char), gf_posix_mt_char);
if (!memptr)
goto error_return;
+ ret = sys_lgetxattr (real_path, key, memptr, xattrsize);
+ if (ret == -1)
+ goto freemem;
- op_ret = sys_lgetxattr (real_path, BITROT_CURRENT_VERSION_KEY,
- memptr, allocsize - xattrsize);
- if (op_ret == -1) {
- op_ret = -errno;
- goto dealloc_mem;
- }
+ ret = dict_set_dynptr (xattr, (char *)key, memptr, xattrsize);
+ if (ret)
+ goto freemem;
- xattrsize = op_ret; /* save for correct _in_ memory pointing */
+ return 0;
- op_ret = sys_lgetxattr (real_path, BITROT_SIGNING_VERSION_KEY,
- (memptr + op_ret + 1), allocsize - op_ret);
- if (op_ret == -1) {
- op_ret = -errno;
- goto dealloc_mem;
- }
+ freemem:
+ GF_FREE (memptr);
+ error_return:
+ return -1;
+}
- /* this is a dynamic set */
- op_ret = dict_set_dynptr (xattr, BITROT_CURRENT_VERSION_KEY,
- memptr, allocsize);
- if (op_ret < 0)
- goto dealloc_mem;
+/**
+ * Fetch on-disk ongoing version and object signature extended attribute.
+ * Be generous to absence of xattrs (just *absence*, other errors are
+ * propagated up to the invoker), higher layer (br-stub) takes care of
+ * interpreting the xattrs for anomalies.
+ */
+int32_t
+posix_get_objectsignature (char *real_path, dict_t *xattr)
+{
+ int32_t ret = 0;
- /* rest all should be static */
- op_ret = dict_set_static_ptr (xattr, BITROT_SIGNING_VERSION_KEY,
- memptr + xattrsize + 1);
- if (op_ret < 0)
+ ret = posix_fetch_signature_xattr
+ (real_path, BITROT_CURRENT_VERSION_KEY, xattr);
+ if (ret)
+ goto error_return;
+
+ ret = posix_fetch_signature_xattr
+ (real_path, BITROT_SIGNING_VERSION_KEY, xattr);
+ if (ret)
goto delkey;
- return allocsize;
+ return 0;
delkey:
dict_del (xattr, BITROT_CURRENT_VERSION_KEY);
- dealloc_mem:
- GF_FREE (memptr);
error_return:
- return op_ret;
-
+ return -1;
}