summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvmallika <vmallika@redhat.com>2015-08-24 13:14:59 +0530
committerRaghavendra G <rgowdapp@redhat.com>2015-08-27 06:44:16 -0700
commit6ad05cd4b7995a3791a9e45ce03dc31641e8d78f (patch)
treea8fe2eedd464815fcfc1c452c07b9c26cca69cf2
parentb883f937cc98d2b659de5c3eb1d12306df19aca3 (diff)
posix: xattrop 'GF_XATTROP_GET_AND_SET' implementation
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> Reviewed-on: http://review.gluster.org/11995 Tested-by: Gluster Build System <jenkins@build.gluster.com> Tested-by: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
-rw-r--r--libglusterfs/src/glusterfs.h3
-rw-r--r--xlators/storage/posix/src/posix.c38
2 files changed, 34 insertions, 7 deletions
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h
index 3e3d0b02dd1..18ffbb1f2b1 100644
--- a/libglusterfs/src/glusterfs.h
+++ b/libglusterfs/src/glusterfs.h
@@ -372,7 +372,8 @@ typedef enum {
GF_XATTROP_ADD_ARRAY,
GF_XATTROP_ADD_ARRAY64,
GF_XATTROP_OR_ARRAY,
- GF_XATTROP_AND_ARRAY
+ GF_XATTROP_AND_ARRAY,
+ GF_XATTROP_GET_AND_SET
} gf_xattrop_flags_t;
#define GF_SET_IF_NOT_PRESENT 0x1 /* default behaviour */
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index ffb9f764c99..9da1cda3411 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -4841,6 +4841,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;
@@ -4904,6 +4905,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.
@@ -4911,7 +4917,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) {
@@ -4919,12 +4926,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:
@@ -4940,10 +4953,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;
@@ -4969,8 +4982,8 @@ unlock:
k, strerror (op_errno));
op_ret = -1;
goto out;
- } else {
- op_ret = dict_set_bin (d, k, array, v->len);
+ } else if (array) {
+ op_ret = dict_set_bin (filler->xattr, k, array, v->len);
if (op_ret) {
if (filler->real_path)
gf_msg_debug (this->name, 0,
@@ -5020,6 +5033,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);
@@ -5052,11 +5066,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);
@@ -5064,7 +5086,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;
}