diff options
author | Jeff Darcy <jdarcy@redhat.com> | 2014-01-28 12:49:39 +0000 |
---|---|---|
committer | Jeff Darcy <jdarcy@redhat.com> | 2014-01-28 12:49:39 +0000 |
commit | 738e76f0799fa598eac308144174c6cf9db21b7a (patch) | |
tree | 0cb787d50ff0753b81cd3b0913476c27adbe4686 | |
parent | 007182f1aad9d14e8d5bc7771d500b35026f0afa (diff) | |
parent | 6dfe01d7e726675913e98dc65c6c7406e5060e15 (diff) |
Merge branch 'upstream'
66 files changed, 1464 insertions, 781 deletions
diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c index aa359a992..05f0997a8 100644 --- a/api/src/glfs-fops.c +++ b/api/src/glfs-fops.c @@ -2682,23 +2682,23 @@ glfs_fgetxattr (struct glfs_fd *glfd, const char *name, void *value, int glfs_listxattr_process (void *value, size_t size, dict_t *xattr) { - int ret = -1; - - ret = dict_keys_join (NULL, 0, xattr, NULL); + int ret = -1; - if (!value || !size) + if (!value || !size || !xattr) goto out; + ret = dict_keys_join (NULL, 0, xattr, NULL); + if (size < ret) { ret = -1; errno = ERANGE; - goto out; + } else { + dict_keys_join (value, size, xattr, NULL); } - dict_keys_join (value, size, xattr, NULL); + dict_unref (xattr); + out: - if (xattr) - dict_unref (xattr); return ret; } diff --git a/api/src/glfs.c b/api/src/glfs.c index 1bae78d23..174076e39 100644 --- a/api/src/glfs.c +++ b/api/src/glfs.c @@ -68,6 +68,10 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx) xlator_mem_acct_init (THIS, glfs_mt_end + 1); + if (!ctx) { + goto err; + } + ctx->process_uuid = generate_glusterfs_ctx_id (); if (!ctx->process_uuid) { goto err; @@ -210,20 +214,11 @@ err: static FILE * get_volfp (struct glfs *fs) { - int ret = 0; cmd_args_t *cmd_args = NULL; FILE *specfp = NULL; - struct stat statbuf; cmd_args = &fs->ctx->cmd_args; - ret = lstat (cmd_args->volfile, &statbuf); - if (ret == -1) { - gf_log ("glfs", GF_LOG_ERROR, - "%s: %s", cmd_args->volfile, strerror (errno)); - return NULL; - } - if ((specfp = fopen (cmd_args->volfile, "r")) == NULL) { gf_log ("glfs", GF_LOG_ERROR, "volume file %s: %s", diff --git a/argp-standalone/argp-fmtstream.c b/argp-standalone/argp-fmtstream.c index 7f792854f..494b6b31d 100644 --- a/argp-standalone/argp-fmtstream.c +++ b/argp-standalone/argp-fmtstream.c @@ -389,6 +389,7 @@ __argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...) weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf) #endif +#if __STDC_VERSION__ - 199900L < 1 /* Duplicate the inline definitions in argp-fmtstream.h, for compilers * that don't do inlining. */ size_t @@ -471,5 +472,6 @@ __argp_fmtstream_point (argp_fmtstream_t __fs) __argp_fmtstream_update (__fs); return __fs->point_col >= 0 ? __fs->point_col : 0; } +#endif /* __STDC_VERSION__ - 199900L < 1 */ #endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */ diff --git a/argp-standalone/argp-fmtstream.h b/argp-standalone/argp-fmtstream.h index e797b119e..828f4357d 100644 --- a/argp-standalone/argp-fmtstream.h +++ b/argp-standalone/argp-fmtstream.h @@ -153,6 +153,7 @@ extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs, __const char *__fmt, ...) PRINTF_STYLE(2,3); +#if __STDC_VERSION__ - 199900L < 1 extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); @@ -163,6 +164,7 @@ extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs, __const char *__str, size_t __len); extern size_t argp_fmtstream_write (argp_fmtstream_t __fs, __const char *__str, size_t __len); +#endif /* __STDC_VERSION__ - 199900L < 1 */ /* Access macros for various bits of state. */ #define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin) @@ -172,6 +174,7 @@ extern size_t argp_fmtstream_write (argp_fmtstream_t __fs, #define __argp_fmtstream_rmargin argp_fmtstream_rmargin #define __argp_fmtstream_wmargin argp_fmtstream_wmargin +#if __STDC_VERSION__ - 199900L < 1 /* Set __FS's left margin to LMARGIN and return the old value. */ extern size_t argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin); @@ -193,6 +196,7 @@ extern size_t __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, /* Return the column number of the current output point in __FS. */ extern size_t argp_fmtstream_point (argp_fmtstream_t __fs); extern size_t __argp_fmtstream_point (argp_fmtstream_t __fs); +#endif /* __STDC_VERSION__ - 199900L < 1 */ /* Internal routines. */ extern void _argp_fmtstream_update (argp_fmtstream_t __fs); @@ -216,7 +220,11 @@ extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount); #endif #ifndef ARGP_FS_EI +#if defined(__GNUC__) && !defined(__GNUC_STDC_INLINE__) #define ARGP_FS_EI extern inline +#else +#define ARGP_FS_EI inline +#endif #endif ARGP_FS_EI size_t diff --git a/cli/src/Makefile.am b/cli/src/Makefile.am index 6370c2203..300c00ee9 100644 --- a/cli/src/Makefile.am +++ b/cli/src/Makefile.am @@ -27,3 +27,6 @@ CLEANFILES = $(top_builddir)/libglusterfs/src/libglusterfs.la: $(MAKE) -C $(top_builddir)/libglusterfs/src/ all + +install-data-hook: + $(mkdir_p) $(DESTDIR)$(localstatedir)/run/gluster diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index dd9398184..7a2ff026d 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -1972,10 +1972,13 @@ int32_t cli_cmd_volume_profile_parse (const char **words, int wordcount, dict_t **options) { - dict_t *dict = NULL; - char *volname = NULL; - int ret = -1; - gf1_cli_stats_op op = GF_CLI_STATS_NONE; + dict_t *dict = NULL; + char *volname = NULL; + int ret = -1; + gf1_cli_stats_op op = GF_CLI_STATS_NONE; + gf1_cli_info_op info_op = GF_CLI_INFO_NONE; + gf_boolean_t is_peek = _gf_false; + char *opwords[] = { "start", "stop", "info", NULL }; char *w = NULL; @@ -2005,7 +2008,7 @@ cli_cmd_volume_profile_parse (const char **words, int wordcount, wordcount > 5) goto out; - if (strcmp (w, "info") == 0 && wordcount > 6) + if (strcmp (w, "info") == 0 && wordcount > 7) goto out; if (strcmp (w, "start") == 0) { @@ -2014,16 +2017,22 @@ cli_cmd_volume_profile_parse (const char **words, int wordcount, op = GF_CLI_STATS_STOP; } else if (strcmp (w, "info") == 0) { op = GF_CLI_STATS_INFO; + info_op = GF_CLI_INFO_ALL; if (wordcount > 4) { if (strcmp (words[4], "incremental") == 0) { - op = GF_CLI_STATS_INFO_INCREMENTAL; + info_op = GF_CLI_INFO_INCREMENTAL; + if (wordcount > 5 && + strcmp (words[5], "peek") == 0) { + is_peek = _gf_true; + } } else if (strcmp (words[4], "cumulative") == 0) { - op = GF_CLI_STATS_INFO_CUMULATIVE; + info_op = GF_CLI_INFO_CUMULATIVE; + } else if (strcmp (words[4], "clear") == 0) { + info_op = GF_CLI_INFO_CLEAR; + } else if (strcmp (words[4], "peek") == 0) { + is_peek = _gf_true; } } - ret = dict_set_int32 (dict, "info-op", op); - if (ret) - goto out; } else GF_ASSERT (!"opword mismatch"); @@ -2031,6 +2040,14 @@ cli_cmd_volume_profile_parse (const char **words, int wordcount, if (ret) goto out; + ret = dict_set_int32 (dict, "info-op", (int32_t)info_op); + if (ret) + goto out; + + ret = dict_set_int32 (dict, "peek", is_peek); + if (ret) + goto out; + if (!strcmp (words[wordcount - 1], "nfs")) { ret = dict_set_int32 (dict, "nfs", _gf_true); if (ret) diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index a7e72dabd..9c29b7f3b 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -2334,7 +2334,7 @@ struct cli_cmd volume_cmds[] = { cli_cmd_check_gsync_exists_cbk}, #endif - { "volume profile <VOLNAME> {start | info [incremental | cumulative] | stop} [nfs]", + { "volume profile <VOLNAME> {start|info [peek|incremental [peek]|cumulative|clear]|stop} [nfs]", cli_cmd_volume_profile_cbk, "volume profile operations"}, diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index d1b39014d..0b6bcb54b 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -4775,6 +4775,8 @@ gf_cli_profile_volume_cbk (struct rpc_req *req, struct iovec *iov, char *volname = NULL; char *brick = NULL; char str[1024] = {0,}; + int stats_cleared = 0; + gf1_cli_info_op info_op = GF_CLI_INFO_NONE; if (-1 == req->rpc_status) { goto out; @@ -4840,8 +4842,6 @@ gf_cli_profile_volume_cbk (struct rpc_req *req, struct iovec *iov, (rsp.op_ret) ? "unsuccessful": "successful"); break; case GF_CLI_STATS_INFO: - case GF_CLI_STATS_INFO_INCREMENTAL: - case GF_CLI_STATS_INFO_CUMULATIVE: break; default: cli_out ("volume profile on %s has been %s ", @@ -4856,11 +4856,15 @@ gf_cli_profile_volume_cbk (struct rpc_req *req, struct iovec *iov, goto out; } - if (op < GF_CLI_STATS_INFO || GF_CLI_STATS_INFO_CUMULATIVE < op) { + if (GF_CLI_STATS_INFO != op) { ret = 0; goto out; } + ret = dict_get_int32 (dict, "info-op", (int32_t*)&info_op); + if (ret) + goto out; + ret = dict_get_int32 (dict, "count", &brick_count); if (ret) goto out; @@ -4880,6 +4884,7 @@ gf_cli_profile_volume_cbk (struct rpc_req *req, struct iovec *iov, } ret = dict_get_str_boolean (dict, "nfs", _gf_false); + if (ret) snprintf (str, sizeof (str), "NFS Server : %s", brick); else @@ -4888,15 +4893,25 @@ gf_cli_profile_volume_cbk (struct rpc_req *req, struct iovec *iov, memset (str, '-', strlen (str)); cli_out ("%s", str); - snprintf (key, sizeof (key), "%d-cumulative", i); - ret = dict_get_int32 (dict, key, &interval); - if (ret == 0) { - cmd_profile_volume_brick_out (dict, i, interval); - } - snprintf (key, sizeof (key), "%d-interval", i); - ret = dict_get_int32 (dict, key, &interval); - if (ret == 0) { - cmd_profile_volume_brick_out (dict, i, interval); + if (GF_CLI_INFO_CLEAR == info_op) { + snprintf (key, sizeof (key), "%d-stats-cleared", i); + ret = dict_get_int32 (dict, key, &stats_cleared); + if (ret) + goto out; + cli_out (stats_cleared ? "Cleared stats." : + "Failed to clear stats."); + } else { + snprintf (key, sizeof (key), "%d-cumulative", i); + ret = dict_get_int32 (dict, key, &interval); + if (ret == 0) + cmd_profile_volume_brick_out (dict, i, + interval); + + snprintf (key, sizeof (key), "%d-interval", i); + ret = dict_get_int32 (dict, key, &interval); + if (ret == 0) + cmd_profile_volume_brick_out (dict, i, + interval); } i++; } diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c index 886c372dc..822b98df5 100644 --- a/cli/src/cli-xml-output.c +++ b/cli/src/cli-xml-output.c @@ -2229,11 +2229,13 @@ cli_xml_output_vol_profile (dict_t *dict, int op_ret, int op_errno, xmlDocPtr doc = NULL; char *volname = NULL; int op = GF_CLI_STATS_NONE; + int info_op = GF_CLI_INFO_NONE; int brick_count = 0; char *brick_name = NULL; int interval = 0; char key[1024] = {0,}; int i = 0; + int stats_cleared = 0; ret = cli_begin_xml_output (&writer, &doc); if (ret) @@ -2261,7 +2263,7 @@ cli_xml_output_vol_profile (dict_t *dict, int op_ret, int op_errno, "%d", op); XML_RET_CHECK_AND_GOTO (ret, out); - if (op < GF_CLI_STATS_INFO || GF_CLI_STATS_INFO_CUMULATIVE < op) + if (GF_CLI_STATS_INFO != op) goto cont; ret = dict_get_int32 (dict, "count", &brick_count); @@ -2271,6 +2273,10 @@ cli_xml_output_vol_profile (dict_t *dict, int op_ret, int op_errno, "%d", brick_count); XML_RET_CHECK_AND_GOTO (ret, out); + ret = dict_get_int32 (dict, "info-op", &info_op); + if (ret) + goto out; + while (i < brick_count) { i++; @@ -2286,23 +2292,37 @@ cli_xml_output_vol_profile (dict_t *dict, int op_ret, int op_errno, (writer, (xmlChar *)"brickName", "%s", brick_name); XML_RET_CHECK_AND_GOTO (ret, out); - snprintf (key, sizeof (key), "%d-cumulative", i); - ret = dict_get_int32 (dict, key, &interval); - if (ret == 0) { - ret = cli_xml_output_vol_profile_stats - (writer, dict, i, interval); + if (GF_CLI_INFO_CLEAR == info_op) { + snprintf (key, sizeof (key), "%d-stats-cleared", i); + ret = dict_get_int32 (dict, key, &stats_cleared); if (ret) goto out; - } - memset (key, 0, sizeof (key)); - snprintf (key, sizeof (key), "%d-interval", i); - ret = dict_get_int32 (dict, key, &interval); - if (ret == 0) { - ret = cli_xml_output_vol_profile_stats - (writer, dict, i, interval); + ret = xmlTextWriterWriteFormatElement + (writer, (xmlChar *)"clearStats", "%s", + stats_cleared ? "Cleared stats." : + "Failed to clear stats."); if (ret) goto out; + } else { + snprintf (key, sizeof (key), "%d-cumulative", i); + ret = dict_get_int32 (dict, key, &interval); + if (ret == 0) { + ret = cli_xml_output_vol_profile_stats + (writer, dict, i, interval); + if (ret) + goto out; + } + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%d-interval", i); + ret = dict_get_int32 (dict, key, &interval); + if (ret == 0) { + ret = cli_xml_output_vol_profile_stats + (writer, dict, i, interval); + if (ret) + goto out; + } } /* </brick> */ diff --git a/extras/Makefile.am b/extras/Makefile.am index 2633e20a5..faa91cddf 100644 --- a/extras/Makefile.am +++ b/extras/Makefile.am @@ -5,14 +5,17 @@ SUBDIRS = init.d systemd benchmarking hook-scripts $(OCF_SUBDIR) LinuxRPM geo-re confdir = $(sysconfdir)/glusterfs conf_DATA = glusterfs-logrotate gluster-rsyslog-7.2.conf gluster-rsyslog-5.8.conf \ - logger.conf.example glusterfs-georep-logrotate + logger.conf.example glusterfs-georep-logrotate group-virt.example voldir = $(sysconfdir)/glusterfs vol_DATA = glusterd.vol -EXTRA_DIST = specgen.scm MacOSX/Portfile glusterfs-mode.el glusterfs.vim \ - migrate-unify-to-distribute.sh backend-xattr-sanitize.sh \ - backend-cleanup.sh disk_usage_sync.sh glusterfs-logrotate \ - clear_xattrs.sh group-virt.example glusterd-sysconfig \ - gluster-rsyslog-7.2.conf gluster-rsyslog-5.8.conf \ - logger.conf.example glusterd.vol glusterfs-georep-logrotate +EXTRA_DIST = $(conf_DATA) specgen.scm MacOSX/Portfile glusterfs-mode.el \ + glusterfs.vim migrate-unify-to-distribute.sh backend-xattr-sanitize.sh \ + backend-cleanup.sh disk_usage_sync.sh clear_xattrs.sh \ + glusterd-sysconfig glusterd.vol + +install-data-local: + $(mkdir_p) $(DESTDIR)$(localstatedir)/lib/glusterd/groups + $(INSTALL_DATA) $(top_srcdir)/extras/group-virt.example \ + $(DESTDIR)$(localstatedir)/lib/glusterd/groups/virt diff --git a/geo-replication/src/gverify.sh b/geo-replication/src/gverify.sh index bd1b25f24..24580be44 100755 --- a/geo-replication/src/gverify.sh +++ b/geo-replication/src/gverify.sh @@ -32,7 +32,7 @@ echo 0:0; exit 1; fi; cd \$d; -available_size=\$(df \$d | tail -1 | awk "{print \\\$2}"); +available_size=\$(df -B1 \$d | tail -1 | awk "{print \\\$2}"); umount -l \$d; rmdir \$d; ver=\$(gluster --version | head -1 | cut -f2 -d " "); @@ -61,7 +61,7 @@ echo 0:0; exit 1; fi; cd \$d; -available_size=\$(df \$d | tail -1 | awk "{print \\\$4}"); +available_size=\$(df -B1 \$d | tail -1 | awk "{print \\\$4}"); no_of_files=\$(find \$d -maxdepth 0 -empty); umount -l \$d; rmdir \$d; diff --git a/geo-replication/syncdaemon/configinterface.py b/geo-replication/syncdaemon/configinterface.py index 0f764c47a..8353c1161 100644 --- a/geo-replication/syncdaemon/configinterface.py +++ b/geo-replication/syncdaemon/configinterface.py @@ -82,6 +82,7 @@ class GConffile(object): if sys.exc_info()[1].errno == errno.ENOENT: sres = None + self.config = ConfigParser.RawConfigParser() self.config.read(self.path) self._normconfig() diff --git a/geo-replication/syncdaemon/master.py b/geo-replication/syncdaemon/master.py index 721fe18bd..662d2ba74 100644 --- a/geo-replication/syncdaemon/master.py +++ b/geo-replication/syncdaemon/master.py @@ -1091,6 +1091,7 @@ class GMasterXsyncMixin(GMasterChangelogMixin): def register(self): self.counter = 0 self.comlist = [] + self.stimes = [] self.sleep_interval = 60 self.tempdir = self.setup_working_dir()[0] self.tempdir = os.path.join(self.tempdir, 'xsync') @@ -1169,10 +1170,15 @@ class GMasterXsyncMixin(GMasterChangelogMixin): if last: self.put('finale', None) - def sync_done(self, stime=None, last=False): + def sync_done(self, stime=[], last=False): self.sync_xsync(last) if stime: - self.sync_stime(stime, last) + # Send last as True only for last stime entry + for st in stime[:-1]: + self.sync_stime(st, False) + + if stime and stime[-1]: + self.sync_stime(stime[-1], last) def Xcrawl(self, path='.', xtr_root=None): """ @@ -1204,7 +1210,7 @@ class GMasterXsyncMixin(GMasterChangelogMixin): xtr = max(xtr, xtr_root) if not self.need_sync(path, xtl, xtr): if path == '.': - self.sync_done((path, xtl), True) + self.sync_done([(path, xtl)], True) return self.xtime_reversion_hook(path, xtl, xtr) logging.debug("entering " + path) @@ -1232,11 +1238,12 @@ class GMasterXsyncMixin(GMasterChangelogMixin): mo = st.st_mode self.counter += 1 if self.counter == self.XSYNC_MAX_ENTRIES: - self.sync_done() + self.sync_done(self.stimes, False) + self.stimes = [] if stat.S_ISDIR(mo): self.write_entry_change("E", [gfid, 'MKDIR', str(mo), str(st.st_uid), str(st.st_gid), escape(os.path.join(pargfid, bname))]) self.Xcrawl(e, xtr_root) - self.sync_done((e, xte), False) + self.stimes.append((e, xte)) elif stat.S_ISLNK(mo): self.write_entry_change("E", [gfid, 'SYMLINK', escape(os.path.join(pargfid, bname))]) elif stat.S_ISREG(mo): @@ -1250,7 +1257,8 @@ class GMasterXsyncMixin(GMasterChangelogMixin): self.write_entry_change("E", [gfid, 'LINK', escape(os.path.join(pargfid, bname))]) self.write_entry_change("D", [gfid]) if path == '.': - self.sync_done((path, xtl), True) + self.stimes.append((path, xtl)) + self.sync_done(self.stimes, True) class BoxClosedErr(Exception): pass diff --git a/glusterfs.spec.in b/glusterfs.spec.in index 43817a4cf..a409142ac 100644 --- a/glusterfs.spec.in +++ b/glusterfs.spec.in @@ -605,7 +605,6 @@ mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/gsync-create/pre mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/glustershd mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/peers mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/vols -mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/groups mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/nfs/run touch %{buildroot}%{_sharedstatedir}/glusterd/nfs/nfs-server.vol touch %{buildroot}%{_sharedstatedir}/glusterd/nfs/run/nfs.pid @@ -722,6 +721,8 @@ fi %endif %config(noreplace) %{_sysconfdir}/sysconfig/glusterd %config(noreplace) %{_sysconfdir}/glusterfs +%dir %{_sharedstatedir}/glusterd/groups +%config(noreplace) %{_sharedstatedir}/glusterd/groups/virt # Legacy configs %if ( 0%{_for_fedora_koji_builds} ) %config(noreplace) %{_sysconfdir}/logrotate.d/glusterfsd @@ -772,7 +773,6 @@ fi %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/glustershd %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/vols %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/peers -%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/groups %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/nfs %ghost %attr(0600,-,-) %{_sharedstatedir}/glusterd/nfs/nfs-server.vol %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/nfs/run @@ -876,6 +876,9 @@ if [ $1 -ge 1 ]; then fi %changelog +* Wed Jan 15 2014 Niels de Vos <ndevos@redhat.com> +- Install /var/lib/glusterd/groups/virt by default + * Sat Jan 4 2014 Niels de Vos <ndevos@redhat.com> - The main glusterfs package should not provide glusterfs-libs (#1048489) diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c index de2829ddd..69c049d67 100644 --- a/glusterfsd/src/glusterfsd-mgmt.c +++ b/glusterfsd/src/glusterfsd-mgmt.c @@ -1572,7 +1572,9 @@ glusterfs_rebalance_event_notify (dict_t *dict) GF_FREE (req.dict.dict_val); - STACK_DESTROY (frame->root); + if (frame) { + STACK_DESTROY (frame->root); + } return ret; } diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c index 7c8c3cdba..9ce52407f 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -650,6 +650,45 @@ loc_gfid_utoa (loc_t *loc) } int +loc_copy_overload_parent (loc_t *dst, loc_t *src, inode_t *parent) +{ + int ret = -1; + + GF_VALIDATE_OR_GOTO ("xlator", dst, err); + GF_VALIDATE_OR_GOTO ("xlator", src, err); + GF_VALIDATE_OR_GOTO ("xlator", parent, err); + + uuid_copy (dst->gfid, src->gfid); + uuid_copy (dst->pargfid, parent->gfid); + + if (src->inode) + dst->inode = inode_ref (src->inode); + + if (parent) + dst->parent = inode_ref (parent); + + if (src->path) { + dst->path = gf_strdup (src->path); + + if (!dst->path) + goto out; + + if (src->name) + dst->name = strrchr (dst->path, '/'); + if (dst->name) + dst->name++; + } + + ret = 0; +out: + if (ret == -1) + loc_wipe (dst); + +err: + return ret; +} + +int loc_copy (loc_t *dst, loc_t *src) { int ret = -1; diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index 2f3bc9d6f..1daa06ec2 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -937,6 +937,8 @@ xlator_t *xlator_search_by_name (xlator_t *any, const char *name); void inode_destroy_notify (inode_t *inode, const char *xlname); int loc_copy (loc_t *dst, loc_t *src); +int loc_copy_overload_parent (loc_t *dst, + loc_t *src, inode_t *parent); #define loc_dup(src, dst) loc_copy(dst, src) void loc_wipe (loc_t *loc); int loc_path (loc_t *loc, const char *bname); diff --git a/rpc/rpc-lib/src/rpc-clnt.c b/rpc/rpc-lib/src/rpc-clnt.c index 1e9f307be..4920edaa3 100644 --- a/rpc/rpc-lib/src/rpc-clnt.c +++ b/rpc/rpc-lib/src/rpc-clnt.c @@ -1695,7 +1695,7 @@ rpc_clnt_reconfig (struct rpc_clnt *rpc, struct rpc_clnt_config *config) "changing hostname to %s (from %s)", config->remote_host, rpc->conn.config.remote_host); - FREE (rpc->conn.config.remote_host); + GF_FREE (rpc->conn.config.remote_host); } else { gf_log (rpc->conn.trans->name, GF_LOG_INFO, "setting hostname to %s", diff --git a/rpc/rpc-transport/socket/src/socket.c b/rpc/rpc-transport/socket/src/socket.c index c6b293be4..490fe8a7e 100644 --- a/rpc/rpc-transport/socket/src/socket.c +++ b/rpc/rpc-transport/socket/src/socket.c @@ -3341,6 +3341,34 @@ reconfigure (rpc_transport_t *this, dict_t *options) priv->windowsize = (int)windowsize; + if (dict_get (this->options, "non-blocking-io")) { + optstr = data_to_str (dict_get (this->options, + "non-blocking-io")); + + if (gf_string2boolean (optstr, &tmp_bool) == -1) { + gf_log (this->name, GF_LOG_ERROR, + "'non-blocking-io' takes only boolean options," + " not taking any action"); + tmp_bool = 1; + } + + if (!tmp_bool) { + priv->bio = 1; + gf_log (this->name, GF_LOG_WARNING, + "disabling non-blocking IO"); + } + } + + if (!priv->bio) { + ret = __socket_nonblock (priv->sock); + if (ret == -1) { + gf_log (this->name, GF_LOG_WARNING, + "NBIO on %d failed (%s)", + priv->sock, strerror (errno)); + goto out; + } + } + ret = 0; out: return ret; diff --git a/rpc/xdr/src/cli1-xdr.c b/rpc/xdr/src/cli1-xdr.c index 7d85b43c1..bf58e9904 100644 --- a/rpc/xdr/src/cli1-xdr.c +++ b/rpc/xdr/src/cli1-xdr.c @@ -157,6 +157,17 @@ xdr_gf1_cli_stats_op (XDR *xdrs, gf1_cli_stats_op *objp) } bool_t +xdr_gf1_cli_info_op (XDR *xdrs, gf1_cli_info_op *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!xdr_enum (xdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +bool_t xdr_gf1_cli_top_op (XDR *xdrs, gf1_cli_top_op *objp) { register int32_t *buf; diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h index 815384e80..11297cc25 100644 --- a/rpc/xdr/src/cli1-xdr.h +++ b/rpc/xdr/src/cli1-xdr.h @@ -140,12 +140,19 @@ enum gf1_cli_stats_op { GF_CLI_STATS_START = 1, GF_CLI_STATS_STOP = 2, GF_CLI_STATS_INFO = 3, - GF_CLI_STATS_INFO_INCREMENTAL = 4, - GF_CLI_STATS_INFO_CUMULATIVE = 5, - GF_CLI_STATS_TOP = 6 + GF_CLI_STATS_TOP = 4, }; typedef enum gf1_cli_stats_op gf1_cli_stats_op; +enum gf1_cli_info_op { + GF_CLI_INFO_NONE = 0, + GF_CLI_INFO_ALL = 1, + GF_CLI_INFO_INCREMENTAL = 2, + GF_CLI_INFO_CUMULATIVE = 3, + GF_CLI_INFO_CLEAR = 4, +}; +typedef enum gf1_cli_info_op gf1_cli_info_op; + enum gf1_cli_top_op { GF_CLI_TOP_NONE = 0, GF_CLI_TOP_OPEN = 0 + 1, @@ -286,6 +293,7 @@ extern bool_t xdr_gf1_cli_sync_volume (XDR *, gf1_cli_sync_volume*); extern bool_t xdr_gf1_cli_op_flags (XDR *, gf1_cli_op_flags*); extern bool_t xdr_gf1_cli_gsync_set (XDR *, gf1_cli_gsync_set*); extern bool_t xdr_gf1_cli_stats_op (XDR *, gf1_cli_stats_op*); +extern bool_t xdr_gf1_cli_info_op (XDR *, gf1_cli_info_op*); extern bool_t xdr_gf1_cli_top_op (XDR *, gf1_cli_top_op*); extern bool_t xdr_gf_cli_status_type (XDR *, gf_cli_status_type*); extern bool_t xdr_gf_cli_req (XDR *, gf_cli_req*); @@ -314,6 +322,7 @@ extern bool_t xdr_gf1_cli_sync_volume (); extern bool_t xdr_gf1_cli_op_flags (); extern bool_t xdr_gf1_cli_gsync_set (); extern bool_t xdr_gf1_cli_stats_op (); +extern bool_t xdr_gf1_cli_info_op (); extern bool_t xdr_gf1_cli_top_op (); extern bool_t xdr_gf_cli_status_type (); extern bool_t xdr_gf_cli_req (); diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x index 46f4581ee..a283006b0 100644 --- a/rpc/xdr/src/cli1-xdr.x +++ b/rpc/xdr/src/cli1-xdr.x @@ -97,6 +97,14 @@ enum gf1_cli_stats_op { GF_CLI_STATS_TOP = 4 }; +enum gf1_cli_info_op { + GF_CLI_INFO_NONE = 0, + GF_CLI_INFO_ALL = 1, + GF_CLI_INFO_INCREMENTAL = 2, + GF_CLI_INFO_CUMULATIVE = 3, + GF_CLI_INFO_CLEAR = 4 +}; + enum gf1_cli_top_op { GF_CLI_TOP_NONE = 0, GF_CLI_TOP_OPEN, diff --git a/tests/basic/cdc.t b/tests/basic/cdc.t index 4cd915aa9..69f39f7d1 100755 --- a/tests/basic/cdc.t +++ b/tests/basic/cdc.t @@ -24,21 +24,21 @@ EXPECT 'off' volinfo_field $V0 'performance.quick-read' TEST $CLI volume set $V0 strict-write-ordering on EXPECT 'on' volinfo_field $V0 'performance.strict-write-ordering' -## Turn on cdc xlator by setting features.compress to on -TEST $CLI volume set $V0 compress on -EXPECT 'on' volinfo_field $V0 'features.compress' -EXPECT 'server' volinfo_field $V0 'compress.mode' +## Turn on cdc xlator by setting network.compression to on +TEST $CLI volume set $V0 network.compression on +EXPECT 'on' volinfo_field $V0 'network.compression' +EXPECT 'server' volinfo_field $V0 'network.compression.mode' -## Make sure that user cannot change compress.mode +## Make sure that user cannot change network.compression.mode ## This would break the cdc xlator if allowed! -TEST $CLI volume set $V0 compress.mode client -EXPECT 'server' volinfo_field $V0 'compress.mode' +TEST $CLI volume set $V0 network.compression.mode client +EXPECT 'server' volinfo_field $V0 'network.compression.mode' -## Turn on compress.debug option +## Turn on network.compression.debug option ## This will dump compressed data onto disk as gzip file ## This is used to check if compression actually happened -TEST $CLI volume set $V0 compress.debug on -EXPECT 'on' volinfo_field $V0 'compress.debug' +TEST $CLI volume set $V0 network.compression.debug on +EXPECT 'on' volinfo_field $V0 'network.compression.debug' ## Start the volume TEST $CLI volume start $V0; @@ -96,11 +96,11 @@ TEST umount $M0 TEST $CLI volume stop $V0; EXPECT 'Stopped' volinfo_field $V0 'Status'; -## Turn on compress.min-size and set it to 100 bytes +## Turn on network.compression.min-size and set it to 100 bytes ## Compression should not take place if file size ## is less than 100 bytes -TEST $CLI volume set $V0 compress.min-size 100 -EXPECT '100' volinfo_field $V0 'compress.min-size' +TEST $CLI volume set $V0 network.compression.min-size 100 +EXPECT '100' volinfo_field $V0 'network.compression.min-size' ## Start the volume TEST $CLI volume start $V0; @@ -118,11 +118,11 @@ TEST ! test -e /tmp/cdcdump.gz TEST rm -f /tmp/cdc* $M0/cdc* TEST umount $M0 -## Reset the compress options -TEST $CLI volume reset $V0 compress.debug -TEST $CLI volume reset $V0 compress.min-size -TEST $CLI volume reset $V0 compress.mode -TEST $CLI volume reset $V0 features.compress +## Reset the network.compression options +TEST $CLI volume reset $V0 network.compression.debug +TEST $CLI volume reset $V0 network.compression.min-size +TEST $CLI volume reset $V0 network.compression.mode +TEST $CLI volume reset $V0 network.compression ## Stop the volume TEST $CLI volume stop $V0; diff --git a/tests/basic/quota-anon-fd-nfs.t b/tests/basic/quota-anon-fd-nfs.t new file mode 100755 index 000000000..be7bc35db --- /dev/null +++ b/tests/basic/quota-anon-fd-nfs.t @@ -0,0 +1,84 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../fileio.rc + +cleanup; + +TESTS_EXPECTED_IN_LOOP=16 +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + +TEST $CLI volume create $V0 $H0:$B0/brick1; +EXPECT 'Created' volinfo_field $V0 'Status'; + + +# The test makes use of inode-lru-limit to hit a scenario, where we +# find an inode whose ancestry is not there. Following is the +# hypothesis (which is confirmed by seeing logs indicating that +# codepath has been executed, but not through a good understanding of +# NFS internals). + +# At the end of an fop, the reference count of an inode would be +# zero. The inode (and its ancestry) persists in memory only +# because of non-zero lookup count. These looked up inodes are put +# in an lru queue of size 1 (here). So, there can be at most one +# such inode in memory. + +# NFS Server makes use of anonymous fds. So, if it cannot find +# valid fd, it does a nameless lookup. This gives us an inode +# whose ancestry is NULL. When a write happens on this inode, +# quota-enforcer/marker finds a NULL ancestry and asks +# storage/posix to build it. + +TEST $CLI volume set $V0 network.inode-lru-limit 1 +TEST $CLI volume set $V0 performance.nfs.write-behind off + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +TEST $CLI volume quota $V0 enable +TEST $CLI volume quota $V0 limit-usage / 1 + +TEST mount -t nfs -o noac,soft,nolock,vers=3 $H0:/$V0 $N0 +deep=/0/1/2/3/4/5/6/7/8/9 +TEST mkdir -p $N0/$deep + +TEST touch $N0/$deep/file1 $N0/$deep/file2 $N0/$deep/file3 $N0/$deep/file4 + +TEST fd_open 3 'w' "$N0/$deep/file1" +TEST fd_open 4 'w' "$N0/$deep/file2" +TEST fd_open 5 'w' "$N0/$deep/file3" +TEST fd_open 6 'w' "$N0/$deep/file4" + +# consume all quota +TEST ! dd if=/dev/zero of="$N0/$deep/file" bs=1MB count=1 + +# At the end of each fop in server, reference count of the +# inode associated with each of the file above drops to zero and hence +# put into lru queue. Since lru-limit is set to 1, an fop next file +# will displace the current inode from itable. This will ensure that +# when writes happens on same fd, fd resolution results in +# nameless lookup from server and quota_writev encounters an fd +# associated with an inode whose parent is not present in itable. + +for j in $(seq 1 2); do + for i in $(seq 3 6); do + # failing writes indicate that we are enforcing quota set on / + # even with anonymous fds. + TEST_IN_LOOP ! fd_write $i "content" + TEST_IN_LOOP sync + done +done + +exec 3>&- +exec 4>&- +exec 5>&- +exec 6>&- + +$CLI volume statedump $V0 all + +TEST umount -l $N0 + +cleanup; diff --git a/tests/basic/quota-nfs-anon.t b/tests/basic/quota-nfs-anon.t deleted file mode 100644 index 7b5ea5f28..000000000 --- a/tests/basic/quota-nfs-anon.t +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash - -. $(dirname $0)/../include.rc -. $(dirname $0)/../volume.rc - -cleanup; - -TEST glusterd -TEST $CLI volume create $V0 $H0:$B0/${V0}{1} - -function volinfo_field() -{ - local vol=$1; - local field=$2; - - $CLI volume info $vol | grep "^$field: " | sed 's/.*: //'; -} - - -## Verify volume is is created -EXPECT "$V0" volinfo_field $V0 'Volume Name'; -EXPECT 'Created' volinfo_field $V0 'Status'; - - -## Start volume and verify -TEST $CLI volume start $V0; -EXPECT 'Started' volinfo_field $V0 'Status'; - -TEST $CLI volume quota $V0 enable; - -## Mount NFS -TEST mount -t nfs -o nolock,soft,intr $H0:/$V0 $N0; -mkdir -p $N0/0/1 -TEST $CLI volume quota $V0 limit-usage /0/1 1GB 75%; - -deep=/0/1/2/3/4/5/6/7/8/9 -mkdir -p $N0/$deep -dd if=/dev/zero of=$N0/$deep/file bs=1M count=502 & - -kill_brick $V0 $H0 $B0/${V0}{1} -kill -TERM $(get_nfs_pid) - -$CLI volume start $V0 force; - - -cleanup; diff --git a/tests/basic/quota.t b/tests/basic/quota.t index 5c531adbf..81b1c2100 100755 --- a/tests/basic/quota.t +++ b/tests/basic/quota.t @@ -5,6 +5,8 @@ cleanup; +TESTS_EXPECTED_IN_LOOP=19 + TEST glusterd TEST pidof glusterd TEST $CLI volume info; @@ -102,6 +104,75 @@ TEST $CLI volume quota $V0 limit-usage /test_dir/in_test_dir 150MB EXPECT "150.0MB" hard_limit "/test_dir/in_test_dir"; ## ----------------------------- + +################################################### +## ------------------------------------------------ +## <Test quota functionality in add-brick senarios> +## ------------------------------------------------ +################################################### +QUOTALIMIT=1024 +QUOTALIMITROOT=2048 +TESTDIR="addbricktest" + +rm -rf $M0/*; + +## <Create directories and test> +## ----------------------------- +# 41-42 +TEST mkdir $M0/$TESTDIR +TEST mkdir $M0/$TESTDIR/dir{1..10}; + + +# 43-52 +## <set limits> +## ----------------------------- +TEST $CLI volume quota $V0 limit-usage / "$QUOTALIMITROOT"MB; +for i in {1..10}; do + TEST_IN_LOOP $CLI volume quota $V0 limit-usage /$TESTDIR/dir$i \ + "$QUOTALIMIT"MB; +done +## </Enable quota and set limits> + +#53-62 +for i in `seq 1 9`; do + TEST_IN_LOOP dd if=/dev/urandom of="$M0/$TESTDIR/dir1/100MBfile$i" \ + bs=1M count=100; +done + +# 63-64 +## <Add brick and start rebalance> +## ------------------------------- +TEST $CLI volume add-brick $V0 $H0:$B0/brick{3,4} +TEST $CLI volume rebalance $V0 start; + + +## <Try creating data beyond limit> +## -------------------------------- +for i in `seq 1 200`; do + dd if=/dev/urandom of="$M0/$TESTDIR/dir1/10MBfile$i" bs=1M count=10 \ + &>/dev/null +done + +# 65 +## <Test whether quota limit crossed more than 10% of limit> +## --------------------------------------------------------- +USED_KB=`du -s $M0/$TESTDIR/dir1 | cut -f1`; +USED_MB=$(($USED_KB/1024)); +TEST [ $USED_MB -le $((($QUOTALIMIT * 110) / 100)) ] + +# 66-67 +## <Test the xattrs healed to new brick> +## ------------------------------------- +TEST getfattr -d -m "trusted.glusterfs.quota.limit-set" -e hex \ + --absolute-names $B0/brick{3,4}/$TESTDIR/dir{1..10}; +# Test on root. +TEST getfattr -d -m "trusted.glusterfs.quota.limit-set" -e hex \ + --absolute-names $B0/brick{3,4}; + +## ------------------------------------------------- +## </Test quota functionality in add-brick senarios> +## ------------------------------------------------- + TEST $CLI volume quota $V0 disable TEST $CLI volume stop $V0; EXPECT 'Stopped' volinfo_field $V0 'Status'; diff --git a/extras/rpc-coverage.sh b/tests/basic/rpc-coverage.sh index 9148a73e2..dc66969d0 100755 --- a/extras/rpc-coverage.sh +++ b/tests/basic/rpc-coverage.sh @@ -48,7 +48,7 @@ set -o pipefail; function fail() { - echo "$*: failed."; + echo "$*: failed."; exit 1; } @@ -139,7 +139,10 @@ function test_symlink() { local msg; - ln -s $PFX/dir/file $PFX/dir/symlink; + pushd; + cd $PFX/dir; + ln -s file symlink; + popd; test "$(stat -c '%F' $PFX/dir/symlink)" == "symbolic link" || fail "Creation of symlink" msg=$(cat $PFX/dir/symlink); diff --git a/tests/basic/rpc-coverage.t b/tests/basic/rpc-coverage.t new file mode 100644 index 000000000..5dfeaa942 --- /dev/null +++ b/tests/basic/rpc-coverage.t @@ -0,0 +1,25 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + +TEST $CLI volume create $V0 replica 2 stripe 2 $H0:$B0/${V0}{1,2,3,4,5,6,7,8}; + +EXPECT "$V0" volinfo_field $V0 'Volume Name'; +EXPECT 'Created' volinfo_field $V0 'Status'; +EXPECT '8' brick_count $V0 + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +## Mount FUSE +TEST glusterfs -s $H0 --volfile-id $V0 $M1; + +TEST $(dirname $0)/rpc-coverage.sh $M1 +cleanup; diff --git a/tests/bugs/bug-1023974.t b/tests/bugs/bug-1023974.t index 56766b979..06d33c12f 100644 --- a/tests/bugs/bug-1023974.t +++ b/tests/bugs/bug-1023974.t @@ -21,6 +21,8 @@ TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0; TEST mkdir -p $M0/1/2; TEST $CLI volume quota $V0 limit-usage /1/2 100MB 70%; +TEST $CLI volume quota $V0 hard-timeout 0 +TEST $CLI volume quota $V0 soft-timeout 0 #The corresponding write(3) should fail with EDQUOT ("Disk quota exceeded") TEST ! dd if=/dev/urandom of=$M0/1/2/file bs=1M count=102; diff --git a/tests/bugs/bug-1030580.t b/tests/bugs/bug-1030580.t index ed1cdb864..642c6dc44 100644 --- a/tests/bugs/bug-1030580.t +++ b/tests/bugs/bug-1030580.t @@ -9,14 +9,6 @@ function write_to_file { dd of=$M0/1 if=/dev/zero bs=1M count=128 oflag=append 2>&1 >/dev/null } -function cumulative_stat_count { - echo "$1" | grep "Cumulative Stats:" | wc -l -} - -function incremental_stat_count { - echo "$1" | grep "Interval$2Stats:" | wc -l -} - TEST glusterd TEST pidof glusterd TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}0 $H0:$B0/${V0}1 diff --git a/tests/bugs/bug-1035576.t b/tests/bugs/bug-1035576.t index 08c8a5ea2..52d93dd87 100644 --- a/tests/bugs/bug-1035576.t +++ b/tests/bugs/bug-1035576.t @@ -21,7 +21,7 @@ TEST $CLI volume set $V0 performance.read-ahead off TEST $CLI volume set $V0 background-self-heal-count 0 TEST $CLI volume set $V0 self-heal-daemon off TEST $CLI volume quota $V0 enable -sleep 5 # wait for brick to connect to quotad + TEST kill_brick $V0 $H0 $B0/${V0}0 TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0 cd $M0 diff --git a/tests/bugs/bug-1040423.t b/tests/bugs/bug-1040423.t new file mode 100755 index 000000000..6dae9eac6 --- /dev/null +++ b/tests/bugs/bug-1040423.t @@ -0,0 +1,72 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup + +function _init() { +# Start glusterd +TEST glusterd; +TEST pidof glusterd; +TEST $CLI volume info; + +# Lets create volume +TEST $CLI volume create $V0 $H0:$B0/${V0}{1,2}; + +## Verify volume is created +EXPECT "$V0" volinfo_field $V0 'Volume Name'; +EXPECT 'Created' volinfo_field $V0 'Status'; + +#Start volume and verify +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; +TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0 + +#Enable Quota +TEST $CLI volume quota $V0 enable + +#As quotad consumes some time to connect to brick process we invoke sleep +sleep 10; + +#set limit of 1GB of quota on root +TEST $CLI volume quota $V0 limit-usage / 1GB +} + +function get_hardlimit() +{ + VOLUME=$1 + + $CLI volume quota $VOLUME list | tail -1 | sed "s/ \{1,\}/ /g" | + cut -d' ' -f 2 +} + +function check_fattrs { + +touch $M0/file1; + +#This confirms that pgfid is also filtered +TEST ! "getfattr -d -e hex -m . $M0/file1 | grep pgfid "; + +#just check for quota xattr are visible or not +TEST ! "getfattr -d -e hex -m . $M0 | grep quota"; + +#setfattr should fail +TEST ! setfattr -n trusted.glusterfs.quota.limit-set -v 10 $M0; + +#remove xattr should fail +TEST ! setfattr -x trusted.glusterfs.quota.limit-set $M0; + +#check if list command still shows the correct value or not + +EXPECT "1.0GB" get_hardlimit $V0 + +} + +_init; +check_fattrs; +cleanup + + + + diff --git a/tests/bugs/bug-1047416.t b/tests/bugs/bug-1047416.t new file mode 100644 index 000000000..53c7f8614 --- /dev/null +++ b/tests/bugs/bug-1047416.t @@ -0,0 +1,66 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; + +function write_to_file { + dd of=$M0/1 if=/dev/zero bs=1M count=128 oflag=append 2>&1 >/dev/null +} + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}0 $H0:$B0/${V0}1 +TEST $CLI volume start $V0 +TEST $CLI volume profile $V0 start +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0 + +# Verify 'volume profile info' prints both cumulative and incremental stats +write_to_file & +wait +output=$($CLI volume profile $V0 info) +EXPECT 2 cumulative_stat_count "$output" +EXPECT 2 incremental_stat_count "$output" ' 0 ' + +# Verify 'volume profile info peek' prints both cumulative and incremental stats +# without clearing incremental stats +write_to_file & +wait +output=$($CLI volume profile $V0 info peek) +EXPECT 2 cumulative_stat_count "$output" +EXPECT 2 incremental_stat_count "$output" ' 1 ' + +write_to_file & +wait +output=$($CLI volume profile $V0 info peek) +EXPECT 2 cumulative_stat_count "$output" +EXPECT 2 incremental_stat_count "$output" ' 1 ' + +# Verify 'volume profile info incremental peek' prints incremental stats only +# without clearing incremental stats +write_to_file & +wait +output=$($CLI volume profile $V0 info incremental peek) +EXPECT 0 cumulative_stat_count "$output" +EXPECT 2 incremental_stat_count "$output" ' 1 ' + +write_to_file & +wait +output=$($CLI volume profile $V0 info incremental peek) +EXPECT 0 cumulative_stat_count "$output" +EXPECT 2 incremental_stat_count "$output" ' 1 ' + +# Verify 'volume profile info clear' clears both incremental and cumulative stats +write_to_file & +wait +output=$($CLI volume profile $V0 info clear) +EXPECT 2 cleared_stat_count "$output" + +output=$($CLI volume profile $V0 info) +EXPECT 2 cumulative_stat_count "$output" +EXPECT 2 incremental_stat_count "$output" ' 0 ' +EXPECT 4 data_read_count "$output" ' 0 ' +EXPECT 4 data_written_count "$output" ' 0 ' + +cleanup; diff --git a/tests/bugs/bug-848251.t b/tests/bugs/bug-848251.t index 844162283..a5c80b1b4 100644 --- a/tests/bugs/bug-848251.t +++ b/tests/bugs/bug-848251.t @@ -19,7 +19,6 @@ TEST $CLI volume quota $V0 enable; TEST MOUNTDIR="/tmp/$RANDOM" TEST mkdir $MOUNTDIR TEST glusterfs -s $H0 --volfile-id=$V0 $MOUNTDIR -sleep 10 function set_quota(){ mkdir "$MOUNTDIR/$name" diff --git a/tests/bugs/bug-990028.t b/tests/bugs/bug-990028.t index ece7235cd..fbf4175be 100755 --- a/tests/bugs/bug-990028.t +++ b/tests/bugs/bug-990028.t @@ -22,7 +22,6 @@ function __init() TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0 TEST $CLI volume quota $V0 enable - sleep 15 } #CASE-1 diff --git a/tests/include.rc b/tests/include.rc index 0369d2610..44259872a 100644 --- a/tests/include.rc +++ b/tests/include.rc @@ -67,10 +67,10 @@ function test_expect_footer() local a=$2 local err="" - if [ "x${e}" != "x${a}" ]; then + if ! [[ "$a" =~ $e ]]; then err="Got \"$a\" instead of \"$e\"" fi - [[ "x${e}" == "x${a}" ]]; + [[ "$a" =~ $e ]]; test_footer "$err"; } @@ -96,11 +96,11 @@ function test_expect_not_footer() local a=$2 local err="" - if [ "x${e}" == "x${a}" ]; then + if [[ "$a" =~ $e ]]; then err="Got \"$a\" when not expecting it" fi - [[ "x${e}" != "x${a}" ]]; + ! [[ "$a" =~ "$e" ]]; test_footer "$err"; } diff --git a/tests/volume.rc b/tests/volume.rc index b1aa904fb..5e2f95e76 100644 --- a/tests/volume.rc +++ b/tests/volume.rc @@ -279,3 +279,26 @@ function get_hex_xattr { local path=$2 getfattr -d -m. -e hex $2 2>/dev/null | grep $1 | cut -f2 -d'=' | cut -f2 -d'x' } + +function cumulative_stat_count { + echo "$1" | grep "Cumulative Stats:" | wc -l +} + +function incremental_stat_count { + echo "$1" | grep "Interval$2Stats:" | wc -l +} + +function cleared_stat_count { + echo "$1" | grep "Cleared stats." | wc -l +} + +function data_read_count { + echo "$1" | grep "Data Read:$2bytes" | wc -l +} + +function data_written_count { + echo "$1" | grep "Data Written:$2bytes" | wc -l +} + + + diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c index b43fde47d..c26453807 100644 --- a/xlators/cluster/afr/src/afr.c +++ b/xlators/cluster/afr/src/afr.c @@ -716,7 +716,7 @@ struct volume_options options[] = { }, { .key = {"self-heal-daemon"}, .type = GF_OPTION_TYPE_BOOL, - .default_value = "off", + .default_value = "on", .description = "This option applies to only self-heal-daemon. " "Index directory crawl and automatic healing of files " "will not be performed if this option is turned off." diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index f59bc9667..cf4ec258d 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -2010,6 +2010,12 @@ dht_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (dict_get (xattr, conf->xattr_name)) { dict_del (xattr, conf->xattr_name); } + + if (frame->root->pid >= 0 ) { + GF_REMOVE_INTERNAL_XATTR("trusted.glusterfs.quota*", xattr); + GF_REMOVE_INTERNAL_XATTR("trusted.pgfid*", xattr); + } + local->op_ret = 0; if (!local->xattr) { diff --git a/xlators/cluster/dht/src/dht-helper.c b/xlators/cluster/dht/src/dht-helper.c index 76bfbaedb..381643b22 100644 --- a/xlators/cluster/dht/src/dht-helper.c +++ b/xlators/cluster/dht/src/dht-helper.c @@ -747,8 +747,10 @@ dht_migration_complete_check_task (void *data) src_node = local->cached_subvol; - if (!local->loc.inode && !local->fd) + if (!local->loc.inode && !local->fd) { + local->op_errno = EINVAL; goto out; + } inode = (!local->fd) ? local->loc.inode : local->fd->inode; @@ -770,19 +772,23 @@ dht_migration_complete_check_task (void *data) if (ret) { if (!dht_inode_missing(-ret) || (!local->loc.inode)) { + local->op_errno = -ret; gf_log (this->name, GF_LOG_ERROR, "%s: failed to get the 'linkto' xattr %s", local->loc.path, strerror (-ret)); ret = -1; goto out; } + /* Need to do lookup on hashed subvol, then get the file */ ret = syncop_lookup (this, &local->loc, NULL, &stbuf, NULL, NULL); if (ret) { + local->op_errno = -ret; ret = -1; goto out; } + dst_node = dht_subvol_get_cached (this, local->loc.inode); } @@ -791,17 +797,20 @@ dht_migration_complete_check_task (void *data) "%s: failed to get the destination node", local->loc.path); ret = -1; + local->op_errno = EINVAL; goto out; } /* lookup on dst */ if (local->loc.inode) { - ret = syncop_lookup (dst_node, &local->loc, NULL, &stbuf, NULL, NULL); + ret = syncop_lookup (dst_node, &local->loc, NULL, &stbuf, NULL, + NULL); if (ret) { gf_log (this->name, GF_LOG_ERROR, "%s: failed to lookup the file on %s", local->loc.path, dst_node->name); + local->op_errno = -ret; ret = -1; goto out; } @@ -811,6 +820,7 @@ dht_migration_complete_check_task (void *data) "%s: gfid different on the target file on %s", local->loc.path, dst_node->name); ret = -1; + local->op_errno = EIO; goto out; } } @@ -824,6 +834,7 @@ dht_migration_complete_check_task (void *data) "%s: could not set preset layout for subvol %s", local->loc.path, dst_node->name); ret = -1; + local->op_errno = EINVAL; goto out; } @@ -833,6 +844,7 @@ dht_migration_complete_check_task (void *data) "%s: no pre-set layout for subvolume %s", local->loc.path, dst_node ? dst_node->name : "<nil>"); ret = -1; + local->op_errno = EINVAL; goto out; } @@ -841,6 +853,7 @@ dht_migration_complete_check_task (void *data) gf_log (this->name, GF_LOG_ERROR, "%s: failed to set the new layout", local->loc.path); + local->op_errno = EINVAL; goto out; } @@ -877,13 +890,15 @@ dht_migration_complete_check_task (void *data) gf_log (this->name, GF_LOG_ERROR, "failed to open " "the fd (%p, flags=0%o) on file %s @ %s", iter_fd, iter_fd->flags, path, dst_node->name); - ret = -1; open_failed = 1; + local->op_errno = -ret; + ret = -1; } } GF_FREE (path); SYNCTASK_SETID (frame->root->uid, frame->root->gid); + if (open_failed) { ret = -1; goto out; diff --git a/xlators/cluster/dht/src/dht-layout.c b/xlators/cluster/dht/src/dht-layout.c index f7413c8a0..1e38d6be1 100644 --- a/xlators/cluster/dht/src/dht-layout.c +++ b/xlators/cluster/dht/src/dht-layout.c @@ -443,8 +443,13 @@ dht_is_subvol_in_layout (dht_layout_t *layout, xlator_t *xlator) int i = 0; for (i = 0; i < layout->cnt; i++) { - if (!strcmp (layout->list[i].xlator->name, xlator->name)) - return _gf_true; + /* Check if xlator is already part of layout, and layout is + * non-zero. */ + if (!strcmp (layout->list[i].xlator->name, xlator->name)) { + if (layout->list[i].start != layout->list[i].stop) + return _gf_true; + break; + } } return _gf_false; } diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c index 06fa1ed3a..0e6527544 100644 --- a/xlators/cluster/dht/src/dht-selfheal.c +++ b/xlators/cluster/dht/src/dht-selfheal.c @@ -127,6 +127,7 @@ dht_selfheal_dir_xattr_persubvol (call_frame_t *frame, loc_t *loc, int32_t *disk_layout = NULL; dht_local_t *local = NULL; dht_conf_t *conf = NULL; + data_t *data = NULL; local = frame->local; if (req_subvol) @@ -171,7 +172,16 @@ dht_selfheal_dir_xattr_persubvol (call_frame_t *frame, loc_t *loc, layout->type, subvol->name, loc->path); dict_ref (xattr); - + if (local->xattr) { + data = dict_get (local->xattr, QUOTA_LIMIT_KEY); + if (data) { + ret = dict_add (xattr, QUOTA_LIMIT_KEY, data); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "set quota limit key on %s",loc->path); + } + } + } if (!uuid_is_null (local->gfid)) uuid_copy (loc->gfid, local->gfid); @@ -265,7 +275,14 @@ dht_selfheal_dir_xattr (call_frame_t *frame, loc_t *loc, dht_layout_t *layout) } missing_xattr++; } - + /* Also account for subvolumes with no-layout. Used for zero'ing out + * the layouts and for setting quota key's if present */ + for (i = 0; i < conf->subvolume_cnt; i++) { + if (_gf_false == + dht_is_subvol_in_layout (layout, conf->subvolumes[i])) { + missing_xattr++; + } + } gf_log (this->name, GF_LOG_TRACE, "%d subvolumes missing xattr for %s", missing_xattr, loc->path); @@ -276,7 +293,6 @@ dht_selfheal_dir_xattr (call_frame_t *frame, loc_t *loc, dht_layout_t *layout) } local->call_cnt = missing_xattr; - for (i = 0; i < layout->cnt; i++) { if (layout->list[i].err != -1 || !layout->list[i].stop) continue; @@ -289,13 +305,15 @@ dht_selfheal_dir_xattr (call_frame_t *frame, loc_t *loc, dht_layout_t *layout) dummy = dht_layout_new (this, 1); if (!dummy) goto out; - for (i = 0; i < conf->subvolume_cnt; i++) { + for (i = 0; i < conf->subvolume_cnt && missing_xattr; i++) { if (_gf_false == dht_is_subvol_in_layout (layout, conf->subvolumes[i])) { dht_selfheal_dir_xattr_persubvol (frame, loc, dummy, 0, conf->subvolumes[i]); + missing_xattr--; } } + dht_layout_unref (this, dummy); out: return 0; diff --git a/xlators/cluster/dht/src/switch.c b/xlators/cluster/dht/src/switch.c index d3ea90ba8..2717ce975 100644 --- a/xlators/cluster/dht/src/switch.c +++ b/xlators/cluster/dht/src/switch.c @@ -670,6 +670,7 @@ set_switch_pattern (xlator_t *this, dht_conf_t *conf, GF_FREE (dup_str); continue; } + GF_FREE (dup_str); memcpy (switch_opt->path_pattern, pattern, strlen (pattern)); if (childs) { dup_childs = gf_strdup (childs); @@ -726,7 +727,6 @@ set_switch_pattern (xlator_t *this, dht_conf_t *conf, "option in unify volume. Exiting"); goto err; } - GF_FREE (dup_str); /* Link it to the main structure */ if (switch_buf) { diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c index c98126225..c736e83ed 100644 --- a/xlators/cluster/stripe/src/stripe.c +++ b/xlators/cluster/stripe/src/stripe.c @@ -4211,30 +4211,6 @@ stripe_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, op_errno = ENOMEM; goto err; } - fctx = (stripe_fd_ctx_t *)(long)tmp_fctx; - stripe_size = fctx->stripe_size; - - STRIPE_VALIDATE_FCTX (fctx, err); - - remaining_size = len; - - local = mem_get0 (this->local_pool); - if (!local) { - op_errno = ENOMEM; - goto err; - } - fctx = (stripe_fd_ctx_t *)(long)tmp_fctx; - stripe_size = fctx->stripe_size; - - STRIPE_VALIDATE_FCTX (fctx, err); - - remaining_size = len; - - local = mem_get0 (this->local_pool); - if (!local) { - op_errno = ENOMEM; - goto err; - } frame->local = local; local->stripe_size = stripe_size; local->fctx = fctx; diff --git a/xlators/debug/io-stats/src/io-stats.c b/xlators/debug/io-stats/src/io-stats.c index 65aeee52b..fa0dd395c 100644 --- a/xlators/debug/io-stats/src/io-stats.c +++ b/xlators/debug/io-stats/src/io-stats.c @@ -917,9 +917,19 @@ ios_dump_args_init (struct ios_dump_args *args, ios_dump_type_t type, return ret; } +static void +ios_global_stats_clear (struct ios_global_stats *stats, struct timeval *now) +{ + GF_ASSERT (stats); + GF_ASSERT (now); + + memset (stats, 0, sizeof (*stats)); + stats->started_at = *now; +} + int io_stats_dump (xlator_t *this, struct ios_dump_args *args, - gf1_cli_stats_op op) + gf1_cli_stats_op op, gf_boolean_t is_peek) { struct ios_conf *conf = NULL; struct ios_global_stats cumulative = {0, }; @@ -937,29 +947,31 @@ io_stats_dump (xlator_t *this, struct ios_dump_args *args, gettimeofday (&now, NULL); LOCK (&conf->lock); { - if (op == GF_CLI_STATS_INFO || - op == GF_CLI_STATS_INFO_CUMULATIVE) + if (op == GF_CLI_INFO_ALL || + op == GF_CLI_INFO_CUMULATIVE) cumulative = conf->cumulative; - if (op == GF_CLI_STATS_INFO || - op == GF_CLI_STATS_INFO_INCREMENTAL) { + if (op == GF_CLI_INFO_ALL || + op == GF_CLI_INFO_INCREMENTAL) { incremental = conf->incremental; + increment = conf->increment; - increment = conf->increment++; + if (!is_peek) { + increment = conf->increment++; - memset (&conf->incremental, 0, - sizeof (conf->incremental)); - conf->incremental.started_at = now; + ios_global_stats_clear (&conf->incremental, + &now); + } } } UNLOCK (&conf->lock); - if (op == GF_CLI_STATS_INFO || - op == GF_CLI_STATS_INFO_CUMULATIVE) + if (op == GF_CLI_INFO_ALL || + op == GF_CLI_INFO_CUMULATIVE) io_stats_dump_global (this, &cumulative, &now, -1, args); - if (op == GF_CLI_STATS_INFO || - op == GF_CLI_STATS_INFO_INCREMENTAL) + if (op == GF_CLI_INFO_ALL || + op == GF_CLI_INFO_INCREMENTAL) io_stats_dump_global (this, &incremental, &now, increment, args); return 0; @@ -2218,10 +2230,10 @@ conditional_dump (dict_t *dict, char *key, data_t *value, void *data) gf_log (this->name, GF_LOG_ERROR, "failed to open %s " "for writing", filename); return -1; - } + } (void) ios_dump_args_init (&args, IOS_DUMP_TYPE_FILE, logfp); - io_stats_dump (this, &args, GF_CLI_STATS_INFO); + io_stats_dump (this, &args, GF_CLI_INFO_ALL, _gf_false); fclose (logfp); } return 0; @@ -2625,6 +2637,29 @@ ios_destroy_top_stats (struct ios_conf *conf) return; } +static int +io_stats_clear (struct ios_conf *conf) +{ + struct timeval now; + int ret = -1; + + GF_ASSERT (conf); + + if (!gettimeofday (&now, NULL)) + { + LOCK (&conf->lock); + { + ios_global_stats_clear (&conf->cumulative, &now); + ios_global_stats_clear (&conf->incremental, &now); + conf->increment = 0; + } + UNLOCK (&conf->lock); + ret = 0; + } + + return ret; +} + int reconfigure (xlator_t *this, dict_t *options) { @@ -2791,6 +2826,7 @@ notify (xlator_t *this, int32_t event, void *data, ...) int32_t list_cnt = 0; double throughput = 0; double time = 0; + gf_boolean_t is_peek = _gf_false; va_list ap; dict = data; @@ -2851,13 +2887,40 @@ notify (xlator_t *this, int32_t event, void *data, ...) } } else { ret = dict_get_int32 (dict, "info-op", &op); - if (ret || op < GF_CLI_STATS_INFO || - GF_CLI_STATS_INFO_CUMULATIVE < op) - op = GF_CLI_STATS_INFO; + if (ret || op < GF_CLI_INFO_ALL || + GF_CLI_INFO_CLEAR < op) + op = GF_CLI_INFO_ALL; + + ret = dict_set_int32 (output, "info-op", op); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to set info-op in dict"); + goto out; + } + + if (GF_CLI_INFO_CLEAR == op) { + ret = io_stats_clear (this->private); + if (ret) + gf_log (this->name, GF_LOG_ERROR, + "Failed to clear info stats"); - (void) ios_dump_args_init (&args, IOS_DUMP_TYPE_DICT, - output); - ret = io_stats_dump (this, &args, op); + ret = dict_set_int32 (output, "stats-cleared", + ret ? 0 : 1); + if (ret) + gf_log (this->name, GF_LOG_ERROR, + "Failed to set stats-cleared" + " in dict"); + } + else { + ret = dict_get_str_boolean (dict, "peek", + _gf_false); + if (-1 != ret) + is_peek = ret; + + (void) ios_dump_args_init (&args, + IOS_DUMP_TYPE_DICT, output); + ret = io_stats_dump (this, &args, op, is_peek); + } } break; default: diff --git a/xlators/features/gfid-access/src/gfid-access.c b/xlators/features/gfid-access/src/gfid-access.c index 1566278ef..362fdab5a 100644 --- a/xlators/features/gfid-access/src/gfid-access.c +++ b/xlators/features/gfid-access/src/gfid-access.c @@ -252,7 +252,7 @@ err: } static int32_t -ga_fill_tmp_loc (loc_t *loc, xlator_t *this, char *gfid, +ga_fill_tmp_loc (loc_t *loc, xlator_t *this, uuid_t gfid, char *bname, dict_t *xdata, loc_t *new_loc) { int ret = -1; @@ -263,6 +263,8 @@ ga_fill_tmp_loc (loc_t *loc, xlator_t *this, char *gfid, ret = inode_ctx_get (loc->inode, this, &value); if (!ret) { parent = (void *)value; + if (uuid_is_null (parent->gfid)) + parent = loc->inode; } /* parent itself should be looked up */ @@ -421,15 +423,20 @@ ga_new_entry (call_frame_t *frame, xlator_t *this, loc_t *loc, data_t *data, call_frame_t *new_frame = NULL; mode_t mode = 0; ga_local_t *local = NULL; + uuid_t gfid = {0,}; args = ga_newfile_parse_args (this, data); if (!args) goto out; + ret = uuid_parse (args->gfid, gfid); + if (ret) + goto out; + if (!xdata) xdata = dict_new (); - ret = ga_fill_tmp_loc (loc, this, args->gfid, + ret = ga_fill_tmp_loc (loc, this, gfid, args->bname, xdata, &tmp_loc); if (ret) goto out; @@ -485,15 +492,20 @@ ga_heal_entry (call_frame_t *frame, xlator_t *this, loc_t *loc, data_t *data, ga_heal_args_t *args = NULL; loc_t tmp_loc = {0,}; call_frame_t *new_frame = NULL; + uuid_t gfid = {0,}; args = ga_heal_parse_args (this, data); if (!args) goto out; + ret = uuid_parse (args->gfid, gfid); + if (ret) + goto out; + if (!xdata) xdata = dict_new (); - ret = ga_fill_tmp_loc (loc, this, args->gfid, args->bname, + ret = ga_fill_tmp_loc (loc, this, gfid, args->bname, xdata, &tmp_loc); if (ret) goto out; @@ -617,7 +629,8 @@ ga_virtual_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, /* the inode is not present in itable, ie, the actual path is not yet looked up. Use the current inode itself for now */ - inode_ref (inode); + + inode_link (inode, NULL, NULL, buf); } else { /* 'inode_ref()' has been done in inode_find() */ inode = true_inode; @@ -708,8 +721,30 @@ ga_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) /* if its revalidate, and inode is not of type directory, proceed with 'wind' */ if (loc->inode && loc->inode->ia_type && - !IA_ISDIR (loc->inode->ia_type)) + !IA_ISDIR (loc->inode->ia_type)) { + + /* a revalidate on ".gfid/<dentry>" is possible, check for it */ + if (((loc->parent && + __is_gfid_access_dir (loc->parent->gfid)) || + __is_gfid_access_dir (loc->pargfid))) { + + /* here, just send 'loc->gfid' and 'loc->inode' */ + tmp_loc.inode = inode_ref (loc->inode); + uuid_copy (tmp_loc.gfid, loc->inode->gfid); + + STACK_WIND (frame, default_lookup_cbk, + FIRST_CHILD(this), + FIRST_CHILD(this)->fops->lookup, + &tmp_loc, xdata); + + inode_unref (tmp_loc.inode); + + return 0; + } + + /* not something to bother, continue the flow */ goto wind; + } priv = this->private; @@ -729,8 +764,26 @@ ga_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) /* now, check if the lookup() is on an existing entry, but on gfid-path */ if (!((loc->parent && __is_gfid_access_dir (loc->parent->gfid)) || - __is_gfid_access_dir (loc->pargfid))) - goto wind; + __is_gfid_access_dir (loc->pargfid))) { + if (!loc->parent) + goto wind; + + ret = inode_ctx_get (loc->parent, this, &value); + if (ret) + goto wind; + + inode = (inode_t *) value; + + ret = loc_copy_overload_parent (&tmp_loc, loc, inode); + if (ret) + goto err; + + STACK_WIND (frame, ga_lookup_cbk, FIRST_CHILD (this), + FIRST_CHILD (this)->fops->lookup, &tmp_loc, xdata); + + loc_wipe (&tmp_loc); + return 0; + } /* make sure the 'basename' is actually a 'canonical-gfid', otherwise, return error */ diff --git a/xlators/features/gfid-access/src/gfid-access.h b/xlators/features/gfid-access/src/gfid-access.h index 3b74ce112..e883eca69 100644 --- a/xlators/features/gfid-access/src/gfid-access.h +++ b/xlators/features/gfid-access/src/gfid-access.h @@ -44,8 +44,7 @@ if (ret) \ goto lbl; \ tmp_inode = (inode_t *)value; \ - unref = inode_ref (tmp_inode); \ - l->parent = tmp_inode; \ + l->parent = inode_ref (tmp_inode); \ /* if parent is virtual, no need to handle */ \ /* loc->inode */ \ break; \ @@ -59,8 +58,7 @@ if (ret) \ goto lbl; \ tmp_inode = (inode_t *)value; \ - unref = inode_ref (tmp_inode); \ - l->inode = tmp_inode; \ + l->inode = inode_ref (tmp_inode); \ } \ \ } while (0) diff --git a/xlators/features/locks/src/entrylk.c b/xlators/features/locks/src/entrylk.c index 208bc140e..c176306fe 100644 --- a/xlators/features/locks/src/entrylk.c +++ b/xlators/features/locks/src/entrylk.c @@ -371,7 +371,6 @@ __lock_entrylk (xlator_t *this, pl_inode_t *pinode, pl_entry_lock_t *lock, __pl_entrylk_ref (lock); gettimeofday (&lock->granted_time, NULL); list_add (&lock->domain_list, &dom->entrylk_list); - lock->frame = NULL; ret = 0; out: @@ -576,10 +575,12 @@ pl_common_entrylk (call_frame_t *frame, xlator_t *this, reqlock->pinode = pinode; ret = __lock_entrylk (this, pinode, reqlock, nonblock, dom); - if (ret == 0) + if (ret == 0) { + reqlock->frame = NULL; op_ret = 0; - else + } else { op_errno = -ret; + } if (ctx && (!ret || !nonblock)) list_add (&reqlock->client_list, diff --git a/xlators/features/locks/src/inodelk.c b/xlators/features/locks/src/inodelk.c index 969b67a61..e7093e60e 100644 --- a/xlators/features/locks/src/inodelk.c +++ b/xlators/features/locks/src/inodelk.c @@ -478,6 +478,7 @@ pl_inode_setlk (xlator_t *this, pl_ctx_t *ctx, pl_inode_t *pl_inode, if (lock->fl_type != F_UNLCK) { ret = __lock_inodelk (this, pl_inode, lock, can_block, dom); if (ret == 0) { + lock->frame = NULL; gf_log (this->name, GF_LOG_TRACE, "%s (pid=%d) (lk-owner=%s) %"PRId64" - %"PRId64" => OK", lock->fl_type == F_UNLCK ? "Unlock" : "Lock", diff --git a/xlators/features/quota/src/quota-enforcer-client.c b/xlators/features/quota/src/quota-enforcer-client.c index bfea5e420..7d8ab937d 100644 --- a/xlators/features/quota/src/quota-enforcer-client.c +++ b/xlators/features/quota/src/quota-enforcer-client.c @@ -295,6 +295,37 @@ quota_enforcer_notify (struct rpc_clnt *rpc, void *mydata, return ret; } +int +quota_enforcer_blocking_connect (rpc_clnt_t *rpc) +{ + dict_t *options = NULL; + int ret = -1; + + options = dict_new (); + if (options == NULL) + goto out; + + ret = dict_set_str (options, "non-blocking-io", "no"); + if (ret) + goto out; + + rpc->conn.trans->reconfigure (rpc->conn.trans, options); + + rpc_clnt_start (rpc); + + ret = dict_set_str (options, "non-blocking-io", "yes"); + if (ret) + goto out; + + rpc->conn.trans->reconfigure (rpc->conn.trans, options); + + ret = 0; +out: + dict_unref (options); + + return ret; +} + //Returns a started rpc_clnt. Creates a new rpc_clnt if quota_priv doesn't have //one already struct rpc_clnt * @@ -309,9 +340,13 @@ quota_enforcer_init (xlator_t *this, dict_t *options) gf_log (this->name, GF_LOG_TRACE, "quota enforcer clnt already " "inited"); //Turns out to be a NOP if the clnt is already connected. - rpc_clnt_start (priv->rpc_clnt); + ret = quota_enforcer_blocking_connect (priv->rpc_clnt); + if (ret) + goto out; + return priv->rpc_clnt; } + priv->quota_enforcer = "a_enforcer_clnt; ret = dict_set_str (options, "transport.address-family", "unix"); @@ -339,7 +374,11 @@ quota_enforcer_init (xlator_t *this, dict_t *options) goto out; } - rpc_clnt_start (rpc); + ret = quota_enforcer_blocking_connect (rpc); + if (ret) + goto out; + + ret = 0; out: if (ret) { if (rpc) diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c index 5cbd9f02d..2812a2b13 100644 --- a/xlators/features/quota/src/quota.c +++ b/xlators/features/quota/src/quota.c @@ -215,6 +215,7 @@ __quota_dentry_new (quota_inode_ctx_t *ctx, char *name, uuid_t par) dentry->name = gf_strdup (name); if (dentry->name == NULL) { GF_FREE (dentry); + dentry = NULL; goto err; } @@ -244,7 +245,7 @@ out: } inline void -quota_resume_fop_if_validation_done (quota_local_t *local) +quota_link_count_decrement (quota_local_t *local) { call_stub_t *stub = NULL; int link_count = -1; @@ -254,7 +255,7 @@ quota_resume_fop_if_validation_done (quota_local_t *local) LOCK (&local->lock); { - link_count = local->link_count; + link_count = --local->link_count; if (link_count == 0) { stub = local->stub; local->stub = NULL; @@ -282,13 +283,11 @@ quota_handle_validate_error (quota_local_t *local, int32_t op_ret, local->op_ret = op_ret; local->op_errno = op_errno; } - - /* we abort checking limits on this path to root */ - local->link_count--; } UNLOCK (&local->lock); - quota_resume_fop_if_validation_done (local); + /* we abort checking limits on this path to root */ + quota_link_count_decrement (local); out: return; } @@ -378,31 +377,51 @@ quota_timeout (struct timeval *tv, int32_t timeout) return timed_out; } +inline void +quota_add_parent (quota_dentry_t *dentry, struct list_head *list) +{ + quota_dentry_t *entry = NULL; + gf_boolean_t found = _gf_false; + + if ((dentry == NULL) || (list == NULL)) { + goto out; + } + + list_for_each_entry (entry, list, next) { + if (uuid_compare (dentry->par, entry->par) == 0) { + found = _gf_true; + goto out; + } + } + + list_add_tail (&dentry->next, list); + +out: + return; +} + int32_t quota_build_ancestry_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata) { - inode_t *parent = NULL; - gf_dirent_t *entry = NULL; - loc_t loc = {0, }; - quota_dentry_t *dentry = NULL, *tmp = NULL; - quota_inode_ctx_t *ctx = NULL; - struct list_head parents = {0, }; - quota_local_t *local = NULL; - call_frame_t *continuation_frame = NULL; + inode_t *parent = NULL, *tmp_parent = NULL; + gf_dirent_t *entry = NULL; + loc_t loc = {0, }; + quota_dentry_t *dentry = NULL, *tmp = NULL; + quota_inode_ctx_t *ctx = NULL; + struct list_head parents = {0, }; + quota_local_t *local = NULL; INIT_LIST_HEAD (&parents); - continuation_frame = frame->local; + local = frame->local; frame->local = NULL; - local = continuation_frame->local; - if (op_ret < 0) goto err; - parent = inode_parent (local->validate_loc.inode, 0, NULL); + parent = inode_parent (local->loc.inode, 0, NULL); if (parent == NULL) { gf_log (this->name, GF_LOG_WARNING, "parent is NULL"); op_errno = EINVAL; @@ -423,61 +442,77 @@ quota_build_ancestry_cbk (call_frame_t *frame, void *cookie, xlator_t *this, * pointer and continue */ - parent = NULL; + tmp_parent = NULL; } uuid_copy (loc.gfid, entry->d_stat.ia_gfid); loc.inode = inode_ref (entry->inode); - loc.parent = inode_ref (parent); + loc.parent = inode_ref (tmp_parent); loc.name = entry->d_name; quota_fill_inodectx (this, entry->inode, entry->dict, &loc, &entry->d_stat, &op_errno); - parent = entry->inode; + tmp_parent = entry->inode; loc_wipe (&loc); } } - quota_inode_ctx_get (local->validate_loc.inode, this, &ctx, 0); - - local->link_count = 0; + quota_inode_ctx_get (local->loc.inode, this, &ctx, 0); if (ctx != NULL) { LOCK (&ctx->lock); { list_for_each_entry (dentry, &ctx->parents, next) { + /* we built ancestry for a non-directory */ tmp = __quota_dentry_new (NULL, dentry->name, dentry->par); - list_add_tail (&tmp->next, &parents); - local->link_count++; + quota_add_parent (tmp, &parents); + + if (list_empty (&tmp->next)) { + __quota_dentry_free (tmp); + tmp = NULL; + } } } UNLOCK (&ctx->lock); } - if (local->link_count != 0) { - list_for_each_entry_safe (dentry, tmp, &parents, next) { - quota_check_limit (continuation_frame, - local->validate_loc.inode, - this, dentry->name, dentry->par); - __quota_dentry_free (dentry); + if (list_empty (&parents)) { + /* we built ancestry for a directory */ + list_for_each_entry (entry, &entries->list, list) { + if (entry->inode == local->loc.inode) + break; } - } else { - local->link_count = 1; - quota_check_limit (continuation_frame, parent, this, NULL, - NULL); + + GF_ASSERT (&entry->list != &entries->list); + + tmp = __quota_dentry_new (NULL, entry->d_name, parent->gfid); + quota_add_parent (tmp, &parents); } - STACK_DESTROY (frame->root); - return 0; + local->ancestry_cbk (&parents, local->loc.inode, 0, 0, + local->ancestry_data); + goto cleanup; err: + local->ancestry_cbk (NULL, NULL, -1, op_errno, local->ancestry_data); + +cleanup: STACK_DESTROY (frame->root); + quota_local_cleanup (this, local); + + if (parent != NULL) { + inode_unref (parent); + parent = NULL; + } + + list_for_each_entry_safe (dentry, tmp, &parents, next) { + __quota_dentry_free (dentry); + } - quota_handle_validate_error (local, -1, op_errno); return 0; } @@ -486,85 +521,91 @@ quota_build_ancestry_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { - int ret = -1; - dict_t *xdata_req = NULL; - quota_local_t *local = NULL; - call_frame_t *continuation_frame = NULL; + dict_t *xdata_req = NULL; + quota_local_t *local = NULL; + + if (op_ret < 0) { + goto err; + } xdata_req = dict_new (); if (xdata_req == NULL) { - ret = -ENOMEM; + op_ret = -ENOMEM; goto err; } - ret = dict_set_int8 (xdata_req, QUOTA_LIMIT_KEY, 1); - if (ret < 0) + op_ret = dict_set_int8 (xdata_req, QUOTA_LIMIT_KEY, 1); + if (op_ret < 0) { + op_errno = -op_ret; goto err; + } - ret = dict_set_int8 (xdata_req, GET_ANCESTRY_DENTRY_KEY, 1); - if (ret < 0) + op_ret = dict_set_int8 (xdata_req, GET_ANCESTRY_DENTRY_KEY, 1); + if (op_ret < 0) { + op_errno = -op_ret; goto err; + } /* This would ask posix layer to construct dentry chain till root */ STACK_WIND (frame, quota_build_ancestry_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, fd, 0, 0, xdata_req); - ret = 0; + op_ret = 0; err: fd_unref (fd); dict_unref (xdata_req); - if (ret < 0) { - continuation_frame = frame->local; + if (op_ret < 0) { + local = frame->local; frame->local = NULL; + local->ancestry_cbk (NULL, NULL, -1, op_errno, + local->ancestry_data); + quota_local_cleanup (this, local); STACK_DESTROY (frame->root); - - local = continuation_frame->local; - quota_handle_validate_error (local, -1, op_errno); } - return ret; + return 0; } int -quota_build_ancestry (call_frame_t *frame, inode_t *inode, xlator_t *this) +quota_build_ancestry (inode_t *inode, quota_ancestry_built_t ancestry_cbk, + void *data) { loc_t loc = {0, }; fd_t *fd = NULL; quota_local_t *local = NULL; call_frame_t *new_frame = NULL; - int ret = -1; + int op_errno = EINVAL; + xlator_t *this = NULL; + + this = THIS; loc.inode = inode_ref (inode); uuid_copy (loc.gfid, inode->gfid); - gf_log (this->name, GF_LOG_WARNING, "building ancestry"); - - local = frame->local; - - LOCK (&local->lock); - { - loc_wipe (&local->validate_loc); + fd = fd_create (inode, 0); - ret = quota_inode_loc_fill (inode, &local->validate_loc); - if (ret < 0) { - gf_log (this->name, GF_LOG_WARNING, - "cannot fill loc for inode (gfid:%s), hence " - "aborting quota-checks and continuing with fop", - uuid_utoa (inode->gfid)); - } + new_frame = create_frame (this, this->ctx->pool); + if (new_frame == NULL) { + op_errno = ENOMEM; + goto err; } - UNLOCK (&local->lock); - fd = fd_create (inode, 0); - - new_frame = copy_frame (frame); new_frame->root->uid = new_frame->root->gid = 0; - new_frame->local = frame; + local = quota_local_new (); + if (local == NULL) { + op_errno = ENOMEM; + goto err; + } + + new_frame->local = local; + local->ancestry_cbk = ancestry_cbk; + local->ancestry_data = data; + local->loc.inode = inode_ref (inode); if (IA_ISDIR (inode->ia_type)) { STACK_WIND (new_frame, quota_build_ancestry_open_cbk, @@ -579,7 +620,25 @@ quota_build_ancestry (call_frame_t *frame, inode_t *inode, xlator_t *this) } loc_wipe (&loc); + return 0; + +err: + ancestry_cbk (NULL, NULL, -1, op_errno, data); + + fd_unref (fd); + + local = new_frame->local; + new_frame->local = NULL; + if (local != NULL) { + quota_local_cleanup (this, local); + } + + if (new_frame != NULL) { + STACK_DESTROY (new_frame->root); + } + + loc_wipe (&loc); return 0; } @@ -646,6 +705,56 @@ err: return ret; } +void +quota_check_limit_continuation (struct list_head *parents, inode_t *inode, + int32_t op_ret, int32_t op_errno, void *data) +{ + call_frame_t *frame = NULL; + xlator_t *this = NULL; + quota_local_t *local = NULL; + quota_dentry_t *entry = NULL; + inode_t *parent = NULL; + int parent_count = 0; + + frame = data; + local = frame->local; + this = THIS; + + if ((op_ret < 0) || list_empty (parents)) { + if (list_empty (parents)) { + gf_log (this->name, GF_LOG_WARNING, + "Couldn't build ancestry for inode (gfid:%s). " + "Without knowing ancestors till root, quota " + "cannot be enforced. " + "Hence, failing fop with EIO", + uuid_utoa (inode->gfid)); + op_errno = EIO; + } + + quota_handle_validate_error (local, -1, op_errno); + goto out; + } + + list_for_each_entry (entry, parents, next) { + parent_count++; + } + + LOCK (&local->lock); + { + local->link_count += (parent_count - 1); + } + UNLOCK (&local->lock); + + list_for_each_entry (entry, parents, next) { + parent = inode_find (inode->table, entry->par); + + quota_check_limit (frame, parent, this, NULL, NULL); + } + +out: + return; +} + int32_t quota_check_limit (call_frame_t *frame, inode_t *inode, xlator_t *this, char *name, uuid_t par) @@ -684,12 +793,8 @@ quota_check_limit (call_frame_t *frame, inode_t *inode, xlator_t *this, */ if (0 > frame->root->pid) { ret = 0; - LOCK (&local->lock); - { - --local->link_count; - } - UNLOCK (&local->lock); - goto resume; + quota_link_count_decrement (local); + goto done; } priv = this->private; @@ -772,12 +877,7 @@ quota_check_limit (call_frame_t *frame, inode_t *inode, xlator_t *this, } if (__is_root_gfid (_inode->gfid)) { - LOCK (&local->lock); - { - --local->link_count; - } - UNLOCK (&local->lock); - + quota_link_count_decrement (local); break; } @@ -789,7 +889,9 @@ quota_check_limit (call_frame_t *frame, inode_t *inode, xlator_t *this, } if (parent == NULL) { - ret = quota_build_ancestry (frame, _inode, this); + ret = quota_build_ancestry (_inode, + quota_check_limit_continuation, + frame); if (ret < 0) { op_errno = -ret; goto err; @@ -816,8 +918,7 @@ quota_check_limit (call_frame_t *frame, inode_t *inode, xlator_t *this, _inode = NULL; } -resume: - quota_resume_fop_if_validation_done (local); +done: return 0; err: @@ -978,7 +1079,7 @@ quota_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, if (!xattr_req) goto err; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); local = quota_local_new (); if (local == NULL) { @@ -995,14 +1096,8 @@ quota_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, goto err; } -wind: - /* TODO: check with vshastry@redhat.com to cleanup the ugliness of - * checking priv->is_quota_on here by using STACK_WIND_TAIL macro - */ - STACK_WIND (frame, - priv->is_quota_on ? quota_lookup_cbk : default_lookup_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, - xattr_req); + STACK_WIND (frame, quota_lookup_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->lookup, loc, xattr_req); ret = 0; @@ -1016,79 +1111,13 @@ err: } return 0; -} - - -void -quota_update_size (xlator_t *this, inode_t *inode, char *name, uuid_t par, - int64_t delta) -{ - inode_t *_inode = NULL; - inode_t *parent = NULL; - uint64_t value = 0; - quota_inode_ctx_t *ctx = NULL; - uuid_t trav_uuid = {0,}; - - GF_VALIDATE_OR_GOTO ("quota", this, out); - GF_VALIDATE_OR_GOTO (this->name, inode, out); - - inode_ctx_get (inode, this, &value); - ctx = (quota_inode_ctx_t *)(unsigned long)value; - - _inode = inode_ref (inode); - - if ( par != NULL ) { - uuid_copy (trav_uuid, par); - } - - do { - if ((ctx != NULL) && (ctx->hard_lim >= 0)) { - quota_log_usage (this, ctx, _inode, delta); - LOCK (&ctx->lock); - { - ctx->size += delta; - if (ctx->size < 0) - ctx->size = 0; - } - UNLOCK (&ctx->lock); - } - - if (__is_root_gfid (_inode->gfid)) { - break; - } - - parent = inode_parent (_inode, trav_uuid, name); - if (parent == NULL) { - /* TODO: build ancestry and continue updating size */ - gf_log (this->name, GF_LOG_DEBUG, - "cannot find parent for inode (gfid:%s), hence " - "aborting size updation of parents", - uuid_utoa (_inode->gfid)); - } - - if (name != NULL) { - name = NULL; - uuid_clear (trav_uuid); - } - - inode_unref (_inode); - _inode = parent; - - if (_inode == NULL) { - break; - } - value = 0; - ctx = NULL; - inode_ctx_get (_inode, this, &value); - ctx = (quota_inode_ctx_t *)(unsigned long)value; - } while (1); - -out: - return; +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->lookup, loc, xattr_req); + return 0; } - int32_t quota_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iatt *prebuf, @@ -1098,9 +1127,6 @@ quota_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, uint64_t ctx_int = 0; quota_inode_ctx_t *ctx = NULL; quota_local_t *local = NULL; - quota_dentry_t *dentry = NULL, *tmp = NULL; - int64_t delta = 0; - struct list_head head = {0, }; local = frame->local; @@ -1108,8 +1134,6 @@ quota_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, goto out; } - INIT_LIST_HEAD (&head); - ret = inode_ctx_get (local->loc.inode, this, &ctx_int); if (ret) { gf_log (this->name, GF_LOG_WARNING, @@ -1129,25 +1153,9 @@ quota_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, LOCK (&ctx->lock); { ctx->buf = *postbuf; - - list_for_each_entry (dentry, &ctx->parents, next) { - tmp = __quota_dentry_new (NULL, dentry->name, - dentry->par); - list_add_tail (&tmp->next, &head); - } - } UNLOCK (&ctx->lock); - if (postbuf->ia_blocks != prebuf->ia_blocks) - delta = local->delta; - - list_for_each_entry_safe (dentry, tmp, &head, next) { - quota_update_size (this, local->loc.inode, dentry->name, - dentry->par, delta); - __quota_dentry_free (dentry); - } - out: QUOTA_STACK_UNWIND (writev, frame, op_ret, op_errno, prebuf, postbuf, xdata); @@ -1202,8 +1210,7 @@ quota_writev_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, } } - STACK_WIND (frame, - priv->is_quota_on? quota_writev_cbk: default_writev_cbk, + STACK_WIND (frame, quota_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, off, flags, iobref, xdata); @@ -1235,7 +1242,7 @@ quota_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); INIT_LIST_HEAD (&head); @@ -1284,13 +1291,18 @@ quota_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, UNLOCK (&ctx->lock); } - local->delta = size; - - local->link_count = parents; - local->stub = stub; + LOCK (&local->lock); + { + local->delta = size; + local->link_count = (parents != 0) ? parents : 1; + local->stub = stub; + } + UNLOCK (&local->lock); if (parents == 0) { - local->link_count = 1; + /* nameless lookup on this inode, allow quota to reconstruct + * ancestry as part of check_limit. + */ quota_check_limit (frame, fd->inode, this, NULL, NULL); } else { list_for_each_entry_safe (dentry, tmp, &head, next) { @@ -1306,10 +1318,10 @@ unwind: QUOTA_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL, NULL); return 0; -wind: - STACK_WIND (frame, default_writev_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->writev, fd, - vector, count, off, flags, iobref, xdata); +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->writev, fd, + vector, count, off, flags, iobref, xdata); return 0; } @@ -1345,8 +1357,7 @@ quota_mkdir_helper (call_frame_t *frame, xlator_t *this, loc_t *loc, goto unwind; } - STACK_WIND (frame, - quota_mkdir_cbk, + STACK_WIND (frame, quota_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata); @@ -1370,7 +1381,7 @@ quota_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); local = quota_local_new (); if (local == NULL) { @@ -1394,9 +1405,13 @@ quota_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, goto err; } - local->stub = stub; - local->delta = 0; - local->link_count = 1; + LOCK (&local->lock); + { + local->stub = stub; + local->delta = 0; + local->link_count = 1; + } + UNLOCK (&local->lock); quota_check_limit (frame, loc->parent, this, NULL, NULL); return 0; @@ -1407,11 +1422,10 @@ err: return 0; -wind: - STACK_WIND (frame, - priv->is_quota_on? quota_mkdir_cbk: default_mkdir_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, loc, - mode, umask, xdata); +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->mkdir, + loc, mode, umask, xdata); return 0; } @@ -1493,8 +1507,7 @@ quota_create_helper (call_frame_t *frame, xlator_t *this, loc_t *loc, } - STACK_WIND (frame, - priv->is_quota_on? quota_create_cbk: default_create_cbk, + STACK_WIND (frame, quota_create_cbk, FIRST_CHILD (this), FIRST_CHILD (this)->fops->create, loc, flags, mode, umask, fd, xdata); return 0; @@ -1518,7 +1531,7 @@ quota_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); local = quota_local_new (); if (local == NULL) { @@ -1541,9 +1554,13 @@ quota_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, goto err; } - local->link_count = 1; - local->stub = stub; - local->delta = 0; + LOCK (&local->lock); + { + local->link_count = 1; + local->stub = stub; + local->delta = 0; + } + UNLOCK (&local->lock); quota_check_limit (frame, loc->parent, this, NULL, NULL); return 0; @@ -1553,11 +1570,10 @@ err: return 0; -wind: - STACK_WIND (frame, - priv->is_quota_on? quota_create_cbk: default_create_cbk, - FIRST_CHILD (this), FIRST_CHILD (this)->fops->create, loc, - flags, mode, umask, fd, xdata); +off: + STACK_WIND_TAIL (frame, FIRST_CHILD (this), + FIRST_CHILD (this)->fops->create, loc, + flags, mode, umask, fd, xdata); return 0; } @@ -1589,12 +1605,6 @@ quota_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, goto out; } - if (!local->skip_check) - quota_update_size (this, local->loc.inode, - (char *)local->loc.name, - local->loc.parent->gfid, - (-(ctx->buf.ia_blocks * 512))); - LOCK (&ctx->lock); { list_for_each_entry (dentry, &ctx->parents, next) { @@ -1627,7 +1637,7 @@ quota_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); local = quota_local_new (); if (local == NULL) { @@ -1646,11 +1656,8 @@ quota_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, goto err; } -wind: - STACK_WIND (frame, - priv->is_quota_on? quota_unlink_cbk: default_unlink_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, loc, - xflag, xdata); + STACK_WIND (frame, quota_unlink_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata); ret = 0; @@ -1660,6 +1667,11 @@ err: } return 0; + +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata); + return 0; } @@ -1684,9 +1696,6 @@ quota_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (local->skip_check) goto out; - quota_update_size (this, local->loc.parent, NULL, NULL, - (buf->ia_blocks * 512)); - ret = quota_inode_ctx_get (inode, this, &ctx, 0); if ((ret == -1) || (ctx == NULL)) { gf_log (this->name, GF_LOG_DEBUG, "quota context is NULL on " @@ -1763,7 +1772,7 @@ quota_link_helper (call_frame_t *frame, xlator_t *this, loc_t *oldloc, goto unwind; } - STACK_WIND (frame, priv->is_quota_on? quota_link_cbk: default_link_cbk, + STACK_WIND (frame, quota_link_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); return 0; @@ -1787,7 +1796,11 @@ quota_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); + + if (xdata && dict_get (xdata, GLUSTERFS_INTERNAL_FOP_KEY)) { + goto off; + } quota_inode_ctx_get (oldloc->inode, this, &ctx, 0); if (ctx == NULL) { @@ -1805,10 +1818,6 @@ quota_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, frame->local = (void *) local; - if (xdata && dict_get (xdata, GLUSTERFS_INTERNAL_FOP_KEY)) { - local->skip_check = _gf_true; - goto wind; - } ret = loc_copy (&local->loc, newloc); if (ret == -1) { @@ -1821,9 +1830,13 @@ quota_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, goto err; } - local->link_count = 1; - local->stub = stub; - local->delta = (ctx != NULL) ? ctx->buf.ia_blocks * 512 : 0; + LOCK (&local->lock); + { + local->link_count = 1; + local->stub = stub; + local->delta = (ctx != NULL) ? ctx->buf.ia_blocks * 512 : 0; + } + UNLOCK (&local->lock); quota_check_limit (frame, newloc->parent, this, NULL, NULL); return 0; @@ -1831,13 +1844,12 @@ quota_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, err: QUOTA_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); - return 0; -wind: - STACK_WIND (frame, default_link_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, oldloc, - newloc, xdata); +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->link, oldloc, + newloc, xdata); return 0; } @@ -1872,13 +1884,6 @@ quota_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this, size = buf->ia_blocks * 512; } - if (local->oldloc.parent != local->newloc.parent) { - quota_update_size (this, local->oldloc.parent, NULL, NULL, - (-size)); - quota_update_size (this, local->newloc.parent, NULL, NULL, - size); - } - if (!QUOTA_REG_OR_LNK_FILE (local->oldloc.inode->ia_type)) { goto out; } @@ -1980,8 +1985,7 @@ quota_rename_helper (call_frame_t *frame, xlator_t *this, loc_t *oldloc, goto unwind; } - STACK_WIND (frame, - priv->is_quota_on? quota_rename_cbk: default_rename_cbk, + STACK_WIND (frame, quota_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); @@ -2046,7 +2050,7 @@ quota_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); local = quota_local_new (); if (local == NULL) { @@ -2073,8 +2077,12 @@ quota_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, goto err; } - local->link_count = 1; - local->stub = stub; + LOCK (&local->lock); + { + local->link_count = 1; + local->stub = stub; + } + UNLOCK (&local->lock); if (QUOTA_REG_OR_LNK_FILE (oldloc->inode->ia_type)) { ret = quota_inode_ctx_get (oldloc->inode, this, &ctx, 0); @@ -2122,10 +2130,10 @@ err: NULL, NULL, NULL, NULL, NULL); return 0; -wind: - STACK_WIND (frame, default_rename_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, oldloc, - newloc, xdata); +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->rename, oldloc, + newloc, xdata); return 0; } @@ -2137,7 +2145,6 @@ quota_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { - int64_t size = 0; quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; quota_dentry_t *dentry = NULL; @@ -2147,9 +2154,6 @@ quota_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } local = frame->local; - size = buf->ia_blocks * 512; - - quota_update_size (this, local->loc.parent, NULL, NULL, size); quota_inode_ctx_get (local->loc.inode, this, &ctx, 1); if (ctx == NULL) { @@ -2208,8 +2212,7 @@ quota_symlink_helper (call_frame_t *frame, xlator_t *this, const char *linkpath, goto unwind; } - STACK_WIND (frame, - priv->is_quota_on? quota_symlink_cbk: default_symlink_cbk, + STACK_WIND (frame, quota_symlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, linkpath, loc, umask, xdata); return 0; @@ -2233,7 +2236,7 @@ quota_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath, priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); local = quota_local_new (); if (local == NULL) { @@ -2254,9 +2257,13 @@ quota_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath, goto err; } - local->stub = stub; - local->delta = strlen (linkpath); - local->link_count = 1; + LOCK (&local->lock); + { + local->stub = stub; + local->delta = strlen (linkpath); + local->link_count = 1; + } + UNLOCK (&local->lock); quota_check_limit (frame, loc->parent, this, NULL, NULL); return 0; @@ -2267,11 +2274,10 @@ err: return 0; -wind: - STACK_WIND (frame, - priv->is_quota_on? quota_symlink_cbk: default_symlink_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, - linkpath, loc, umask, xdata); +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->symlink, + linkpath, loc, umask, xdata); return 0; } @@ -2283,7 +2289,6 @@ quota_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, { quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; - int64_t delta = 0; if (op_ret < 0) { goto out; @@ -2295,10 +2300,6 @@ quota_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, goto out; } - delta = (postbuf->ia_blocks - prebuf->ia_blocks) * 512; - - quota_update_size (this, local->loc.inode, NULL, NULL, delta); - quota_inode_ctx_get (local->loc.inode, this, &ctx, 0); if (ctx == NULL) { gf_log (this->name, GF_LOG_DEBUG, "quota context is NULL on " @@ -2332,8 +2333,7 @@ quota_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); - + WIND_IF_QUOTAOFF (priv->is_quota_on, off); local = quota_local_new (); if (local == NULL) { @@ -2348,17 +2348,19 @@ quota_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, goto err; } -wind: - STACK_WIND (frame, - priv->is_quota_on? quota_truncate_cbk: default_truncate_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, loc, - offset, xdata); + STACK_WIND (frame, quota_truncate_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); return 0; + err: QUOTA_STACK_UNWIND (truncate, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); + return 0; } @@ -2369,7 +2371,6 @@ quota_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, { quota_local_t *local = NULL; quota_inode_ctx_t *ctx = NULL; - int64_t delta = 0; if (op_ret < 0) { goto out; @@ -2381,10 +2382,6 @@ quota_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, goto out; } - delta = (postbuf->ia_blocks - prebuf->ia_blocks) * 512; - - quota_update_size (this, local->loc.inode, NULL, NULL, delta); - quota_inode_ctx_get (local->loc.inode, this, &ctx, 0); if (ctx == NULL) { gf_log (this->name, GF_LOG_DEBUG, "quota context is NULL on " @@ -2417,7 +2414,7 @@ quota_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); local = quota_local_new (); if (local == NULL) @@ -2427,9 +2424,7 @@ quota_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, local->loc.inode = inode_ref (fd->inode); -wind: - STACK_WIND (frame, priv->is_quota_on? - quota_ftruncate_cbk: default_ftruncate_cbk, + STACK_WIND (frame, quota_ftruncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); @@ -2438,6 +2433,12 @@ err: QUOTA_STACK_UNWIND (ftruncate, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; + +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->ftruncate, fd, + offset, xdata); + return 0; } @@ -2581,8 +2582,7 @@ quota_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); - + WIND_IF_QUOTAOFF (priv->is_quota_on, off); local = quota_local_new (); if (local == NULL) { @@ -2596,15 +2596,20 @@ quota_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) goto unwind; } -wind: - STACK_WIND (frame, priv->is_quota_on? quota_stat_cbk: default_stat_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat, loc, + STACK_WIND (frame, quota_stat_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->stat, loc, xdata); return 0; unwind: QUOTA_STACK_UNWIND (stat, frame, -1, ENOMEM, NULL, NULL); return 0; + +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->stat, loc, + xdata); + return 0; } @@ -2661,7 +2666,7 @@ quota_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); local = quota_local_new (); if (local == NULL) { @@ -2672,9 +2677,7 @@ quota_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) local->loc.inode = inode_ref (fd->inode); -wind: - STACK_WIND (frame, - priv->is_quota_on? quota_fstat_cbk: default_fstat_cbk, + STACK_WIND (frame, quota_fstat_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, fd, xdata); return 0; @@ -2682,6 +2685,12 @@ wind: unwind: QUOTA_STACK_UNWIND (fstat, frame, -1, ENOMEM, NULL, NULL); return 0; + +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fstat, fd, + xdata); + return 0; } @@ -2736,7 +2745,7 @@ quota_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); local = quota_local_new (); if (local == NULL) { @@ -2751,9 +2760,7 @@ quota_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, goto unwind; } -wind: - STACK_WIND (frame, priv->is_quota_on? - quota_readlink_cbk: default_readlink_cbk, + STACK_WIND (frame, quota_readlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readlink, loc, size, xdata); return 0; @@ -2761,6 +2768,12 @@ wind: unwind: QUOTA_STACK_UNWIND (readlink, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; + +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->readlink, loc, + size, xdata); + return 0; } @@ -2815,7 +2828,7 @@ quota_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); local = quota_local_new (); if (local == NULL) { @@ -2826,9 +2839,7 @@ quota_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, local->loc.inode = inode_ref (fd->inode); -wind: - STACK_WIND (frame, - priv->is_quota_on? quota_readv_cbk: default_readv_cbk, + STACK_WIND (frame, quota_readv_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); return 0; @@ -2837,6 +2848,12 @@ unwind: QUOTA_STACK_UNWIND (readv, frame, -1, ENOMEM, NULL, -1, NULL, NULL, NULL); return 0; + +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->readv, fd, + size, offset, flags, xdata); + return 0; } @@ -2890,7 +2907,7 @@ quota_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); local = quota_local_new (); if (local == NULL) { @@ -2901,10 +2918,8 @@ quota_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, frame->local = local; -wind: - STACK_WIND (frame, - priv->is_quota_on? quota_fsync_cbk: default_fsync_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync, fd, + STACK_WIND (frame, quota_fsync_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fsync, fd, flags, xdata); return 0; @@ -2912,6 +2927,11 @@ unwind: QUOTA_STACK_UNWIND (fsync, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fsync, fd, + flags, xdata); + return 0; } @@ -2970,7 +2990,7 @@ quota_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); local = quota_local_new (); if (local == NULL) { @@ -2985,16 +3005,20 @@ quota_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, goto unwind; } -wind: - STACK_WIND (frame, - priv->is_quota_on? quota_setattr_cbk: default_setattr_cbk, - FIRST_CHILD (this), FIRST_CHILD (this)->fops->setattr, loc, + STACK_WIND (frame, quota_setattr_cbk, FIRST_CHILD (this), + FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid, xdata); return 0; unwind: QUOTA_STACK_UNWIND (setattr, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; + +off: + STACK_WIND_TAIL (frame, FIRST_CHILD (this), + FIRST_CHILD (this)->fops->setattr, loc, + stbuf, valid, xdata); + return 0; } @@ -3051,8 +3075,7 @@ quota_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); - + WIND_IF_QUOTAOFF (priv->is_quota_on, off); local = quota_local_new (); if (local == NULL) { @@ -3063,9 +3086,7 @@ quota_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, local->loc.inode = inode_ref (fd->inode); -wind: - STACK_WIND (frame, - priv->is_quota_on? quota_fsetattr_cbk: default_fsetattr_cbk, + STACK_WIND (frame, quota_fsetattr_cbk, FIRST_CHILD (this), FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid, xdata); return 0; @@ -3073,6 +3094,12 @@ wind: unwind: QUOTA_STACK_UNWIND (fsetattr, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; + +off: + STACK_WIND_TAIL (frame, FIRST_CHILD (this), + FIRST_CHILD (this)->fops->fsetattr, fd, + stbuf, valid, xdata); + return 0; } @@ -3148,8 +3175,7 @@ quota_mknod_helper (call_frame_t *frame, xlator_t *this, loc_t *loc, goto unwind; } - STACK_WIND (frame, - priv->is_quota_on? quota_mknod_cbk: default_mknod_cbk, + STACK_WIND (frame, quota_mknod_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask, xdata); @@ -3173,7 +3199,7 @@ quota_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); local = quota_local_new (); if (local == NULL) { @@ -3194,26 +3220,27 @@ quota_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, goto err; } - local->link_count = 1; - local->stub = stub; - local->delta = 0; + LOCK (&local->lock); + { + local->link_count = 1; + local->stub = stub; + local->delta = 0; + } + UNLOCK (&local->lock); quota_check_limit (frame, loc->parent, this, NULL, NULL); return 0; + err: QUOTA_STACK_UNWIND (mknod, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL); - return 0; -wind: - STACK_WIND (frame, - priv->is_quota_on? quota_mknod_cbk: default_mknod_cbk, - FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, loc, - mode, rdev, umask, xdata); - +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->mknod, loc, + mode, rdev, umask, xdata); return 0; - } int @@ -3255,42 +3282,20 @@ quota_setxattr (call_frame_t *frame, xlator_t *this, int op_ret = -1; int64_t hard_lim = -1, soft_lim = -1; quota_local_t *local = NULL; - char *src = NULL; - char *dst = NULL; - int len = 0; - int ret = -1; priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); VALIDATE_OR_GOTO (frame, err); VALIDATE_OR_GOTO (this, err); VALIDATE_OR_GOTO (loc, err); - if (0 <= frame->root->pid) { - ret = dict_get_ptr_and_len (dict, QUOTA_LIMIT_KEY, - (void **)&src, &len); - if (ret) { - gf_log (this->name, GF_LOG_DEBUG, "dict_get on %s " - "failed", QUOTA_LIMIT_KEY); - } else { - dst = GF_CALLOC (len, sizeof (char), gf_common_mt_char); - if (dst) - memcpy (dst, src, len); - } - - GF_REMOVE_INTERNAL_XATTR ("trusted.glusterfs.quota*", - dict); - if (!ret && IA_ISDIR (loc->inode->ia_type) && dst) { - ret = dict_set_dynptr (dict, QUOTA_LIMIT_KEY, - dst, len); - if (ret) - gf_log (this->name, GF_LOG_WARNING, "setting " - "key %s failed", QUOTA_LIMIT_KEY); - else - dst = NULL; - } + if (frame->root->pid >= 0) { + GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.quota*", dict, + op_errno, err); + GF_IF_INTERNAL_XATTR_GOTO ("trusted.pgfid*", dict, op_errno, + err); } quota_get_limits (this, dict, &hard_lim, &soft_lim); @@ -3309,15 +3314,19 @@ quota_setxattr (call_frame_t *frame, xlator_t *this, local->limit.soft_lim_percent = soft_lim; } -wind: - STACK_WIND (frame, - priv->is_quota_on? quota_setxattr_cbk: default_setxattr_cbk, + STACK_WIND (frame, quota_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); return 0; err: QUOTA_STACK_UNWIND (setxattr, frame, op_ret, op_errno, NULL); return 0; + +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->setxattr, loc, + dict, flags, xdata); + return 0; } int @@ -3361,15 +3370,18 @@ quota_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); VALIDATE_OR_GOTO (frame, err); VALIDATE_OR_GOTO (this, err); VALIDATE_OR_GOTO (fd, err); - if (0 <= frame->root->pid) - GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.quota*", dict, + if (0 <= frame->root->pid) { + GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.quota*", + dict, op_errno, err); + GF_IF_INTERNAL_XATTR_GOTO ("trusted.pgfid*", dict, op_errno, err); + } quota_get_limits (this, dict, &hard_lim, &soft_lim); @@ -3382,15 +3394,19 @@ quota_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, local->limit.soft_lim_percent = soft_lim; } -wind: - STACK_WIND (frame, priv->is_quota_on? - quota_fsetxattr_cbk: default_fsetxattr_cbk, + STACK_WIND (frame, quota_fsetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); return 0; - err: +err: QUOTA_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno, NULL); return 0; + +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fsetxattr, fd, + dict, flags, xdata); + return 0; } @@ -3411,28 +3427,37 @@ quota_removexattr (call_frame_t *frame, xlator_t *this, priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); VALIDATE_OR_GOTO (this, err); /* all quota xattrs can be cleaned up by doing setxattr on special key. * Hence its ok that we don't allow removexattr on quota keys here. */ - GF_IF_NATIVE_XATTR_GOTO ("trusted.quota*", - name, op_errno, err); + if (frame->root->pid >= 0) { + GF_IF_NATIVE_XATTR_GOTO ("trusted.glusterfs.quota*", + name, op_errno, err); + GF_IF_NATIVE_XATTR_GOTO ("trusted.pgfid*", name, + op_errno, err); + } VALIDATE_OR_GOTO (frame, err); VALIDATE_OR_GOTO (loc, err); -wind: - STACK_WIND (frame, priv->is_quota_on? - quota_removexattr_cbk: default_removexattr_cbk, + STACK_WIND (frame, quota_removexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); return 0; + err: QUOTA_STACK_UNWIND (removexattr, frame, -1, op_errno, NULL); return 0; + +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->removexattr, + loc, name, xdata); + return 0; } @@ -3454,24 +3479,31 @@ quota_fremovexattr (call_frame_t *frame, xlator_t *this, priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); VALIDATE_OR_GOTO (frame, err); VALIDATE_OR_GOTO (this, err); VALIDATE_OR_GOTO (fd, err); - GF_IF_NATIVE_XATTR_GOTO ("trusted.quota*", - name, op_errno, err); - -wind: - STACK_WIND (frame, priv->is_quota_on? - quota_fremovexattr_cbk: default_fremovexattr_cbk, + if (frame->root->pid >= 0) { + GF_IF_NATIVE_XATTR_GOTO ("trusted.glusterfs.quota*", + name, op_errno, err); + GF_IF_NATIVE_XATTR_GOTO ("trusted.pgfid*", name, + op_errno, err); + } + STACK_WIND (frame, quota_fremovexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); return 0; - err: +err: QUOTA_STACK_UNWIND (fremovexattr, frame, op_ret, op_errno, NULL); return 0; + +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fremovexattr, + fd, name, xdata); + return 0; } @@ -3640,9 +3672,7 @@ quota_statfs_validate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, UNLOCK (&ctx->lock); resume: - --local->link_count; - - quota_resume_fop_if_validation_done (local); + quota_link_count_decrement (local); return 0; } @@ -3657,7 +3687,7 @@ quota_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); if (priv->consider_statfs && loc->inode) { local = quota_local_new (); @@ -3667,44 +3697,46 @@ quota_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) } frame->local = local; - local->inode = inode_ref (loc->inode); - local->link_count = 1; - stub = fop_statfs_stub (frame, quota_statfs_helper, loc, xdata); if (!stub) { op_errno = ENOMEM; goto err; } - local->stub = stub; + LOCK (&local->lock); + { + local->inode = inode_ref (loc->inode); + local->link_count = 1; + local->stub = stub; + } + UNLOCK (&local->lock); ret = quota_validate (frame, local->inode, this, quota_statfs_validate_cbk); if (0 > ret) { - op_errno = -ret; - --local->link_count; + quota_handle_validate_error (local, -1, -ret); } - quota_resume_fop_if_validation_done (local); - } - else { - /* - * We have to make sure that we never get to quota_statfs_cbk - * with a cookie that points to something other than an inode, - * which is exactly what would happen with STACK_UNWIND using - * that as a callback. Therefore, use default_statfs_cbk in - * this case instead. - * - * Also if the option deem-statfs is not set to "on" don't - * bother calculating quota limit on / in statfs_cbk. - */ - if (priv->consider_statfs) - gf_log(this->name,GF_LOG_WARNING, - "missing inode, cannot adjust for quota"); -wind: - STACK_WIND (frame, default_statfs_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->statfs, loc, xdata); + return 0; } + + /* + * We have to make sure that we never get to quota_statfs_cbk + * with a cookie that points to something other than an inode, + * which is exactly what would happen with STACK_UNWIND using + * that as a callback. Therefore, use default_statfs_cbk in + * this case instead. + * + * Also if the option deem-statfs is not set to "on" don't + * bother calculating quota limit on / in statfs_cbk. + */ + if (priv->consider_statfs) + gf_log (this->name,GF_LOG_WARNING, + "missing inode, cannot adjust for quota"); + +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->statfs, loc, xdata); return 0; err: @@ -3763,7 +3795,7 @@ quota_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, priv = this->private; - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); local = quota_local_new (); @@ -3789,9 +3821,7 @@ quota_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, } } -wind: - STACK_WIND (frame, - priv->is_quota_on? quota_readdirp_cbk: default_readdirp_cbk, + STACK_WIND (frame, quota_readdirp_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, fd, size, offset, dict); @@ -3808,6 +3838,12 @@ err: } return 0; + +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->readdirp, fd, + size, offset, dict); + return 0; } int32_t @@ -3819,8 +3855,6 @@ quota_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, uint64_t ctx_int = 0; quota_inode_ctx_t *ctx = NULL; quota_local_t *local = NULL; - quota_dentry_t *dentry = NULL; - int64_t delta = 0; local = frame->local; @@ -3850,12 +3884,6 @@ quota_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, } UNLOCK (&ctx->lock); - list_for_each_entry (dentry, &ctx->parents, next) { - delta = (postbuf->ia_blocks - prebuf->ia_blocks) * 512; - quota_update_size (this, local->loc.inode, - dentry->name, dentry->par, delta); - } - out: QUOTA_STACK_UNWIND (fallocate, frame, op_ret, op_errno, prebuf, postbuf, xdata); @@ -3885,8 +3913,7 @@ quota_fallocate_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, goto unwind; } - STACK_WIND (frame, priv->is_quota_on? - quota_fallocate_cbk: default_fallocate_cbk, + STACK_WIND (frame, quota_fallocate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len, xdata); @@ -3913,7 +3940,7 @@ quota_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, priv = this->private; GF_VALIDATE_OR_GOTO (this->name, priv, unwind); - WIND_IF_QUOTAOFF (priv->is_quota_on, wind); + WIND_IF_QUOTAOFF (priv->is_quota_on, off); GF_ASSERT (frame); GF_VALIDATE_OR_GOTO ("quota", this, unwind); @@ -3981,12 +4008,10 @@ unwind: QUOTA_STACK_UNWIND (fallocate, frame, -1, op_errno, NULL, NULL, NULL); return 0; -wind: - STACK_WIND (frame, priv->is_quota_on? - quota_fallocate_cbk: default_fallocate_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len, - xdata); +off: + STACK_WIND_TAIL (frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, + len, xdata); return 0; } @@ -4152,14 +4177,15 @@ err: int reconfigure (xlator_t *this, dict_t *options) { - int32_t ret = -1; - quota_priv_t *priv = NULL; + int32_t ret = -1; + quota_priv_t *priv = NULL; + gf_boolean_t quota_on = _gf_false; priv = this->private; GF_OPTION_RECONF ("deem-statfs", priv->consider_statfs, options, bool, out); - GF_OPTION_RECONF ("server-quota", priv->is_quota_on, options, bool, + GF_OPTION_RECONF ("server-quota", quota_on, options, bool, out); GF_OPTION_RECONF ("default-soft-limit", priv->default_soft_lim, options, percent, out); @@ -4170,7 +4196,7 @@ reconfigure (xlator_t *this, dict_t *options) GF_OPTION_RECONF ("hard-timeout", priv->hard_timeout, options, time, out); - if (priv->is_quota_on) { + if (quota_on) { priv->rpc_clnt = quota_enforcer_init (this, this->options); if (priv->rpc_clnt == NULL) { @@ -4191,6 +4217,8 @@ reconfigure (xlator_t *this, dict_t *options) } } + priv->is_quota_on = quota_on; + ret = 0; out: return ret; diff --git a/xlators/features/quota/src/quota.h b/xlators/features/quota/src/quota.h index 02bc0d8b6..84c3257fe 100644 --- a/xlators/features/quota/src/quota.h +++ b/xlators/features/quota/src/quota.h @@ -160,28 +160,34 @@ struct quota_limit { } __attribute__ ((packed)); typedef struct quota_limit quota_limit_t; +typedef void +(*quota_ancestry_built_t) (struct list_head *parents, inode_t *inode, + int32_t op_ret, int32_t op_errno, void *data); + struct quota_local { - gf_lock_t lock; - uint32_t validate_count; - uint32_t link_count; - loc_t loc; - loc_t oldloc; - loc_t newloc; - loc_t validate_loc; - int64_t delta; - int32_t op_ret; - int32_t op_errno; - int64_t size; - gf_boolean_t skip_check; - char just_validated; - fop_lookup_cbk_t validate_cbk; - inode_t *inode; - call_stub_t *stub; - struct iobref *iobref; - quota_limit_t limit; - int64_t space_available; + gf_lock_t lock; + uint32_t validate_count; + uint32_t link_count; + loc_t loc; + loc_t oldloc; + loc_t newloc; + loc_t validate_loc; + int64_t delta; + int32_t op_ret; + int32_t op_errno; + int64_t size; + gf_boolean_t skip_check; + char just_validated; + fop_lookup_cbk_t validate_cbk; + inode_t *inode; + call_stub_t *stub; + struct iobref *iobref; + quota_limit_t limit; + int64_t space_available; + quota_ancestry_built_t ancestry_cbk; + void *ancestry_data; }; -typedef struct quota_local quota_local_t; +typedef struct quota_local quota_local_t; struct quota_priv { uint32_t soft_timeout; diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 06ee849f5..963aa0762 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -1094,8 +1094,7 @@ glusterd_op_stage_stats_volume (dict_t *dict, char **op_errstr) } if ((GF_CLI_STATS_STOP == stats_op) || - (GF_CLI_STATS_INFO <= stats_op && - stats_op <= GF_CLI_STATS_INFO_CUMULATIVE)) { + (GF_CLI_STATS_INFO == stats_op)) { if (_gf_false == glusterd_is_profile_on (volinfo)) { snprintf (msg, sizeof (msg), "Profile on Volume %s is" " not started", volinfo->volname); @@ -1105,8 +1104,7 @@ glusterd_op_stage_stats_volume (dict_t *dict, char **op_errstr) } } if ((GF_CLI_STATS_TOP == stats_op) || - (GF_CLI_STATS_INFO <= stats_op && - stats_op <= GF_CLI_STATS_INFO_CUMULATIVE)) { + (GF_CLI_STATS_INFO == stats_op)) { if (_gf_false == glusterd_is_volume_started (volinfo)) { snprintf (msg, sizeof (msg), "Volume %s is not started.", volinfo->volname); @@ -1541,10 +1539,12 @@ glusterd_op_set_volume (dict_t *dict) if (dict_count == 0) { ret = glusterd_volset_help (NULL, &op_errstr); if (ret) { - op_errstr = (op_errstr)? op_errstr: - "Volume set help internal error"; - gf_log (this->name, GF_LOG_ERROR, "%s", op_errstr); + gf_log (this->name, GF_LOG_ERROR, "%s", + (op_errstr)? op_errstr: + "Volume set help internal error"); } + + GF_FREE(op_errstr); goto out; } @@ -1908,8 +1908,6 @@ glusterd_op_stats_volume (dict_t *dict, char **op_errstr, glusterd_remove_profile_volume_options (volinfo); break; case GF_CLI_STATS_INFO: - case GF_CLI_STATS_INFO_INCREMENTAL: - case GF_CLI_STATS_INFO_CUMULATIVE: case GF_CLI_STATS_TOP: //info is already collected in brick op. //just goto out; @@ -4480,8 +4478,6 @@ glusterd_bricks_select_profile_volume (dict_t *dict, char **op_errstr, goto out; break; case GF_CLI_STATS_INFO: - case GF_CLI_STATS_INFO_INCREMENTAL: - case GF_CLI_STATS_INFO_CUMULATIVE: ret = dict_get_str_boolean (dict, "nfs", _gf_false); if (ret) { if (!glusterd_is_nodesvc_online ("nfs")) { diff --git a/xlators/mgmt/glusterd/src/glusterd-quota.c b/xlators/mgmt/glusterd/src/glusterd-quota.c index ffde532bd..d13533aa6 100644 --- a/xlators/mgmt/glusterd/src/glusterd-quota.c +++ b/xlators/mgmt/glusterd/src/glusterd-quota.c @@ -996,14 +996,6 @@ glusterd_quotad_op (int opcode) ret = glusterd_check_generate_start_quotad (); break; - case GF_QUOTA_OPTION_TYPE_DEFAULT_SOFT_LIMIT: - case GF_QUOTA_OPTION_TYPE_HARD_TIMEOUT: - case GF_QUOTA_OPTION_TYPE_SOFT_TIMEOUT: - case GF_QUOTA_OPTION_TYPE_ALERT_TIME: - - ret = glusterd_reconfigure_quotad (); - break; - default: ret = 0; break; @@ -1131,6 +1123,12 @@ glusterd_op_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict) goto out; } + if (priv->op_version > GD_OP_VERSION_MIN) { + ret = glusterd_quotad_op (type); + if (ret) + goto out; + } + ret = glusterd_create_volfiles_and_notify_services (volinfo); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Unable to re-create " @@ -1151,11 +1149,6 @@ glusterd_op_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict) if (rsp_dict && start_crawl == _gf_true) glusterd_quota_initiate_fs_crawl (priv, volname, type); - if (priv->op_version > GD_OP_VERSION_MIN) { - ret = glusterd_quotad_op (type); - if (ret) - goto out; - } ret = 0; out: return ret; diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c index d0ad7dcdb..2c2fc6fb4 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.c +++ b/xlators/mgmt/glusterd/src/glusterd-store.c @@ -2582,8 +2582,10 @@ glusterd_store_retrieve_peers (xlator_t *this) ret = gf_store_iter_get_next (iter, &key, &value, &op_errno); } - if (op_errno != GD_STORE_EOF) + if (op_errno != GD_STORE_EOF) { + GF_FREE(hostname); goto out; + } (void) gf_store_iter_destroy (iter); diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index fc4018190..21a973086 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -1295,11 +1295,14 @@ glusterd_brick_connect (glusterd_volinfo_t *volinfo, glusterd_brick_rpc_notify, brickid); synclock_lock (&priv->big_lock); - if (ret) + if (ret) { + GF_FREE (brickid); goto out; + } brickinfo->rpc = rpc; } out: + gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); return ret; } @@ -3965,7 +3968,7 @@ glusterd_nodesvc_disconnect (char *server) } int32_t -glusterd_nodesvc_start (char *server) +glusterd_nodesvc_start (char *server, gf_boolean_t wait) { int32_t ret = -1; xlator_t *this = NULL; @@ -4051,7 +4054,16 @@ glusterd_nodesvc_start (char *server) runner_log (&runner, "", GF_LOG_DEBUG, "Starting the nfs/glustershd services"); - ret = runner_run_nowait (&runner); + if (!wait) { + ret = runner_run_nowait (&runner); + } else { + synclock_unlock (&priv->big_lock); + { + ret = runner_run (&runner); + } + synclock_lock (&priv->big_lock); + } + if (ret == 0) { glusterd_nodesvc_connect (server, sockfpath); } @@ -4062,19 +4074,19 @@ out: int glusterd_nfs_server_start () { - return glusterd_nodesvc_start ("nfs"); + return glusterd_nodesvc_start ("nfs", _gf_false); } int glusterd_shd_start () { - return glusterd_nodesvc_start ("glustershd"); + return glusterd_nodesvc_start ("glustershd", _gf_false); } int glusterd_quotad_start () { - return glusterd_nodesvc_start ("quotad"); + return glusterd_nodesvc_start ("quotad", _gf_true); } gf_boolean_t @@ -4805,8 +4817,8 @@ _local_gsyncd_start (dict_t *this, char *key, data_t *value, void *data) uuid_str, NULL); out: - if (path_list) - GF_FREE (path_list); + GF_FREE (path_list); + GF_FREE (op_errstr); return ret; } diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index a94a47af3..303abd1bc 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -1974,13 +1974,13 @@ server_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, } /* Check for compress volume option, and add it to the graph on server side */ - if (dict_get_str_boolean (set_dict, "features.compress", 0)) { + if (dict_get_str_boolean (set_dict, "network.compression", 0)) { xl = volgen_graph_add (graph, "features/cdc", volname); if (!xl) { ret = -1; goto out; } - ret = dict_set_str (set_dict, "compress.mode", "server"); + ret = dict_set_str (set_dict, "network.compression.mode", "server"); if (ret) goto out; } @@ -2852,13 +2852,13 @@ client_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, goto out; /* Check for compress volume option, and add it to the graph on client side */ - if (dict_get_str_boolean (set_dict, "features.compress", 0)) { + if (dict_get_str_boolean (set_dict, "network.compression", 0)) { xl = volgen_graph_add (graph, "features/cdc", volname); if (!xl) { ret = -1; goto out; } - ret = dict_set_str (set_dict, "compress.mode", "client"); + ret = dict_set_str (set_dict, "network.compression.mode", "client"); if (ret) goto out; diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c index 520b0f774..8d29e8edc 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c @@ -1023,47 +1023,52 @@ struct volopt_map_entry glusterd_volopt_map[] = { #ifdef HAVE_LIB_Z /* Compressor-decompressor xlator options - * defaults used from xlator/feature/compress/src/cdc.h + * defaults used from xlator/features/compress/src/cdc.h */ - { .key = "features.compress", + { .key = "network.compression", .voltype = "features/cdc", - .option = "!compress", .value = "off", .type = NO_DOC, - .op_version = 2, - .description = "enable/disable compression translator" + .op_version = 3, + .description = "enable/disable network compression translator" }, - { .key = "compress.mode", + { .key = "network.compression.mode", .voltype = "features/cdc", + .option = "mode", .type = NO_DOC, - .op_version = 2 + .op_version = 3 }, - { .key = "compress.window-size", + { .key = "network.compression.window-size", .voltype = "features/cdc", + .option = "window-size", .type = NO_DOC, - .op_version = 2 + .op_version = 3 }, - { .key = "compress.mem-level", + { .key = "network.compression.mem-level", .voltype = "features/cdc", + .option = "mem-level", .type = NO_DOC, - .op_version = 2 + .op_version = 3 }, - { .key = "compress.min-size", + { .key = "network.compression.min-size", .voltype = "features/cdc", + .option = "min-size", .type = NO_DOC, - .op_version = 2 + .op_version = 3 }, - { .key = "compress.compression-level", + { .key = "network.compression.compression-level", .voltype = "features/cdc", + .option = "compression-level", .type = NO_DOC, - .op_version = 2 + .op_version = 3 }, - { .key = "compress.debug", + { .key = "network.compression.debug", .voltype = "features/cdc", + .option = "debug", .type = NO_DOC, - .op_version = 2 + .op_version = 3 }, - #endif +#endif /* Quota xlator options */ { .key = VKEY_FEATURES_LIMIT_USAGE, @@ -1470,27 +1475,27 @@ struct volopt_map_entry glusterd_volopt_map[] = { { .key = "changelog.changelog", .voltype = "features/changelog", .type = NO_DOC, - .op_version = 2 + .op_version = 3 }, { .key = "changelog.changelog-dir", .voltype = "features/changelog", .type = NO_DOC, - .op_version = 2 + .op_version = 3 }, { .key = "changelog.encoding", .voltype = "features/changelog", .type = NO_DOC, - .op_version = 2 + .op_version = 3 }, { .key = "changelog.rollover-time", .voltype = "features/changelog", .type = NO_DOC, - .op_version = 2 + .op_version = 3 }, { .key = "changelog.fsync-interval", .voltype = "features/changelog", .type = NO_DOC, - .op_version = 2 + .op_version = 3 }, { .key = NULL } diff --git a/xlators/mount/fuse/src/fuse-helpers.c b/xlators/mount/fuse/src/fuse-helpers.c index 6c54cb882..2774bdaa8 100644 --- a/xlators/mount/fuse/src/fuse-helpers.c +++ b/xlators/mount/fuse/src/fuse-helpers.c @@ -596,6 +596,8 @@ fuse_ignore_xattr_set (fuse_private_t *priv, char *key) || (fnmatch ("*.glusterfs.volume-mark", key, FNM_PERIOD) == 0) || (fnmatch ("*.glusterfs.volume-mark.*", + key, FNM_PERIOD) == 0) + || (fnmatch ("glusterfs.gfid.newfile", key, FNM_PERIOD) == 0))) ret = -1; diff --git a/xlators/nfs/server/src/mount3.c b/xlators/nfs/server/src/mount3.c index e86235522..47ff3845e 100644 --- a/xlators/nfs/server/src/mount3.c +++ b/xlators/nfs/server/src/mount3.c @@ -469,7 +469,7 @@ mount_rewrite_rmtab (struct mount3_state *ms, char *new_rmtab) "%s as rmtab", nfs->rmtab); } else { GF_FREE (nfs->rmtab); - nfs->rmtab = new_rmtab; + nfs->rmtab = rmtab; } gf_store_unlock (nsh); diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c index d8c5f4262..b0a71d3f9 100644 --- a/xlators/protocol/client/src/client.c +++ b/xlators/protocol/client/src/client.c @@ -943,6 +943,7 @@ client_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, args.vector = vector; args.count = count; args.offset = off; + args.size = iov_length (vector, count); args.flags = flags; args.iobref = iobref; args.xdata = xdata; diff --git a/xlators/protocol/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server-rpc-fops.c index d43571e87..c56da30a7 100644 --- a/xlators/protocol/server/src/server-rpc-fops.c +++ b/xlators/protocol/server/src/server-rpc-fops.c @@ -3735,6 +3735,7 @@ server3_3_writev (rpcsvc_request_t *req) state->resolve.type = RESOLVE_MUST; state->resolve.fd_no = args.fd; state->offset = args.offset; + state->size = args.size; state->flags = args.flag; state->iobref = iobref_ref (req->iobref); memcpy (state->resolve.gfid, args.gfid, 16); diff --git a/xlators/storage/posix/src/posix-handle.c b/xlators/storage/posix/src/posix-handle.c index 613709fc8..adb8acc07 100644 --- a/xlators/storage/posix/src/posix-handle.c +++ b/xlators/storage/posix/src/posix-handle.c @@ -145,7 +145,7 @@ posix_make_ancestryfromgfid (xlator_t *this, char *path, int pathsize, dir_handle = alloca (handle_size); linkname = alloca (PATH_MAX); snprintf (dir_handle, handle_size, "%s/%s/%02x/%02x/%s", - priv_base_path, HANDLE_PFX, gfid[0], gfid[1], + priv_base_path, GF_HIDDEN_PATH, gfid[0], gfid[1], uuid_utoa (gfid)); len = readlink (dir_handle, linkname, PATH_MAX); @@ -343,13 +343,13 @@ posix_handle_path (xlator_t *this, uuid_t gfid, const char *basename, buf = alloca (maxlen); } - base_len = (priv->base_path_length + SLEN(HANDLE_PFX) + 45); + base_len = (priv->base_path_length + SLEN(GF_HIDDEN_PATH) + 45); base_str = alloca (base_len + 1); base_len = snprintf (base_str, base_len + 1, "%s/%s/%02x/%02x/%s", - priv->base_path, HANDLE_PFX, gfid[0], gfid[1], + priv->base_path, GF_HIDDEN_PATH, gfid[0], gfid[1], uuid_str); - pfx_len = priv->base_path_length + 1 + SLEN(HANDLE_PFX) + 1; + pfx_len = priv->base_path_length + 1 + SLEN(GF_HIDDEN_PATH) + 1; if (basename) { len = snprintf (buf, maxlen, "%s/%s", base_str, basename); @@ -391,7 +391,7 @@ posix_handle_gfid_path (xlator_t *this, uuid_t gfid, const char *basename, len = priv->base_path_length /* option directory "/export" */ + SLEN("/") - + SLEN(HANDLE_PFX) + + SLEN(GF_HIDDEN_PATH) + SLEN("/") + SLEN("00/") + SLEN("00/") @@ -422,10 +422,10 @@ posix_handle_gfid_path (xlator_t *this, uuid_t gfid, const char *basename, if (basename) { len = snprintf (buf, buflen, "%s/%s/%02x/%02x/%s/%s", priv->base_path, - HANDLE_PFX, gfid[0], gfid[1], uuid_str, basename); + GF_HIDDEN_PATH, gfid[0], gfid[1], uuid_str, basename); } else { len = snprintf (buf, buflen, "%s/%s/%02x/%02x/%s", priv->base_path, - HANDLE_PFX, gfid[0], gfid[1], uuid_str); + GF_HIDDEN_PATH, gfid[0], gfid[1], uuid_str); } out: return len; @@ -454,10 +454,10 @@ posix_handle_init (xlator_t *this) return -1; } - handle_pfx = alloca (priv->base_path_length + 1 + strlen (HANDLE_PFX) + handle_pfx = alloca (priv->base_path_length + 1 + strlen (GF_HIDDEN_PATH) + 1); - sprintf (handle_pfx, "%s/%s", priv->base_path, HANDLE_PFX); + sprintf (handle_pfx, "%s/%s", priv->base_path, GF_HIDDEN_PATH); ret = stat (handle_pfx, &stbuf); switch (ret) { @@ -621,7 +621,7 @@ posix_handle_trash_init (xlator_t *this) priv = this->private; priv->trash_path = GF_CALLOC (1, priv->base_path_length + strlen ("/") - + strlen (HANDLE_PFX) + strlen ("/") + + strlen (GF_HIDDEN_PATH) + strlen ("/") + strlen (TRASH_DIR) + 1, gf_posix_mt_trash_path); @@ -629,7 +629,7 @@ posix_handle_trash_init (xlator_t *this) goto out; strncpy (priv->trash_path, priv->base_path, priv->base_path_length); - strcat (priv->trash_path, "/" HANDLE_PFX "/" TRASH_DIR); + strcat (priv->trash_path, "/" GF_HIDDEN_PATH "/" TRASH_DIR); ret = posix_handle_new_trash_init (this, priv->trash_path); if (ret) goto out; diff --git a/xlators/storage/posix/src/posix-handle.h b/xlators/storage/posix/src/posix-handle.h index 8874ca265..31cbf83fd 100644 --- a/xlators/storage/posix/src/posix-handle.h +++ b/xlators/storage/posix/src/posix-handle.h @@ -19,7 +19,6 @@ #include "xlator.h" #include "gf-dirent.h" -#define HANDLE_PFX ".glusterfs" #define TRASH_DIR "landfill" #define UUID0_STR "00000000-0000-0000-0000-000000000000" diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 83b689d06..c1cbc83f4 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -885,7 +885,6 @@ posix_opendir (call_frame_t *frame, xlator_t *this, VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (this, out); VALIDATE_OR_GOTO (loc, out); - VALIDATE_OR_GOTO (loc->path, out); VALIDATE_OR_GOTO (fd, out); SET_FS_ID (frame->root->uid, frame->root->gid); diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index d579bf673..91e0664ed 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -54,7 +54,7 @@ #define MAX_NO_VECT 1024 #define POSIX_GFID_HANDLE_SIZE(base_path_len) (base_path_len + SLEN("/") \ - + SLEN(HANDLE_PFX) + SLEN("/") \ + + SLEN(GF_HIDDEN_PATH) + SLEN("/") \ + SLEN("00/") \ + SLEN("00/") + SLEN(UUID0_STR) + 1) /* '\0' */; |