diff options
-rw-r--r-- | libglusterfs/src/glusterfs.h | 5 | ||||
-rw-r--r-- | tests/bugs/distribute/bug-1193636.c | 70 | ||||
-rw-r--r-- | tests/bugs/distribute/bug-1193636.t | 72 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 391 | ||||
-rw-r--r-- | xlators/cluster/ec/src/ec-combine.c | 1 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.c | 123 |
6 files changed, 631 insertions, 31 deletions
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index 9ed02e5400f..6f20185f80b 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -230,8 +230,9 @@ #define DHT_LINKFILE_STR "linkto" #define DHT_COMMITHASH_STR "commithash" -#define DHT_SKIP_NON_LINKTO_UNLINK "unlink-only-if-dht-linkto-file" -#define DHT_SKIP_OPEN_FD_UNLINK "dont-unlink-for-open-fd" +#define DHT_SKIP_NON_LINKTO_UNLINK "unlink-only-if-dht-linkto-file" +#define DHT_SKIP_OPEN_FD_UNLINK "dont-unlink-for-open-fd" +#define DHT_IATT_IN_XDATA_KEY "dht-get-iatt-in-xattr" /*CTR requires inode dentry link count from posix*/ #define CTR_RESPONSE_LINK_COUNT_XDATA "ctr_response_link_count" diff --git a/tests/bugs/distribute/bug-1193636.c b/tests/bugs/distribute/bug-1193636.c new file mode 100644 index 00000000000..eae90783f8e --- /dev/null +++ b/tests/bugs/distribute/bug-1193636.c @@ -0,0 +1,70 @@ +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <attr/xattr.h> +#include <fcntl.h> +#include <string.h> + + +#define MY_XATTR_NAME "user.ftest" +#define MY_XATTR_VAL "ftestval" + + +void usage (void) +{ + printf ("Usage : bug-1193636 <filename> <xattr_name> <op>\n"); + printf (" op : 0 - set, 1 - remove\n"); +} + + +int main (int argc, char **argv) +{ + int fd; + int err = 0; + char *xattr_name = NULL; + int op = 0; + + if (argc != 4) { + usage (); + exit (1); + } + + op = atoi (argv[3]); + + if ((op != 0) && (op != 1)) { + printf ("Invalid operation specified.\n"); + usage (); + exit (1); + } + + xattr_name = argv[2]; + + fd = open(argv[1], O_RDWR); + if (fd == -1) { + printf ("Failed to open file %s\n", argv[1]); + exit (1); + } + + if (!op) { + err = fsetxattr (fd, xattr_name, MY_XATTR_VAL, + strlen (MY_XATTR_VAL) + 1, XATTR_CREATE); + + if (err) { + printf ("Failed to set xattr %s: %m\n", xattr_name); + exit (1); + } + + } else { + err = fremovexattr (fd, xattr_name); + + if (err) { + printf ("Failed to remove xattr %s: %m\n", xattr_name); + exit (1); + } + } + + close (fd); + + return 0; +} + diff --git a/tests/bugs/distribute/bug-1193636.t b/tests/bugs/distribute/bug-1193636.t new file mode 100644 index 00000000000..ccde02edc70 --- /dev/null +++ b/tests/bugs/distribute/bug-1193636.t @@ -0,0 +1,72 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + + +checksticky () { + i=0; + while [ ! -k $1 ]; do + sleep 1 + i=$((i+1)); + if [[ $i == 10 ]]; then + return $i + fi + echo "Waiting... $i" + done + echo "done ...got out @ $i" + return 0 +} + +cleanup; + +#Basic checks +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info + +#Create a distributed volume +TEST $CLI volume create $V0 $H0:$B0/${V0}{1..3}; +TEST $CLI volume start $V0 + +# Mount FUSE +TEST glusterfs -s $H0 --volfile-id $V0 $M0 + +TEST mkdir $M0/dir1 + +# Create a large file (1GB), so that rebalance takes time +dd if=/dev/zero of=$M0/dir1/FILE2 bs=64k count=10240 + +# Rename the file to create a linkto, for rebalance to +# act on the file +TEST mv $M0/dir1/FILE2 $M0/dir1/FILE1 + +build_tester $(dirname $0)/bug-1193636.c + +TEST $CLI volume rebalance $V0 start force + +TEST checksticky $B0/${V0}3/dir1/FILE1 + +TEST setfattr -n "user.test1" -v "test1" $M0/dir1/FILE1 +TEST setfattr -n "user.test2" -v "test1" $M0/dir1/FILE1 +TEST setfattr -n "user.test3" -v "test1" $M0/dir1/FILE1 + +TEST $(dirname $0)/bug-1193636 $M0/dir1/FILE1 user.fsetx 0 +TEST $(dirname $0)/bug-1193636 $M0/dir1/FILE1 user.fremx 0 + +TEST getfattr -n "user.fremx" $M0/dir1/FILE1 +TEST setfattr -x "user.test2" $M0/dir1/FILE1 + + +TEST $(dirname $0)/bug-1193636 $M0/dir1/FILE1 user.fremx 1 + +EXPECT_WITHIN $REBALANCE_TIMEOUT "completed" rebalance_status_field $V0 + +TEST getfattr -n "user.fsetx" $M0/dir1/FILE1 +TEST getfattr -n "user.test1" $M0/dir1/FILE1 +TEST ! getfattr -n "user.test2" $M0/dir1/FILE1 +TEST ! getfattr -n "user.fremx" $M0/dir1/FILE1 +TEST getfattr -n "user.test3" $M0/dir1/FILE1 + + +cleanup; diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index 72ca77ea5ab..092ddebb8f5 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -32,6 +32,13 @@ int dht_link2 (xlator_t *this, call_frame_t *frame, int op_ret); int +dht_removexattr2 (xlator_t *this, call_frame_t *frame, int op_ret); + +int +dht_setxattr2 (xlator_t *this, call_frame_t *frame, int op_ret); + + +int dht_aggregate_quota_xattr (dict_t *dst, char *key, data_t *value) { int ret = -1; @@ -96,6 +103,8 @@ out: return ret; } + + int dht_aggregate (dict_t *this, char *key, data_t *value, void *data) { @@ -3265,6 +3274,78 @@ err: } int +dht_file_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int op_ret, int op_errno, dict_t *xdata) +{ + int ret = -1; + dht_local_t *local = NULL; + call_frame_t *prev = NULL; + struct iatt *stbuf = NULL; + inode_t *inode = NULL; + xlator_t *subvol = NULL; + + + local = frame->local; + prev = cookie; + + local->op_errno = op_errno; + + if ((op_ret == -1) && !dht_inode_missing (op_errno)) { + gf_msg_debug (this->name, op_errno, + "subvolume %s returned -1.", + prev->this->name); + goto out; + } + + if (local->call_cnt != 1) + goto out; + + ret = dict_get_bin (xdata, DHT_IATT_IN_XDATA_KEY, (void **) &stbuf); + + if ((!op_ret) && !stbuf) { + goto out; + } + + local->op_ret = 0; + + local->rebalance.target_op_fn = dht_setxattr2; + + /* Phase 2 of migration */ + if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2 (stbuf)) { + ret = dht_rebalance_complete_check (this, frame); + if (!ret) + return 0; + } + + /* Phase 1 of migration */ + if (IS_DHT_MIGRATION_PHASE1 (stbuf)) { + inode = (local->fd) ? local->fd->inode : local->loc.inode; + dht_inode_ctx_get1 (this, inode, &subvol); + if (subvol) { + dht_setxattr2 (this, frame, 0); + return 0; + } + ret = dht_rebalance_in_progress_check (this, frame); + if (!ret) + return 0; + } + +out: + if (local->rebalance.xdata) + dict_unref (local->rebalance.xdata); + + if (local->fop == GF_FOP_SETXATTR) { + DHT_STACK_UNWIND (setxattr, frame, op_ret, op_errno, NULL); + } else { + DHT_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno, NULL); + } + + return 0; +} + + + +int dht_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xattr, int flags, dict_t *xdata) { @@ -3272,6 +3353,10 @@ dht_fsetxattr (call_frame_t *frame, xlator_t *this, dht_local_t *local = NULL; int op_errno = EINVAL; dht_conf_t *conf = NULL; + dht_layout_t *layout = NULL; + int ret = -1; + int call_cnt = 0; + int i = 0; VALIDATE_OR_GOTO (frame, err); VALIDATE_OR_GOTO (this, err); @@ -3299,11 +3384,47 @@ dht_fsetxattr (call_frame_t *frame, xlator_t *this, goto err; } - local->call_cnt = 1; + layout = local->layout; + if (!layout) { + gf_msg_debug (this->name, 0, + "no layout for fd=%p", fd); + op_errno = EINVAL; + goto err; + } + + local->call_cnt = call_cnt = layout->cnt; + + if (IA_ISDIR (fd->inode->ia_type)) { + for (i = 0; i < call_cnt; i++) { + STACK_WIND (frame, dht_err_cbk, + layout->list[i].xlator, + layout->list[i].xlator->fops->fsetxattr, + fd, xattr, flags, NULL); + } + + } else { + + local->call_cnt = 1; + local->rebalance.xdata = dict_ref (xattr); + local->rebalance.flags = flags; + + xdata = xdata ? dict_ref (xdata) : dict_new (); + if (xdata) + ret = dict_set_dynstr_with_alloc (xdata, + DHT_IATT_IN_XDATA_KEY, "yes"); + if (ret) { + gf_msg_debug (this->name, 0, + "Failed to set dictionary key %s for fd=%p", + DHT_IATT_IN_XDATA_KEY, fd); + } - STACK_WIND (frame, dht_err_cbk, subvol, subvol->fops->fsetxattr, - fd, xattr, flags, NULL); + STACK_WIND (frame, dht_file_setxattr_cbk, subvol, + subvol->fops->fsetxattr, fd, xattr, flags, xdata); + + if (xdata) + dict_unref (xdata); + } return 0; err: @@ -3324,6 +3445,7 @@ dht_common_setxattr_cbk (call_frame_t *frame, void *cookie, return 0; } + int dht_checking_pathinfo_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xattr, @@ -3365,6 +3487,55 @@ out: } + +int +dht_setxattr2 (xlator_t *this, call_frame_t *frame, int op_ret) +{ + dht_local_t *local = NULL; + xlator_t *subvol = NULL; + int op_errno = EINVAL; + inode_t *inode = NULL; + + local = frame->local; + + inode = (local->fd) ? local->fd->inode : local->loc.inode; + + dht_inode_ctx_get1 (this, inode, &subvol); + + /* In phase2, dht_migration_complete_check_task will + * reset inode_ctx_reset1 and update local->cached_subvol + * with the dst subvol. + */ + if (!subvol) + subvol = local->cached_subvol; + + if (!subvol) { + op_errno = EINVAL; + goto err; + } + + local->call_cnt = 2; /* This is the second attempt */ + + if (local->fop == GF_FOP_SETXATTR) { + STACK_WIND (frame, dht_file_setxattr_cbk, subvol, + subvol->fops->setxattr, &local->loc, + local->rebalance.xdata, local->rebalance.flags, + NULL); + } else { + STACK_WIND (frame, dht_file_setxattr_cbk, subvol, + subvol->fops->fsetxattr, local->fd, + local->rebalance.xdata, local->rebalance.flags, + NULL); + } + + return 0; + +err: + DHT_STACK_UNWIND (setxattr, frame, local->op_ret, op_errno, NULL); + return 0; +} + + int dht_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr, int flags, dict_t *xdata) @@ -3588,11 +3759,32 @@ dht_setxattr (call_frame_t *frame, xlator_t *this, goto err; } - for (i = 0; i < call_cnt; i++) { - STACK_WIND (frame, dht_err_cbk, - layout->list[i].xlator, - layout->list[i].xlator->fops->setxattr, + if (IA_ISDIR (loc->inode->ia_type)) { + + for (i = 0; i < call_cnt; i++) { + STACK_WIND (frame, dht_err_cbk, + layout->list[i].xlator, + layout->list[i].xlator->fops->setxattr, + loc, xattr, flags, xdata); + } + + } else { + + local->rebalance.xdata = dict_ref (xattr); + local->rebalance.flags = flags; + local->call_cnt = 1; + + xdata = xdata ? dict_ref (xdata) : dict_new (); + if (xdata) + ret = dict_set_dynstr_with_alloc (xdata, + DHT_IATT_IN_XDATA_KEY, "yes"); + + STACK_WIND (frame, dht_file_setxattr_cbk, + subvol, subvol->fops->setxattr, loc, xattr, flags, xdata); + + if (xdata) + dict_unref (xdata); } return 0; @@ -3605,6 +3797,123 @@ err: } + + +int +dht_file_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int op_ret, int op_errno, dict_t *xdata) +{ + int ret = -1; + dht_local_t *local = NULL; + call_frame_t *prev = NULL; + struct iatt *stbuf = NULL; + inode_t *inode = NULL; + xlator_t *subvol = NULL; + + + local = frame->local; + prev = cookie; + + local->op_errno = op_errno; + + if ((op_ret == -1) && !dht_inode_missing (op_errno)) { + gf_msg_debug (this->name, op_errno, + "subvolume %s returned -1", + prev->this->name); + goto out; + } + + if (local->call_cnt != 1) + goto out; + + ret = dict_get_bin (xdata, DHT_IATT_IN_XDATA_KEY, (void **) &stbuf); + + if ((!op_ret) && !stbuf) { + goto out; + } + + local->op_ret = 0; + + local->rebalance.target_op_fn = dht_removexattr2; + + /* Phase 2 of migration */ + if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2 (stbuf)) { + ret = dht_rebalance_complete_check (this, frame); + if (!ret) + return 0; + } + + /* Phase 1 of migration */ + if (IS_DHT_MIGRATION_PHASE1 (stbuf)) { + inode = (local->fd) ? local->fd->inode : local->loc.inode; + dht_inode_ctx_get1 (this, inode, &subvol); + if (subvol) { + dht_removexattr2 (this, frame, 0); + return 0; + } + ret = dht_rebalance_in_progress_check (this, frame); + if (!ret) + return 0; + } + +out: + if (local->fop == GF_FOP_REMOVEXATTR) { + DHT_STACK_UNWIND (removexattr, frame, op_ret, op_errno, NULL); + } else { + DHT_STACK_UNWIND (fremovexattr, frame, op_ret, op_errno, NULL); + } + return 0; + +} + +int +dht_removexattr2 (xlator_t *this, call_frame_t *frame, int op_ret) +{ + dht_local_t *local = NULL; + xlator_t *subvol = NULL; + int op_errno = EINVAL; + inode_t *inode = NULL; + + local = frame->local; + + inode = (local->fd) ? local->fd->inode : local->loc.inode; + + dht_inode_ctx_get1 (this, inode, &subvol); + + /* In phase2, dht_migration_complete_check_task will + * reset inode_ctx_reset1 and update local->cached_subvol + * with the dst subvol. + */ + if (!subvol) + subvol = local->cached_subvol; + + if (!subvol) { + op_errno = EINVAL; + goto err; + + } + + + local->call_cnt = 2; /* This is the second attempt */ + + if (local->fop == GF_FOP_REMOVEXATTR) { + STACK_WIND (frame, dht_file_removexattr_cbk, subvol, + subvol->fops->removexattr, &local->loc, + local->key, NULL); + } else { + STACK_WIND (frame, dht_file_removexattr_cbk, subvol, + subvol->fops->fremovexattr, local->fd, + local->key, NULL); + } + + return 0; + +err: + DHT_STACK_UNWIND (removexattr, frame, local->op_ret, op_errno, NULL); + return 0; +} + + int dht_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *xdata) @@ -3631,6 +3940,8 @@ dht_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, unlock: UNLOCK (&frame->lock); + + this_call_cnt = dht_frame_return (frame); if (is_last_call (this_call_cnt)) { DHT_STACK_UNWIND (removexattr, frame, local->op_ret, @@ -3652,6 +3963,7 @@ dht_removexattr (call_frame_t *frame, xlator_t *this, int call_cnt = 0; dht_conf_t *conf = NULL; int i; + int ret = 0; VALIDATE_OR_GOTO (this, err); VALIDATE_OR_GOTO (this->private, err); @@ -3689,11 +4001,33 @@ dht_removexattr (call_frame_t *frame, xlator_t *this, local->call_cnt = call_cnt = layout->cnt; local->key = gf_strdup (key); - for (i = 0; i < call_cnt; i++) { - STACK_WIND (frame, dht_removexattr_cbk, - layout->list[i].xlator, - layout->list[i].xlator->fops->removexattr, - loc, key, NULL); + if (IA_ISDIR (loc->inode->ia_type)) { + for (i = 0; i < call_cnt; i++) { + STACK_WIND (frame, dht_removexattr_cbk, + layout->list[i].xlator, + layout->list[i].xlator->fops->removexattr, + loc, key, NULL); + } + + } else { + + local->call_cnt = 1; + xdata = xdata ? dict_ref (xdata) : dict_new (); + if (xdata) + ret = dict_set_dynstr_with_alloc (xdata, + DHT_IATT_IN_XDATA_KEY, "yes"); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "set dictionary key %s for %s", + DHT_IATT_IN_XDATA_KEY, loc->path); + } + + STACK_WIND (frame, dht_file_removexattr_cbk, + subvol, subvol->fops->removexattr, + loc, key, xdata); + + if (xdata) + dict_unref (xdata); } return 0; @@ -3715,6 +4049,7 @@ dht_fremovexattr (call_frame_t *frame, xlator_t *this, dht_layout_t *layout = NULL; int call_cnt = 0; dht_conf_t *conf = 0; + int ret = 0; int i; @@ -3754,11 +4089,33 @@ dht_fremovexattr (call_frame_t *frame, xlator_t *this, local->call_cnt = call_cnt = layout->cnt; local->key = gf_strdup (key); - for (i = 0; i < call_cnt; i++) { - STACK_WIND (frame, dht_removexattr_cbk, - layout->list[i].xlator, - layout->list[i].xlator->fops->fremovexattr, - fd, key, NULL); + if (IA_ISDIR (fd->inode->ia_type)) { + for (i = 0; i < call_cnt; i++) { + STACK_WIND (frame, dht_removexattr_cbk, + layout->list[i].xlator, + layout->list[i].xlator->fops->fremovexattr, + fd, key, NULL); + } + + } else { + + local->call_cnt = 1; + xdata = xdata ? dict_ref (xdata) : dict_new (); + if (xdata) + ret = dict_set_dynstr_with_alloc (xdata, + DHT_IATT_IN_XDATA_KEY, "yes"); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "set dictionary key %s for fd=%p", + DHT_IATT_IN_XDATA_KEY, fd); + } + + STACK_WIND (frame, dht_file_removexattr_cbk, + subvol, subvol->fops->fremovexattr, + fd, key, xdata); + + if (xdata) + dict_unref (xdata); } return 0; diff --git a/xlators/cluster/ec/src/ec-combine.c b/xlators/cluster/ec/src/ec-combine.c index 4617a0430f1..5842a4dd0a8 100644 --- a/xlators/cluster/ec/src/ec-combine.c +++ b/xlators/cluster/ec/src/ec-combine.c @@ -191,6 +191,7 @@ ec_value_ignore (char *key) (strcmp(key, GLUSTERFS_ENTRYLK_COUNT) == 0) || (strncmp(key, GF_XATTR_CLRLK_CMD, strlen (GF_XATTR_CLRLK_CMD)) == 0) || + (strcmp(key, DHT_IATT_IN_XDATA_KEY) == 0) || (strncmp(key, EC_QUOTA_PREFIX, strlen(EC_QUOTA_PREFIX)) == 0) || (fnmatch(MARKER_XATTR_PREFIX ".*." XTIME, key, 0) == 0) || (fnmatch(GF_XATTR_MARKER_KEY ".*", key, 0) == 0) || diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index b235ff4a794..d38964143ba 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -3239,6 +3239,31 @@ map_xattr_flags(int flags) } #endif +static +int32_t posix_set_iatt_in_dict (dict_t *dict, struct iatt *in_stbuf) +{ + int ret = -1; + struct iatt *stbuf = NULL; + int32_t len = sizeof(struct iatt); + + if (!dict || !in_stbuf) + return ret; + + stbuf = GF_CALLOC (1, len, gf_common_mt_char); + if (!stbuf) + return ret; + + memcpy (stbuf, in_stbuf, len); + + ret = dict_set_bin (dict, DHT_IATT_IN_XDATA_KEY, stbuf, len); + if (ret) + GF_FREE (stbuf); + + return ret; +} + + + int32_t posix_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int flags, dict_t *xdata) @@ -3246,7 +3271,9 @@ posix_setxattr (call_frame_t *frame, xlator_t *this, int32_t op_ret = -1; int32_t op_errno = 0; char * real_path = NULL; - + struct iatt stbuf = {0}; + int32_t ret = 0; + dict_t *xattr = NULL; posix_xattr_filler_t filler = {0,}; DECLARE_OLD_FS_ID_VAR; @@ -3265,6 +3292,7 @@ posix_setxattr (call_frame_t *frame, xlator_t *this, } op_ret = -1; + dict_del (dict, GFID_XATTR_KEY); dict_del (dict, GF_XATTR_VOL_ID_KEY); @@ -3280,12 +3308,31 @@ posix_setxattr (call_frame_t *frame, xlator_t *this, if (op_ret < 0) { op_errno = -op_ret; op_ret = -1; + goto out; } +/* + * FIXFIX: Send the stbuf info in the xdata for now + * This is used by DHT to redirect FOPs if the file is being migrated + * Ignore errors for now + */ + if (dict_get (xdata, DHT_IATT_IN_XDATA_KEY)) { + ret = posix_pstat(this, loc->gfid, real_path, &stbuf); + if (ret) + goto out; + + xattr = dict_new(); + if (!xattr) + goto out; + ret = posix_set_iatt_in_dict (xattr, &stbuf); + } out: SET_TO_OLD_FS_ID (); - STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, NULL); + STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xattr); + + if (xattr) + dict_unref(xattr); return 0; } @@ -4313,13 +4360,14 @@ int32_t posix_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int flags, dict_t *xdata) { - int32_t op_ret = -1; - int32_t op_errno = 0; - struct posix_fd * pfd = NULL; - int _fd = -1; - int ret = -1; - - posix_xattr_filler_t filler = {0,}; + int32_t op_ret = -1; + int32_t op_errno = 0; + struct posix_fd *pfd = NULL; + int _fd = -1; + int ret = -1; + struct iatt stbuf = {0,}; + dict_t *xattr = NULL; + posix_xattr_filler_t filler = {0,}; DECLARE_OLD_FS_ID_VAR; SET_FS_ID (frame->root->uid, frame->root->gid); @@ -4366,10 +4414,28 @@ posix_fsetxattr (call_frame_t *frame, xlator_t *this, } } + if (dict_get (xdata, DHT_IATT_IN_XDATA_KEY)) { + ret = posix_fdstat (this, pfd->fd, &stbuf); + if (ret == -1) { + gf_log (this->name, GF_LOG_ERROR, + "fsetxattr (fstat) failed on fd=%p: %s", + fd, strerror (op_errno)); + goto out; + } + + xattr = dict_new (); + if (!xattr) + goto out; + ret = posix_set_iatt_in_dict (xattr, &stbuf); + } + out: SET_TO_OLD_FS_ID (); - STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, NULL); + STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, xattr); + + if (xattr) + dict_unref (xattr); return 0; } @@ -4429,7 +4495,10 @@ posix_removexattr (call_frame_t *frame, xlator_t *this, { int32_t op_ret = -1; int32_t op_errno = 0; + int32_t ret = -1; char * real_path = NULL; + struct iatt stbuf = {0}; + dict_t *xattr = NULL; posix_xattr_filler_t filler = {0,}; DECLARE_OLD_FS_ID_VAR; @@ -4485,12 +4554,26 @@ posix_removexattr (call_frame_t *frame, xlator_t *this, goto out; } + if (dict_get (xdata, DHT_IATT_IN_XDATA_KEY)) { + ret = posix_pstat(this, loc->gfid, real_path, &stbuf); + if (ret) + goto out; + xattr = dict_new(); + if (!xattr) + goto out; + + ret = posix_set_iatt_in_dict (xattr, &stbuf); + } op_ret = 0; out: SET_TO_OLD_FS_ID (); - STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno, NULL); + STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno, xattr); + + if (xattr) + dict_unref (xattr); + return 0; } @@ -4501,6 +4584,8 @@ posix_fremovexattr (call_frame_t *frame, xlator_t *this, int32_t op_ret = -1; int32_t op_errno = 0; struct posix_fd * pfd = NULL; + struct iatt stbuf = {0,}; + dict_t *xattr = NULL; int _fd = -1; int ret = -1; @@ -4541,12 +4626,26 @@ posix_fremovexattr (call_frame_t *frame, xlator_t *this, goto out; } + if (dict_get (xdata, DHT_IATT_IN_XDATA_KEY)) { + ret = posix_fdstat (this, pfd->fd, &stbuf); + if (ret) + goto out; + xattr = dict_new(); + if (!xattr) + goto out; + + ret = posix_set_iatt_in_dict (xattr, &stbuf); + } op_ret = 0; out: SET_TO_OLD_FS_ID (); - STACK_UNWIND_STRICT (fremovexattr, frame, op_ret, op_errno, NULL); + STACK_UNWIND_STRICT (fremovexattr, frame, op_ret, op_errno, xattr); + + if (xattr) + dict_unref (xattr); + return 0; } |