diff options
author | Jeff Darcy <jdarcy@fb.com> | 2017-08-31 12:33:59 -0700 |
---|---|---|
committer | Jeff Darcy <jdarcy@fb.com> | 2017-08-31 12:33:59 -0700 |
commit | ed23e379ee397b3fed479c15b7551d2dbba9a05f (patch) | |
tree | fe9bc23b851e0ee5502a48f1362b3ef9b10052f3 | |
parent | f2d57485d57e14a064c9ca6e83fe6c92131a8e37 (diff) | |
parent | d174f021a4e0667e60ce6abc038106ad9b74dc74 (diff) |
Merge remote-tracking branch 'origin/release-3.8' into release-3.8-fb
Change-Id: Ie35cd1c8c7808949ddf79b3189f1f8bf0ff70ed8
92 files changed, 1579 insertions, 627 deletions
diff --git a/api/src/glfs-handleops.c b/api/src/glfs-handleops.c index a464b2ed195..b5fcfab713c 100644 --- a/api/src/glfs-handleops.c +++ b/api/src/glfs-handleops.c @@ -2297,13 +2297,15 @@ pub_glfs_h_acl_get (struct glfs *fs, struct glfs_object *object, goto out; ret = dict_get_str (xattr, (char *)acl_key, &acl_s); - if (ret == -1) + if (ret) goto out; acl = acl_from_text (acl_s); out: - GF_FREE (acl_s); + if (xattr) + dict_unref (xattr); + if (IA_ISLNK (object->inode->ia_type) && new_object) glfs_h_close (new_object); diff --git a/api/src/glfs-resolve.c b/api/src/glfs-resolve.c index f8b437bab0e..d495cd21413 100644 --- a/api/src/glfs-resolve.c +++ b/api/src/glfs-resolve.c @@ -385,6 +385,9 @@ priv_glfs_resolve_at (struct glfs *fs, xlator_t *subvol, inode_t *at, int ret = -1; struct iatt ciatt = {0, }; + DECLARE_OLD_THIS; + __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs); + path = gf_strdup (origpath); if (!path) { errno = ENOMEM; @@ -510,9 +513,10 @@ priv_glfs_resolve_at (struct glfs *fs, xlator_t *subvol, inode_t *at, } out: GF_FREE (path); + __GLFS_EXIT_FS; /* do NOT loc_wipe here as only last component might be missing */ - +invalid_fs: return ret; } diff --git a/cli/src/Makefile.am b/cli/src/Makefile.am index 91819d111e3..8e47e209056 100644 --- a/cli/src/Makefile.am +++ b/cli/src/Makefile.am @@ -17,7 +17,7 @@ AM_CPPFLAGS = $(GF_CPPFLAGS) \ -I$(top_srcdir)/rpc/xdr/src\ -DDATADIR=\"$(localstatedir)\" \ -DCONFDIR=\"$(sysconfdir)/glusterfs\" \ - -DGSYNCD_PREFIX=\"$(libexecdir)/glusterfs\"\ + -DGSYNCD_PREFIX=\"$(GLUSTERFS_LIBEXECDIR)\"\ -DSYNCDAEMON_COMPILE=$(SYNCDAEMON_COMPILE) -DSBIN_DIR=\"$(sbindir)\"\ $(XML_CPPFLAGS) diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 602d3ff1611..07a63364ebe 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -3400,6 +3400,26 @@ out: } int +gluster_remove_auxiliary_mount (char *volname) +{ + int ret = -1; + char mountdir[PATH_MAX] = {0,}; + xlator_t *this = NULL; + + this = THIS; + GF_ASSERT (this); + + GLUSTERD_GET_QUOTA_LIST_MOUNT_PATH (mountdir, volname, "/"); + ret = gf_umount_lazy (this->name, mountdir, 1); + if (ret) { + gf_log("cli", GF_LOG_ERROR, "umount on %s failed, " + "reason : %s", mountdir, strerror (errno)); + } + + return ret; +} + +int gf_cli_print_limit_list_from_dict (cli_local_t *local, char *volname, dict_t *dict, char *default_sl, int count, int op_ret, int op_errno, char *op_errstr) @@ -3447,7 +3467,7 @@ gf_cli_print_limit_list_from_dict (cli_local_t *local, char *volname, ret = gf_canonicalize_path (path); if (ret) goto out; - GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (mountdir, volname, path); + GLUSTERD_GET_QUOTA_LIST_MOUNT_PATH (mountdir, volname, path); ret = print_quota_list_from_mountdir (local, mountdir, default_sl, path, type); } @@ -3930,6 +3950,7 @@ gf_cli_quota_cbk (struct rpc_req *req, struct iovec *iov, } xml_output: + if (global_state->mode & GLUSTER_MODE_XML) { ret = cli_xml_output_str ("volQuota", NULL, rsp.op_ret, rsp.op_errno, rsp.op_errstr); @@ -3945,6 +3966,12 @@ xml_output: ret = rsp.op_ret; out: + + if ((type == GF_QUOTA_OPTION_TYPE_LIST) + || (type == GF_QUOTA_OPTION_TYPE_LIST_OBJECTS)) { + gluster_remove_auxiliary_mount (volname); + } + cli_cmd_broadcast_response (ret); if (dict) dict_unref (dict); diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c index 4eafc0b5e68..0704174c211 100644 --- a/cli/src/cli-xml-output.c +++ b/cli/src/cli-xml-output.c @@ -194,6 +194,8 @@ cli_xml_output_data_pair (dict_t *this, char *key, data_t *value, ret = xmlTextWriterWriteFormatElement (*writer, (xmlChar *)key, "%s", value->data); + XML_RET_CHECK_AND_GOTO (ret, out); +out: return ret; } #endif @@ -324,7 +326,7 @@ cli_xml_output_vol_status_common (xmlTextWriterPtr writer, dict_t *dict, ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"port", "%s", "N/A"); - + XML_RET_CHECK_AND_GOTO (ret, out); ret = xmlTextWriterStartElement (writer, (xmlChar *)"ports"); if (*online == 1 && (port != 0 || rdma_port != 0)) { @@ -337,7 +339,7 @@ cli_xml_output_vol_status_common (xmlTextWriterPtr writer, dict_t *dict, (xmlChar *)"tcp", "%s", "N/A"); } - + XML_RET_CHECK_AND_GOTO (ret, out); if (rdma_port) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"rdma", @@ -347,14 +349,16 @@ cli_xml_output_vol_status_common (xmlTextWriterPtr writer, dict_t *dict, (xmlChar *)"rdma", "%s", "N/A"); } - + XML_RET_CHECK_AND_GOTO (ret, out); } else { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"tcp", "%s", "N/A"); + XML_RET_CHECK_AND_GOTO (ret, out); ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"rdma", "%s", "N/A"); + XML_RET_CHECK_AND_GOTO (ret, out); } ret = xmlTextWriterEndElement (writer); @@ -392,77 +396,86 @@ cli_xml_output_vol_status_detail (xmlTextWriterPtr writer, dict_t *dict, snprintf (key, sizeof (key), "brick%d.total", brick_index); ret = dict_get_uint64 (dict, key, &size_total); - if (!ret) + if (!ret) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"sizeTotal", "%"PRIu64, size_total); - + XML_RET_CHECK_AND_GOTO (ret, out); + } memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "brick%d.free", brick_index); ret = dict_get_uint64 (dict, key, &size_free); - if (!ret) + if (!ret) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"sizeFree", "%"PRIu64, size_free); - + XML_RET_CHECK_AND_GOTO (ret, out); + } memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "brick%d.device", brick_index); ret = dict_get_str (dict, key, &device); - if (!ret) + if (!ret) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"device", "%s", device); - + XML_RET_CHECK_AND_GOTO (ret, out); + } memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "brick%d.block_size", brick_index); ret = dict_get_uint64 (dict, key, &block_size); - if (!ret) + if (!ret) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"blockSize", "%"PRIu64, block_size); - XML_RET_CHECK_AND_GOTO (ret, out); - + XML_RET_CHECK_AND_GOTO (ret, out); + } memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "brick%d.mnt_options", brick_index); ret = dict_get_str (dict, key, &mnt_options); - if (!ret) + if (!ret) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"mntOptions", "%s", mnt_options); - + XML_RET_CHECK_AND_GOTO (ret, out); + } memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "brick%d.fs_name", brick_index); ret = dict_get_str (dict, key, &fs_name); - if (!ret) + if (!ret) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"fsName", "%s", fs_name); - + XML_RET_CHECK_AND_GOTO (ret, out); + } memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "brick%d.inode_size", brick_index); ret = dict_get_str (dict, key, &inode_size); - if (!ret) + if (!ret) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"inodeSize", "%s", fs_name); - + XML_RET_CHECK_AND_GOTO (ret, out); + } memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "brick%d.total_inodes", brick_index); ret = dict_get_uint64 (dict, key, &inodes_total); - if (!ret) + if (!ret) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"inodesTotal", "%"PRIu64, inodes_total); - + XML_RET_CHECK_AND_GOTO (ret, out); + } memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "brick%d.free_inodes", brick_index); ret = dict_get_uint64 (dict, key, &inodes_free); - if (!ret) + if (!ret) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"inodesFree", "%"PRIu64, inodes_free); - else + XML_RET_CHECK_AND_GOTO (ret, out); + } else { ret = 0; + } out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); @@ -1366,6 +1379,7 @@ cli_xml_output_vol_status_callpool (xmlTextWriterPtr writer, dict_t *dict, goto out; ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"count", "%d", call_count); + XML_RET_CHECK_AND_GOTO (ret, out); for (i = 0; i < call_count; i++) { memset (key, 0, sizeof (key)); @@ -1476,7 +1490,7 @@ cli_xml_output_remove_brick_task_params (xmlTextWriterPtr writer, dict_t *dict, /* </param> */ ret = xmlTextWriterEndElement (writer); - + XML_RET_CHECK_AND_GOTO (ret, out); out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); return ret; @@ -1560,7 +1574,7 @@ cli_xml_output_vol_status_tasks (cli_local_t *local, dict_t *dict) { /* </tasks> */ ret = xmlTextWriterEndElement (local->writer); - + XML_RET_CHECK_AND_GOTO (ret, out); out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); return ret; @@ -1637,8 +1651,8 @@ cli_xml_output_vol_status (cli_local_t *local, dict_t *dict) ret = xmlTextWriterWriteFormatElement (local->writer, (xmlChar *)"nodeCount", "%d", brick_count); - if (ret) - goto out; + + XML_RET_CHECK_AND_GOTO (ret, out); ret = dict_get_uint32 (dict, "cmd", &cmd); if (ret) @@ -2018,6 +2032,7 @@ cli_xml_output_vol_top (dict_t *dict, int op_ret, int op_errno, ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"timeTaken", "%f", time_taken); + XML_RET_CHECK_AND_GOTO (ret, out); } break; @@ -2320,8 +2335,7 @@ cli_xml_output_vol_profile (dict_t *dict, int op_ret, int op_errno, (writer, (xmlChar *)"clearStats", "%s", stats_cleared ? "Cleared stats." : "Failed to clear stats."); - if (ret) - goto out; + XML_RET_CHECK_AND_GOTO (ret, out); } else { snprintf (key, sizeof (key), "%d-cumulative", i); ret = dict_get_int32 (dict, key, &interval); @@ -2832,6 +2846,7 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict) ret = xmlTextWriterWriteFormatElement (local->writer, (xmlChar *)"hotBrickType", "%s", cli_vol_type_str[tier_vol_type]); + XML_RET_CHECK_AND_GOTO (ret, out); ret = xmlTextWriterWriteFormatElement (local->writer, (xmlChar *)"hotreplicaCount", @@ -2852,7 +2867,6 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict) (local->writer, (xmlChar *)"numberOfBricks", "%d", value[HOT_BRICK_COUNT]); - XML_RET_CHECK_AND_GOTO (ret, out); } else { ret = xmlTextWriterWriteFormatElement (local->writer, @@ -2863,6 +2877,7 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict) hot_dist_count, value[HOT_BRICK_COUNT]); } + XML_RET_CHECK_AND_GOTO (ret, out); while (index <= value[HOT_BRICK_COUNT]) { snprintf (key, 1024, "volume%d.brick%d", i, @@ -2924,6 +2939,7 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict) ret = xmlTextWriterWriteFormatElement (local->writer, (xmlChar *)"coldBrickType", "%s", cli_vol_type_str[tier_vol_type]); + XML_RET_CHECK_AND_GOTO (ret, out); ret = xmlTextWriterWriteFormatElement (local->writer, (xmlChar *)"coldreplicaCount", @@ -2953,8 +2969,6 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict) (local->writer, (xmlChar *)"numberOfBricks", "%d", value[COLD_BRICK_COUNT]); - XML_RET_CHECK_AND_GOTO (ret, out); - } else if (value[COLD_TYPE] == GF_CLUSTER_TYPE_DISPERSE) { ret = xmlTextWriterWriteFormatElement @@ -2979,6 +2993,7 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict) } start_index = index = value[HOT_BRICK_COUNT] + 1; + XML_RET_CHECK_AND_GOTO (ret, out); while (index <= brick_count) { snprintf (key, 1024, "volume%d.brick%d", i, @@ -3170,7 +3185,7 @@ cli_xml_output_vol_info_end (cli_local_t *local) ret = xmlTextWriterWriteFormatElement (local->writer, (xmlChar *)"count", "%d", local->vol_count); - + XML_RET_CHECK_AND_GOTO (ret, out); /* </volumes> */ ret = xmlTextWriterEndElement (local->writer); XML_RET_CHECK_AND_GOTO (ret, out); @@ -3196,9 +3211,7 @@ cli_xml_output_vol_quota_limit_list_end (cli_local_t *local) int ret = -1; ret = xmlTextWriterEndElement (local->writer); - if (ret) { - goto out; - } + XML_RET_CHECK_AND_GOTO (ret, out); ret = cli_end_xml_output (local->writer, local->doc); @@ -3266,7 +3279,7 @@ cli_xml_output_peer_hostnames (xmlTextWriterPtr writer, dict_t *dict, /* </hostnames> */ ret = xmlTextWriterEndElement (writer); - + XML_RET_CHECK_AND_GOTO (ret, out); out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); return ret; @@ -3470,6 +3483,7 @@ cli_xml_output_vol_rebalance_status (xmlTextWriterPtr writer, dict_t *dict, ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"nodeName", "%s", node_name); + XML_RET_CHECK_AND_GOTO (ret, out); memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "node-uuid-%d", i); @@ -3554,6 +3568,7 @@ cli_xml_output_vol_rebalance_status (xmlTextWriterPtr writer, dict_t *dict, (xmlChar *)"statusStr", "%s", cli_vol_task_status_str[status_rcd]); + XML_RET_CHECK_AND_GOTO (ret, out); memset (key, 0, 256); snprintf (key, 256, "run-time-%d", i); @@ -5767,7 +5782,6 @@ cli_xml_snapshot_delete (xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict, ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "status", "Success"); - XML_RET_CHECK_AND_GOTO (ret, xmlend); } else { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "status", @@ -5777,9 +5791,8 @@ cli_xml_snapshot_delete (xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict, ret = cli_xml_output_common (writer, rsp->op_ret, rsp->op_errno, rsp->op_errstr); - XML_RET_CHECK_AND_GOTO (ret, xmlend); } - + XML_RET_CHECK_AND_GOTO (ret, xmlend); ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "name", "%s", str_value); diff --git a/cli/src/cli.h b/cli/src/cli.h index 8acec640c83..b59e254d44f 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -62,9 +62,10 @@ typedef enum { #define GLUSTER_MODE_WIGNORE (1 << 3) -#define GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH(abspath, volname, path) \ - snprintf (abspath, sizeof (abspath)-1, \ - DEFAULT_VAR_RUN_DIRECTORY"/%s%s", volname, path); +#define GLUSTERD_GET_QUOTA_LIST_MOUNT_PATH(abspath, volname, path) do { \ + snprintf (abspath, sizeof (abspath)-1, \ + DEFAULT_VAR_RUN_DIRECTORY"/%s_quota_list%s", volname, path);\ + } while (0) struct cli_state; struct cli_cmd_word; diff --git a/configure.ac b/configure.ac index 8b369f52e36..97eb137c752 100644 --- a/configure.ac +++ b/configure.ac @@ -1057,24 +1057,24 @@ old_prefix=$prefix if test "x$prefix" = xNONE; then prefix=$ac_default_prefix fi -GLUSTERFS_LIBEXECDIR="$(eval echo $prefix)/libexec/glusterfs" -GLUSTERFSD_MISCDIR="$(eval echo $prefix)/var/lib/misc/glusterfsd" +GLUSTERFS_LIBEXECDIR="$libexecdir/glusterfs" +GLUSTERFSD_MISCDIR="$prefix/var/lib/misc/glusterfsd" prefix=$old_prefix ### Dirty hacky stuff to make LOCALSTATEDIR work if test "x$prefix" = xNONE; then - test $localstatedir = '${prefix}/var' && localstatedir=$ac_default_prefix/var + test $localstatedir = '$prefix/var' && localstatedir=$ac_default_prefix/var localstatedir=/var - LOCALSTATEDIR=$(eval echo ${localstatedir}) + LOCALSTATEDIR=$localstatedir else - LOCALSTATEDIR=$(eval echo ${localstatedir}) + LOCALSTATEDIR=$localstatedir fi old_prefix=$prefix if test "x$prefix" = xNONE; then prefix=$ac_default_prefix fi -GLUSTERD_VOLFILE="$(eval echo ${sysconfdir})/glusterfs/glusterd.vol" +GLUSTERD_VOLFILE="$sysconfdir/glusterfs/glusterd.vol" prefix=$old_prefix diff --git a/doc/release-notes/3.8.11.md b/doc/release-notes/3.8.11.md new file mode 100644 index 00000000000..1d368469906 --- /dev/null +++ b/doc/release-notes/3.8.11.md @@ -0,0 +1,26 @@ +# Release notes for Gluster 3.8.11 + +This is a bugfix release. The [Release Notes for 3.8.0](3.8.0.md), +[3.8.1](3.8.1.md), [3.8.2](3.8.2.md), [3.8.3](3.8.3.md), [3.8.4](3.8.4.md), +[3.8.5](3.8.5.md), [3.8.6](3.8.6.md), [3.8.7](3.8.7.md), [3.8.8](3.8.8.md), +[3.8.9](3.8.9.md) and [3.8.10](3.8.10.md) contain a listing of all the new +features that were added and bugs fixed in the GlusterFS 3.8 stable release. + + +## Bugs addressed + +A total of 15 patches have been merged, addressing 13 bugs: + +- [#1422788](https://bugzilla.redhat.com/1422788): [Replicate] "RPC call decoding failed" leading to IO hang & mount inaccessible +- [#1427390](https://bugzilla.redhat.com/1427390): systemic testing: seeing lot of ping time outs which would lead to splitbrains +- [#1430845](https://bugzilla.redhat.com/1430845): build/packaging: Debian and Ubuntu don't have /usr/libexec/; results in bad packages +- [#1431592](https://bugzilla.redhat.com/1431592): memory leak in features/locks xlator +- [#1434298](https://bugzilla.redhat.com/1434298): [Disperse] Metadata version is not healing when a brick is down +- [#1434302](https://bugzilla.redhat.com/1434302): Move spit-brain msg in read txn to debug +- [#1435645](https://bugzilla.redhat.com/1435645): Disperse: Provide description of disperse.eager-lock option. +- [#1436231](https://bugzilla.redhat.com/1436231): Undo pending xattrs only on the up bricks +- [#1436412](https://bugzilla.redhat.com/1436412): Unrecognized filesystems (i.e. btrfs, zfs) log many errors about "getinode size" +- [#1437330](https://bugzilla.redhat.com/1437330): Sharding: Fix a performance bug +- [#1438424](https://bugzilla.redhat.com/1438424): [Ganesha + EC] : Input/Output Error while creating LOTS of smallfiles +- [#1439112](https://bugzilla.redhat.com/1439112): File-level WORM allows ftruncate() on read-only files +- [#1440635](https://bugzilla.redhat.com/1440635): Application VMs with their disk images on sharded-replica 3 volume are unable to boot after performing rebalance diff --git a/doc/release-notes/3.8.12.md b/doc/release-notes/3.8.12.md new file mode 100644 index 00000000000..06ed30cc5de --- /dev/null +++ b/doc/release-notes/3.8.12.md @@ -0,0 +1,25 @@ +# Release notes for Gluster 3.8.12 + +This is a bugfix release. The [Release Notes for 3.8.0](3.8.0.md), +[3.8.1](3.8.1.md), [3.8.2](3.8.2.md), [3.8.3](3.8.3.md), [3.8.4](3.8.4.md), +[3.8.5](3.8.5.md), [3.8.6](3.8.6.md), [3.8.7](3.8.7.md), [3.8.8](3.8.8.md), +[3.8.9](3.8.9.md), [3.8.10](3.8.10.md) and [3.8.11](3.8.11.md) contain a +listing of all the new features that were added and bugs fixed in the GlusterFS +3.8 stable release. + + +## Bugs addressed + +A total of 13 patches have been merged, addressing 11 bugs: + +- [#1440228](https://bugzilla.redhat.com/1440228): NFS Sub-directory mount not working on solaris10 client +- [#1440635](https://bugzilla.redhat.com/1440635): Application VMs with their disk images on sharded-replica 3 volume are unable to boot after performing rebalance +- [#1440810](https://bugzilla.redhat.com/1440810): Update rfc.sh to check Change-Id consistency for backports +- [#1441574](https://bugzilla.redhat.com/1441574): [geo-rep]: rsync should not try to sync internal xattrs +- [#1441930](https://bugzilla.redhat.com/1441930): [geo-rep]: Worker crashes with [Errno 16] Device or resource busy: '.gfid/00000000-0000-0000-0000-000000000001/dir.166 while renaming directories +- [#1441933](https://bugzilla.redhat.com/1441933): [Geo-rep] If for some reason MKDIR failed to sync, it should not proceed further. +- [#1442933](https://bugzilla.redhat.com/1442933): Segmentation fault when creating a qcow2 with qemu-img +- [#1443012](https://bugzilla.redhat.com/1443012): snapshot: snapshots appear to be failing with respect to secure geo-rep slave +- [#1443319](https://bugzilla.redhat.com/1443319): Don't wind post-op on a brick where the fop phase failed. +- [#1445213](https://bugzilla.redhat.com/1445213): Unable to take snapshot on a geo-replicated volume, even after stopping the session +- [#1449314](https://bugzilla.redhat.com/1449314): [whql][virtio-block+glusterfs]"Disk Stress" and "Disk Verification" job always failed on win7-32/win2012/win2k8R2 guest diff --git a/doc/release-notes/3.8.13.md b/doc/release-notes/3.8.13.md new file mode 100644 index 00000000000..15f85598626 --- /dev/null +++ b/doc/release-notes/3.8.13.md @@ -0,0 +1,22 @@ +# Release notes for Gluster 3.8.13 + +This is a bugfix release. The [Release Notes for 3.8.0](3.8.0.md), +[3.8.1](3.8.1.md), [3.8.2](3.8.2.md), [3.8.3](3.8.3.md), [3.8.4](3.8.4.md), +[3.8.5](3.8.5.md), [3.8.6](3.8.6.md), [3.8.7](3.8.7.md), [3.8.8](3.8.8.md), +[3.8.9](3.8.9.md), [3.8.10](3.8.10.md), [3.8.11](3.8.11.md) and +[3.8.12](3.8.12.md) contain a listing of all the new features that were added +and bugs fixed in the GlusterFS 3.8 stable release. + + +## Bugs addressed + +A total of 13 patches have been merged, addressing 8 bugs: + +- [#1447523](https://bugzilla.redhat.com/1447523): Glusterd segmentation fault in ' _Unwind_Backtrace' while running peer probe +- [#1449782](https://bugzilla.redhat.com/1449782): quota: limit-usage command failed with error " Failed to start aux mount" +- [#1449941](https://bugzilla.redhat.com/1449941): When either killing or restarting a brick with performance.stat-prefetch on, stat sometimes returns a bad st_size value. +- [#1450055](https://bugzilla.redhat.com/1450055): [GANESHA] Adding a node to existing cluster failed to start pacemaker service on new node +- [#1450380](https://bugzilla.redhat.com/1450380): GNFS crashed while taking lock on a file from 2 different clients having same volume mounted from 2 different servers +- [#1450937](https://bugzilla.redhat.com/1450937): [New] - Replacing an arbiter brick while I/O happens causes vm pause +- [#1460650](https://bugzilla.redhat.com/1460650): posix-acl: Whitelist virtual ACL xattrs +- [#1460661](https://bugzilla.redhat.com/1460661): "split-brain observed [Input/output error]" error messages in samba logs during parallel rm -rf diff --git a/doc/release-notes/3.8.14.md b/doc/release-notes/3.8.14.md new file mode 100644 index 00000000000..46868c21675 --- /dev/null +++ b/doc/release-notes/3.8.14.md @@ -0,0 +1,16 @@ +# Release notes for Gluster 3.8.14 + +This is a bugfix release. The [Release Notes for 3.8.0](3.8.0.md), +[3.8.1](3.8.1.md), [3.8.2](3.8.2.md), [3.8.3](3.8.3.md), [3.8.4](3.8.4.md), +[3.8.5](3.8.5.md), [3.8.6](3.8.6.md), [3.8.7](3.8.7.md), [3.8.8](3.8.8.md), +[3.8.9](3.8.9.md), [3.8.10](3.8.10.md), [3.8.11](3.8.11.md), +[3.8.12](3.8.12.md) and [3.8.13](3.8.13.md) contain a listing of all the new +features that were added and bugs fixed in the GlusterFS 3.8 stable release. + + +## Bugs addressed + +A total of 3 patches have been merged, addressing 2 bugs: + +- [#1462447](https://bugzilla.redhat.com/1462447): brick maintenance - no client reconnect +- [#1467272](https://bugzilla.redhat.com/1467272): Heal info shows incorrect status diff --git a/doc/release-notes/3.8.15.md b/doc/release-notes/3.8.15.md new file mode 100644 index 00000000000..f8ddf5c74c4 --- /dev/null +++ b/doc/release-notes/3.8.15.md @@ -0,0 +1,30 @@ +# Release notes for Gluster 3.8.15 + +This is a bugfix release. The [Release Notes for 3.8.0](3.8.0.md), +[3.8.1](3.8.1.md), [3.8.2](3.8.2.md), [3.8.3](3.8.3.md), [3.8.4](3.8.4.md), +[3.8.5](3.8.5.md), [3.8.6](3.8.6.md), [3.8.7](3.8.7.md), [3.8.8](3.8.8.md), +[3.8.9](3.8.9.md), [3.8.10](3.8.10.md), [3.8.11](3.8.11.md), +[3.8.12](3.8.12.md), [3.8.13](3.8.13.md) and [3.8.14](3.8.14.md) contain a +listing of all the new features that were added and bugs fixed in the GlusterFS +3.8 stable release. + + +## End Of Life Notice + +This is most likely the last bugfix release for the GlusterFS 3.8 +Long-Term-Support version. GlusterFS 3.12 is planned to be released at the end +of August 2017 and will be the next Long-Term-Support version. It is highly +recommended to upgrade any Gluster 3.8 environment to either the 3.10 or 3.12 +release. More details about the different Long-Term-Support versions can be +found on the [release +schedule](https://www.gluster.org/community/release-schedule/). + + +## Bugs addressed + +A total of 4 patches have been merged, addressing 4 bugs: + +- [#1470495](https://bugzilla.redhat.com/1470495): gluster volume status --xml fails when there are 100 volumes +- [#1471613](https://bugzilla.redhat.com/1471613): metadata heal not happening despite having an active sink +- [#1480193](https://bugzilla.redhat.com/1480193): Running sysbench on vm disk from plain distribute gluster volume causes disk corruption +- [#1481398](https://bugzilla.redhat.com/1481398): libgfapi: memory leak in glfs_h_acl_get diff --git a/extras/Makefile.am b/extras/Makefile.am index 609d497f5b8..5ebb45a9a79 100644 --- a/extras/Makefile.am +++ b/extras/Makefile.am @@ -1,4 +1,4 @@ -addonexecdir = $(libexecdir)/glusterfs +addonexecdir = $(GLUSTERFS_LIBEXECDIR) addonexec_SCRIPTS = peer_add_secret_pub EditorModedir = $(docdir) diff --git a/extras/ganesha/scripts/ganesha-ha.sh b/extras/ganesha/scripts/ganesha-ha.sh index 0692df8f5dd..4b9d8a3891a 100644 --- a/extras/ganesha/scripts/ganesha-ha.sh +++ b/extras/ganesha/scripts/ganesha-ha.sh @@ -161,25 +161,8 @@ determine_servers() } -setup_cluster() +start_cluster() { - local name=${1} - local num_servers=${2} - local servers=${3} - local unclean="" - local quorum_policy="stop" - - - logger "setting up cluster ${name} with the following ${servers}" - - pcs cluster auth ${servers} - # pcs cluster setup --name ${name} ${servers} - pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} --transport udpu ${servers} - if [ $? -ne 0 ]; then - logger "pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} ${servers} failed" - exit 1; - fi - # BZ 1284404, 1425110, allow time for SSL certs to propagate, until then # pcsd will not accept connections. sleep 12 @@ -202,6 +185,29 @@ setup_cluster() unclean=$(pcs status | grep -u "UNCLEAN") done sleep 1 +} + + +setup_cluster() +{ + local name=${1} + local num_servers=${2} + local servers=${3} + local unclean="" + local quorum_policy="stop" + + + logger "setting up cluster ${name} with the following ${servers}" + + pcs cluster auth ${servers} + # pcs cluster setup --name ${name} ${servers} + pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} --transport udpu ${servers} + if [ $? -ne 0 ]; then + logger "pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} ${servers} failed" + exit 1; + fi + + start_cluster if [ ${num_servers} -lt 3 ]; then quorum_policy="ignore" @@ -1047,7 +1053,7 @@ main() # from the entries in the ganesha-ha.conf file. Adding the # newly added node to the file so that the resources specfic # to this node is correctly recreated in the future. - clean_node=${node//[-.]/_} + clean_node=${node//[.]/_} echo "VIP_$clean_node=\"${vip}\"" >> ${HA_CONFDIR}/ganesha-ha.conf NEW_NODES="$HA_CLUSTER_NODES,${node}" diff --git a/geo-replication/src/Makefile.am b/geo-replication/src/Makefile.am index 1572698f8ae..04355bf8d52 100644 --- a/geo-replication/src/Makefile.am +++ b/geo-replication/src/Makefile.am @@ -1,4 +1,4 @@ -gsyncddir = $(libexecdir)/glusterfs +gsyncddir = $(GLUSTERFS_LIBEXECDIR) gsyncd_SCRIPTS = gverify.sh peer_gsec_create \ set_geo_rep_pem_keys.sh peer_mountbroker @@ -19,7 +19,7 @@ noinst_HEADERS = procdiggy.h AM_CPPFLAGS = $(GF_CPPFLAGS) \ -I$(top_srcdir)/libglusterfs/src\ - -DGSYNCD_PREFIX=\"$(libexecdir)/glusterfs\"\ + -DGSYNCD_PREFIX=\"$(GLUSTERFS_LIBEXECDIR)\"\ -DUSE_LIBGLUSTERFS\ -DSBIN_DIR=\"$(sbindir)\" -DPYTHON=\"$(PYTHON)\" diff --git a/geo-replication/syncdaemon/Makefile.am b/geo-replication/syncdaemon/Makefile.am index ed0f5e40924..6449d9ecc18 100644 --- a/geo-replication/syncdaemon/Makefile.am +++ b/geo-replication/syncdaemon/Makefile.am @@ -1,4 +1,4 @@ -syncdaemondir = $(libexecdir)/glusterfs/python/syncdaemon +syncdaemondir = $(GLUSTERFS_LIBEXECDIR)/python/syncdaemon syncdaemon_PYTHON = gconf.py gsyncd.py __init__.py master.py README.md repce.py \ resource.py configinterface.py syncdutils.py monitor.py libcxattr.py \ diff --git a/geo-replication/syncdaemon/master.py b/geo-replication/syncdaemon/master.py index 6437dcc4295..f7667cf0cf6 100644 --- a/geo-replication/syncdaemon/master.py +++ b/geo-replication/syncdaemon/master.py @@ -783,6 +783,9 @@ class GMasterChangelogMixin(GMasterCommon): num_failures += 1 logging.error('%s FAILED: %s' % (log_prefix, repr(failure))) + if failure[0]['op'] == 'MKDIR': + raise GsyncdError("The above directory failed to sync." + " Please fix it to proceed further.") self.status.inc_value("failures", num_failures) diff --git a/geo-replication/syncdaemon/resource.py b/geo-replication/syncdaemon/resource.py index ecb94d56c7f..3e4be2b9cc9 100644 --- a/geo-replication/syncdaemon/resource.py +++ b/geo-replication/syncdaemon/resource.py @@ -24,7 +24,7 @@ import tempfile import threading import subprocess from errno import EEXIST, ENOENT, ENODATA, ENOTDIR, ELOOP -from errno import EISDIR, ENOTEMPTY, ESTALE, EINVAL +from errno import EISDIR, ENOTEMPTY, ESTALE, EINVAL, EBUSY from select import error as SelectError import shutil @@ -618,11 +618,12 @@ class Server(object): if not matching_disk_gfid(gfid, entry): return - er = errno_wrap(os.unlink, [entry], [ENOENT, ESTALE, EISDIR]) + er = errno_wrap(os.unlink, [entry], [ENOENT, ESTALE, EISDIR], + [EBUSY]) if isinstance(er, int): if er == EISDIR: er = errno_wrap(os.rmdir, [entry], [ENOENT, ESTALE, - ENOTEMPTY]) + ENOTEMPTY], [EBUSY]) if er == ENOTEMPTY: return er @@ -630,16 +631,19 @@ class Server(object): # We do this for failing fops on Slave # Master should be logging this if cmd_ret is None: - return + return False if cmd_ret == EEXIST: disk_gfid = cls.gfid_mnt(e['entry']) - if isinstance(disk_gfid, basestring): - if e['gfid'] != disk_gfid: - failures.append((e, cmd_ret, disk_gfid)) + if isinstance(disk_gfid, basestring) and e['gfid'] != disk_gfid: + failures.append((e, cmd_ret, disk_gfid)) + else: + return False else: failures.append((e, cmd_ret)) + return True + failures = [] def matching_disk_gfid(gfid, entry): @@ -674,7 +678,7 @@ class Server(object): if not matching_disk_gfid(gfid, entry): return er = errno_wrap(os.remove, [fullname], [ENOENT, ESTALE, - EISDIR]) + EISDIR], [EBUSY]) if er == EISDIR: recursive_rmdir(gfid, entry, fullname) @@ -682,7 +686,7 @@ class Server(object): if not matching_disk_gfid(gfid, entry): return - errno_wrap(os.rmdir, [path], [ENOENT, ESTALE]) + errno_wrap(os.rmdir, [path], [ENOENT, ESTALE], [EBUSY]) def rename_with_disk_gfid_confirmation(gfid, entry, en): if not matching_disk_gfid(gfid, entry): @@ -695,7 +699,7 @@ class Server(object): cmd_ret = errno_wrap(os.rename, [entry, en], - [ENOENT, EEXIST], [ESTALE]) + [ENOENT, EEXIST], [ESTALE, EBUSY]) collect_failure(e, cmd_ret) @@ -785,12 +789,12 @@ class Server(object): # we have a hard link, we can now unlink source try: errno_wrap(os.unlink, [entry], - [ENOENT, ESTALE]) + [ENOENT, ESTALE], [EBUSY]) except OSError as e: if e.errno == EISDIR: try: errno_wrap(os.rmdir, [entry], - [ENOENT, ESTALE]) + [ENOENT, ESTALE], [EBUSY]) except OSError as e: if e.errno == ENOTEMPTY: logging.error( @@ -808,8 +812,16 @@ class Server(object): cmd_ret = errno_wrap(Xattr.lsetxattr, [pg, 'glusterfs.gfid.newfile', blob], [EEXIST, ENOENT], - [ESTALE, EINVAL]) - collect_failure(e, cmd_ret) + [ESTALE, EINVAL, EBUSY]) + failed = collect_failure(e, cmd_ret) + + # If directory creation is failed, return immediately before + # further processing. Allowing it to further process will + # cause the entire directory tree to fail syncing to slave. + # Hence master will log and raise exception if it's + # directory failure. + if failed and op == 'MKDIR': + return failures # If UID/GID is different than zero that means we are trying # create Entry with different UID/GID. Create Entry with @@ -818,7 +830,7 @@ class Server(object): path = os.path.join(pfx, gfid) cmd_ret = errno_wrap(os.chown, [path, uid, gid], [ENOENT], [ESTALE, EINVAL]) - collect_failure(e, cmd_ret) + collect_failure(e, cmd_ret) return failures diff --git a/geo-replication/syncdaemon/syncdutils.py b/geo-replication/syncdaemon/syncdutils.py index 987e1bf186e..08450695a84 100644 --- a/geo-replication/syncdaemon/syncdutils.py +++ b/geo-replication/syncdaemon/syncdutils.py @@ -18,7 +18,7 @@ import logging import socket from threading import Lock, Thread as baseThread from errno import EACCES, EAGAIN, EPIPE, ENOTCONN, ECONNABORTED -from errno import EINTR, ENOENT, EPERM, ESTALE, errorcode +from errno import EINTR, ENOENT, EPERM, ESTALE, EBUSY, errorcode from signal import signal, SIGTERM import select as oselect from os import waitpid as owaitpid @@ -487,12 +487,12 @@ def errno_wrap(call, arg=[], errnos=[], retry_errnos=[]): # probably a screwed state, cannot do much... logging.warn('reached maximum retries (%s)...%s' % (repr(arg), ex)) - return ex.errno + raise time.sleep(0.250) # retry the call def lstat(e): - return errno_wrap(os.lstat, [e], [ENOENT], [ESTALE]) + return errno_wrap(os.lstat, [e], [ENOENT], [ESTALE, EBUSY]) class NoPurgeTimeAvailable(Exception): pass diff --git a/heal/src/glfs-heal.c b/heal/src/glfs-heal.c index c65682a5517..8236c693b8e 100644 --- a/heal/src/glfs-heal.c +++ b/heal/src/glfs-heal.c @@ -876,6 +876,11 @@ glfsh_set_heal_options (glfs_t *fs, gf_xl_afr_op_t heal_op) { int ret = 0; + ret = glfs_set_xlator_option (fs, "*-replicate-*", + "background-self-heal-count", "0"); + if (ret) + goto out; + if ((heal_op != GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE) && (heal_op != GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) && (heal_op != GF_SHD_OP_SBRAIN_HEAL_FROM_LATEST_MTIME)) @@ -892,6 +897,7 @@ glfsh_set_heal_options (glfs_t *fs, gf_xl_afr_op_t heal_op) ret = glfs_set_xlator_option (fs, "*-replicate-*", "entry-self-heal", "on"); + out: return ret; } diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 6a5889207d4..e533992556b 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -3019,14 +3019,14 @@ gf_ports_reserved (char *blocked_port, gf_boolean_t *ports, uint32_t ceiling) { gf_boolean_t result = _gf_false; char *range_port = NULL; - int16_t tmp_port1 = -1; - int16_t tmp_port2 = -1; + int32_t tmp_port1 = -1; + int32_t tmp_port2 = -1; if (strstr (blocked_port, "-") == NULL) { /* get rid of the new line character*/ if (blocked_port[strlen(blocked_port) -1] == '\n') blocked_port[strlen(blocked_port) -1] = '\0'; - if (gf_string2int16 (blocked_port, &tmp_port1) == 0) { + if (gf_string2int32 (blocked_port, &tmp_port1) == 0) { if (tmp_port1 > ceiling || tmp_port1 < 0) { gf_msg ("glusterfs-socket", GF_LOG_WARNING, 0, @@ -3052,7 +3052,7 @@ gf_ports_reserved (char *blocked_port, gf_boolean_t *ports, uint32_t ceiling) result = _gf_true; goto out; } - if (gf_string2int16 (range_port, &tmp_port1) == 0) { + if (gf_string2int32 (range_port, &tmp_port1) == 0) { if (tmp_port1 > ceiling) tmp_port1 = ceiling; if (tmp_port1 < 0) @@ -3066,7 +3066,7 @@ gf_ports_reserved (char *blocked_port, gf_boolean_t *ports, uint32_t ceiling) /* get rid of the new line character*/ if (range_port[strlen(range_port) -1] == '\n') range_port[strlen(range_port) - 1] = '\0'; - if (gf_string2int16 (range_port, &tmp_port2) == 0) { + if (gf_string2int32 (range_port, &tmp_port2) == 0) { if (tmp_port2 > ceiling) tmp_port2 = ceiling; if (tmp_port2 < 0) @@ -46,6 +46,72 @@ is_num() [ -z "$(echo $num | sed -e 's/[0-9]//g')" ] } +backport_id_message() +{ + echo "" + echo "This commit is to a non-master branch, and hence is treated as a backport." + echo "" + echo "For backports we would like to retain the same gerrit Change-Id across" + echo "branches. On auto inspection it is found that a gerrit Change-Id is" + echo "missing, or the Change-Id is not found on your local master" + echo "" + echo "This could mean a few things:" + echo " 1. This is not a backport, hence choose Y on the prompt to proceed" + echo " 2. Your origin master is not up to date, hence the script is unable" + echo " to find the corresponding Change-Id on master. Either choose N," + echo " 'git fetch', and try again, OR if you are sure you used the" + echo " same Change-Id, choose Y at the prompt to proceed" + echo " 3. You commented or removed the Change-Id in your commit message after" + echo " cherry picking the commit. Choose N, fix the commit message to" + echo " use the same Change-Id as master (git commit --amend), resubmit" + echo "" +} + +check_backport() +{ + moveon='N' + + # Backports are never made to master + if [ $branch = "master" ]; then + return; + fi + + # Extract the change ID from the commit message + changeid=$(git show --format='%b' | grep -i '^Change-Id: ' | awk '{print $2}') + + # If there is no change ID ask if we should continue + if [ -z "$changeid" ]; then + backport_id_message; + echo -n "Did not find a Change-Id for a possible backport. Continue (y/N): " + read moveon + else + # Search master for the same change ID (rebase_changes has run, so we + # should never not find a Change-Id) + mchangeid=$(git log origin/master --format='%b' --grep="^Change-Id: ${changeid}" | grep ${changeid} | awk '{print $2}') + + # Check if we found the change ID on master, else throw a message to + # decide if we should continue. + # NOTE: If master was not rebased, we will not find the Change-ID and + # could hit a false positive case here (or if someone checks out some + # other branch as master). + if [ $mchangeid = $changeid ]; then + moveon="Y" + else + backport_id_message; + echo "Change-Id of commit: $changeid" + echo "Change-Id on master: $mchangeid" + echo -n "Did not find mentioned Change-Id on master for a possible backport. Continue (y/N): " + read moveon + fi + fi + + if [ "${moveon}" = 'Y' ] || [ "${moveon}" = 'y' ]; then + return; + else + exit 1 + fi +} + rebase_changes() { @@ -139,6 +205,8 @@ main() { set_hooks_commit_msg; + # rfc.sh calls itself from rebase_changes, which uses rfc.sh as the EDITOR + # thus, getting the commit message to work with in the editor_mode. if [ -e "$1" ]; then editor_mode "$@"; return; @@ -148,6 +216,8 @@ main() rebase_changes; + check_backport; + assert_diverge; bug=$(git show --format='%b' | grep -i '^BUG: ' | awk '{print $2}'); diff --git a/rpc/rpc-lib/src/rpc-clnt.c b/rpc/rpc-lib/src/rpc-clnt.c index 014b2a25d11..406efdb2d4f 100644 --- a/rpc/rpc-lib/src/rpc-clnt.c +++ b/rpc/rpc-lib/src/rpc-clnt.c @@ -520,8 +520,10 @@ rpc_clnt_reconnect_cleanup (rpc_clnt_connection_t *conn) if (conn->reconnect) { ret = gf_timer_call_cancel (clnt->ctx, conn->reconnect); - if (!ret) + if (!ret) { reconnect_unref = _gf_true; + conn->cleanup_gen++; + } conn->reconnect = NULL; } @@ -575,6 +577,7 @@ rpc_clnt_connection_cleanup (rpc_clnt_connection_t *conn) /*reset rpc msgs stats*/ conn->pingcnt = 0; conn->msgcnt = 0; + conn->cleanup_gen++; } pthread_mutex_unlock (&conn->lock); @@ -900,10 +903,29 @@ rpc_clnt_destroy (struct rpc_clnt *rpc); static int rpc_clnt_handle_disconnect (struct rpc_clnt *clnt, rpc_clnt_connection_t *conn) { - struct timespec ts = {0, }; - gf_boolean_t unref_clnt = _gf_false; + struct timespec ts = {0, }; + gf_boolean_t unref_clnt = _gf_false; + uint64_t pre_notify_gen = 0, post_notify_gen = 0; - rpc_clnt_connection_cleanup (conn); + pthread_mutex_lock (&conn->lock); + { + pre_notify_gen = conn->cleanup_gen; + } + pthread_mutex_unlock (&conn->lock); + + if (clnt->notifyfn) + clnt->notifyfn (clnt, clnt->mydata, RPC_CLNT_DISCONNECT, NULL); + + pthread_mutex_lock (&conn->lock); + { + post_notify_gen = conn->cleanup_gen; + } + pthread_mutex_unlock (&conn->lock); + + if (pre_notify_gen == post_notify_gen) { + /* program didn't invoke cleanup, so rpc has to do it */ + rpc_clnt_connection_cleanup (conn); + } pthread_mutex_lock (&conn->lock); { @@ -923,8 +945,6 @@ rpc_clnt_handle_disconnect (struct rpc_clnt *clnt, rpc_clnt_connection_t *conn) } pthread_mutex_unlock (&conn->lock); - if (clnt->notifyfn) - clnt->notifyfn (clnt, clnt->mydata, RPC_CLNT_DISCONNECT, NULL); if (unref_clnt) rpc_clnt_ref (clnt); @@ -957,11 +977,7 @@ rpc_clnt_notify (rpc_transport_t *trans, void *mydata, switch (event) { case RPC_TRANSPORT_DISCONNECT: { - pthread_mutex_lock (&clnt->notifylock); - { - rpc_clnt_handle_disconnect (clnt, conn); - } - pthread_mutex_unlock (&clnt->notifylock); + rpc_clnt_handle_disconnect (clnt, conn); break; } @@ -1016,21 +1032,19 @@ rpc_clnt_notify (rpc_transport_t *trans, void *mydata, case RPC_TRANSPORT_CONNECT: { - pthread_mutex_lock (&clnt->notifylock); - { - /* Every time there is a disconnection, processes - * should try to connect to 'glusterd' (ie, default - * port) or whichever port given as 'option remote-port' - * in volume file. */ - /* Below code makes sure the (re-)configured port lasts - * for just one successful attempt */ - conn->config.remote_port = 0; - - if (clnt->notifyfn) - ret = clnt->notifyfn (clnt, clnt->mydata, - RPC_CLNT_CONNECT, NULL); - } - pthread_mutex_unlock (&clnt->notifylock); + + /* Every time there is a disconnection, processes + * should try to connect to 'glusterd' (ie, default + * port) or whichever port given as 'option remote-port' + * in volume file. */ + /* Below code makes sure the (re-)configured port lasts + * for just one successful attempt */ + conn->config.remote_port = 0; + + if (clnt->notifyfn) + ret = clnt->notifyfn (clnt, clnt->mydata, + RPC_CLNT_CONNECT, NULL); + break; } @@ -1154,7 +1168,6 @@ rpc_clnt_new (dict_t *options, xlator_t *owner, char *name, } pthread_mutex_init (&rpc->lock, NULL); - pthread_mutex_init (&rpc->notifylock, NULL); rpc->ctx = ctx; rpc->owner = owner; @@ -1164,7 +1177,6 @@ rpc_clnt_new (dict_t *options, xlator_t *owner, char *name, rpc->reqpool = mem_pool_new (struct rpc_req, reqpool_size); if (rpc->reqpool == NULL) { pthread_mutex_destroy (&rpc->lock); - pthread_mutex_destroy (&rpc->notifylock); GF_FREE (rpc); rpc = NULL; goto out; @@ -1174,7 +1186,6 @@ rpc_clnt_new (dict_t *options, xlator_t *owner, char *name, reqpool_size); if (rpc->saved_frames_pool == NULL) { pthread_mutex_destroy (&rpc->lock); - pthread_mutex_destroy (&rpc->notifylock); mem_pool_destroy (rpc->reqpool); GF_FREE (rpc); rpc = NULL; @@ -1184,7 +1195,6 @@ rpc_clnt_new (dict_t *options, xlator_t *owner, char *name, ret = rpc_clnt_connection_init (rpc, ctx, options, name); if (ret == -1) { pthread_mutex_destroy (&rpc->lock); - pthread_mutex_destroy (&rpc->notifylock); mem_pool_destroy (rpc->reqpool); mem_pool_destroy (rpc->saved_frames_pool); GF_FREE (rpc); @@ -1230,6 +1240,33 @@ rpc_clnt_start (struct rpc_clnt *rpc) int +rpc_clnt_cleanup_and_start (struct rpc_clnt *rpc) +{ + struct rpc_clnt_connection *conn = NULL; + + if (!rpc) + return -1; + + conn = &rpc->conn; + + rpc_clnt_connection_cleanup (conn); + + pthread_mutex_lock (&conn->lock); + { + rpc->disabled = 0; + } + pthread_mutex_unlock (&conn->lock); + /* Corresponding unref will be either on successful timer cancel or last + * rpc_clnt_reconnect fire event. + */ + rpc_clnt_ref (rpc); + rpc_clnt_reconnect (conn); + + return 0; +} + + +int rpc_clnt_register_notify (struct rpc_clnt *rpc, rpc_clnt_notify_t fn, void *mydata) { @@ -1780,7 +1817,6 @@ rpc_clnt_destroy (struct rpc_clnt *rpc) saved_frames_destroy (rpc->conn.saved_frames); pthread_mutex_destroy (&rpc->lock); pthread_mutex_destroy (&rpc->conn.lock); - pthread_mutex_destroy (&rpc->notifylock); /* mem-pool should be destroyed, otherwise, it will cause huge memory leaks */ diff --git a/rpc/rpc-lib/src/rpc-clnt.h b/rpc/rpc-lib/src/rpc-clnt.h index 2ccaa56e4cb..5ad4fd42298 100644 --- a/rpc/rpc-lib/src/rpc-clnt.h +++ b/rpc/rpc-lib/src/rpc-clnt.h @@ -151,6 +151,7 @@ struct rpc_clnt_connection { int32_t ping_timeout; uint64_t pingcnt; uint64_t msgcnt; + uint64_t cleanup_gen; }; typedef struct rpc_clnt_connection rpc_clnt_connection_t; @@ -173,7 +174,6 @@ struct rpc_req { typedef struct rpc_clnt { pthread_mutex_t lock; - pthread_mutex_t notifylock; rpc_clnt_notify_t notifyfn; rpc_clnt_connection_t conn; void *mydata; @@ -200,6 +200,8 @@ struct rpc_clnt *rpc_clnt_new (dict_t *options, xlator_t *owner, int rpc_clnt_start (struct rpc_clnt *rpc); +int rpc_clnt_cleanup_and_start (struct rpc_clnt *rpc); + int rpc_clnt_register_notify (struct rpc_clnt *rpc, rpc_clnt_notify_t fn, void *mydata); diff --git a/rpc/rpc-lib/src/rpcsvc.c b/rpc/rpc-lib/src/rpcsvc.c index 617e3cc76ed..bc661043674 100644 --- a/rpc/rpc-lib/src/rpcsvc.c +++ b/rpc/rpc-lib/src/rpcsvc.c @@ -1026,6 +1026,7 @@ int rpcsvc_request_submit (rpcsvc_t *rpc, rpc_transport_t *trans, struct iovec iov = {0, }; struct iobuf *iobuf = NULL; ssize_t xdr_size = 0; + struct iobref *iobref = NULL; if (!req) goto out; @@ -1048,20 +1049,33 @@ int rpcsvc_request_submit (rpcsvc_t *rpc, rpc_transport_t *trans, iov.iov_len = ret; count = 1; + iobref = iobref_new (); + if (!iobref) { + ret = -1; + gf_log ("rpcsvc", GF_LOG_WARNING, "Failed to create iobref"); + goto out; + } + + iobref_add (iobref, iobuf); + ret = rpcsvc_callback_submit (rpc, trans, prog, procnum, - &iov, count); + &iov, count, iobref); out: if (iobuf) iobuf_unref (iobuf); + if (iobref) + iobref_unref (iobref); + return ret; } int rpcsvc_callback_submit (rpcsvc_t *rpc, rpc_transport_t *trans, rpcsvc_cbk_program_t *prog, int procnum, - struct iovec *proghdr, int proghdrcount) + struct iovec *proghdr, int proghdrcount, + struct iobref *iobref) { struct iobuf *request_iob = NULL; struct iovec rpchdr = {0,}; @@ -1069,6 +1083,7 @@ rpcsvc_callback_submit (rpcsvc_t *rpc, rpc_transport_t *trans, int ret = -1; int proglen = 0; uint32_t xid = 0; + gf_boolean_t new_iobref = _gf_false; if (!rpc) { goto out; @@ -1090,11 +1105,22 @@ rpcsvc_callback_submit (rpcsvc_t *rpc, rpc_transport_t *trans, "cannot build rpc-record"); goto out; } + if (!iobref) { + iobref = iobref_new (); + if (!iobref) { + gf_log ("rpcsvc", GF_LOG_WARNING, "Failed to create iobref"); + goto out; + } + new_iobref = 1; + } + + iobref_add (iobref, request_iob); req.msg.rpchdr = &rpchdr; req.msg.rpchdrcount = 1; req.msg.proghdr = proghdr; req.msg.proghdrcount = proghdrcount; + req.msg.iobref = iobref; ret = rpc_transport_submit_request (trans, &req); if (ret == -1) { @@ -1108,6 +1134,9 @@ rpcsvc_callback_submit (rpcsvc_t *rpc, rpc_transport_t *trans, out: iobuf_unref (request_iob); + if (new_iobref) + iobref_unref (iobref); + return ret; } diff --git a/rpc/rpc-lib/src/rpcsvc.h b/rpc/rpc-lib/src/rpcsvc.h index 9a2257a6087..17e72482531 100644 --- a/rpc/rpc-lib/src/rpcsvc.h +++ b/rpc/rpc-lib/src/rpcsvc.h @@ -591,7 +591,8 @@ int rpcsvc_request_submit (rpcsvc_t *rpc, rpc_transport_t *trans, int rpcsvc_callback_submit (rpcsvc_t *rpc, rpc_transport_t *trans, rpcsvc_cbk_program_t *prog, int procnum, - struct iovec *proghdr, int proghdrcount); + struct iovec *proghdr, int proghdrcount, + struct iobref *iobref); rpcsvc_actor_t * rpcsvc_program_actor (rpcsvc_request_t *req); diff --git a/tests/basic/ec/quota.t b/tests/basic/ec/quota.t index b023240b87e..c9612c8b76a 100755 --- a/tests/basic/ec/quota.t +++ b/tests/basic/ec/quota.t @@ -40,7 +40,6 @@ EXPECT_WITHIN $MARKER_UPDATE_TIMEOUT "8.0MB" quotausage "/test" TEST rm $M0/test/file2.txt EXPECT_WITHIN $MARKER_UPDATE_TIMEOUT "0Bytes" quotausage "/test" TEST $CLI volume stop $V0 -EXPECT "1" get_aux rm -f $QDD cleanup; diff --git a/tests/basic/geo-replication/marker-xattrs.t b/tests/basic/geo-replication/marker-xattrs.t index dd5483d7e95..e5b26a6bd5b 100755 --- a/tests/basic/geo-replication/marker-xattrs.t +++ b/tests/basic/geo-replication/marker-xattrs.t @@ -24,11 +24,11 @@ TEST touch $M0 vol_uuid=$(get_volume_mark $M1) xtime=trusted.glusterfs.$vol_uuid.xtime -TEST "getfattr -n $xtime $M1 | grep -q ${xtime}=" +TEST "getfattr -n $xtime $B0/${V0}-1 | grep -q ${xtime}=" TEST kill_brick $V0 $H0 $B0/${V0}-0 -TEST "getfattr -n $xtime $M1 | grep -q ${xtime}=" +TEST "getfattr -n $xtime $B0/${V0}-1 | grep -q ${xtime}=" TEST getfattr -d -m. -e hex $M1 EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0 @@ -61,13 +61,13 @@ vol_uuid=$(get_volume_mark $M1) xtime=trusted.glusterfs.$vol_uuid.xtime stime=trusted.glusterfs.$vol_uuid.stime -stime_val=$(getfattr -e hex -n $xtime $M1 | grep ${xtime}= | cut -f2 -d'=') +stime_val=$(getfattr -e hex -n $xtime $B0/${V0}-1 | grep ${xtime}= | cut -f2 -d'=') TEST "setfattr -n $stime -v $stime_val $B0/${V0}-1" -TEST "getfattr -n $xtime $M1 | grep -q ${xtime}=" +TEST "getfattr -n $xtime $B0/${V0}-1 | grep -q ${xtime}=" TEST kill_brick $V0 $H0 $B0/${V0}-0 -TEST "getfattr -n $xtime $M1 | grep -q ${xtime}=" +TEST "getfattr -n $xtime $B0/${V0}-1 | grep -q ${xtime}=" TEST "getfattr -n $stime $M1 | grep -q ${stime}=" TEST getfattr -d -m. -e hex $M1 @@ -98,12 +98,9 @@ TEST touch $M0 vol_uuid=$(get_volume_mark $M1) xtime=trusted.glusterfs.$vol_uuid.xtime -TEST "getfattr -n $xtime $M1 | grep -q ${xtime}=" +TEST "getfattr -n $xtime $B0/${V0}-0 | grep -q ${xtime}=" -TEST kill_brick $V0 $H0 $B0/${V0}-0 - -#Stripe doesn't tolerate ENOTCONN -TEST ! "getfattr -n $xtime $M1 | grep -q ${xtime}=" +TEST "getfattr -n $xtime $B0/${V0}-1 | grep -q ${xtime}=" EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0 EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M1 diff --git a/tests/basic/quota-ancestry-building.t b/tests/basic/quota-ancestry-building.t index 99c971859e8..5d2f4a7dd66 100755 --- a/tests/basic/quota-ancestry-building.t +++ b/tests/basic/quota-ancestry-building.t @@ -65,7 +65,6 @@ exec 5>&- exec 6>&- TEST $CLI volume stop $V0 -EXPECT "1" get_aux rm -f $QDD cleanup; diff --git a/tests/basic/quota-anon-fd-nfs.t b/tests/basic/quota-anon-fd-nfs.t index 52bce4b08aa..a6dec6bfcf8 100755 --- a/tests/basic/quota-anon-fd-nfs.t +++ b/tests/basic/quota-anon-fd-nfs.t @@ -99,7 +99,6 @@ $CLI volume statedump $V0 all EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $N0 TEST $CLI volume stop $V0 -EXPECT "1" get_aux rm -f $QDD diff --git a/tests/basic/quota-nfs.t b/tests/basic/quota-nfs.t index 74fde400bd1..663a8da90ad 100755 --- a/tests/basic/quota-nfs.t +++ b/tests/basic/quota-nfs.t @@ -58,7 +58,6 @@ TEST rm -f $N0/$deep/newfile_2 EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" umount_nfs $N0 TEST $CLI volume stop $V0 -EXPECT "1" get_aux rm -f $QDD cleanup; diff --git a/tests/basic/quota.t b/tests/basic/quota.t index c902eaa1fe1..99af5a4e7e4 100755 --- a/tests/basic/quota.t +++ b/tests/basic/quota.t @@ -41,12 +41,8 @@ EXPECT 'on' volinfo_field $V0 'features.quota' EXPECT 'on' volinfo_field $V0 'features.inode-quota' EXPECT 'on' volinfo_field $V0 'features.quota-deem-statfs' -#Wait for the auxiliarymount to come up -sleep 3 TEST $CLI volume quota $V0 limit-usage /test_dir 100MB -# Checking for auxiliary mount -EXPECT "0" get_aux TEST $CLI volume quota $V0 limit-usage /test_dir/in_test_dir 150MB @@ -232,9 +228,7 @@ EXPECT 'off' volinfo_field $V0 'features.quota' EXPECT 'off' volinfo_field $V0 'features.inode-quota' EXPECT '' volinfo_field $V0 'features.quota-deem-statfs' -# aux mount should be removed TEST $CLI volume stop $V0; -EXPECT "1" get_aux rm -f $QDD cleanup; diff --git a/tests/basic/quota_aux_mount.t b/tests/basic/quota_aux_mount.t new file mode 100755 index 00000000000..78d7f47e373 --- /dev/null +++ b/tests/basic/quota_aux_mount.t @@ -0,0 +1,53 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; + +##------------------------------------------------------------- +## Tests to verify that aux mount is unmounted after each quota +## command executes. +##------------------------------------------------------------- + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{1,2,3,4}; + +EXPECT "$V0" volinfo_field $V0 'Volume Name'; +EXPECT 'Created' volinfo_field $V0 'Status'; +EXPECT '4' brick_count $V0 + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +TEST $GFS -s $H0 --volfile-id $V0 $M0; + +TEST mkdir -p $M0/test_dir/ + +TEST $CLI volume quota $V0 enable +EXPECT 'on' volinfo_field $V0 'features.quota' +EXPECT 'on' volinfo_field $V0 'features.inode-quota' + +TEST $CLI volume quota $V0 limit-usage /test_dir 150MB +EXPECT "1" get_limit_aux +TEST $CLI volume quota $V0 limit-objects /test_dir 10 +EXPECT "1" get_limit_aux +EXPECT "150.0MB" quota_hard_limit "/test_dir"; +EXPECT "1" get_list_aux +EXPECT "10" quota_object_hard_limit "/test_dir"; +EXPECT "1" get_list_aux + +TEST $CLI volume quota $V0 remove /test_dir/ +EXPECT "1" get_limit_aux +TEST $CLI volume quota $V0 remove-objects /test_dir +EXPECT "1" get_limit_aux + +TEST $CLI volume quota $V0 disable + +TEST $CLI volume stop $V0; + +cleanup; +#G_TESTDEF_TEST_STATUS_NETBSD7=BAD_TEST,BUG=1447344 diff --git a/tests/bugs/cli/bug-1022905.t b/tests/bugs/cli/bug-1022905.t index 1d8981e0e9c..ee629e970d9 100644 --- a/tests/bugs/cli/bug-1022905.t +++ b/tests/bugs/cli/bug-1022905.t @@ -32,7 +32,6 @@ TEST $CLI volume set $V0 diagnostics.client-log-level DEBUG TEST $CLI volume reset $V0 force; TEST $CLI volume stop $V0 -EXPECT "1" get_aux TEST $CLI volume delete $V0 cleanup; diff --git a/tests/bugs/distribute/bug-1099890.t b/tests/bugs/distribute/bug-1099890.t index 29ceccf2309..9f8ae1487cc 100644 --- a/tests/bugs/distribute/bug-1099890.t +++ b/tests/bugs/distribute/bug-1099890.t @@ -125,7 +125,6 @@ EXPECT "1" is_dht_linkfile "$B0/${V0}1/zz" force_umount $M0 TEST $CLI volume stop $V0 -EXPECT "1" get_aux UMOUNT_LOOP ${B0}/${V0}{1,2} rm -f ${B0}/brick{1,2} diff --git a/tests/bugs/distribute/bug-1161156.t b/tests/bugs/distribute/bug-1161156.t index 44a234c60dc..fed90e7f478 100755 --- a/tests/bugs/distribute/bug-1161156.t +++ b/tests/bugs/distribute/bug-1161156.t @@ -50,7 +50,6 @@ TEST ! mv $N0/dir/newfile_3 $N0/newdir/ umount_nfs $N0 TEST $CLI volume stop $V0 -EXPECT "1" get_aux rm -f $QDD diff --git a/tests/bugs/geo-replication/bug-1296496.t b/tests/bugs/geo-replication/bug-1296496.t index 703fda65b84..a157be7849a 100644 --- a/tests/bugs/geo-replication/bug-1296496.t +++ b/tests/bugs/geo-replication/bug-1296496.t @@ -29,7 +29,8 @@ xtime="trusted.glusterfs.$vol_uuid.xtime" #TEST xtime TEST ! getfattr -n $xtime $M0 -TEST getfattr -n $xtime $M1 +TEST getfattr -n $xtime $B0/${V0}-0 +TEST getfattr -n $xtime $B0/${V0}-1 #TEST stime slave_uuid=$(uuidgen) diff --git a/tests/bugs/geo-replication/bug-877293.t b/tests/bugs/geo-replication/bug-877293.t index 542774ab900..c5205e8109e 100755 --- a/tests/bugs/geo-replication/bug-877293.t +++ b/tests/bugs/geo-replication/bug-877293.t @@ -26,11 +26,11 @@ TEST touch $M0 vol_uuid=`getfattr -n trusted.glusterfs.volume-mark -ehex $M1 | sed -n 's/^trusted.glusterfs.volume-mark=0x//p' | cut -b5-36 | sed 's/\([a-f0-9]\{8\}\)\([a-f0-9]\{4\}\)\([a-f0-9]\{4\}\)\([a-f0-9]\{4\}\)/\1-\2-\3-\4-/'` xtime=trusted.glusterfs.$vol_uuid.xtime -TEST "getfattr -n $xtime $M1 | grep -q ${xtime}=" +TEST "getfattr -n $xtime $B0/${V0}-0 | grep -q ${xtime}=" TEST kill_brick $V0 $H0 $B0/${V0}-0 -TEST "getfattr -n $xtime $M1 | grep -q ${xtime}=" +TEST "getfattr -n $xtime $B0/${V0}-1 | grep -q ${xtime}=" EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0 EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M1 diff --git a/tests/bugs/glusterd/bug-1433578-invalid-peer-glusterd-crash.t b/tests/bugs/glusterd/bug-1433578-invalid-peer-glusterd-crash.t new file mode 100644 index 00000000000..1aea8bc134d --- /dev/null +++ b/tests/bugs/glusterd/bug-1433578-invalid-peer-glusterd-crash.t @@ -0,0 +1,14 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc + +cleanup; + +## Start glusterd +TEST glusterd; +TEST pidof glusterd; + +TEST ! $CLI peer probe invalid-peer + +TEST pidof glusterd; +cleanup; diff --git a/tests/bugs/glusterd/bug-1454418-seg-fault.t b/tests/bugs/glusterd/bug-1454418-seg-fault.t new file mode 100644 index 00000000000..eafaa55ede8 --- /dev/null +++ b/tests/bugs/glusterd/bug-1454418-seg-fault.t @@ -0,0 +1,25 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../cluster.rc + + +cleanup; + +## Setting Port number in specific range +sysctl net.ipv4.ip_local_reserved_ports="24007-24008,32765-32768,49152-49156" + +## Start a 2 node virtual cluster +TEST launch_cluster 2; + + +## Peer probe server 2 from server 1 cli +TEST $CLI_1 peer probe $H2; + +EXPECT_WITHIN $PROBE_TIMEOUT 1 peer_count + +sysctl net.ipv4.ip_local_reserved_ports=" +" + +cleanup; + diff --git a/tests/bugs/glusterd/bug-765230-remove-quota-related-option-after-disabling-quota.t b/tests/bugs/glusterd/bug-765230-remove-quota-related-option-after-disabling-quota.t index 9fe55a3d9df..de48c091c7e 100755 --- a/tests/bugs/glusterd/bug-765230-remove-quota-related-option-after-disabling-quota.t +++ b/tests/bugs/glusterd/bug-765230-remove-quota-related-option-after-disabling-quota.t @@ -54,7 +54,6 @@ EXPECT '' volinfo_field $V0 'features.quota-deem-statfs' ## Finish up TEST $CLI volume stop $V0 -EXPECT "1" get_aux EXPECT 'Stopped' volinfo_field $V0 'Status'; TEST $CLI volume delete $V0; diff --git a/tests/bugs/glusterfs/bug-848251.t b/tests/bugs/glusterfs/bug-848251.t index ed3caa34b01..69ffe680f7f 100644 --- a/tests/bugs/glusterfs/bug-848251.t +++ b/tests/bugs/glusterfs/bug-848251.t @@ -48,6 +48,5 @@ EXPECT "80%" quota_list EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $MOUNTDIR TEST rm -rf $MOUNTDIR TEST $CLI volume stop $V0 -EXPECT "1" get_aux cleanup; diff --git a/tests/bugs/posix/bug-990028.t b/tests/bugs/posix/bug-990028.t index d04bb2b4af1..c86421492cd 100755 --- a/tests/bugs/posix/bug-990028.t +++ b/tests/bugs/posix/bug-990028.t @@ -153,6 +153,5 @@ __init; links_in_same_directory; links_across_directories; TEST $CLI volume stop $V0 -EXPECT "1" get_aux cleanup diff --git a/tests/bugs/quota/bug-1087198.t b/tests/bugs/quota/bug-1087198.t index 0694b251d9f..95133085f13 100644 --- a/tests/bugs/quota/bug-1087198.t +++ b/tests/bugs/quota/bug-1087198.t @@ -78,7 +78,6 @@ TEST grep -e "\"Usage is above soft limit:.*used by /\"" -- $BRICK_LOG_DIR/* EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $N0 TEST $CLI volume stop $V0 -EXPECT "1" get_aux rm -f $QDD diff --git a/tests/bugs/replicate/bug-1433571-undo-pending-only-on-up-bricks.t b/tests/bugs/replicate/bug-1433571-undo-pending-only-on-up-bricks.t new file mode 100644 index 00000000000..271abb4fe9a --- /dev/null +++ b/tests/bugs/replicate/bug-1433571-undo-pending-only-on-up-bricks.t @@ -0,0 +1,89 @@ +#!/bin/bash +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +cleanup; + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 replica 3 $H0:$B0/${V0}{0,1,2} +TEST $CLI volume start $V0 +TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0; + +# Disable self-heal-daemon, client-side-heal and set quorum-type to none +TEST $CLI volume set $V0 cluster.self-heal-daemon off +TEST $CLI volume set $V0 cluster.data-self-heal off +TEST $CLI volume set $V0 cluster.metadata-self-heal off +TEST $CLI volume set $V0 cluster.entry-self-heal off +TEST $CLI volume set $V0 cluster.quorum-type none + +#Kill bricks 0 & 1 and create a file to have pending entry for 0 & 1 on brick 2 +TEST kill_brick $V0 $H0 $B0/${V0}0 +TEST kill_brick $V0 $H0 $B0/${V0}1 +echo "file 1" >> $M0/f1 +EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}2 +EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}2 + +TEST $CLI volume start $V0 force +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 0 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 1 + +#Kill bricks 1 & 2 and create a file to have pending entry for 1 & 2 on brick 0 +TEST kill_brick $V0 $H0 $B0/${V0}1 +TEST kill_brick $V0 $H0 $B0/${V0}2 +echo "file 2" >> $M0/f2 +EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}0 +EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}0 + +TEST $CLI volume start $V0 force +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 1 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 2 + +#Kill bricks 2 & 0 and create a file to have pending entry for 2 & 0 on brick 1 +TEST kill_brick $V0 $H0 $B0/${V0}2 +TEST kill_brick $V0 $H0 $B0/${V0}0 +echo "file 3" >> $M0/f3 +EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}1 +EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}1 + +TEST $CLI volume start $V0 force +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 0 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 2 + +#Kill brick 0 and turn on the client side heal and do ls to trigger the heal. +#The pending xattrs on bricks 1 & 2 should have pending entry on brick 0. +TEST kill_brick $V0 $H0 $B0/${V0}0 +TEST $CLI volume set $V0 cluster.data-self-heal on +TEST $CLI volume set $V0 cluster.metadata-self-heal on +TEST $CLI volume set $V0 cluster.entry-self-heal on + +TEST ls $M0 +EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}1 +EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}1 +EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}2 +EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}2 + +#Bring back all the bricks and trigger the heal again by doing ls. Now the +#pending xattrs on all the bricks should be 0. +TEST $CLI volume start $V0 force +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 0 +TEST ls $M0 + +TEST cat $M0/f1 +TEST cat $M0/f2 +TEST cat $M0/f3 + +EXPECT_WITHIN $HEAL_TIMEOUT "^0$" get_pending_heal_count $V0 + +EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}0 +EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}0 +EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}1 +EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}1 +EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}2 +EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}2 + +#Check whether all the bricks contains all the 3 files. +EXPECT "3" echo $(ls $B0/${V0}0 | wc -l) +EXPECT "3" echo $(ls $B0/${V0}1 | wc -l) +EXPECT "3" echo $(ls $B0/${V0}2 | wc -l) + +cleanup; diff --git a/tests/bugs/replicate/bug-1438255-do-not-mark-self-accusing-xattrs.t b/tests/bugs/replicate/bug-1438255-do-not-mark-self-accusing-xattrs.t new file mode 100644 index 00000000000..edfd0d7820d --- /dev/null +++ b/tests/bugs/replicate/bug-1438255-do-not-mark-self-accusing-xattrs.t @@ -0,0 +1,46 @@ +#!/bin/bash +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +cleanup; + +NEW_USER=bug1438255 +NEW_UID=1438255 +NEW_GID=1438255 + +TEST groupadd -o -g ${NEW_GID} ${NEW_USER}-${NEW_GID} +TEST useradd -o -M -u ${NEW_UID} -g ${NEW_GID} -K MAIL_DIR=/dev/null ${NEW_USER} + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 replica 3 $H0:$B0/${V0}{0,1,2} +TEST $CLI volume set $V0 cluster.self-heal-daemon off +TEST $CLI volume set $V0 cluster.data-self-heal off +TEST $CLI volume set $V0 cluster.metadata-self-heal off +TEST $CLI volume set $V0 cluster.entry-self-heal off + +TEST $CLI volume start $V0 +EXPECT 'Started' volinfo_field $V0 'Status' +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0 + +TEST touch $M0/FILE +TEST kill_brick $V0 $H0 $B0/${V0}2 +chown $NEW_UID:$NEW_GID $M0/FILE +EXPECT "000000000000000100000000" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}0/FILE +EXPECT "000000000000000100000000" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}1/FILE +TEST $CLI volume start $V0 force +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 2 + +# setfattr done as NEW_USER fails on 3rd brick with EPERM but suceeds on +# the first 2 and hence on the mount. +su -m bug1438255 -c "setfattr -n user.myattr -v myvalue $M0/FILE" +TEST [ $? -eq 0 ] +EXPECT "000000000000000200000000" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}0/FILE +EXPECT "000000000000000200000000" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}1/FILE +# Brick 3 does not have any self-blaming pending xattr. +TEST ! getfattr -n trusted.afr.$V0-client-2 $B0/${V0}2/FILE + +TEST userdel --force ${NEW_USER} +TEST groupdel ${NEW_USER}-${NEW_GID} +cleanup + + diff --git a/tests/bugs/replicate/bug-1468279-source-not-blaming-sinks.t b/tests/bugs/replicate/bug-1468279-source-not-blaming-sinks.t new file mode 100644 index 00000000000..054a4adb90d --- /dev/null +++ b/tests/bugs/replicate/bug-1468279-source-not-blaming-sinks.t @@ -0,0 +1,64 @@ +#!/bin/bash +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +cleanup; + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 replica 3 $H0:$B0/${V0}{0,1,2} +TEST $CLI volume start $V0 +TEST $CLI volume set $V0 cluster.self-heal-daemon off +TEST $CLI volume set $V0 cluster.metadata-self-heal off +TEST $GFS --volfile-id=$V0 --volfile-server=$H0 --attribute-timeout=0 --entry-timeout=0 $M0; +TEST touch $M0/file + +# Kill B1, create a pending metadata heal. +TEST kill_brick $V0 $H0 $B0/${V0}0 +TEST setfattr -n user.xattr -v value1 $M0/file +EXPECT "0000000000000010000000" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}1/file +EXPECT "0000000000000010000000" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}2/file + +# Kill B2, heal from B3 to B1. +TEST $CLI volume start $V0 force +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 0 +TEST kill_brick $V0 $H0 $B0/${V0}1 +TEST $CLI volume set $V0 cluster.self-heal-daemon on +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 2 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 0 +$CLI volume heal $V0 +EXPECT_WITHIN $HEAL_TIMEOUT "00000000" afr_get_specific_changelog_xattr $B0/${V0}2/file trusted.afr.$V0-client-0 "metadata" +TEST $CLI volume set $V0 cluster.self-heal-daemon off + +# Create another pending metadata heal. +TEST setfattr -n user.xattr -v value2 $M0/file +EXPECT "0000000000000010000000" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}0/file +EXPECT "0000000000000010000000" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}2/file + +# Kill B1, heal from B3 to B2 +TEST $CLI volume start $V0 force +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 1 +TEST kill_brick $V0 $H0 $B0/${V0}0 +TEST $CLI volume set $V0 cluster.self-heal-daemon on +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 2 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 1 +$CLI volume heal $V0 +EXPECT_WITHIN $HEAL_TIMEOUT "00000000" afr_get_specific_changelog_xattr $B0/${V0}2/file trusted.afr.$V0-client-1 "metadata" +TEST $CLI volume set $V0 cluster.self-heal-daemon off + +# ALL bricks up again. +TEST $CLI volume start $V0 force +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 1 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 1 +# B1 and B2 blame each other, B3 doesn't blame anyone. +EXPECT "0000000000000010000000" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}0/file +EXPECT "0000000000000010000000" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}1/file +EXPECT "0000000000000000000000" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}2/file +EXPECT "0000000000000000000000" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}2/file +TEST $CLI volume set $V0 cluster.self-heal-daemon on +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 0 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 1 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 2 +TEST $CLI volume heal $V0 +EXPECT_WITHIN $HEAL_TIMEOUT "^0$" get_pending_heal_count $V0 + +cleanup; diff --git a/tests/bugs/snapshot/bug-1202436-calculate-quota-cksum-during-snap-restore.t b/tests/bugs/snapshot/bug-1202436-calculate-quota-cksum-during-snap-restore.t index 366937245f2..addc05917d8 100644 --- a/tests/bugs/snapshot/bug-1202436-calculate-quota-cksum-during-snap-restore.t +++ b/tests/bugs/snapshot/bug-1202436-calculate-quota-cksum-during-snap-restore.t @@ -27,7 +27,6 @@ EXPECT '1' get_snap_count CLI_1 $V0 TEST $CLI_1 volume stop $V0 EXPECT 'Stopped' volinfo_field $V0 'Status' -EXPECT "1" get_aux TEST $CLI_1 snapshot restore $($CLI_1 snapshot list) EXPECT '0' get_snap_count CLI_1 $V0 diff --git a/tests/volume.rc b/tests/volume.rc index f75d8969e94..84630f3d4b4 100644 --- a/tests/volume.rc +++ b/tests/volume.rc @@ -568,8 +568,9 @@ function num_graphs function get_aux() { ##Check if a auxiliary mount is there +local aux_suffix=$1 local rundir=$(gluster --print-statedumpdir) -local pidfile="${rundir}/${V0}.pid" +local pidfile="${rundir}/${V0}$aux_suffix.pid" if [ -f $pidfile ]; then local pid=$(cat ${rundir}/${V0}.pid) @@ -586,6 +587,18 @@ else fi } +function get_list_aux() +{ +# check for quota list aux mount + get_aux "_quota_list" +} + +function get_limit_aux() +{ +# check for quota list aux mount + get_aux "_quota_limit" +} + function get_bitd_count { ps auxww | grep glusterfs | grep bitd.pid | grep -v grep | wc -l } @@ -664,6 +677,10 @@ function quota_hl_exceeded() } +function quota_object_hard_limit() +{ + quota_object_list_field $1 2 +} function scrub_status() { diff --git a/tools/gfind_missing_files/Makefile.am b/tools/gfind_missing_files/Makefile.am index 043c34c4182..f77f7899efb 100644 --- a/tools/gfind_missing_files/Makefile.am +++ b/tools/gfind_missing_files/Makefile.am @@ -1,4 +1,4 @@ -gfindmissingfilesdir = $(libexecdir)/glusterfs/gfind_missing_files +gfindmissingfilesdir = $(GLUSTERFS_LIBEXECDIR)/gfind_missing_files gfindmissingfiles_SCRIPTS = gfind_missing_files.sh gfid_to_path.sh \ gfid_to_path.py @@ -21,6 +21,6 @@ uninstall-local: install-data-local: rm -f $(DESTDIR)$(sbindir)/gfind_missing_files - ln -s $(libexecdir)/glusterfs/gfind_missing_files/gfind_missing_files.sh $(DESTDIR)$(sbindir)/gfind_missing_files + ln -s $(GLUSTERFS_LIBEXECDIR)/gfind_missing_files/gfind_missing_files.sh $(DESTDIR)$(sbindir)/gfind_missing_files CLEANFILES = diff --git a/tools/glusterfind/Makefile.am b/tools/glusterfind/Makefile.am index 37f23bed1bb..92fa61461ad 100644 --- a/tools/glusterfind/Makefile.am +++ b/tools/glusterfind/Makefile.am @@ -6,7 +6,7 @@ bin_SCRIPTS = glusterfind CLEANFILES = $(bin_SCRIPTS) -deletehookscriptsdir = $(libexecdir)/glusterfs/glusterfind/ +deletehookscriptsdir = $(GLUSTERFS_LIBEXECDIR)/glusterfind/ deletehookscripts_SCRIPTS = S57glusterfind-delete-post.py uninstall-local: @@ -16,5 +16,5 @@ install-data-local: $(mkdir_p) $(DESTDIR)$(GLUSTERD_WORKDIR)/glusterfind/.keys $(mkdir_p) $(DESTDIR)$(GLUSTERD_WORKDIR)/hooks/1/delete/post/ rm -f $(DESTDIR)$(GLUSTERD_WORKDIR)/hooks/1/delete/post/S57glusterfind-delete-post - ln -s $(libexecdir)/glusterfs/glusterfind/S57glusterfind-delete-post.py \ + ln -s $(GLUSTERFS_LIBEXECDIR)/glusterfind/S57glusterfind-delete-post.py \ $(DESTDIR)$(GLUSTERD_WORKDIR)/hooks/1/delete/post/S57glusterfind-delete-post diff --git a/tools/glusterfind/src/Makefile.am b/tools/glusterfind/src/Makefile.am index 541ff946c04..e4469c1c0cf 100644 --- a/tools/glusterfind/src/Makefile.am +++ b/tools/glusterfind/src/Makefile.am @@ -1,4 +1,4 @@ -glusterfinddir = $(libexecdir)/glusterfs/glusterfind +glusterfinddir = $(GLUSTERFS_LIBEXECDIR)/glusterfind glusterfind_PYTHON = conf.py utils.py __init__.py \ main.py libgfchangelog.py changelogdata.py diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 6a9b20d4443..4c2343f8e9b 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -1083,7 +1083,7 @@ refresh_done: } int -afr_inode_refresh_done (call_frame_t *frame, xlator_t *this) +afr_inode_refresh_done (call_frame_t *frame, xlator_t *this, int error) { afr_private_t *priv = NULL; call_frame_t *heal_frame = NULL; @@ -1094,6 +1094,11 @@ afr_inode_refresh_done (call_frame_t *frame, xlator_t *this) int ret = 0; int err = 0; + if (error != 0) { + err = error; + goto refresh_done; + } + local = frame->local; priv = this->private; @@ -1159,7 +1164,7 @@ afr_inode_refresh_subvol_cbk (call_frame_t *frame, void *cookie, xlator_t *this, call_count = afr_frame_return (frame); if (call_count == 0) { afr_set_need_heal (this, local); - afr_inode_refresh_done (frame, this); + afr_inode_refresh_done (frame, this, 0); } } @@ -1250,20 +1255,21 @@ afr_inode_refresh_do (call_frame_t *frame, xlator_t *this) if (local->fd) { fd_ctx = afr_fd_ctx_get (local->fd, this); if (!fd_ctx) { - afr_inode_refresh_done (frame, this); + afr_inode_refresh_done (frame, this, EINVAL); return 0; } } xdata = dict_new (); if (!xdata) { - afr_inode_refresh_done (frame, this); + afr_inode_refresh_done (frame, this, ENOMEM); return 0; } - if (afr_xattr_req_prepare (this, xdata) != 0) { + ret = afr_xattr_req_prepare (this, xdata); + if (ret != 0) { dict_unref (xdata); - afr_inode_refresh_done (frame, this); + afr_inode_refresh_done (frame, this, -ret); return 0; } @@ -1296,7 +1302,10 @@ afr_inode_refresh_do (call_frame_t *frame, xlator_t *this) call_count = local->call_count; if (!call_count) { dict_unref (xdata); - afr_inode_refresh_done (frame, this); + if (local->fd && AFR_COUNT(local->child_up, priv->child_count)) + afr_inode_refresh_done (frame, this, EBADFD); + else + afr_inode_refresh_done (frame, this, ENOTCONN); return 0; } for (i = 0; i < priv->child_count; i++) { @@ -3230,47 +3239,65 @@ afr_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, struct iatt *postbuf, dict_t *xdata) { afr_local_t *local = NULL; + afr_private_t *priv = NULL; + int i = 0; int call_count = -1; int child_index = (long) cookie; int read_subvol = 0; call_stub_t *stub = NULL; local = frame->local; - - read_subvol = afr_data_subvol_get (local->inode, this, NULL, NULL, - NULL, NULL); + priv = this->private; LOCK (&frame->lock); { + local->replies[child_index].valid = 1; + local->replies[child_index].op_ret = op_ret; + local->replies[child_index].op_errno = op_errno; if (op_ret == 0) { - if (local->op_ret == -1) { - local->op_ret = 0; - - local->cont.inode_wfop.prebuf = *prebuf; - local->cont.inode_wfop.postbuf = *postbuf; - - if (xdata) - local->xdata_rsp = dict_ref (xdata); - } - - if (child_index == read_subvol) { - local->cont.inode_wfop.prebuf = *prebuf; - local->cont.inode_wfop.postbuf = *postbuf; - if (xdata) { - if (local->xdata_rsp) - dict_unref (local->xdata_rsp); - local->xdata_rsp = dict_ref (xdata); - } - } - } else { - local->op_errno = op_errno; - } + if (prebuf) + local->replies[child_index].prestat = *prebuf; + if (postbuf) + local->replies[child_index].poststat = *postbuf; + if (xdata) + local->replies[child_index].xdata = + dict_ref (xdata); + } } UNLOCK (&frame->lock); call_count = afr_frame_return (frame); if (call_count == 0) { + local->op_ret = -1; + local->op_errno = afr_final_errno (local, priv); + read_subvol = afr_data_subvol_get (local->inode, this, NULL, + local->readable, NULL, NULL); + /* Pick a reply that is valid and readable, with a preference + * given to read_subvol. */ + for (i = 0; i < priv->child_count; i++) { + if (!local->replies[i].valid) + continue; + if (local->replies[i].op_ret != 0) + continue; + if (!local->readable[i]) + continue; + local->op_ret = local->replies[i].op_ret; + local->op_errno = local->replies[i].op_errno; + local->cont.inode_wfop.prebuf = + local->replies[i].prestat; + local->cont.inode_wfop.postbuf = + local->replies[i].poststat; + if (local->replies[i].xdata) { + if (local->xdata_rsp) + dict_unref (local->xdata_rsp); + local->xdata_rsp = + dict_ref (local->replies[i].xdata); + } + if (i == read_subvol) + break; + } + /* Make a stub out of the frame, and register it with the waking up post-op. When the call-stub resumes, we are guaranteed that there was no post-op pending diff --git a/xlators/cluster/afr/src/afr-dir-write.c b/xlators/cluster/afr/src/afr-dir-write.c index 8e483c382c4..9099b8c1eee 100644 --- a/xlators/cluster/afr/src/afr-dir-write.c +++ b/xlators/cluster/afr/src/afr-dir-write.c @@ -183,7 +183,6 @@ __afr_dir_write_finalize (call_frame_t *frame, xlator_t *this) } } - afr_txn_arbitrate_fop_cbk (frame, this); } diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c index ddc257dbde4..8c312a89e53 100644 --- a/xlators/cluster/afr/src/afr-inode-write.c +++ b/xlators/cluster/afr/src/afr-inode-write.c @@ -131,7 +131,6 @@ __afr_inode_write_finalize (call_frame_t *frame, xlator_t *this) } } - afr_txn_arbitrate_fop_cbk (frame, this); afr_set_in_flight_sb_status (this, local, local->inode); } diff --git a/xlators/cluster/afr/src/afr-read-txn.c b/xlators/cluster/afr/src/afr-read-txn.c index 2390764bccd..a7a2d2999bf 100644 --- a/xlators/cluster/afr/src/afr-read-txn.c +++ b/xlators/cluster/afr/src/afr-read-txn.c @@ -222,9 +222,8 @@ afr_read_txn (call_frame_t *frame, xlator_t *this, inode_t *inode, local->readable, NULL); if (read_subvol < 0 || read_subvol > priv->child_count) { - gf_msg (this->name, GF_LOG_WARNING, 0, AFR_MSG_SPLIT_BRAIN, - "Unreadable subvolume %d found with event generation " - "%d for gfid %s. (Possible split-brain)", + gf_msg_debug (this->name, 0, "Unreadable subvolume %d found " + "with event generation %d for gfid %s.", read_subvol, event_generation, uuid_utoa(inode->gfid)); goto refresh; } diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c index 1df3ddde1cb..629f1c6a7da 100644 --- a/xlators/cluster/afr/src/afr-self-heal-common.c +++ b/xlators/cluster/afr/src/afr-self-heal-common.c @@ -247,7 +247,7 @@ afr_selfheal_undo_pending (call_frame_t *frame, xlator_t *this, inode_t *inode, output_matrix[i][j] = 1; if (type == AFR_ENTRY_TRANSACTION) full_heal_mtx_out[i][j] = 1; - } else { + } else if (locked_on[j]) { output_matrix[i][j] = -input_matrix[i][j]; if (type == AFR_ENTRY_TRANSACTION) full_heal_mtx_out[i][j] = -full_heal_mtx_in[i][j]; diff --git a/xlators/cluster/afr/src/afr-self-heal-data.c b/xlators/cluster/afr/src/afr-self-heal-data.c index 0b4d58dbabc..c1e945bfd82 100644 --- a/xlators/cluster/afr/src/afr-self-heal-data.c +++ b/xlators/cluster/afr/src/afr-self-heal-data.c @@ -562,7 +562,7 @@ __afr_selfheal_data_finalize_source (call_frame_t *frame, xlator_t *this, AFR_DATA_TRANSACTION, locked_on, replies); - return source; + goto out; } /* No split brain at this point. If we were called from diff --git a/xlators/cluster/afr/src/afr-self-heal-metadata.c b/xlators/cluster/afr/src/afr-self-heal-metadata.c index f3fa5d39506..4570ace7ef7 100644 --- a/xlators/cluster/afr/src/afr-self-heal-metadata.c +++ b/xlators/cluster/afr/src/afr-self-heal-metadata.c @@ -241,7 +241,7 @@ __afr_selfheal_metadata_finalize_source (call_frame_t *frame, xlator_t *this, undid_pending, AFR_METADATA_TRANSACTION, locked_on, replies); - return source; + goto out; } /* If this is a directory mtime/ctime only split brain @@ -255,7 +255,7 @@ __afr_selfheal_metadata_finalize_source (call_frame_t *frame, xlator_t *this, uuid_utoa (replies[source].poststat.ia_gfid)); sources[source] = 1; healed_sinks[source] = 0; - return source; + goto out; } if (!priv->metadata_splitbrain_forced_heal) { @@ -314,6 +314,8 @@ __afr_selfheal_metadata_finalize_source (call_frame_t *frame, xlator_t *this, } } +out: + afr_mark_active_sinks (this, sources, locked_on, healed_sinks); return source; } diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c index 8178fc0d18b..9b5063d8aa8 100644 --- a/xlators/cluster/afr/src/afr-transaction.c +++ b/xlators/cluster/afr/src/afr-transaction.c @@ -301,22 +301,21 @@ afr_compute_pre_op_sources (call_frame_t *frame, xlator_t *this) } } -void -afr_txn_arbitrate_fop_cbk (call_frame_t *frame, xlator_t *this) +gf_boolean_t +afr_has_arbiter_fop_cbk_quorum (call_frame_t *frame) { afr_local_t *local = NULL; afr_private_t *priv = NULL; + xlator_t *this = NULL; gf_boolean_t fop_failed = _gf_false; unsigned char *pre_op_sources = NULL; int i = 0; local = frame->local; + this = frame->this; priv = this->private; pre_op_sources = local->transaction.pre_op_sources; - if (priv->arbiter_count != 1 || local->op_ret < 0) - return; - /* If the fop failed on the brick, it is not a source. */ for (i = 0; i < priv->child_count; i++) if (local->transaction.failed_subvols[i]) @@ -332,12 +331,10 @@ afr_txn_arbitrate_fop_cbk (call_frame_t *frame, xlator_t *this) break; } - if (fop_failed) { - local->op_ret = -1; - local->op_errno = ENOTCONN; - } + if (fop_failed) + return _gf_false; - return; + return _gf_true; } void @@ -588,11 +585,17 @@ afr_locked_nodes_get (afr_transaction_type type, afr_internal_lock_t *int_lock) int afr_changelog_call_count (afr_transaction_type type, unsigned char *pre_op_subvols, + unsigned char *failed_subvols, unsigned int child_count) { + int i = 0; int call_count = 0; - call_count = AFR_COUNT(pre_op_subvols, child_count); + for (i = 0; i < child_count; i++) { + if (pre_op_subvols[i] && !failed_subvols[i]) { + call_count++; + } + } if (type == AFR_ENTRY_RENAME_TRANSACTION) call_count *= 2; @@ -779,8 +782,12 @@ afr_handle_quorum (call_frame_t *frame) * no split-brain with the fix. The problem is eliminated completely. */ - if (afr_has_fop_cbk_quorum (frame)) + if (priv->arbiter_count) { + if (afr_has_arbiter_fop_cbk_quorum (frame)) + return; + } else if (afr_has_fop_cbk_quorum (frame)) { return; + } for (i = 0; i < priv->child_count; i++) { if (local->transaction.pre_op[i]) @@ -1244,6 +1251,7 @@ afr_changelog_do (call_frame_t *frame, xlator_t *this, dict_t *xattr, call_count = afr_changelog_call_count (local->transaction.type, local->transaction.pre_op, + local->transaction.failed_subvols, priv->child_count); if (call_count == 0) { @@ -1257,7 +1265,8 @@ afr_changelog_do (call_frame_t *frame, xlator_t *this, dict_t *xattr, local->transaction.changelog_resume = changelog_resume; for (i = 0; i < priv->child_count; i++) { - if (!local->transaction.pre_op[i]) + if (!local->transaction.pre_op[i] || + local->transaction.failed_subvols[i]) continue; switch (local->transaction.type) { diff --git a/xlators/cluster/afr/src/afr-transaction.h b/xlators/cluster/afr/src/afr-transaction.h index ca8fcfefa89..dcdadbc84f4 100644 --- a/xlators/cluster/afr/src/afr-transaction.h +++ b/xlators/cluster/afr/src/afr-transaction.h @@ -16,8 +16,6 @@ void afr_transaction_fop_failed (call_frame_t *frame, xlator_t *this, int child_index); -void -afr_txn_arbitrate_fop_cbk (call_frame_t *frame, xlator_t *this); int afr_lock_server_count (afr_private_t *priv, afr_transaction_type type); diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c index fc5fda6844f..86f667116af 100644 --- a/xlators/cluster/afr/src/afr.c +++ b/xlators/cluster/afr/src/afr.c @@ -930,16 +930,17 @@ struct volume_options options[] = { { .key = {"eager-lock"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", - .description = "Lock phase of a transaction has two sub-phases. " + .description = "Enable/Disable eager lock for replica volume. " + "Lock phase of a transaction has two sub-phases. " "First is an attempt to acquire locks in parallel by " "broadcasting non-blocking lock requests. If lock " "acquisition fails on any server, then the held locks " - "are unlocked and revert to a blocking locked mode " + "are unlocked and we revert to a blocking locks mode " "sequentially on one server after another. If this " "option is enabled the initial broadcasting lock " - "request attempt to acquire lock on the entire file. " + "request attempts to acquire a full lock on the entire file. " "If this fails, we revert back to the sequential " - "\"regional\" blocking lock as before. In the case " + "\"regional\" blocking locks as before. In the case " "where such an \"eager\" lock is granted in the " "non-blocking phase, it gives rise to an opportunity " "for optimization. i.e, if the next write transaction " diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index c120dffbf23..cd35080e243 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -809,8 +809,6 @@ dht_lookup_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!op_ret && gf_uuid_is_null (local->gfid)) memcpy (local->gfid, stbuf->ia_gfid, 16); - memcpy (local->loc.gfid, local->gfid, 16); - /* Check if the gfid is different for file from other node */ if (!op_ret && gf_uuid_compare (local->gfid, stbuf->ia_gfid)) { @@ -879,6 +877,8 @@ unlock: this_call_cnt = dht_frame_return (frame); if (is_last_call (this_call_cnt)) { + gf_uuid_copy (local->loc.gfid, local->gfid); + if (local->need_selfheal) { local->need_selfheal = 0; dht_lookup_everywhere (frame, this, &local->loc); @@ -919,7 +919,6 @@ unlock: selfheal: FRAME_SU_DO (frame, dht_local_t); - gf_uuid_copy (local->loc.gfid, local->gfid); ret = dht_selfheal_directory (frame, dht_lookup_selfheal_cbk, &local->loc, layout); out: @@ -3826,6 +3825,7 @@ dht_fsetxattr (call_frame_t *frame, xlator_t *this, goto err; } + local->xattr_req = xdata ? dict_ref (xdata) : dict_new (); local->call_cnt = call_cnt = layout->cnt; if (IA_ISDIR (fd->inode->ia_type)) { @@ -3833,7 +3833,7 @@ dht_fsetxattr (call_frame_t *frame, xlator_t *this, STACK_WIND (frame, dht_err_cbk, layout->list[i].xlator, layout->list[i].xlator->fops->fsetxattr, - fd, xattr, flags, NULL); + fd, xattr, flags, xdata); } } else { @@ -3842,10 +3842,8 @@ dht_fsetxattr (call_frame_t *frame, xlator_t *this, local->rebalance.xattr = 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"); + ret = dict_set_dynstr_with_alloc (local->xattr_req, + DHT_IATT_IN_XDATA_KEY, "yes"); if (ret) { gf_msg_debug (this->name, 0, "Failed to set dictionary key %s for fd=%p", @@ -3853,11 +3851,8 @@ dht_fsetxattr (call_frame_t *frame, xlator_t *this, } STACK_WIND (frame, dht_file_setxattr_cbk, subvol, - subvol->fops->fsetxattr, fd, xattr, flags, xdata); - - if (xdata) - dict_unref (xdata); - + subvol->fops->fsetxattr, fd, xattr, flags, + local->xattr_req); } return 0; @@ -3953,12 +3948,12 @@ dht_setxattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) STACK_WIND (frame, dht_file_setxattr_cbk, subvol, subvol->fops->setxattr, &local->loc, local->rebalance.xattr, local->rebalance.flags, - NULL); + local->xattr_req); } else { STACK_WIND (frame, dht_file_setxattr_cbk, subvol, subvol->fops->fsetxattr, local->fd, local->rebalance.xattr, local->rebalance.flags, - NULL); + local->xattr_req); } return 0; @@ -4242,6 +4237,7 @@ dht_setxattr (call_frame_t *frame, xlator_t *this, if (tmp) { return dht_nuke_dir (frame, this, loc, tmp); } + local->xattr_req = xdata ? dict_ref (xdata) : dict_new (); if (IA_ISDIR (loc->inode->ia_type)) { @@ -4258,17 +4254,12 @@ dht_setxattr (call_frame_t *frame, xlator_t *this, 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"); + ret = dict_set_dynstr_with_alloc (local->xattr_req, + 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); + loc, xattr, flags, local->xattr_req); } return 0; @@ -4387,11 +4378,11 @@ dht_removexattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, if (local->fop == GF_FOP_REMOVEXATTR) { STACK_WIND (frame, dht_file_removexattr_cbk, subvol, subvol->fops->removexattr, &local->loc, - local->key, NULL); + local->key, local->xattr_req); } else { STACK_WIND (frame, dht_file_removexattr_cbk, subvol, subvol->fops->fremovexattr, local->fd, - local->key, NULL); + local->key, local->xattr_req); } return 0; @@ -4428,8 +4419,6 @@ 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, @@ -4485,6 +4474,7 @@ dht_removexattr (call_frame_t *frame, xlator_t *this, op_errno = EINVAL; goto err; } + local->xattr_req = (xdata) ? dict_ref (xdata) : dict_new (); local->call_cnt = call_cnt = layout->cnt; local->key = gf_strdup (key); @@ -4494,16 +4484,15 @@ dht_removexattr (call_frame_t *frame, xlator_t *this, STACK_WIND (frame, dht_removexattr_cbk, layout->list[i].xlator, layout->list[i].xlator->fops->removexattr, - loc, key, NULL); + loc, key, local->xattr_req); } } 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"); + + ret = dict_set_dynstr_with_alloc (local->xattr_req, + DHT_IATT_IN_XDATA_KEY, "yes"); if (ret) { gf_msg (this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_DICT_SET_FAILED, "Failed to " @@ -4513,10 +4502,7 @@ dht_removexattr (call_frame_t *frame, xlator_t *this, STACK_WIND (frame, dht_file_removexattr_cbk, subvol, subvol->fops->removexattr, - loc, key, xdata); - - if (xdata) - dict_unref (xdata); + loc, key, local->xattr_req); } return 0; @@ -4574,6 +4560,7 @@ dht_fremovexattr (call_frame_t *frame, xlator_t *this, op_errno = EINVAL; goto err; } + local->xattr_req = xdata ? dict_ref (xdata) : dict_new (); local->call_cnt = call_cnt = layout->cnt; local->key = gf_strdup (key); @@ -4583,29 +4570,23 @@ dht_fremovexattr (call_frame_t *frame, xlator_t *this, STACK_WIND (frame, dht_removexattr_cbk, layout->list[i].xlator, layout->list[i].xlator->fops->fremovexattr, - fd, key, NULL); + fd, key, local->xattr_req); } } 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"); + ret = dict_set_dynstr_with_alloc (local->xattr_req, + DHT_IATT_IN_XDATA_KEY, "yes"); if (ret) { gf_msg (this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_DICT_SET_FAILED, "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); + fd, key, local->xattr_req); } return 0; @@ -6527,7 +6508,7 @@ dht_link2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) local->call_cnt = 2; STACK_WIND (frame, dht_link_cbk, subvol, subvol->fops->link, - &local->loc, &local->loc2, NULL); + &local->loc, &local->loc2, local->xattr_req); return 0; err: @@ -6554,7 +6535,7 @@ dht_link_linkfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this, srcvol = local->linkfile.srcvol; STACK_WIND (frame, dht_link_cbk, srcvol, srcvol->fops->link, - &local->loc, &local->loc2, xdata); + &local->loc, &local->loc2, local->xattr_req); return 0; @@ -6563,7 +6544,7 @@ err: dht_set_fixed_dir_stat (preparent); dht_set_fixed_dir_stat (postparent); DHT_STACK_UNWIND (link, frame, op_ret, op_errno, inode, stbuf, preparent, - postparent, NULL); + postparent, xdata); return 0; } @@ -6614,6 +6595,8 @@ dht_link (call_frame_t *frame, xlator_t *this, op_errno = ENOMEM; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); if (hashed_subvol != cached_subvol) { gf_uuid_copy (local->gfid, oldloc->inode->gfid); diff --git a/xlators/cluster/dht/src/dht-inode-read.c b/xlators/cluster/dht/src/dht-inode-read.c index ac0f0e186fa..05f71fbcc86 100644 --- a/xlators/cluster/dht/src/dht-inode-read.c +++ b/xlators/cluster/dht/src/dht-inode-read.c @@ -76,7 +76,7 @@ dht_open2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) if (we_are_not_migrating (ret)) { /* This DHT layer is not migrating the file */ DHT_STACK_UNWIND (open, frame, -1, local->op_errno, - NULL, NULL); + NULL, local->rebalance.xdata); return 0; } @@ -88,7 +88,7 @@ dht_open2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) STACK_WIND (frame, dht_open_cbk, subvol, subvol->fops->open, &local->loc, local->rebalance.flags, local->fd, - NULL); + local->xattr_req); return 0; out: @@ -132,6 +132,8 @@ dht_open (call_frame_t *frame, xlator_t *this, op_errno = ENOSPC; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); local->rebalance.flags = flags; local->call_cnt = 1; @@ -249,10 +251,10 @@ dht_attr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) if (local->fop == GF_FOP_FSTAT) { STACK_WIND (frame, dht_file_attr_cbk, subvol, - subvol->fops->fstat, local->fd, NULL); + subvol->fops->fstat, local->fd, local->xattr_req); } else { STACK_WIND (frame, dht_file_attr_cbk, subvol, - subvol->fops->stat, &local->loc, NULL); + subvol->fops->stat, &local->loc, local->xattr_req); } return 0; @@ -335,6 +337,8 @@ dht_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); if (IA_ISREG (loc->inode->ia_type)) { local->call_cnt = 1; @@ -395,6 +399,8 @@ dht_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); if (IA_ISREG (fd->inode->ia_type)) { local->call_cnt = 1; @@ -516,7 +522,7 @@ dht_readv2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) STACK_WIND (frame, dht_readv_cbk, subvol, subvol->fops->readv, local->fd, local->rebalance.size, local->rebalance.offset, - local->rebalance.flags, NULL); + local->rebalance.flags, local->xattr_req); return 0; @@ -551,6 +557,8 @@ dht_readv (call_frame_t *frame, xlator_t *this, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); local->rebalance.offset = off; local->rebalance.size = size; @@ -645,7 +653,7 @@ dht_access2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) local->call_cnt = 2; STACK_WIND (frame, dht_access_cbk, subvol, subvol->fops->access, - &local->loc, local->rebalance.flags, NULL); + &local->loc, local->rebalance.flags, local->xattr_req); return 0; @@ -684,6 +692,8 @@ dht_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); STACK_WIND (frame, dht_access_cbk, subvol, subvol->fops->access, loc, mask, xdata); @@ -718,9 +728,6 @@ dht_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this, local->op_ret = op_ret; local->op_errno = op_errno; - if (xdata) - local->rebalance.xdata = dict_ref (xdata); - /* If context is set, then send flush() it to the destination */ dht_inode_ctx_get_mig_info (this, local->fd->inode, NULL, &subvol); if (subvol && dht_fd_open_on_dst (this, local->fd, subvol)) { @@ -761,7 +768,7 @@ dht_flush2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) STACK_WIND (frame, dht_flush_cbk, subvol, subvol->fops->flush, local->fd, - local->rebalance.xdata); + local->xattr_req); return 0; @@ -795,6 +802,8 @@ dht_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); local->call_cnt = 1; @@ -917,7 +926,7 @@ dht_fsync2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) local->call_cnt = 2; /* This is the second attempt */ STACK_WIND (frame, dht_fsync_cbk, subvol, subvol->fops->fsync, - local->fd, local->rebalance.flags, NULL); + local->fd, local->rebalance.flags, local->xattr_req); return 0; @@ -944,6 +953,8 @@ dht_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync, goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); local->call_cnt = 1; local->rebalance.flags = datasync; @@ -1034,7 +1045,7 @@ dht_lk2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) STACK_WIND (frame, dht_lk_cbk, subvol, subvol->fops->lk, local->fd, local->rebalance.lock_cmd, &local->rebalance.flock, - local->rebalance.xdata); + local->xattr_req); return 0; @@ -1069,6 +1080,8 @@ dht_lk (call_frame_t *frame, xlator_t *this, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); local->rebalance.flock = *flock; local->rebalance.lock_cmd = cmd; diff --git a/xlators/cluster/dht/src/dht-inode-write.c b/xlators/cluster/dht/src/dht-inode-write.c index 7420461da76..48d49dd3475 100644 --- a/xlators/cluster/dht/src/dht-inode-write.c +++ b/xlators/cluster/dht/src/dht-inode-write.c @@ -143,7 +143,7 @@ dht_writev2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) subvol, subvol->fops->writev, local->fd, local->rebalance.vector, local->rebalance.count, local->rebalance.offset, local->rebalance.flags, - local->rebalance.iobref, NULL); + local->rebalance.iobref, local->xattr_req); return 0; @@ -192,6 +192,8 @@ dht_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, op_errno = ENOSPC; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); local->rebalance.vector = iov_dup (vector, count); local->rebalance.offset = off; @@ -334,11 +336,11 @@ dht_truncate2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) if (local->fop == GF_FOP_TRUNCATE) { STACK_WIND (frame, dht_truncate_cbk, subvol, subvol->fops->truncate, &local->loc, - local->rebalance.offset, NULL); + local->rebalance.offset, local->xattr_req); } else { STACK_WIND (frame, dht_truncate_cbk, subvol, subvol->fops->ftruncate, local->fd, - local->rebalance.offset, NULL); + local->rebalance.offset, local->xattr_req); } return 0; @@ -377,6 +379,8 @@ dht_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); STACK_WIND (frame, dht_truncate_cbk, subvol, subvol->fops->truncate, @@ -418,6 +422,8 @@ dht_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); STACK_WIND (frame, dht_truncate_cbk, subvol, subvol->fops->ftruncate, @@ -544,7 +550,7 @@ dht_fallocate2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) STACK_WIND(frame, dht_fallocate_cbk, subvol, subvol->fops->fallocate, local->fd, local->rebalance.flags, local->rebalance.offset, - local->rebalance.size, NULL); + local->rebalance.size, local->xattr_req); return 0; @@ -583,6 +589,8 @@ dht_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); STACK_WIND (frame, dht_fallocate_cbk, subvol, subvol->fops->fallocate, @@ -709,7 +717,7 @@ dht_discard2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) STACK_WIND(frame, dht_discard_cbk, subvol, subvol->fops->discard, local->fd, local->rebalance.offset, local->rebalance.size, - NULL); + local->xattr_req); return 0; @@ -747,6 +755,8 @@ dht_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); STACK_WIND (frame, dht_discard_cbk, subvol, subvol->fops->discard, fd, offset, len, xdata); @@ -872,7 +882,7 @@ dht_zerofill2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) STACK_WIND(frame, dht_zerofill_cbk, subvol, subvol->fops->zerofill, local->fd, local->rebalance.offset, local->rebalance.size, - NULL); + local->xattr_req); return 0; @@ -911,6 +921,8 @@ dht_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); STACK_WIND (frame, dht_zerofill_cbk, subvol, subvol->fops->zerofill, fd, offset, len, xdata); @@ -1015,12 +1027,12 @@ dht_setattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) STACK_WIND (frame, dht_file_setattr_cbk, subvol, subvol->fops->setattr, &local->loc, &local->rebalance.stbuf, local->rebalance.flags, - NULL); + local->xattr_req); } else { STACK_WIND (frame, dht_file_setattr_cbk, subvol, subvol->fops->fsetattr, local->fd, &local->rebalance.stbuf, local->rebalance.flags, - NULL); + local->xattr_req); } return 0; @@ -1113,6 +1125,8 @@ dht_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); if (IA_ISREG (loc->inode->ia_type)) { /* in the regular file _cbk(), we need to check for @@ -1184,6 +1198,8 @@ dht_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); if (IA_ISREG (fd->inode->ia_type)) { /* in the regular file _cbk(), we need to check for diff --git a/xlators/cluster/ec/src/ec-heal.c b/xlators/cluster/ec/src/ec-heal.c index da08f6c9a75..2373e6f93d5 100644 --- a/xlators/cluster/ec/src/ec-heal.c +++ b/xlators/cluster/ec/src/ec-heal.c @@ -410,6 +410,8 @@ ec_adjust_versions (call_frame_t *frame, ec_t *ec, ec_txn_t type, if (EC_COUNT (sources, ec->nodes) + EC_COUNT (healed_sinks, ec->nodes) == ec->nodes) erase_dirty = _gf_true; + else + op_ret = -ENOTCONN; for (i = 0; i < ec->nodes; i++) { if (!sources[i] && !healed_sinks[i]) @@ -509,7 +511,7 @@ ec_heal_metadata_find_direction (ec_t *ec, default_args_cbk_t *replies, if (!are_dicts_equal(replies[i].xdata, replies[j].xdata, ec_sh_key_match, NULL)) continue; - groups[j] = i; /*If iatts match put them into a group*/ + groups[j] = i; same_count++; } @@ -541,7 +543,6 @@ out: return ret; } - int __ec_heal_metadata_prepare (call_frame_t *frame, ec_t *ec, inode_t *inode, unsigned char *locked_on, default_args_cbk_t *replies, @@ -679,15 +680,12 @@ __ec_heal_metadata (call_frame_t *frame, ec_t *ec, inode_t *inode, goto out; } - if (EC_COUNT (sources, ec->nodes) == ec->nodes) { + if ((EC_COUNT (sources, ec->nodes) == ec->nodes) || + (EC_COUNT (healed_sinks, ec->nodes) == 0)) { ret = 0; goto erase_dirty; } - if (EC_COUNT (healed_sinks, ec->nodes) == 0) { - ret = -ENOTCONN; - goto out; - } source_buf = replies[source].stat; ret = cluster_setattr (ec->xl_list, healed_sinks, ec->nodes, sreplies, output, frame, ec->xl, &loc, diff --git a/xlators/cluster/ec/src/ec-inode-read.c b/xlators/cluster/ec/src/ec-inode-read.c index c3d9c879eb7..fc121bcceb2 100644 --- a/xlators/cluster/ec/src/ec-inode-read.c +++ b/xlators/cluster/ec/src/ec-inode-read.c @@ -1577,23 +1577,16 @@ int32_t ec_manager_seek(ec_fop_data_t *fop, int32_t state) return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: - cbk = fop->answer; - if (cbk != NULL) { - if (ec_dispatch_one_retry(fop, &cbk)) { - return EC_STATE_DISPATCH; - } - if (cbk->op_ret >= 0) { - ec_t *ec = fop->xl->private; + if (ec_dispatch_one_retry(fop, &cbk)) { + return EC_STATE_DISPATCH; + } + if ((cbk != NULL) && (cbk->op_ret >= 0)) { + ec_t *ec = fop->xl->private; - cbk->offset *= ec->fragments; - if (cbk->offset < fop->user_size) { - cbk->offset = fop->user_size; - } - } else { - ec_fop_set_error(fop, cbk->op_errno); + cbk->offset *= ec->fragments; + if (cbk->offset < fop->user_size) { + cbk->offset = fop->user_size; } - } else { - ec_fop_set_error(fop, EIO); } return EC_STATE_REPORT; diff --git a/xlators/cluster/ec/src/ec.c b/xlators/cluster/ec/src/ec.c index b5e6bc08216..0a3a3cce391 100644 --- a/xlators/cluster/ec/src/ec.c +++ b/xlators/cluster/ec/src/ec.c @@ -1328,8 +1328,18 @@ struct volume_options options[] = { .key = {"eager-lock"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", - .description = "This option will enable/diable eager lock for" - "disperse volume " + .description = "Enable/Disable eager lock for disperse volume. " + "If a fop takes a lock and completes its operation, " + "it waits for next 1 second before releasing the lock, " + "to see if the lock can be reused for next fop from " + "the same client. If ec finds any lock contention within " + "1 second it releases the lock immediately before time " + "expires. This improves the performance of file operations." + "However, as it takes lock on first brick, for few operations " + "like read, discovery of lock contention might take long time " + "and can actually degrade the performance. " + "If eager lock is disabled, lock will be released as soon as fop " + "completes. " }, { .key = {"background-heals"}, .type = GF_OPTION_TYPE_INT, diff --git a/xlators/features/ganesha/src/Makefile.am b/xlators/features/ganesha/src/Makefile.am index 3bf291b92c6..be2f45c6d43 100644 --- a/xlators/features/ganesha/src/Makefile.am +++ b/xlators/features/ganesha/src/Makefile.am @@ -11,7 +11,7 @@ ganesha_la_SOURCES = ganesha.c AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D$(GF_HOST_OS)\ -DGANESHA_DIR=\"$(sysconfdir)/ganesha\" \ - -DGYSNCD_PREFIX=\"$(libexecdir)/glusterfs\" + -DGYSNCD_PREFIX=\"$(GLUSTERFS_LIBEXECDIR)\" AM_CFLAGS = -Wall $(GF_CFLAGS) diff --git a/xlators/features/locks/src/common.c b/xlators/features/locks/src/common.c index c40c29de63a..8a56c4205d9 100644 --- a/xlators/features/locks/src/common.c +++ b/xlators/features/locks/src/common.c @@ -433,7 +433,7 @@ pl_inode_get (xlator_t *this, inode_t *inode) INIT_LIST_HEAD (&pl_inode->blocked_reservelks); INIT_LIST_HEAD (&pl_inode->blocked_calls); INIT_LIST_HEAD (&pl_inode->metalk_list); - INIT_LIST_HEAD (&pl_inode->queued_locks); + INIT_LIST_HEAD (&pl_inode->queued_locks); gf_uuid_copy (pl_inode->gfid, inode->gfid); __inode_ctx_put (inode, this, (uint64_t)(long)(pl_inode)); @@ -505,9 +505,27 @@ __delete_lock (posix_lock_t *lock) void __destroy_lock (posix_lock_t *lock) { + GF_FREE (lock->client_uid); GF_FREE (lock); } +static posix_lock_t * +__copy_lock(posix_lock_t *src) +{ + posix_lock_t *dst; + + dst = GF_CALLOC(1, sizeof(posix_lock_t), gf_locks_mt_posix_lock_t); + if (dst != NULL) { + memcpy (dst, src, sizeof(posix_lock_t)); + dst->client_uid = gf_strdup(src->client_uid); + if (dst->client_uid == NULL) { + GF_FREE(dst); + dst = NULL; + } + } + + return dst; +} /* Convert a posix_lock to a struct gf_flock */ void @@ -613,11 +631,11 @@ subtract_locks (posix_lock_t *big, posix_lock_t *small) if ((big->fl_start == small->fl_start) && (big->fl_end == small->fl_end)) { /* both edges coincide with big */ - v.locks[0] = GF_CALLOC (1, sizeof (posix_lock_t), - gf_locks_mt_posix_lock_t); - if (!v.locks[0]) + v.locks[0] = __copy_lock(big); + if (!v.locks[0]) { goto out; - memcpy (v.locks[0], big, sizeof (posix_lock_t)); + } + v.locks[0]->fl_type = small->fl_type; goto done; } @@ -625,27 +643,15 @@ subtract_locks (posix_lock_t *big, posix_lock_t *small) if ((small->fl_start > big->fl_start) && (small->fl_end < big->fl_end)) { /* both edges lie inside big */ - v.locks[0] = GF_CALLOC (1, sizeof (posix_lock_t), - gf_locks_mt_posix_lock_t); - if (!v.locks[0]) - goto out; - - v.locks[1] = GF_CALLOC (1, sizeof (posix_lock_t), - gf_locks_mt_posix_lock_t); - if (!v.locks[1]) - goto out; - - v.locks[2] = GF_CALLOC (1, sizeof (posix_lock_t), - gf_locks_mt_posix_lock_t); - if (!v.locks[1]) + v.locks[0] = __copy_lock(big); + v.locks[1] = __copy_lock(small); + v.locks[2] = __copy_lock(big); + if ((v.locks[0] == NULL) || (v.locks[1] == NULL) || + (v.locks[2] == NULL)) { goto out; + } - memcpy (v.locks[0], big, sizeof (posix_lock_t)); v.locks[0]->fl_end = small->fl_start - 1; - - memcpy (v.locks[1], small, sizeof (posix_lock_t)); - - memcpy (v.locks[2], big, sizeof (posix_lock_t)); v.locks[2]->fl_start = small->fl_end + 1; goto done; @@ -653,38 +659,24 @@ subtract_locks (posix_lock_t *big, posix_lock_t *small) /* one edge coincides with big */ if (small->fl_start == big->fl_start) { - v.locks[0] = GF_CALLOC (1, sizeof (posix_lock_t), - gf_locks_mt_posix_lock_t); - if (!v.locks[0]) - goto out; - - v.locks[1] = GF_CALLOC (1, sizeof (posix_lock_t), - gf_locks_mt_posix_lock_t); - if (!v.locks[1]) + v.locks[0] = __copy_lock(big); + v.locks[1] = __copy_lock(small); + if ((v.locks[0] == NULL) || (v.locks[1] == NULL)) { goto out; + } - memcpy (v.locks[0], big, sizeof (posix_lock_t)); v.locks[0]->fl_start = small->fl_end + 1; - - memcpy (v.locks[1], small, sizeof (posix_lock_t)); goto done; } if (small->fl_end == big->fl_end) { - v.locks[0] = GF_CALLOC (1, sizeof (posix_lock_t), - gf_locks_mt_posix_lock_t); - if (!v.locks[0]) - goto out; - - v.locks[1] = GF_CALLOC (1, sizeof (posix_lock_t), - gf_locks_mt_posix_lock_t); - if (!v.locks[1]) + v.locks[0] = __copy_lock(big); + v.locks[1] = __copy_lock(small); + if ((v.locks[0] == NULL) || (v.locks[1] == NULL)) { goto out; + } - memcpy (v.locks[0], big, sizeof (posix_lock_t)); v.locks[0]->fl_end = small->fl_start - 1; - - memcpy (v.locks[1], small, sizeof (posix_lock_t)); goto done; } @@ -693,15 +685,15 @@ subtract_locks (posix_lock_t *big, posix_lock_t *small) out: if (v.locks[0]) { - GF_FREE (v.locks[0]); + __destroy_lock(v.locks[0]); v.locks[0] = NULL; } if (v.locks[1]) { - GF_FREE (v.locks[1]); + __destroy_lock(v.locks[1]); v.locks[1] = NULL; } if (v.locks[2]) { - GF_FREE (v.locks[2]); + __destroy_lock(v.locks[2]); v.locks[2] = NULL; } @@ -967,7 +959,7 @@ grant_blocked_locks (xlator_t *this, pl_inode_t *pl_inode) STACK_UNWIND_STRICT (lk, lock->frame, 0, 0, &lock->user_flock, NULL); - GF_FREE (lock); + __destroy_lock(lock); } return; @@ -1013,7 +1005,7 @@ pl_send_prelock_unlock (xlator_t *this, pl_inode_t *pl_inode, STACK_UNWIND_STRICT (lk, lock->frame, 0, 0, &lock->user_flock, NULL); - GF_FREE (lock); + __destroy_lock(lock); } out: diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c index 7f85ba4fca5..616be0f7cff 100644 --- a/xlators/features/locks/src/posix.c +++ b/xlators/features/locks/src/posix.c @@ -3077,8 +3077,7 @@ out: STACK_UNWIND_STRICT (lk, posix_lock->frame, -1, EREMOTE, &posix_lock->user_flock, NULL); - GF_FREE (posix_lock->client_uid); - GF_FREE (posix_lock); + __destroy_lock(posix_lock); } return ret; @@ -3572,8 +3571,7 @@ unlock: STACK_UNWIND_STRICT (lk, posix_lock->frame, -1, EREMOTE, &posix_lock->user_flock, NULL); - GF_FREE (posix_lock->client_uid); - GF_FREE (posix_lock); + __destroy_lock(posix_lock); } return 0; } diff --git a/xlators/features/locks/src/reservelk.c b/xlators/features/locks/src/reservelk.c index 8eb08d0ef79..13b23f9f887 100644 --- a/xlators/features/locks/src/reservelk.c +++ b/xlators/features/locks/src/reservelk.c @@ -18,18 +18,6 @@ #include "locks.h" #include "common.h" -void -__delete_reserve_lock (posix_lock_t *lock) -{ - list_del (&lock->list); -} - -void -__destroy_reserve_lock (posix_lock_t *lock) -{ - GF_FREE (lock); -} - /* Return true if the two reservelks have exactly same lock boundaries */ int reservelks_equal (posix_lock_t *l1, posix_lock_t *l2) @@ -110,7 +98,7 @@ __reservelk_conflict (xlator_t *this, pl_inode_t *pl_inode, list_del_init (&conf->list); gf_log (this->name, GF_LOG_TRACE, "Removing the matching reservelk for setlk to progress"); - GF_FREE (conf); + __destroy_lock(conf); ret = 0; } else { gf_log (this->name, GF_LOG_TRACE, @@ -217,7 +205,7 @@ __reserve_unlock_lock (xlator_t *this, posix_lock_t *lock, pl_inode_t *pl_inode) " Matching lock not found for unlock"); goto out; } - __delete_reserve_lock (conf); + __delete_lock(conf); gf_log (this->name, GF_LOG_DEBUG, " Matching lock found for unlock"); @@ -392,7 +380,7 @@ pl_reserve_unlock (xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock) gf_log (this->name, GF_LOG_TRACE, "Reservelk Unlock successful"); - __destroy_reserve_lock (retlock); + __destroy_lock(retlock); ret = 0; } out: diff --git a/xlators/features/read-only/src/worm.c b/xlators/features/read-only/src/worm.c index 3e32d65dbac..dd9d720e569 100644 --- a/xlators/features/read-only/src/worm.c +++ b/xlators/features/read-only/src/worm.c @@ -35,7 +35,7 @@ worm_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { if (is_readonly_or_worm_enabled (this) && - (flags & (O_WRONLY | O_RDWR | O_APPEND))) { + (flags & (O_WRONLY | O_RDWR | O_APPEND | O_TRUNC))) { STACK_UNWIND_STRICT (open, frame, -1, EROFS, NULL, NULL); return 0; } @@ -175,7 +175,7 @@ worm_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, goto out; } op_errno = gf_worm_state_transition (this, _gf_false, loc, - GF_FOP_TRUNCATE); + GF_FOP_TRUNCATE); out: if (op_errno) @@ -190,6 +190,41 @@ out: static int32_t +worm_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + dict_t *xdata) +{ + int op_errno = EROFS; + read_only_priv_t *priv = NULL; + + priv = this->private; + GF_ASSERT (priv); + if (is_readonly_or_worm_enabled (this)) + goto out; + if (!priv->worm_file) { + op_errno = 0; + goto out; + } + + if (is_wormfile (this, _gf_true, fd)) { + op_errno = 0; + goto out; + } + op_errno = gf_worm_state_transition (this, _gf_true, fd, + GF_FOP_FTRUNCATE); + +out: + if (op_errno) + STACK_UNWIND_STRICT (ftruncate, frame, -1, op_errno, NULL, NULL, + NULL); + else + STACK_WIND_TAIL (frame, FIRST_CHILD (this), + FIRST_CHILD (this)->fops->ftruncate, + fd, offset, xdata); + return 0; +} + + +static int32_t worm_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { @@ -557,6 +592,7 @@ struct xlator_fops fops = { .link = worm_link, .unlink = worm_unlink, .truncate = worm_truncate, + .ftruncate = worm_ftruncate, .create = worm_create, .rmdir = ro_rmdir, diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c index 39d648bb34d..4dd581dd19e 100644 --- a/xlators/features/shard/src/shard.c +++ b/xlators/features/shard/src/shard.c @@ -1269,7 +1269,7 @@ shard_common_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, else inode = local->fd->inode; - shard_inode_ctx_invalidate (inode, this, buf); + shard_inode_ctx_invalidate (inode, this, &local->prebuf); unwind: local->handler (frame, this); @@ -1693,11 +1693,30 @@ shard_common_lookup_shards_cbk (call_frame_t *frame, void *cookie, if (op_ret < 0) { /* Ignore absence of shards in the backend in truncate fop. */ - if (((local->fop == GF_FOP_TRUNCATE) || - (local->fop == GF_FOP_FTRUNCATE) || - (local->fop == GF_FOP_RENAME) || - (local->fop == GF_FOP_UNLINK)) && (op_errno == ENOENT)) - goto done; + switch (local->fop) { + case GF_FOP_TRUNCATE: + case GF_FOP_FTRUNCATE: + case GF_FOP_RENAME: + case GF_FOP_UNLINK: + if (op_errno == ENOENT) + goto done; + break; + case GF_FOP_WRITE: + case GF_FOP_READ: + case GF_FOP_ZEROFILL: + case GF_FOP_DISCARD: + case GF_FOP_FALLOCATE: + if ((!local->first_lookup_done) && + (op_errno == ENOENT)) { + local->create_count++; + goto done; + } + break; + default: + break; + } + + /* else */ gf_msg (this->name, GF_LOG_ERROR, op_errno, SHARD_MSG_LOOKUP_SHARD_FAILED, "Lookup on shard %d " "failed. Base file gfid = %s", shard_block_num, @@ -1714,6 +1733,8 @@ shard_common_lookup_shards_cbk (call_frame_t *frame, void *cookie, done: call_count = shard_call_count_return (frame); if (call_count == 0) { + if (!local->first_lookup_done) + local->first_lookup_done = _gf_true; if (local->op_ret < 0) goto unwind; else @@ -3197,47 +3218,6 @@ next: } int -shard_post_lookup_shards_readv_handler (call_frame_t *frame, xlator_t *this) -{ - shard_local_t *local = NULL; - - local = frame->local; - - if (local->op_ret < 0) { - SHARD_STACK_UNWIND (readv, frame, local->op_ret, - local->op_errno, NULL, 0, NULL, NULL, NULL); - return 0; - } - - shard_readv_do (frame, this); - - return 0; -} - -int -shard_post_mknod_readv_handler (call_frame_t *frame, xlator_t *this) -{ - shard_local_t *local = NULL; - - local = frame->local; - - if (local->op_ret < 0) { - SHARD_STACK_UNWIND (readv, frame, local->op_ret, - local->op_errno, NULL, 0, NULL, NULL, NULL); - return 0; - } - - if (!local->eexist_count) { - shard_readv_do (frame, this); - } else { - local->call_count = local->eexist_count; - shard_common_lookup_shards (frame, this, local->loc.inode, - shard_post_lookup_shards_readv_handler); - } - return 0; -} - -int shard_common_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, @@ -3267,6 +3247,7 @@ done: call_count = shard_call_count_return (frame); if (call_count == 0) { SHARD_UNSET_ROOT_FS_ID (frame, local); + local->create_count = 0; local->post_mknod_handler (frame, this); } @@ -3397,6 +3378,55 @@ err: } int +shard_post_mknod_readv_handler (call_frame_t *frame, xlator_t *this); + +int +shard_post_lookup_shards_readv_handler (call_frame_t *frame, xlator_t *this) +{ + shard_local_t *local = NULL; + + local = frame->local; + + if (local->op_ret < 0) { + SHARD_STACK_UNWIND (readv, frame, local->op_ret, + local->op_errno, NULL, 0, NULL, NULL, NULL); + return 0; + } + + if (local->create_count) { + shard_common_resume_mknod (frame, this, + shard_post_mknod_readv_handler); + } else { + shard_readv_do (frame, this); + } + + return 0; +} + +int +shard_post_mknod_readv_handler (call_frame_t *frame, xlator_t *this) +{ + shard_local_t *local = NULL; + + local = frame->local; + + if (local->op_ret < 0) { + SHARD_STACK_UNWIND (readv, frame, local->op_ret, + local->op_errno, NULL, 0, NULL, NULL, NULL); + return 0; + } + + if (!local->eexist_count) { + shard_readv_do (frame, this); + } else { + local->call_count = local->eexist_count; + shard_common_lookup_shards (frame, this, local->loc.inode, + shard_post_lookup_shards_readv_handler); + } + return 0; +} + +int shard_post_resolve_readv_handler (call_frame_t *frame, xlator_t *this) { shard_local_t *local = NULL; @@ -3422,9 +3452,9 @@ shard_post_resolve_readv_handler (call_frame_t *frame, xlator_t *this) } if (local->call_count) { - local->create_count = local->call_count; - shard_common_resume_mknod (frame, this, - shard_post_mknod_readv_handler); + shard_common_lookup_shards (frame, this, + local->resolver_base_inode, + shard_post_lookup_shards_readv_handler); } else { shard_readv_do (frame, this); } @@ -3566,6 +3596,7 @@ shard_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, local->offset = offset; local->req_size = size; local->flags = flags; + local->fop = GF_FOP_READ; local->xattr_req = (xdata) ? dict_ref (xdata) : dict_new (); if (!local->xattr_req) goto err; @@ -3575,14 +3606,11 @@ shard_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, shard_lookup_base_file (frame, this, &local->loc, shard_post_lookup_readv_handler); - return 0; - err: SHARD_STACK_UNWIND (readv, frame, -1, ENOMEM, NULL, 0, NULL, NULL, NULL); return 0; - } int @@ -3875,6 +3903,10 @@ next: } int +shard_common_inode_write_post_mknod_handler (call_frame_t *frame, + xlator_t *this); + +int shard_common_inode_write_post_lookup_shards_handler (call_frame_t *frame, xlator_t *this) { @@ -3889,7 +3921,12 @@ shard_common_inode_write_post_lookup_shards_handler (call_frame_t *frame, return 0; } - shard_common_inode_write_do (frame, this); + if (local->create_count) { + shard_common_resume_mknod (frame, this, + shard_common_inode_write_post_mknod_handler); + } else { + shard_common_inode_write_do (frame, this); + } return 0; } @@ -3937,11 +3974,13 @@ shard_common_inode_write_post_lookup_handler (call_frame_t *frame, local->postbuf = local->prebuf; - if (local->create_count) - shard_common_resume_mknod (frame, this, - shard_common_inode_write_post_mknod_handler); - else + if (local->call_count) { + shard_common_lookup_shards (frame, this, + local->resolver_base_inode, + shard_common_inode_write_post_lookup_shards_handler); + } else { shard_common_inode_write_do (frame, this); + } return 0; } @@ -3961,8 +4000,6 @@ shard_common_inode_write_post_resolve_handler (call_frame_t *frame, return 0; } - local->create_count = local->call_count; - shard_lookup_base_file (frame, this, &local->loc, shard_common_inode_write_post_lookup_handler); return 0; diff --git a/xlators/features/shard/src/shard.h b/xlators/features/shard/src/shard.h index 09232a45f24..73195983aa4 100644 --- a/xlators/features/shard/src/shard.h +++ b/xlators/features/shard/src/shard.h @@ -255,6 +255,7 @@ typedef struct shard_local { shard_lock_t *shard_lock; } lock; inode_t *resolver_base_inode; + gf_boolean_t first_lookup_done; } shard_local_t; typedef struct shard_inode_ctx { diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am index f938aaf9436..d20fcefd97d 100644 --- a/xlators/mgmt/glusterd/src/Makefile.am +++ b/xlators/mgmt/glusterd/src/Makefile.am @@ -46,7 +46,7 @@ AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(CONTRIBDIR)/mount \ -I$(CONTRIBDIR)/userspace-rcu \ -DSBIN_DIR=\"$(sbindir)\" -DDATADIR=\"$(localstatedir)\" \ - -DGSYNCD_PREFIX=\"$(libexecdir)/glusterfs\" \ + -DGSYNCD_PREFIX=\"$(GLUSTERFS_LIBEXECDIR)\" \ -DCONFDIR=\"$(sysconfdir)/ganesha\" \ -DGANESHA_PREFIX=\"$(libexecdir)/ganesha\" \ -DSYNCDAEMON_COMPILE=$(SYNCDAEMON_COMPILE) $(XML_CPPFLAGS) diff --git a/xlators/mgmt/glusterd/src/glusterd-quota.c b/xlators/mgmt/glusterd/src/glusterd-quota.c index 08fc74f396b..0f973520e58 100644 --- a/xlators/mgmt/glusterd/src/glusterd-quota.c +++ b/xlators/mgmt/glusterd/src/glusterd-quota.c @@ -702,11 +702,6 @@ glusterd_quota_disable (glusterd_volinfo_t *volinfo, char **op_errstr, } } - //Remove aux mount of the volume on every node in the cluster - ret = glusterd_remove_auxiliary_mount (volinfo->volname); - if (ret) - goto out; - *crawl = _gf_true; (void) glusterd_clean_up_quota_store (volinfo); @@ -736,7 +731,7 @@ glusterd_set_quota_limit (char *volname, char *path, char *hard_limit, priv = this->private; GF_ASSERT (priv); - GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (abspath, volname, path); + GLUSTERD_GET_QUOTA_LIMIT_MOUNT_PATH (abspath, volname, path); ret = gf_lstat_dir (abspath, NULL); if (ret) { gf_asprintf (op_errstr, "Failed to find the directory %s. " @@ -1361,7 +1356,7 @@ glusterd_remove_quota_limit (char *volname, char *path, char **op_errstr, priv = this->private; GF_ASSERT (priv); - GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (abspath, volname, path); + GLUSTERD_GET_QUOTA_LIMIT_MOUNT_PATH (abspath, volname, path); ret = gf_lstat_dir (abspath, NULL); if (ret) { gf_asprintf (op_errstr, "Failed to find the directory %s. " @@ -1692,6 +1687,16 @@ glusterd_op_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict) ret = 0; out: + if (type == GF_QUOTA_OPTION_TYPE_LIMIT_USAGE || + type == GF_QUOTA_OPTION_TYPE_LIMIT_OBJECTS || + type == GF_QUOTA_OPTION_TYPE_REMOVE || + type == GF_QUOTA_OPTION_TYPE_REMOVE_OBJECTS) { + /* During a list operation we need the aux mount to be + * accessible until the listing is done at the cli + */ + glusterd_remove_auxiliary_mount (volinfo->volname); + } + return ret; } @@ -1850,7 +1855,7 @@ out: } static int -glusterd_create_quota_auxiliary_mount (xlator_t *this, char *volname) +glusterd_create_quota_auxiliary_mount (xlator_t *this, char *volname, int type) { int ret = -1; int retry = 0; @@ -1861,28 +1866,30 @@ glusterd_create_quota_auxiliary_mount (xlator_t *this, char *volname) char *volfileserver = NULL; glusterd_conf_t *priv = NULL; struct stat buf = {0,}; + FILE *file = NULL; GF_VALIDATE_OR_GOTO ("glusterd", this, out); priv = this->private; GF_VALIDATE_OR_GOTO (this->name, priv, out); - GLUSTERFS_GET_AUX_MOUNT_PIDFILE (pidfile_path, volname); - if (gf_is_service_running (pidfile_path, NULL)) { - gf_msg_debug (this->name, 0, "Aux mount of volume %s is running" - " already", volname); - ret = 0; - goto out; + if (type == GF_QUOTA_OPTION_TYPE_LIST || + type == GF_QUOTA_OPTION_TYPE_LIST_OBJECTS) { + GLUSTERFS_GET_QUOTA_LIST_MOUNT_PIDFILE (pidfile_path, volname); + GLUSTERD_GET_QUOTA_LIST_MOUNT_PATH (mountdir, volname, "/"); + } else { + GLUSTERFS_GET_QUOTA_LIMIT_MOUNT_PIDFILE (pidfile_path, volname); + GLUSTERD_GET_QUOTA_LIMIT_MOUNT_PATH (mountdir, volname, "/"); } - if (glusterd_is_fuse_available () == _gf_false) { - gf_msg (this->name, GF_LOG_ERROR, 0, - GD_MSG_MOUNT_REQ_FAIL, "Fuse unavailable"); - ret = -1; - goto out; + file = fopen (pidfile_path, "r"); + if (file) { + /* Previous command did not clean up pid file. + * remove aux mount if it exists*/ + gf_umount_lazy (this->name, mountdir, 1); + fclose(file); } - GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (mountdir, volname, "/"); ret = sys_mkdir (mountdir, 0777); if (ret && errno != EEXIST) { gf_msg (this->name, GF_LOG_ERROR, errno, @@ -2036,7 +2043,7 @@ glusterd_op_stage_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict) */ if (is_origin_glusterd (dict)) { ret = glusterd_create_quota_auxiliary_mount (this, - volname); + volname, type); if (ret) { *op_errstr = gf_strdup ("Failed to start aux " "mount"); diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c index 36adb7fbfd8..49051182345 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c @@ -3500,6 +3500,7 @@ glusterd_get_geo_rep_session (char *slave_key, char *origin_volname, char *slave) { int32_t ret = -1; + int32_t len = 0; char *token = NULL; char *tok = NULL; char *temp = NULL; @@ -3568,8 +3569,10 @@ glusterd_get_geo_rep_session (char *slave_key, char *origin_volname, * 'root@' */ ip_temp = gf_strdup (ip); tok = strtok_r (ip_temp, "@", &save_ptr); - if (tok && !strcmp (tok, "root")) - ip_i = ip + 5; + len = strlen(tok); + tok = strtok_r (NULL, "@", &save_ptr); + if (tok != NULL) + ip_i = ip + len + 1; ret = snprintf (session, PATH_MAX, "%s_%s_%s", origin_volname, ip_i, slave_temp); diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index cc4f69f3526..e303937579e 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -5013,7 +5013,7 @@ _local_gsyncd_start (dict_t *this, char *key, data_t *value, void *data) glusterd_conf_t *priv = NULL; gf_boolean_t is_template_in_use = _gf_false; gf_boolean_t is_paused = _gf_false; - char *key1 = NULL; + char key1[1024] = {0,}; xlator_t *this1 = NULL; this1 = THIS; @@ -5108,9 +5108,8 @@ _local_gsyncd_start (dict_t *this, char *key, data_t *value, void *data) goto out; } - /* Move the pointer two characters ahead to surpass '//' */ - if ((key1 = strchr (slave, '/'))) - key1 = key1 + 2; + /* Form key1 which is "<user@><slave_host>::<slavevol>" */ + snprintf (key1, sizeof (key1), "%s::%s", slave_url, slave_vol); /* Looks for the last status, to find if the session was running * when the node went down. If the session was just created or @@ -5390,6 +5389,7 @@ static struct fs_info { { "ext3", "tune2fs", "-l", "Inode size:", "e2fsprogs" }, { "ext4", "tune2fs", "-l", "Inode size:", "e2fsprogs" }, { "btrfs", NULL, NULL, NULL, NULL }, + { "zfs", NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL} }; @@ -5434,6 +5434,16 @@ glusterd_add_inode_size_to_dict (dict_t *dict, int count) for (fs = glusterd_fs ; fs->fs_type_name; fs++) { if (strcmp (fs_name, fs->fs_type_name) == 0) { + if (!fs->fs_tool_name) { + /* dynamic inodes */ + gf_msg (THIS->name, GF_LOG_INFO, 0, + GD_MSG_INODE_SIZE_GET_FAIL, "the " + "brick on %s (%s) uses dynamic inode " + "sizes", device, fs_name); + cur_word = "N/A"; + goto cached; + } + snprintf (fs_tool_name, sizeof (fs_tool_name), "/usr/sbin/%s", fs->fs_tool_name); if (sys_access (fs_tool_name, R_OK|X_OK) == 0) @@ -10565,21 +10575,12 @@ glusterd_remove_auxiliary_mount (char *volname) { int ret = -1; char mountdir[PATH_MAX] = {0,}; - char pidfile[PATH_MAX] = {0,}; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); - GLUSTERFS_GET_AUX_MOUNT_PIDFILE (pidfile, volname); - - if (!gf_is_service_running (pidfile, NULL)) { - gf_msg_debug (this->name, 0, "Aux mount of volume %s " - "absent, hence returning", volname); - return 0; - } - - GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (mountdir, volname, "/"); + GLUSTERD_GET_QUOTA_LIMIT_MOUNT_PATH (mountdir, volname, "/"); ret = gf_umount_lazy (this->name, mountdir, 1); if (ret) { gf_msg (this->name, GF_LOG_ERROR, errno, diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index 61c79655ccf..8f2a23a898a 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c @@ -2677,8 +2677,6 @@ glusterd_stop_volume (glusterd_volinfo_t *volinfo) { int ret = -1; glusterd_brickinfo_t *brickinfo = NULL; - char mountdir[PATH_MAX] = {0,}; - char pidfile[PATH_MAX] = {0,}; xlator_t *this = NULL; glusterd_svc_t *svc = NULL; @@ -2707,24 +2705,6 @@ glusterd_stop_volume (glusterd_volinfo_t *volinfo) goto out; } - /* If quota auxiliary mount is present, unmount it */ - GLUSTERFS_GET_AUX_MOUNT_PIDFILE (pidfile, volinfo->volname); - - if (!gf_is_service_running (pidfile, NULL)) { - gf_msg_debug (this->name, 0, "Aux mount of volume %s " - "absent", volinfo->volname); - } else { - GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (mountdir, volinfo->volname, - "/"); - - ret = gf_umount_lazy (this->name, mountdir, 0); - if (ret) - gf_msg (this->name, GF_LOG_ERROR, errno, - GD_MSG_UNOUNT_FAILED, - "umount on %s failed", - mountdir); - } - if (!volinfo->is_snap_volume) { svc = &(volinfo->snapd.svc); ret = svc->manager (svc, volinfo, PROC_START_NO_WAIT); @@ -2809,10 +2789,6 @@ glusterd_op_delete_volume (dict_t *dict) goto out; } - ret = glusterd_remove_auxiliary_mount (volname); - if (ret) - goto out; - ret = glusterd_delete_volume (volinfo); out: gf_msg_debug (this->name, 0, "returning %d", ret); diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c index 26cd0fc4f25..c2272558939 100644 --- a/xlators/mgmt/glusterd/src/glusterd.c +++ b/xlators/mgmt/glusterd/src/glusterd.c @@ -244,7 +244,8 @@ glusterd_fetchspec_notify (xlator_t *this) list_for_each_entry (trans, &priv->xprt_list, list) { rpcsvc_callback_submit (priv->rpc, trans, &glusterd_cbk_prog, - GF_CBK_FETCHSPEC, NULL, 0); + GF_CBK_FETCHSPEC, NULL, 0, + NULL); } } pthread_mutex_unlock (&priv->xprt_lock); @@ -280,7 +281,8 @@ glusterd_fetchsnap_notify (xlator_t *this) list_for_each_entry (trans, &priv->xprt_list, list) { rpcsvc_callback_submit (priv->rpc, trans, &glusterd_cbk_prog, - GF_CBK_GET_SNAPS, NULL, 0); + GF_CBK_GET_SNAPS, NULL, 0, + NULL); } } pthread_mutex_unlock (&priv->xprt_lock); diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 4795f958038..7c59d5501a9 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -597,9 +597,15 @@ typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args); #define GLUSTERD_GET_QUOTAD_DIR(path, priv) \ snprintf (path, PATH_MAX, "%s/quotad", priv->workdir); -#define GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH(abspath, volname, path) \ - snprintf (abspath, sizeof (abspath)-1, \ - DEFAULT_VAR_RUN_DIRECTORY"/%s%s", volname, path); +#define GLUSTERD_GET_QUOTA_LIMIT_MOUNT_PATH(abspath, volname, path) do { \ + snprintf (abspath, sizeof (abspath)-1, \ + DEFAULT_VAR_RUN_DIRECTORY"/%s_quota_limit%s", volname, path);\ + } while (0) + +#define GLUSTERD_GET_QUOTA_LIST_MOUNT_PATH(abspath, volname, path) do { \ + snprintf (abspath, sizeof (abspath)-1, \ + DEFAULT_VAR_RUN_DIRECTORY"/%s_quota_list%s", volname, path);\ + } while (0) #define GLUSTERD_GET_TMP_PATH(abspath, path) do { \ snprintf (abspath, sizeof (abspath)-1, \ @@ -688,11 +694,19 @@ typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args); uuid_utoa(MY_UUID)); \ } while (0) -#define GLUSTERFS_GET_AUX_MOUNT_PIDFILE(pidfile, volname) { \ +#define GLUSTERFS_GET_QUOTA_LIMIT_MOUNT_PIDFILE(pidfile, volname) { \ snprintf (pidfile, PATH_MAX-1, \ - DEFAULT_VAR_RUN_DIRECTORY"/%s.pid", volname); \ + DEFAULT_VAR_RUN_DIRECTORY"/%s_quota_limit.pid", \ + volname); \ } +#define GLUSTERFS_GET_QUOTA_LIST_MOUNT_PIDFILE(pidfile, volname) { \ + snprintf (pidfile, PATH_MAX-1, \ + DEFAULT_VAR_RUN_DIRECTORY"/%s_quota_list.pid", \ + volname); \ + } + + #define GLUSTERD_GET_UUID_NOHYPHEN(ret_string, uuid) do { \ char *snap_volname_ptr = ret_string; \ char *snap_volid_ptr = uuid_utoa(uuid); \ diff --git a/xlators/nfs/server/src/nfs-common.c b/xlators/nfs/server/src/nfs-common.c index a39a0e6ee3a..fca38ba6b87 100644 --- a/xlators/nfs/server/src/nfs-common.c +++ b/xlators/nfs/server/src/nfs-common.c @@ -73,10 +73,11 @@ nfs_xlator_to_xlid (xlator_list_t *cl, xlator_t *xl) xlator_t * nfs_mntpath_to_xlator (xlator_list_t *cl, char *path) { - char *volname = NULL; - char *volptr = NULL; - size_t pathlen; + char *volname = NULL; + char *volptr = NULL; + size_t pathlen = -1; xlator_t *targetxl = NULL; + int i = 0; if ((!cl) || (!path)) return NULL; @@ -89,10 +90,17 @@ nfs_mntpath_to_xlator (xlator_list_t *cl, char *path) else volptr = &volname[0]; - if (pathlen && volname[pathlen - 1] == '/') - volname[pathlen - 1] = '\0'; + for (i = 0; i < pathlen; i++) { + if (volname[i] == '/') { + volname[i] = '\0'; + break; + } + } while (cl) { + gf_msg_trace (GF_NFS, 0, "Volptr: %s and cl->xlator->name: %s", + volptr, cl->xlator->name); + if (strcmp (volptr, cl->xlator->name) == 0) { targetxl = cl->xlator; break; diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c index d7eaca14b38..2426028ed2d 100644 --- a/xlators/nfs/server/src/nfs3.c +++ b/xlators/nfs/server/src/nfs3.c @@ -28,6 +28,7 @@ #include "xdr-rpc.h" #include "xdr-generic.h" #include "nfs-messages.h" +#include "glfs-internal.h" #include <sys/socket.h> #include <sys/uio.h> @@ -367,28 +368,68 @@ out: } -#define nfs3_funge_solaris_zerolen_fh(nfs3st, fhd, enam, nfsst, erl) \ - do { \ - xlator_t *fungexl = NULL; \ - uuid_t zero = {0, }; \ - fungexl =nfs_mntpath_to_xlator ((nfs3st)->exportslist,enam);\ - if (!fungexl) { \ - (nfsst) = NFS3ERR_NOENT; \ - goto erl; \ - } \ - \ - gf_uuid_copy ((fhd)->gfid, zero); \ - (fhd)->gfid[15] = 1; \ - (enam) = NULL; \ - if ((gf_nfs_dvm_off (nfs_state (nfs3st->nfsx)))) \ - (fhd)->exportid[15] = nfs_xlator_to_xlid ((nfs3st)->exportslist, fungexl); \ - else { \ - if(__nfs3_get_volume_id ((nfs3st), fungexl, (fhd)->exportid) < 0) { \ - (nfsst) = NFS3ERR_STALE; \ - goto erl; \ - } \ - } \ - } while (0) \ +static enum nfsstat3 +nfs3_funge_webnfs_zerolen_fh (struct nfs3_state *nfs3st, struct nfs3_fh *fhd, + char *name) +{ + xlator_t *fungexl = NULL; + glfs_t *fs = NULL; + loc_t loc = { 0, }; + enum nfsstat3 nfsstat = NFS3ERR_SERVERFAULT; + int ret = -1; + size_t namelen = -1; + + fungexl = nfs_mntpath_to_xlator (nfs3st->exportslist, name); + if (!fungexl) { + nfsstat = NFS3ERR_NOENT; + goto out; + } + + /* glfs_resolve_at copied from UDP MNT support */ + fs = glfs_new_from_ctx (fungexl->ctx); + if (!fs) { + nfsstat = NFS3ERR_NOENT; + goto out; + } + + /* strip volname/ from 'name' */ + namelen = strlen(name); + while (namelen != 0) { + name++; + if (name[0] == '/') { + break; + } + namelen--; + } + gf_msg_debug (GF_NFS, 0, "NAME :%s ", name); + + ret = glfs_resolve_at (fs, fungexl, NULL, name, &loc, NULL, 1, 0); + if (ret != 0) { + nfsstat = NFS3ERR_NOENT; + goto out; + } + + /* resolved subdir, copy gfid for the fh */ + gf_uuid_copy (fhd->gfid, loc.gfid); + loc_wipe (&loc); + + if (gf_nfs_dvm_off (nfs_state (nfs3st->nfsx))) + fhd->exportid[15] = nfs_xlator_to_xlid (nfs3st->exportslist, + fungexl); + else { + if (__nfs3_get_volume_id (nfs3st, fungexl, fhd->exportid) < 0) { + nfsstat = NFS3ERR_STALE; + goto out; + } + } + + nfsstat = NFS3_OK; +out: + if (fs) + glfs_free_from_ctx (fs); + + return nfsstat; +} /* @@ -1563,9 +1604,14 @@ nfs3_lookup (rpcsvc_request_t *req, struct nfs3_fh *fh, int fhlen, char *name) nfs3_log_fh_entry_call (rpcsvc_request_xid (req), "LOOKUP", fh, name); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); - if (nfs3_solaris_zerolen_fh (fh, fhlen)) - nfs3_funge_solaris_zerolen_fh (nfs3, fh, name, stat, nfs3err); - else + if (nfs3_solaris_zerolen_fh (fh, fhlen)) { + stat = nfs3_funge_webnfs_zerolen_fh (nfs3, fh, name); + if (stat != NFS3_OK) + goto nfs3err; + + /* this fh means we're doing a mount, name is no more useful */ + name = NULL; + } else nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); diff --git a/xlators/nfs/server/src/nlm4.c b/xlators/nfs/server/src/nlm4.c index 3da3b2d1c05..8580448b762 100644 --- a/xlators/nfs/server/src/nlm4.c +++ b/xlators/nfs/server/src/nlm4.c @@ -45,7 +45,7 @@ /* TODO: * 1) 2 opens racing .. creating an fd leak. - * 2) use mempool for nlmclnt - destroy if no fd exists, create during 1st call + * 2) use GF_REF_* for nlm_clnt_t */ typedef ssize_t (*nlm4_serializer) (struct iovec outmsg, void *args); @@ -333,6 +333,24 @@ ret: return rpc_clnt; } +static void +nlm_client_free (nlm_client_t *nlmclnt) +{ + list_del (&nlmclnt->fdes); + list_del (&nlmclnt->nlm_clients); + list_del (&nlmclnt->shares); + + GF_FREE (nlmclnt->caller_name); + + if (nlmclnt->rpc_clnt) { + /* cleanup the saved-frames before last unref */ + rpc_clnt_connection_cleanup (&nlmclnt->rpc_clnt->conn); + /* rpc_clnt_connection_cleanup() calls rpc_clnt_unref() */ + } + + GF_FREE (nlmclnt); +} + int nlm_set_rpc_clnt (rpc_clnt_t *rpc_clnt, char *caller_name) { @@ -375,26 +393,16 @@ int nlm_unset_rpc_clnt (rpc_clnt_t *rpc) { nlm_client_t *nlmclnt = NULL; - rpc_clnt_t *rpc_clnt = NULL; LOCK (&nlm_client_list_lk); list_for_each_entry (nlmclnt, &nlm_client_list, nlm_clients) { if (rpc == nlmclnt->rpc_clnt) { - rpc_clnt = nlmclnt->rpc_clnt; - nlmclnt->rpc_clnt = NULL; + nlm_client_free (nlmclnt); break; } } UNLOCK (&nlm_client_list_lk); - if (rpc_clnt == NULL) { - return -1; - } - if (rpc_clnt) { - /* cleanup the saved-frames before last unref */ - rpc_clnt_connection_cleanup (&rpc_clnt->conn); - rpc_clnt_unref (rpc_clnt); - } return 0; } @@ -923,10 +931,16 @@ nlm_rpcclnt_notify (struct rpc_clnt *rpc_clnt, void *mydata, nfs3_call_state_t *cs = NULL; cs = mydata; - caller_name = cs->args.nlm4_lockargs.alock.caller_name; switch (fn) { case RPC_CLNT_CONNECT: + if (!cs->req) { + gf_msg (GF_NLM, GF_LOG_ERROR, EINVAL, + NFS_MSG_RPC_CLNT_ERROR, "Spurious notify?!"); + goto err; + } + + caller_name = cs->args.nlm4_lockargs.alock.caller_name; ret = nlm_set_rpc_clnt (rpc_clnt, caller_name); if (ret == -1) { gf_msg (GF_NLM, GF_LOG_ERROR, 0, @@ -934,8 +948,8 @@ nlm_rpcclnt_notify (struct rpc_clnt *rpc_clnt, void *mydata, "rpc clnt"); goto err; } - rpc_clnt_unref (rpc_clnt); nlm4svc_send_granted (cs); + rpc_clnt_unref (rpc_clnt); break; @@ -1199,7 +1213,7 @@ ret: } void -nlm_search_and_delete (fd_t *fd, char *caller_name) +nlm_search_and_delete (fd_t *fd, nlm4_lock *lk) { nlm_fde_t *fde = NULL; nlm_client_t *nlmclnt = NULL; @@ -1210,7 +1224,7 @@ nlm_search_and_delete (fd_t *fd, char *caller_name) LOCK (&nlm_client_list_lk); list_for_each_entry (nlmclnt, &nlm_client_list, nlm_clients) { - if (!strcmp(caller_name, nlmclnt->caller_name)) { + if (!strcmp (lk->caller_name, nlmclnt->caller_name)) { nlmclnt_found = 1; break; } @@ -1233,6 +1247,9 @@ nlm_search_and_delete (fd_t *fd, char *caller_name) goto ret; list_del (&fde->fde_list); + if (list_empty (&nlmclnt->fdes) && list_empty (&nlmclnt->shares)) + nlm_client_free (nlmclnt); + ret: UNLOCK (&nlm_client_list_lk); @@ -1348,7 +1365,8 @@ nlm4svc_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (op_ret == -1) { if (transit_cnt == 0) - nlm_search_and_delete (cs->fd, caller_name); + nlm_search_and_delete (cs->fd, + &cs->args.nlm4_lockargs.alock); stat = nlm4_errno_to_nlm4stat (op_errno); goto err; } else { @@ -1539,8 +1557,10 @@ nlm4svc_cancel_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (op_ret == -1) { stat = nlm4_errno_to_nlm4stat (op_errno); goto err; - } else + } else { stat = nlm4_granted; + nlm_search_and_delete (cs->fd, &cs->args.nlm4_lockargs.alock); + } err: nlm4_generic_reply (cs->req, cs->args.nlm4_cancargs.cookie, @@ -1693,7 +1713,7 @@ nlm4svc_unlock_cbk (call_frame_t *frame, void *cookie, xlator_t *this, stat = nlm4_granted; if (flock->l_type == F_UNLCK) nlm_search_and_delete (cs->fd, - cs->args.nlm4_unlockargs.alock.caller_name); + &cs->args.nlm4_unlockargs.alock); } err: @@ -1730,18 +1750,20 @@ nlm4_unlock_resume (void *carg) int ret = -1; nfs3_call_state_t *cs = NULL; nlm_client_t *nlmclnt = NULL; + char *caller_name = NULL; if (!carg) return ret; cs = (nfs3_call_state_t *)carg; nlm4_check_fh_resolve_status (cs, stat, nlm4err); + caller_name = cs->args.nlm4_unlockargs.alock.caller_name; - nlmclnt = nlm_get_uniq (cs->args.nlm4_unlockargs.alock.caller_name); + nlmclnt = nlm_get_uniq (caller_name); if (nlmclnt == NULL) { stat = nlm4_granted; gf_msg (GF_NLM, GF_LOG_WARNING, ENOLCK, NFS_MSG_NO_MEMORY, - "nlm_get_uniq() returned NULL"); + "nlm_get_uniq() returned NULL for %s", caller_name); goto nlm4err; } cs->fd = fd_lookup_uint64 (cs->resolvedloc.inode, (uint64_t)nlmclnt); diff --git a/xlators/performance/read-ahead/src/page.c b/xlators/performance/read-ahead/src/page.c index 216e327af74..17e346ec947 100644 --- a/xlators/performance/read-ahead/src/page.c +++ b/xlators/performance/read-ahead/src/page.c @@ -139,6 +139,7 @@ ra_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this, ra_waitq_t *waitq = NULL; fd_t *fd = NULL; uint64_t tmp_file = 0; + gf_boolean_t stale = _gf_false; GF_ASSERT (frame); @@ -174,6 +175,13 @@ ra_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this, goto unlock; } + if (page->stale) { + page->stale = 0; + page->ready = 0; + stale = 1; + goto unlock; + } + /* * "Dirty" means that the request was a pure read-ahead; it's * set for requests we issue ourselves, and cleared when user @@ -219,6 +227,16 @@ ra_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this, unlock: ra_file_unlock (file); + if (stale) { + STACK_WIND (frame, ra_fault_cbk, + FIRST_CHILD (frame->this), + FIRST_CHILD (frame->this)->fops->readv, + local->fd, local->pending_size, + local->pending_offset, 0, NULL); + + return 0; + } + ra_waitq_return (waitq); fd_unref (local->fd); diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c index 3e18b4870ae..aa9cf9b31e4 100644 --- a/xlators/protocol/client/src/client.c +++ b/xlators/protocol/client/src/client.c @@ -2341,7 +2341,7 @@ client_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, } else { if (conf->quick_reconnect) { conf->quick_reconnect = 0; - rpc_clnt_start (rpc); + rpc_clnt_cleanup_and_start (rpc); } else { rpc->conn.config.remote_port = 0; } diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c index 10009e2b4a7..7ab0862b0a2 100644 --- a/xlators/protocol/server/src/server.c +++ b/xlators/protocol/server/src/server.c @@ -1235,12 +1235,18 @@ server_process_event_upcall (xlator_t *this, void *data) if (!client || strcmp(client->client_uid, client_uid)) continue; - rpcsvc_request_submit(conf->rpc, xprt, - &server_cbk_prog, - cbk_procnum, - up_req, - this->ctx, - xdrproc); + ret = rpcsvc_request_submit (conf->rpc, xprt, + &server_cbk_prog, + cbk_procnum, + up_req, + this->ctx, + xdrproc); + if (ret < 0) { + gf_msg_debug (this->name, 0, "Failed to send " + "upcall to client:%s upcall " + "event:%d", client_uid, + upcall_data->event_type); + } break; } } @@ -1272,7 +1278,7 @@ server_process_child_event (xlator_t *this, int32_t event, void *data, rpcsvc_callback_submit (conf->rpc, xprt, &server_cbk_prog, cbk_procnum, - NULL, 0); + NULL, 0, NULL); } } pthread_mutex_unlock (&conf->mutex); diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index f8e1948e3d5..4aa39514486 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -95,6 +95,57 @@ out: return flag; } +int +posix_handle_georep_xattrs (call_frame_t *frame, const char *name, + int *op_errno, gf_boolean_t is_getxattr) +{ + + int i = 0; + int ret = 0; + int pid = 1; + gf_boolean_t filter_xattr = _gf_true; + static const char *georep_xattr[] = { "*.glusterfs.*.stime", + "*.glusterfs.*.xtime", + "*.glusterfs.*.entry_stime", + NULL + }; + if (frame && frame->root) { + pid = frame->root->pid; + } + + if (!name) { + /* No need to do anything here */ + ret = 0; + goto out; + } + + if (pid == GF_CLIENT_PID_GSYNCD && is_getxattr) { + filter_xattr = _gf_false; + + /* getxattr from gsyncd process should return all the + * internal xattr. In other cases ignore such xattrs + */ + } + + for (i = 0; filter_xattr && georep_xattr[i]; i++) { + if (fnmatch (georep_xattr[i] , name, FNM_PERIOD) == 0) { + ret = -1; + if (op_errno) + *op_errno = ENOATTR; + + gf_msg_debug ("posix", ENOATTR, + "Ignoring the key %s as an internal " + "xattrs.", name); + goto out; + } + } + + ret = 0; +out: + return ret; +} + + static gf_boolean_t _is_in_array (char **str_array, char *str) { @@ -731,7 +782,7 @@ _handle_list_xattr (dict_t *xattr_req, const char *real_path, int fdnum, if (posix_special_xattr (marker_xattrs, key)) goto next; - if (!fnmatch (GF_XATTR_STIME_PATTERN, key, 0)) + if (posix_handle_georep_xattrs (NULL, key, NULL, _gf_false)) goto next; if (dict_get (filler->xattr, key)) @@ -1499,23 +1550,21 @@ posix_gfid_heal (xlator_t *this, const char *path, loc_t *loc, dict_t *xattr_req struct stat stat = {0, }; if (!xattr_req) - goto out; + return 0; - if (sys_lstat (path, &stat) != 0) - goto out; + if (sys_lstat (path, &stat) != 0) { + return -errno; + } ret = sys_lgetxattr (path, GFID_XATTR_KEY, uuid_curr, 16); if (ret != 16) { if (is_fresh_file (&stat)) { - ret = -1; - errno = ENOENT; - goto out; + return -ENOENT; } } - ret = posix_gfid_set (this, path, loc, xattr_req); -out: - return ret; + posix_gfid_set (this, path, loc, xattr_req); + return 0; } @@ -1663,6 +1712,10 @@ __posix_fd_ctx_get (fd_t *fd, xlator_t *this, struct posix_fd **pfd_p, dir = sys_opendir (real_path); if (!dir) { op_errno = errno; + gf_msg (this->name, GF_LOG_ERROR, op_errno, + P_MSG_READ_FAILED, + "Failed to get anonymous fd for " + "real_path: %s.", real_path); GF_FREE (pfd); pfd = NULL; goto out; @@ -1686,8 +1739,9 @@ __posix_fd_ctx_get (fd_t *fd, xlator_t *this, struct posix_fd **pfd_p, op_errno = errno; gf_msg (this->name, GF_LOG_ERROR, op_errno, P_MSG_READ_FAILED, - "Failed to get anonymous " - "real_path: %s _fd = %d", real_path, _fd); + "Failed to get anonymous fd for " + "real_path: %s.", real_path); + GF_FREE (pfd); pfd = NULL; goto out; @@ -2214,10 +2268,14 @@ __posix_inode_ctx_get (inode_t *inode, xlator_t *this) return NULL; pthread_mutex_init (&ctx_p->xattrop_lock, NULL); + pthread_mutex_init (&ctx_p->write_atomic_lock, NULL); + pthread_mutex_init (&ctx_p->pgfid_lock, NULL); ret = __inode_ctx_set (inode, this, (uint64_t *)&ctx_p); if (ret < 0) { pthread_mutex_destroy (&ctx_p->xattrop_lock); + pthread_mutex_destroy (&ctx_p->write_atomic_lock); + pthread_mutex_destroy (&ctx_p->pgfid_lock); GF_FREE (ctx_p); return NULL; } diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 859df6cefac..e56e71e8c27 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -136,6 +136,8 @@ posix_forget (xlator_t *this, inode_t *inode) } out: pthread_mutex_destroy (&ctx->xattrop_lock); + pthread_mutex_destroy (&ctx->write_atomic_lock); + pthread_mutex_destroy (&ctx->pgfid_lock); GF_FREE (ctx); return ret; } @@ -158,6 +160,7 @@ posix_lookup (call_frame_t *frame, xlator_t *this, char *pgfid_xattr_key = NULL; int32_t nlink_samepgfid = 0; struct posix_private *priv = NULL; + posix_inode_ctx_t *ctx = NULL; VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (this, out); @@ -193,7 +196,12 @@ posix_lookup (call_frame_t *frame, xlator_t *this, MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &buf); if (gf_uuid_is_null (loc->inode->gfid)) { - posix_gfid_heal (this, real_path, loc, xdata); + op_ret = posix_gfid_heal (this, real_path, loc, xdata); + if (op_ret < 0) { + op_errno = -op_ret; + op_ret = -1; + goto out; + } MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &buf); } @@ -224,7 +232,14 @@ posix_lookup (call_frame_t *frame, xlator_t *this, PGFID_XATTR_KEY_PREFIX, loc->pargfid); - LOCK (&loc->inode->lock); + op_ret = posix_inode_ctx_get_all (loc->inode, this, + &ctx); + if (op_ret < 0) { + op_errno = ENOMEM; + goto out; + } + + pthread_mutex_lock (&ctx->pgfid_lock); { SET_PGFID_XATTR_IF_ABSENT (real_path, pgfid_xattr_key, @@ -233,7 +248,7 @@ posix_lookup (call_frame_t *frame, xlator_t *this, this, unlock); } unlock: - UNLOCK (&loc->inode->lock); + pthread_mutex_unlock (&ctx->pgfid_lock); } } @@ -768,6 +783,7 @@ posix_do_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd, struct posix_fd *pfd = NULL; gf_boolean_t locked = _gf_false; struct posix_private *priv = this->private; + posix_inode_ctx_t *ctx = NULL; DECLARE_OLD_FS_ID_VAR; @@ -789,9 +805,15 @@ posix_do_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd, goto out; } + ret = posix_inode_ctx_get_all (fd->inode, this, &ctx); + if (ret < 0) { + ret = -ENOMEM; + goto out; + } + if (dict_get (xdata, GLUSTERFS_WRITE_UPDATE_ATOMIC)) { locked = _gf_true; - LOCK(&fd->inode->lock); + pthread_mutex_lock (&ctx->write_atomic_lock); } ret = posix_fdstat (this, pfd->fd, statpre); @@ -818,7 +840,7 @@ posix_do_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd, out: if (locked) { - UNLOCK (&fd->inode->lock); + pthread_mutex_unlock (&ctx->write_atomic_lock); locked = _gf_false; } SET_TO_OLD_FS_ID (); @@ -932,6 +954,7 @@ posix_do_zerofill (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, int32_t flags = 0; struct posix_fd *pfd = NULL; gf_boolean_t locked = _gf_false; + posix_inode_ctx_t *ctx = NULL; DECLARE_OLD_FS_ID_VAR; @@ -947,9 +970,15 @@ posix_do_zerofill (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, goto out; } + ret = posix_inode_ctx_get_all (fd->inode, this, &ctx); + if (ret < 0) { + ret = -ENOMEM; + goto out; + } + if (dict_get (xdata, GLUSTERFS_WRITE_UPDATE_ATOMIC)) { locked = _gf_true; - LOCK(&fd->inode->lock); + pthread_mutex_lock (&ctx->write_atomic_lock); } ret = posix_fdstat (this, pfd->fd, statpre); @@ -999,7 +1028,7 @@ fsync: out: if (locked) { - UNLOCK (&fd->inode->lock); + pthread_mutex_unlock (&ctx->write_atomic_lock); locked = _gf_false; } SET_TO_OLD_FS_ID (); @@ -1998,6 +2027,7 @@ posix_unlink (call_frame_t *frame, xlator_t *this, char uuid_str[GF_UUID_BUF_SIZE] = {0}; char gfid_str[GF_UUID_BUF_SIZE] = {0}; gf_boolean_t get_link_count = _gf_false; + posix_inode_ctx_t *ctx = NULL; DECLARE_OLD_FS_ID_VAR; @@ -2101,14 +2131,19 @@ posix_unlink (call_frame_t *frame, xlator_t *this, if (priv->update_pgfid_nlinks && (stbuf.ia_nlink > 1)) { MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX, loc->pargfid); - LOCK (&loc->inode->lock); + op_ret = posix_inode_ctx_get_all (loc->inode, this, &ctx); + if (op_ret < 0) { + op_errno = ENOMEM; + goto out; + } + pthread_mutex_lock (&ctx->pgfid_lock); { UNLINK_MODIFY_PGFID_XATTR (real_path, pgfid_xattr_key, nlink_samepgfid, 0, op_ret, this, unlock); } unlock: - UNLOCK (&loc->inode->lock); + pthread_mutex_unlock (&ctx->pgfid_lock); if (op_ret < 0) { gf_msg (this->name, GF_LOG_WARNING, 0, @@ -2463,6 +2498,8 @@ posix_rename (call_frame_t *frame, xlator_t *this, dict_t *unwind_dict = NULL; gf_boolean_t locked = _gf_false; gf_boolean_t get_link_count = _gf_false; + posix_inode_ctx_t *ctx_old = NULL; + posix_inode_ctx_t *ctx_new = NULL; DECLARE_OLD_FS_ID_VAR; @@ -2545,10 +2582,26 @@ posix_rename (call_frame_t *frame, xlator_t *this, goto out; } + op_ret = posix_inode_ctx_get_all (oldloc->inode, this, &ctx_old); + if (op_ret < 0) { + op_ret = -1; + op_errno = ENOMEM; + goto out; + } + + if (newloc->inode) { + op_ret = posix_inode_ctx_get_all (newloc->inode, this, &ctx_new); + if (op_ret < 0) { + op_ret = -1; + op_errno = ENOMEM; + goto out; + } + } + if (IA_ISDIR (oldloc->inode->ia_type)) posix_handle_unset (this, oldloc->inode->gfid, NULL); - LOCK (&oldloc->inode->lock); + pthread_mutex_lock (&ctx_old->pgfid_lock); { if (priv->update_pgfid_nlinks) { MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, @@ -2563,7 +2616,7 @@ posix_rename (call_frame_t *frame, xlator_t *this, if ((xdata) && (dict_get (xdata, GET_LINK_COUNT)) && (real_newpath) && (was_present)) { - LOCK (&newloc->inode->lock); + pthread_mutex_lock (&ctx_new->pgfid_lock); locked = _gf_true; get_link_count = _gf_true; op_ret = posix_pstat (this, newloc->gfid, real_newpath, @@ -2605,7 +2658,7 @@ posix_rename (call_frame_t *frame, xlator_t *this, } if (locked) { - UNLOCK (&newloc->inode->lock); + pthread_mutex_unlock (&ctx_new->pgfid_lock); locked = _gf_false; } @@ -2629,10 +2682,10 @@ posix_rename (call_frame_t *frame, xlator_t *this, } unlock: if (locked) { - UNLOCK (&newloc->inode->lock); + pthread_mutex_unlock (&ctx_new->pgfid_lock); locked = _gf_false; } - UNLOCK (&oldloc->inode->lock); + pthread_mutex_unlock (&ctx_old->pgfid_lock); if (op_ret < 0) { gf_msg (this->name, GF_LOG_WARNING, 0, P_MSG_XATTR_FAILED, @@ -2713,6 +2766,7 @@ posix_link (call_frame_t *frame, xlator_t *this, int32_t nlink_samepgfid = 0; char *pgfid_xattr_key = NULL; gf_boolean_t entry_created = _gf_false; + posix_inode_ctx_t *ctx = NULL; DECLARE_OLD_FS_ID_VAR; @@ -2779,14 +2833,20 @@ posix_link (call_frame_t *frame, xlator_t *this, MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX, newloc->pargfid); - LOCK (&newloc->inode->lock); + op_ret = posix_inode_ctx_get_all (newloc->inode, this, &ctx); + if (op_ret < 0) { + op_errno = ENOMEM; + goto out; + } + + pthread_mutex_lock (&ctx->pgfid_lock); { LINK_MODIFY_PGFID_XATTR (real_newpath, pgfid_xattr_key, nlink_samepgfid, 0, op_ret, this, unlock); } unlock: - UNLOCK (&newloc->inode->lock); + pthread_mutex_unlock (&ctx->pgfid_lock); if (op_ret < 0) { gf_msg (this->name, GF_LOG_WARNING, 0, @@ -3401,6 +3461,7 @@ posix_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, gf_boolean_t locked = _gf_false; gf_boolean_t write_append = _gf_false; gf_boolean_t update_atomic = _gf_false; + posix_inode_ctx_t *ctx = NULL; VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (this, out); @@ -3422,7 +3483,6 @@ posix_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, if (ret < 0) { gf_msg (this->name, GF_LOG_WARNING, ret, P_MSG_PFD_NULL, "pfd is NULL from fd=%p", fd); - op_errno = -ret; goto out; } @@ -3450,9 +3510,15 @@ posix_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, * as of today). */ + op_ret = posix_inode_ctx_get_all (fd->inode, this, &ctx); + if (op_ret < 0) { + op_errno = ENOMEM; + goto out; + } + if (write_append || update_atomic) { locked = _gf_true; - LOCK(&fd->inode->lock); + pthread_mutex_lock (&ctx->write_atomic_lock); } op_ret = posix_fdstat (this, _fd, &preop); @@ -3472,7 +3538,7 @@ posix_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, (pfd->flags & O_DIRECT)); if (locked && (!update_atomic)) { - UNLOCK (&fd->inode->lock); + pthread_mutex_unlock (&ctx->write_atomic_lock); locked = _gf_false; } @@ -3502,7 +3568,7 @@ posix_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, } if (locked) { - UNLOCK (&fd->inode->lock); + pthread_mutex_unlock (&ctx->write_atomic_lock); locked = _gf_false; } @@ -3528,7 +3594,7 @@ posix_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, out: if (locked) { - UNLOCK (&fd->inode->lock); + pthread_mutex_unlock (&ctx->write_atomic_lock); locked = _gf_false; } @@ -4416,11 +4482,10 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, op_ret = -1; priv = this->private; - /* Allow access to stime xattr only to geo-rep worker */ - if (frame->root->pid != GF_CLIENT_PID_GSYNCD && name && - fnmatch ("*.glusterfs.*.stime", name, FNM_PERIOD) == 0) { + ret = posix_handle_georep_xattrs (frame, name, &op_errno, _gf_true); + if (ret == -1) { op_ret = -1; - op_errno = ENOATTR; + /* errno should be set from the above function*/ goto out; } @@ -4732,9 +4797,11 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, remaining_size = size; list_offset = 0; while (remaining_size > 0) { - strcpy (keybuffer, list + list_offset); - if (frame->root->pid != GF_CLIENT_PID_GSYNCD && - fnmatch ("*.glusterfs.*.stime", keybuffer, FNM_PERIOD) == 0) + strncpy (keybuffer, list + list_offset, sizeof(keybuffer)); + + ret = posix_handle_georep_xattrs (frame, keybuffer, NULL, + _gf_false); + if (ret == -1) goto ignore; size = sys_lgetxattr (real_path, keybuffer, NULL, 0); @@ -5952,7 +6019,6 @@ posix_fstat (call_frame_t *frame, xlator_t *this, if (ret < 0) { gf_msg (this->name, GF_LOG_WARNING, op_errno, P_MSG_PFD_NULL, "pfd is NULL, fd=%p", fd); - op_errno = -ret; goto out; } @@ -6384,7 +6450,7 @@ posix_do_readdir (call_frame_t *frame, xlator_t *this, ret = posix_fd_ctx_get (fd, this, &pfd, &op_errno); if (ret < 0) { - gf_msg (this->name, GF_LOG_WARNING, -ret, P_MSG_PFD_NULL, + gf_msg (this->name, GF_LOG_WARNING, op_errno, P_MSG_PFD_NULL, "pfd is NULL, fd=%p", fd); goto out; } diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index 2249b238e8b..a2e1201dd72 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -200,6 +200,8 @@ typedef struct { typedef struct { uint64_t unlink_flag; pthread_mutex_t xattrop_lock; + pthread_mutex_t write_atomic_lock; + pthread_mutex_t pgfid_lock; } posix_inode_ctx_t; #define POSIX_BASE_PATH(this) (((struct posix_private *)this->private)->base_path) @@ -280,7 +282,8 @@ int posix_get_ancestry (xlator_t *this, inode_t *leaf_inode, gf_dirent_t *head, char **path, int type, int32_t *op_errno, dict_t *xdata); - +int +posix_handle_georep_xattrs (call_frame_t *, const char *, int *, gf_boolean_t); void posix_gfid_unset (xlator_t *this, dict_t *xdata); diff --git a/xlators/system/posix-acl/src/posix-acl.c b/xlators/system/posix-acl/src/posix-acl.c index 8a212020a5f..1c82e8b2239 100644 --- a/xlators/system/posix-acl/src/posix-acl.c +++ b/xlators/system/posix-acl/src/posix-acl.c @@ -62,6 +62,10 @@ whitelisted_xattr (const char *key) return 1; if (strcmp (POSIX_ACL_DEFAULT_XATTR, key) == 0) return 1; + if (strcmp (GF_POSIX_ACL_ACCESS, key) == 0) + return 1; + if (strcmp (GF_POSIX_ACL_DEFAULT, key) == 0) + return 1; return 0; } |