diff options
author | vmallika <vmallika@redhat.com> | 2015-09-28 16:52:53 +0530 |
---|---|---|
committer | Raghavendra G <rgowdapp@redhat.com> | 2015-09-28 22:35:19 -0700 |
commit | 9d31a55b7c4c4e1aeedfdc74eadbf36902f7bcd9 (patch) | |
tree | 491644f0a1757b6e695e6ae1e25a989fbf654a99 /xlators | |
parent | d41bbb6dbaf64a8ef55e40e0550b83daac1eeb7a (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')
-rw-r--r-- | xlators/storage/posix/src/posix.c | 127 |
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) |