summaryrefslogtreecommitdiffstats
path: root/xlators/storage
diff options
context:
space:
mode:
authorvmallika <vmallika@redhat.com>2015-08-27 11:31:01 +0530
committerRaghavendra G <rgowdapp@redhat.com>2015-08-27 06:45:50 -0700
commit3481e42a5325ba8a53f9121005dca80419658ea8 (patch)
tree0159aea1493c86efec61e53a15e408dba0ab6ec6 /xlators/storage
parent315edb7868fd3a726c9c99a2ce710f8421440a65 (diff)
posix: xattrop 'GF_XATTROP_GET_AND_SET' implementation
This is a backport of http://review.gluster.org/#/c/11995 GF_XATTROP_GET_AND_SET stores the existing xattr value in xdata and sets the new value xattrop was reusing input xattr dict to set the results instead of creating new dict. This can be problem for server side xlators as the inout dict will have the value changed. > Change-Id: I43369082e1d0090d211381181e9f3b9075b8e771 > BUG: 1251454 > Signed-off-by: vmallika <vmallika@redhat.com> Change-Id: I7e0c27fd415131e9983a10d27067f63ed3a7701e BUG: 1257441 Signed-off-by: vmallika <vmallika@redhat.com> Reviewed-on: http://review.gluster.org/12022 Tested-by: NetBSD Build System <jenkins@build.gluster.org> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
Diffstat (limited to 'xlators/storage')
-rw-r--r--xlators/storage/posix/src/posix.c38
1 files changed, 32 insertions, 6 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index ec13a083d0d..b8bb47ac91d 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -4853,6 +4853,7 @@ _posix_handle_xattr_keyvalue_pair (dict_t *d, char *k, data_t *v,
int op_errno = 0;
gf_xattrop_flags_t optype = 0;
char *array = NULL;
+ char *dst_data = NULL;
inode_t *inode = NULL;
xlator_t *this = NULL;
posix_xattr_filler_t *filler = NULL;
@@ -4916,6 +4917,11 @@ _posix_handle_xattr_keyvalue_pair (dict_t *d, char *k, data_t *v,
goto unlock;
}
+ if (size == -1 && optype == GF_XATTROP_GET_AND_SET) {
+ GF_FREE (array);
+ array = NULL;
+ }
+
/* We only write back the xattr if it has been really modified
* (i.e. v->data is not all 0's). Otherwise we return its value
* but we don't update anything.
@@ -4923,7 +4929,8 @@ _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;
- if (mem_0filled(v->data, v->len) == 0)
+ if (optype != GF_XATTROP_GET_AND_SET &&
+ mem_0filled(v->data, v->len) == 0)
goto unlock;
switch (optype) {
@@ -4931,12 +4938,18 @@ _posix_handle_xattr_keyvalue_pair (dict_t *d, char *k, data_t *v,
case GF_XATTROP_ADD_ARRAY:
__add_array ((int32_t *) array,
(int32_t *) v->data, v->len / 4);
+ dst_data = array;
break;
case GF_XATTROP_ADD_ARRAY64:
__add_long_array ((int64_t *) array,
(int64_t *) v->data,
v->len / 8);
+ dst_data = array;
+ break;
+
+ case GF_XATTROP_GET_AND_SET:
+ dst_data = v->data;
break;
default:
@@ -4952,10 +4965,10 @@ _posix_handle_xattr_keyvalue_pair (dict_t *d, char *k, data_t *v,
if (filler->real_path) {
size = sys_lsetxattr (filler->real_path, k,
- array, v->len, 0);
+ dst_data, v->len, 0);
} else {
size = sys_fsetxattr (filler->fdnum, k,
- (char *)array,
+ (char *)dst_data,
v->len, 0);
}
op_errno = errno;
@@ -4981,8 +4994,8 @@ unlock:
k, strerror (op_errno));
op_ret = -1;
goto out;
- } else {
- size = dict_set_bin (d, k, array, v->len);
+ } else if (array) {
+ size = dict_set_bin (filler->xattr, k, array, v->len);
if (size != 0) {
if (filler->real_path)
@@ -5032,6 +5045,7 @@ do_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
struct posix_fd *pfd = NULL;
inode_t *inode = NULL;
posix_xattr_filler_t filler = {0,};
+ dict_t *xdata = NULL;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (xattr, out);
@@ -5064,11 +5078,19 @@ do_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
inode = fd->inode;
}
+ xdata = dict_new ();
+ if (xdata == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
filler.this = this;
filler.fdnum = _fd;
filler.real_path = real_path;
filler.flags = (int)optype;
filler.inode = inode;
+ filler.xattr = xdata;
op_ret = dict_foreach (xattr, _posix_handle_xattr_keyvalue_pair,
&filler);
@@ -5076,7 +5098,11 @@ do_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
out:
- STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, xattr, NULL);
+ STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, xdata, xdata);
+
+ if (xdata)
+ dict_unref (xdata);
+
return 0;
}