Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 4 Jul 2012 20:20:48 +0000 (UTC)
From:      Pawel Jakub Dawidek <pjd@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r238120 - head/sbin/hastd
Message-ID:  <201207042020.q64KKmiI030669@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: pjd
Date: Wed Jul  4 20:20:48 2012
New Revision: 238120
URL: http://svn.freebsd.org/changeset/base/238120

Log:
  Make use of GEOM Gate direct reads feature. This allows HAST to serve
  reads with native speed of the underlying provider.
  There are three situations when direct reads are not used:
  1. Data is being synchronized and synchronization source is the secondary
     node, which means secondary node has more recent data and we should read
     from it.
  2. Local read failed and we have to try to read from the secondary node.
  3. Local component is unavailable and all I/O requests are served from the
     secondary node.
  
  Sponsored by:	Panzura, http://www.panzura.com
  MFC after:	1 month

Modified:
  head/sbin/hastd/primary.c

Modified: head/sbin/hastd/primary.c
==============================================================================
--- head/sbin/hastd/primary.c	Wed Jul  4 20:16:28 2012	(r238119)
+++ head/sbin/hastd/primary.c	Wed Jul  4 20:20:48 2012	(r238120)
@@ -543,6 +543,27 @@ primary_connect(struct hast_resource *re
 
 	return (0);
 }
+ 
+/*
+ * Function instructs GEOM_GATE to handle reads directly from within the kernel.
+ */
+static void
+enable_direct_reads(struct hast_resource *res)
+{
+	struct g_gate_ctl_modify ggiomodify;
+
+	bzero(&ggiomodify, sizeof(ggiomodify));
+	ggiomodify.gctl_version = G_GATE_VERSION;
+	ggiomodify.gctl_unit = res->hr_ggateunit;
+	ggiomodify.gctl_modify = GG_MODIFY_READPROV | GG_MODIFY_READOFFSET;
+	strlcpy(ggiomodify.gctl_readprov, res->hr_localpath,
+	    sizeof(ggiomodify.gctl_readprov));
+	ggiomodify.gctl_readoffset = res->hr_localoff;
+	if (ioctl(res->hr_ggatefd, G_GATE_CMD_MODIFY, &ggiomodify) == 0)
+		pjdlog_debug(1, "Direct reads enabled.");
+	else
+		pjdlog_errno(LOG_WARNING, "Failed to enable direct reads");
+}
 
 static int
 init_remote(struct hast_resource *res, struct proto_conn **inp,
@@ -692,6 +713,8 @@ init_remote(struct hast_resource *res, s
 	res->hr_secondary_localcnt = nv_get_uint64(nvin, "localcnt");
 	res->hr_secondary_remotecnt = nv_get_uint64(nvin, "remotecnt");
 	res->hr_syncsrc = nv_get_uint8(nvin, "syncsrc");
+	if (res->hr_syncsrc == HAST_SYNCSRC_PRIMARY)
+		enable_direct_reads(res);
 	if (nv_exists(nvin, "virgin")) {
 		/*
 		 * Secondary was reinitialized, bump localcnt if it is 0 as
@@ -1789,13 +1812,14 @@ sync_thread(void *arg __unused)
 	struct timeval tstart, tend, tdiff;
 	unsigned int ii, ncomp, ncomps;
 	off_t offset, length, synced;
-	bool dorewind;
+	bool dorewind, directreads;
 	int syncext;
 
 	ncomps = HAST_NCOMPONENTS;
 	dorewind = true;
 	synced = 0;
 	offset = -1;
+	directreads = false;
 
 	for (;;) {
 		mtx_lock(&sync_lock);
@@ -1867,6 +1891,8 @@ sync_thread(void *arg __unused)
 					event_send(res, EVENT_SYNCDONE);
 				}
 				mtx_lock(&metadata_lock);
+				if (res->hr_syncsrc == HAST_SYNCSRC_SECONDARY)
+					directreads = true;
 				res->hr_syncsrc = HAST_SYNCSRC_UNDEF;
 				res->hr_primary_localcnt =
 				    res->hr_secondary_remotecnt;
@@ -1880,6 +1906,10 @@ sync_thread(void *arg __unused)
 				mtx_unlock(&metadata_lock);
 			}
 			rw_unlock(&hio_remote_lock[ncomp]);
+			if (directreads) {
+				directreads = false;
+				enable_direct_reads(res);
+			}
 			continue;
 		}
 		pjdlog_debug(2, "sync: Taking free request.");



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201207042020.q64KKmiI030669>