summaryrefslogtreecommitdiffstats
path: root/xlators/storage/posix/src/posix.c
diff options
context:
space:
mode:
authorvmallika <vmallika@redhat.com>2015-09-28 16:52:53 +0530
committerRaghavendra G <rgowdapp@redhat.com>2015-09-28 22:35:19 -0700
commit9d31a55b7c4c4e1aeedfdc74eadbf36902f7bcd9 (patch)
tree491644f0a1757b6e695e6ae1e25a989fbf654a99 /xlators/storage/posix/src/posix.c
parentd41bbb6dbaf64a8ef55e40e0550b83daac1eeb7a (diff)
posix: xattrop 'GF_XATTROP_ADD_ARRAY_WITH_DEFAULT' implementation
This is a backport of http://review.gluster.org/#/c/11702 Implementation of xattrop type: GF_XATTROP_ADD_ARRAY_WITH_DEFAULT GF_XATTROP_ADD_ARRAY64_WITH_DEFAULT These operations are similar to 'GF_XATTROP_ADD_ARRAY', except that it adds a default value if xattr is missing or its value is zero on disk. One use-case of this operation is in inode-quota. When a new directory is created, its default dir_count should be set to 1. So when a xattrop performed setting inode-xattrs, it should account initial dir_count 1 if the xattrs are not present Here is the usage of this operation value required in xdata for each key struct array { int32_t newvalue_1; int32_t newvalue_2; ... int32_t newvalue_n; int32_t default_1; int32_t default_2; ... int32_t default_n; }; or struct array { int32_t value_1; int32_t value_2; ... int32_t value_n; } data[2]; fill data[0] with new value to add fill data[1] with default value xattrop GF_XATTROP_ADD_ARRAY_WITH_DEFAULT for i from 1 to n { if (xattr (dest_i) is zero or not set in the disk) dest_i = newvalue_i + default_i else dest_i = dest_i + newvalue_i } value in xdata after xattrop is successful struct array { int32_t dest_1; int32_t dest_2; ... int32_t dest_n; }; > Change-Id: Ic6a08473e99fd98299a839d4d8416081a7534efd > BUG: 1243946 > Signed-off-by: vmallika <vmallika@redhat.com> > Reviewed-on: http://review.gluster.org/11702 > Tested-by: NetBSD Build System <jenkins@build.gluster.org> > Reviewed-by: Raghavendra G <rgowdapp@redhat.com> Change-Id: Ie0c8285d9d582afbc808b0fd878f6c02957ff928 BUG: 1266882 Signed-off-by: vmallika <vmallika@redhat.com> Reviewed-on: http://review.gluster.org/12241 Tested-by: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
Diffstat (limited to 'xlators/storage/posix/src/posix.c')
-rw-r--r--xlators/storage/posix/src/posix.c127
1 files changed, 117 insertions, 10 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index 63439d3f707..aded216241d 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -4852,6 +4852,98 @@ __add_long_array (int64_t *dest, int64_t *src, int count)
}
}
+/* functions:
+ __add_array_with_default
+ __add_long_array_with_default
+
+ xattrop type:
+ GF_XATTROP_ADD_ARRAY_WITH_DEFAULT
+ GF_XATTROP_ADD_ARRAY64_WITH_DEFAULT
+
+ These operations are similar to 'GF_XATTROP_ADD_ARRAY',
+ except that it adds a default value if xattr is missing
+ or its value is zero on disk.
+
+ One use-case of this operation is in inode-quota.
+ When a new directory is created, its default dir_count
+ should be set to 1. So when a xattrop performed setting
+ inode-xattrs, it should account initial dir_count
+ 1 if the xattrs are not present
+
+ Here is the usage of this operation
+
+ value required in xdata for each key
+ struct array {
+ int32_t newvalue_1;
+ int32_t newvalue_2;
+ ...
+ int32_t newvalue_n;
+ int32_t default_1;
+ int32_t default_2;
+ ...
+ int32_t default_n;
+ };
+
+ or
+
+ struct array {
+ int32_t value_1;
+ int32_t value_2;
+ ...
+ int32_t value_n;
+ } data[2];
+ fill data[0] with new value to add
+ fill data[1] with default value
+
+ xattrop GF_XATTROP_ADD_ARRAY_WITH_DEFAULT
+ for i from 1 to n
+ {
+ if (xattr (dest_i) is zero or not set in the disk)
+ dest_i = newvalue_i + default_i
+ else
+ dest_i = dest_i + newvalue_i
+ }
+
+ value in xdata after xattrop is successful
+ struct array {
+ int32_t dest_1;
+ int32_t dest_2;
+ ...
+ int32_t dest_n;
+ };
+*/
+static void
+__add_array_with_default (int32_t *dest, int32_t *src, int count)
+{
+ int i = 0;
+ int32_t destval = 0;
+
+ for (i = 0; i < count; i++) {
+ destval = ntoh32 (dest[i]);
+ if (destval == 0)
+ dest[i] = hton32 (ntoh32 (src[i]) +
+ ntoh32 (src[count + i]));
+ else
+ dest[i] = hton32 (destval + ntoh32 (src[i]));
+ }
+}
+
+static void
+__add_long_array_with_default (int64_t *dest, int64_t *src, int count)
+{
+ int i = 0;
+ int64_t destval = 0;
+
+ for (i = 0; i < count; i++) {
+ destval = ntoh64 (dest[i]);
+ if (destval == 0)
+ dest[i] = hton64 (ntoh64 (src[i]) +
+ ntoh64 (src[i + count]));
+ else
+ dest[i] = hton64 (destval + ntoh64 (src[i]));
+ }
+}
+
static int
_posix_handle_xattr_keyvalue_pair (dict_t *d, char *k, data_t *v,
void *tmp)
@@ -4873,6 +4965,10 @@ _posix_handle_xattr_keyvalue_pair (dict_t *d, char *k, data_t *v,
this = filler->this;
inode = filler->inode;
count = v->len;
+ if (optype == GF_XATTROP_ADD_ARRAY_WITH_DEFAULT ||
+ optype == GF_XATTROP_ADD_ARRAY64_WITH_DEFAULT)
+ count = count / 2;
+
array = GF_CALLOC (count, sizeof (char), gf_posix_mt_char);
#ifdef GF_DARWIN_HOST_OS
@@ -4889,10 +4985,10 @@ _posix_handle_xattr_keyvalue_pair (dict_t *d, char *k, data_t *v,
{
if (filler->real_path) {
size = sys_lgetxattr (filler->real_path, k,
- (char *)array, v->len);
+ (char *)array, count);
} else {
size = sys_fgetxattr (filler->fdnum, k, (char *)array,
- v->len);
+ count);
}
op_errno = errno;
@@ -4937,24 +5033,35 @@ _posix_handle_xattr_keyvalue_pair (dict_t *d, char *k, data_t *v,
*
* If the xattr does not exist, a value of all 0's is returned
* without creating it. */
- size = v->len;
+ size = count;
if (optype != GF_XATTROP_GET_AND_SET &&
mem_0filled(v->data, v->len) == 0)
goto unlock;
+ dst_data = array;
switch (optype) {
case GF_XATTROP_ADD_ARRAY:
__add_array ((int32_t *) array,
- (int32_t *) v->data, v->len / 4);
- dst_data = array;
+ (int32_t *) v->data, count / 4);
break;
case GF_XATTROP_ADD_ARRAY64:
__add_long_array ((int64_t *) array,
(int64_t *) v->data,
- v->len / 8);
- dst_data = array;
+ count / 8);
+ break;
+
+ case GF_XATTROP_ADD_ARRAY_WITH_DEFAULT:
+ __add_array_with_default ((int32_t *) array,
+ (int32_t *) v->data,
+ count / 4);
+ break;
+
+ case GF_XATTROP_ADD_ARRAY64_WITH_DEFAULT:
+ __add_long_array_with_default ((int64_t *) array,
+ (int64_t *) v->data,
+ count / 8);
break;
case GF_XATTROP_GET_AND_SET:
@@ -4974,11 +5081,11 @@ _posix_handle_xattr_keyvalue_pair (dict_t *d, char *k, data_t *v,
if (filler->real_path) {
size = sys_lsetxattr (filler->real_path, k,
- dst_data, v->len, 0);
+ dst_data, count, 0);
} else {
size = sys_fsetxattr (filler->fdnum, k,
(char *)dst_data,
- v->len, 0);
+ count, 0);
}
op_errno = errno;
}
@@ -5004,7 +5111,7 @@ unlock:
op_ret = -1;
goto out;
} else if (array) {
- size = dict_set_bin (filler->xattr, k, array, v->len);
+ size = dict_set_bin (filler->xattr, k, array, count);
if (size != 0) {
if (filler->real_path)