From nobody Sat Sep 21 13:05:52 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4X9qJ048gjz5WNQX; Sat, 21 Sep 2024 13:05:52 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4X9qJ03nCJz45Zf; Sat, 21 Sep 2024 13:05:52 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1726923952; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=n4afZ0OF+/+GWDEd9roJBtXZs03XNWfVZRMigyaY41Y=; b=yyvwSbbCpTAZri9bD/gh9dHn8UJyFP8KqjNXu590f7KMJVliOS7TNe9orAbXe5YFlKJzOH UUUOfBD1tnPhjuYJ1zlSKooAj1YN626fe7tF76F0enNybjjK2TYcwPJBvPc8nE2pGKbty2 OvKQa7+IdaocK0j2S2Frq0jK5MbaBMyCt1gvfbOF+J7jIqvL3J5+hegQ3GYc0XV76Ob5SH 7kUHYvOhm/m7Jitcn7c/laBShdmy6SARUsZPF5lh0KW+ZMfk/zxY/0jCp57/jZn6sA4PIp 1o28Bvm/Hh8AaSfGcLGBa5VkWYKv1IGm4XJzLv5L/88vlw1h9pX2PuqWJat0kg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1726923952; a=rsa-sha256; cv=none; b=UBeOUkdnA/RXPPrw47kYxfoJueXtJYXD4lkv1eu8ngcmAA6N1FNtjZOB+7/NAV44+M3YGK E1BczdGgnUuM3K7Ps4eH0Xri8OtLFUDdw7F3aifR+eo1UoyCKsrwwx/Sz6EJxqwQ9tkxnP waORWPnXFJKAq4eCMY6msP/BXi+rELs1XWHPQwjgaooA+viv9d0+/C5J8SVhW0gJ0TiWZl pCjKvf53Iw7dlRAgYTZKPsz37424DOFnc6z1jjuyoKLvao7sG1c8kogQKAAIylvvKu6UNw rT+xzGuXGH1dQhepcHQr11u21tjfgahDPaZ+JvXNJ6sinzyYXf6sdB9tSXLKHg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1726923952; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=n4afZ0OF+/+GWDEd9roJBtXZs03XNWfVZRMigyaY41Y=; b=qkyDhfJz05W6wmoBQIpiS+dI/sGca0Or+UDz4GmJwecfRQk8Oe7XY6yYfUroQ6BIHm8TGN kMZqmEGkLSv8sjy2hRTE9L1AuBjxEw9bVjmvNEdwc47LApH/St3Pvj/28WwaIdIEun5GFt sWEsQcj1nmJcfc61iR9wf2iYVeQ5v8PBCi4gUzluTrFrGfX/9aE+SBP3KEiqIQCioggctN EBRt1roqK43V7AXzC2D4WOaWDZ5Xvfnfi2gnQ7/OsX9pT5l7y0cuWNXyJ8EUs0BRzX7/hi kRc4m3JItqlyHIs4tQL1LeWHHQUiXmsSWLdbnNA9EmbfxS/1mI3rHRwJzMAypg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4X9qJ03NGFzZs0; Sat, 21 Sep 2024 13:05:52 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 48LD5qMZ010644; Sat, 21 Sep 2024 13:05:52 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 48LD5qS1010641; Sat, 21 Sep 2024 13:05:52 GMT (envelope-from git) Date: Sat, 21 Sep 2024 13:05:52 GMT Message-Id: <202409211305.48LD5qS1010641@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mark Johnston Subject: git: 1b1e392aed49 - main - ggate: Add support for O_DIRECT access List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 1b1e392aed4957a38c49599512b4f65b844a0772 Auto-Submitted: auto-generated The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=1b1e392aed4957a38c49599512b4f65b844a0772 commit 1b1e392aed4957a38c49599512b4f65b844a0772 Author: David E. Cross AuthorDate: 2024-09-21 07:22:57 +0000 Commit: Mark Johnston CommitDate: 2024-09-21 13:05:22 +0000 ggate: Add support for O_DIRECT access Adds support for controlling O_DIRECT access to ggated, ggatec, and ggatel. Reviewed by: markj Relnotes: yes MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D45056 --- sbin/ggate/ggatec/ggatec.8 | 25 ++++++++--- sbin/ggate/ggatec/ggatec.c | 12 ++++-- sbin/ggate/ggated/ggated.8 | 54 ++++++++++++++++++++++-- sbin/ggate/ggated/ggated.c | 102 +++++++++++++++++++++++++++++++++++---------- sbin/ggate/ggatel/ggatel.8 | 24 +++++++---- sbin/ggate/ggatel/ggatel.c | 20 ++++++--- sbin/ggate/shared/ggate.h | 7 +++- 7 files changed, 192 insertions(+), 52 deletions(-) diff --git a/sbin/ggate/ggatec/ggatec.8 b/sbin/ggate/ggatec/ggatec.8 index 1b780632f154..99f9bcab5964 100644 --- a/sbin/ggate/ggatec/ggatec.8 +++ b/sbin/ggate/ggatec/ggatec.8 @@ -34,6 +34,7 @@ .Op Fl n .Op Fl v .Op Fl o Cm ro | wo | rw +.Op Fl o Cm direct .Op Fl p Ar port .Op Fl q Ar queue_size .Op Fl R Ar rcvbuf @@ -48,6 +49,7 @@ .Op Fl n .Op Fl v .Op Fl o Cm ro | wo | rw +.Op Fl o Cm direct .Op Fl p Ar port .Op Fl R Ar rcvbuf .Op Fl S Ar sndbuf @@ -108,13 +110,21 @@ provider (cancels all pending requests). Do not use .Dv TCP_NODELAY option on TCP sockets. -.It Fl o Cm ro | wo | rw -Specify permissions to use when opening the file or device: read-only -.Pq Cm ro , +.It Fl o Ar option +Specify permissions and options to use when opening the file or device. +.Bl -tag -width indent +.It Cm ro +read-only +.It Cm wo write-only -.Pq Cm wo , -or read-write -.Pq Cm rw . +.It Cm rw +read-write +.It Cm direct +open with +.Dv O_DIRECT +option on the file +.El +.Pp Default is .Cm rw . .It Fl p Ar port @@ -160,11 +170,14 @@ Use a CD-ROM device on a remote host. .Bd -literal -offset indent server# cat /etc/gg.exports client RO /dev/cd0 +client RW /tmp/image server# ggated client# ggatec create -o ro server /dev/cd0 ggate0 client# mount_cd9660 /dev/ggate0 /cdrom +client# ggatec create -o rw -o direct server /tmp/image +ggate1 .Ed .Sh SEE ALSO .Xr geom 4 , diff --git a/sbin/ggate/ggatec/ggatec.c b/sbin/ggate/ggatec/ggatec.c index 5ce605596fb9..b6f248c05290 100644 --- a/sbin/ggate/ggatec/ggatec.c +++ b/sbin/ggate/ggatec/ggatec.c @@ -52,7 +52,6 @@ #include #include -#include #include "ggate.h" @@ -62,6 +61,7 @@ static const char *path = NULL; static const char *host = NULL; static int unit = G_GATE_UNIT_AUTO; static unsigned flags = 0; +static int direct_flag = 0; static int force = 0; static unsigned queue_size = G_GATE_QUEUE_SIZE; static unsigned port = G_GATE_PORT; @@ -78,10 +78,12 @@ static void usage(void) { - fprintf(stderr, "usage: %s create [-nv] [-o ] [-p port] " + fprintf(stderr, "usage: %s create [-nv] [-o ] " + "[-o ] [-p port] " "[-q queue_size] [-R rcvbuf] [-S sndbuf] [-s sectorsize] " "[-t timeout] [-u unit] \n", getprogname()); - fprintf(stderr, " %s rescue [-nv] [-o ] [-p port] " + fprintf(stderr, " %s rescue [-nv] [-o ] " + "[-o ] [-p port] " "[-R rcvbuf] [-S sndbuf] <-u unit> \n", getprogname()); fprintf(stderr, " %s destroy [-f] <-u unit>\n", getprogname()); fprintf(stderr, " %s list [-v] [-u unit]\n", getprogname()); @@ -361,7 +363,7 @@ handshake(int dir) close(sfd); return (-1); } - cinit.gc_flags = flags | dir; + cinit.gc_flags = flags | direct_flag | dir; cinit.gc_token = token; cinit.gc_nconn = 2; g_gate_swap2n_cinit(&cinit); @@ -585,6 +587,8 @@ main(int argc, char *argv[]) flags = G_GATE_FLAG_WRITEONLY; else if (strcasecmp("rw", optarg) == 0) flags = 0; + else if (strcasecmp("direct", optarg) == 0) + direct_flag = GGATE_FLAG_DIRECT; else { errx(EXIT_FAILURE, "Invalid argument for '-o' option."); diff --git a/sbin/ggate/ggated/ggated.8 b/sbin/ggate/ggated/ggated.8 index 7016dd58f87a..8e3ad68d1db0 100644 --- a/sbin/ggate/ggated/ggated.8 +++ b/sbin/ggate/ggated/ggated.8 @@ -85,10 +85,51 @@ An alternate location for the exports file. .Pp The format of an exports file is as follows: .Bd -literal -offset indent -1.2.3.4 RO /dev/cd0 -1.2.3.0/24 RW /tmp/test.img -hostname WO /tmp/image +1.2.3.4 RO /dev/cd0 +1.2.3.0/24 RW /tmp/test.img +hostname WO /tmp/image +hostname RW,DIRECT /tmp/direct-image +hostname RW,NODIRECT /tmp/nodirect-image .Ed +.Pp +The first colunm specifies the ip, network with netmask, or the hostname +that the export applies to. +.Pp +The next column is the access flags that apply to the export +.Bl -tag -width ".Cm NODIRECT" +.It Cm RO +Read-Only the path specified will be exported to the client read only. +.It Cm WO +Write-Only the path specified will be exported to the client write only. +.It Cm RW +Read-Write the path specified will be exported to the client read-write. +.It Cm DIRECT +The path specified will always be opened with O_DIRECT for clients. +.It Cm NODIRECT +The path specified will never be opened with O_DIRECT for clients. +.El +.Pp +The final column specifies the path to export. +.Pp +Files are opened with the least common flags between the client and the +server. A client may request read or write only to a read-write export +and the server will honor the client request and open the file in the +requested mode. A client requesting greater access than permissions listed +in the file will be rejected. +.Pp +DIRECT and NODIRECT are used to coerce the use of the O_DIRECT flag to +.Xr open 2 when the specified path is opened. If DIRECT is specified the +path is always opened with O_DIRECT. If NODIRECT is specified the path is +never opened with O_DIRECT. DIRECT access limits the cache effects of +IO operaions on the file. This has the effect of having clients accessing +exports to not impact the cache of the local machine, however it +will cause greater IO utilization to the devices on which the files reside. +.Pp +If neither is specified the server will use +the preference specified by the client, with the default to not use O_DIRECT. +If the client specifies a preference against the server's configuration the +client preference will be silently ignored. +.Pp .Sh FILES .Bl -tag -width ".Pa /var/run/ggated.pid" -compact .It Pa /var/run/ggated.pid @@ -104,13 +145,18 @@ should be called with the .Fl v option. .Sh EXAMPLES -Export CD-ROM device and a file: +Export CD-ROM device, a file, and a file with +.Dv O_DIRECT +option: .Bd -literal -offset indent # echo "1.2.3.0/24 RO /dev/cd0" > /etc/gg.exports # echo "client RW /image" >> /etc/gg.exports +# echo "client RW,DIRECT /image2" >> /etc/gg.exports +# echo "client RW,NODIRECT /image3" >> /etc/gg.exports # ggated .Ed .Sh SEE ALSO +.Xr open 2 , .Xr geom 4 , .Xr ggatec 8 , .Xr ggatel 8 diff --git a/sbin/ggate/ggated/ggated.c b/sbin/ggate/ggated/ggated.c index c579da1c1267..ef7b61cb13c4 100644 --- a/sbin/ggate/ggated/ggated.c +++ b/sbin/ggate/ggated/ggated.c @@ -64,7 +64,7 @@ struct ggd_connection { off_t c_mediasize; unsigned c_sectorsize; - unsigned c_flags; /* flags (RO/RW) */ + int c_flags; /* flags (RO/RW) */ int c_diskfd; int c_sendfd; int c_recvfd; @@ -85,11 +85,18 @@ struct ggd_request { #define r_length r_hdr.gh_length #define r_error r_hdr.gh_error +#define EFLAGS_RDONLY 0x0000 +#define EFLAGS_WRONLY 0x0001 +#define EFLAGS_RDWR 0x0002 +#define EFLAGS_ACCMODE 0x0003 +#define EFLAGS_DIRECT 0x0004 +#define EFLAGS_NODIRECT 0x0008 + struct ggd_export { char *e_path; /* path to device/file */ in_addr_t e_ip; /* remote IP address */ in_addr_t e_mask; /* IP mask */ - unsigned e_flags; /* flags (RO/RW) */ + int e_flags; /* flags (WO/RO/RW/DIRECT/NODIRECT) */ SLIST_ENTRY(ggd_export) e_next; }; @@ -146,20 +153,61 @@ countmask(unsigned m) return (mask); } +static int +parse_flags(const char *flagsstr, int lineno) +{ + char *flagscpy; + char *word, *brkf; + int access_flags = -1; + int direct_flags = 0; + + flagscpy = strdup(flagsstr); + if (flagscpy == NULL) { + g_gate_xlog("Not enough memory."); + } + + for (word = strtok_r(flagscpy, ",", &brkf); + word != NULL; + word = strtok_r(NULL, ",", &brkf)) { + if (strcasecmp("ro", word) == 0 || + strcasecmp("rd", word) == 0) { + access_flags = EFLAGS_RDONLY; + } else if (strcasecmp("wo", word) == 0) { + access_flags = EFLAGS_WRONLY; + } else if (strcasecmp("rw", word) == 0) { + access_flags = EFLAGS_RDWR; + } else if (strcasecmp("direct", word) == 0) { + direct_flags = EFLAGS_DIRECT; + } else if (strcasecmp("nodirect", word) == 0) { + direct_flags = EFLAGS_NODIRECT; + } else { + g_gate_xlog("Invalid value (%s) in flags field at " + "line %u.", word, lineno); + } + } + free(flagscpy); + if (access_flags == -1) { + g_gate_xlog("Invalid value (%s) in flags field at " + "line %u.", flagsstr, lineno); + } + return (direct_flags | access_flags); +} + static void line_parse(char *line, unsigned lineno) { struct ggd_export *ex; - char *word, *path, *sflags; - unsigned flags, i, vmask; + char *word, *path, *sflags, *brkl; + unsigned i, vmask; + int flags; in_addr_t ip, mask; ip = mask = flags = vmask = 0; path = NULL; sflags = NULL; - for (i = 0, word = strtok(line, " \t"); word != NULL; - i++, word = strtok(NULL, " \t")) { + for (i = 0, word = strtok_r(line, " \t", &brkl); word != NULL; + i++, word = strtok_r(NULL, " \t", &brkl)) { switch (i) { case 0: /* IP address or host name */ ip = g_gate_str2ip(strsep(&word, "/")); @@ -185,17 +233,7 @@ line_parse(char *line, unsigned lineno) mask = countmask(vmask); break; case 1: /* flags */ - if (strcasecmp("rd", word) == 0 || - strcasecmp("ro", word) == 0) { - flags = O_RDONLY; - } else if (strcasecmp("wo", word) == 0) { - flags = O_WRONLY; - } else if (strcasecmp("rw", word) == 0) { - flags = O_RDWR; - } else { - g_gate_xlog("Invalid value in flags field at " - "line %u.", lineno); - } + flags = parse_flags(word, lineno); sflags = word; break; case 2: /* path */ @@ -306,13 +344,16 @@ exports_check(struct ggd_export *ex, struct g_gate_cinit *cinit, struct ggd_connection *conn) { char ipmask[32]; /* 32 == strlen("xxx.xxx.xxx.xxx/xxx.xxx.xxx.xxx")+1 */ - int error = 0, flags; + int error = 0, flags, access_flags, direct_flags = 0; strlcpy(ipmask, ip2str(ex->e_ip), sizeof(ipmask)); strlcat(ipmask, "/", sizeof(ipmask)); strlcat(ipmask, ip2str(ex->e_mask), sizeof(ipmask)); + + access_flags = ex->e_flags & EFLAGS_ACCMODE; + if ((cinit->gc_flags & GGATE_FLAG_RDONLY) != 0) { - if (ex->e_flags == O_WRONLY) { + if (access_flags == EFLAGS_WRONLY) { g_gate_log(LOG_WARNING, "Read-only access requested, " "but %s (%s) is exported write-only.", ex->e_path, ipmask); @@ -321,7 +362,7 @@ exports_check(struct ggd_export *ex, struct g_gate_cinit *cinit, conn->c_flags |= GGATE_FLAG_RDONLY; } } else if ((cinit->gc_flags & GGATE_FLAG_WRONLY) != 0) { - if (ex->e_flags == O_RDONLY) { + if (access_flags == EFLAGS_RDONLY) { g_gate_log(LOG_WARNING, "Write-only access requested, " "but %s (%s) is exported read-only.", ex->e_path, ipmask); @@ -330,24 +371,41 @@ exports_check(struct ggd_export *ex, struct g_gate_cinit *cinit, conn->c_flags |= GGATE_FLAG_WRONLY; } } else { - if (ex->e_flags == O_RDONLY) { + if (access_flags == EFLAGS_RDONLY) { g_gate_log(LOG_WARNING, "Read-write access requested, " "but %s (%s) is exported read-only.", ex->e_path, ipmask); return (EPERM); - } else if (ex->e_flags == O_WRONLY) { + } else if (access_flags == EFLAGS_WRONLY) { g_gate_log(LOG_WARNING, "Read-write access requested, " "but %s (%s) is exported write-only.", ex->e_path, ipmask); return (EPERM); } } + + if ((cinit->gc_flags & GGATE_FLAG_DIRECT) != 0) { + if (ex->e_flags & EFLAGS_NODIRECT) { + g_gate_log(LOG_WARNING, "Direct IO requested, " + "but %s (%s) is exported NODIRECT.", ex->e_path, + ipmask); + } else { + conn->c_flags |= GGATE_FLAG_DIRECT; + direct_flags = O_DIRECT; + } + } + + if (ex->e_flags & EFLAGS_DIRECT) { + direct_flags = O_DIRECT; + } + if ((conn->c_flags & GGATE_FLAG_RDONLY) != 0) flags = O_RDONLY; else if ((conn->c_flags & GGATE_FLAG_WRONLY) != 0) flags = O_WRONLY; else flags = O_RDWR; + flags |= direct_flags; if (conn->c_diskfd != -1) { if (strcmp(conn->c_path, ex->e_path) != 0) { g_gate_log(LOG_ERR, "old %s and new %s: " diff --git a/sbin/ggate/ggatel/ggatel.8 b/sbin/ggate/ggatel/ggatel.8 index 816a5b9a6e0e..0dd4f30041c5 100644 --- a/sbin/ggate/ggatel/ggatel.8 +++ b/sbin/ggate/ggatel/ggatel.8 @@ -32,7 +32,7 @@ .Nm .Cm create .Op Fl v -.Op Fl o Cm ro | wo | rw +.Oo Fl o option Oc ... .Op Fl s Ar sectorsize .Op Fl t Ar timeout .Op Fl u Ar unit @@ -48,7 +48,7 @@ .Nm .Cm rescue .Op Fl v -.Op Fl o Cm ro | wo | rw +.Oo Fl o option Oc ... .Fl u Ar unit .Ar path .Sh DESCRIPTION @@ -92,13 +92,21 @@ Available options: Forcibly destroy .Nm ggate provider (cancels all pending requests). -.It Fl o Cm ro | wo | rw -Specify permissions to use when opening the file or device: read-only -.Pq Cm ro , +.It Fl o Ar option +Specify permissions and options to use when opening the file or device. +.Bl -tag -width indent +.It Cm ro +read-only +.It Cm wo write-only -.Pq Cm wo , -or read-write -.Pq Cm rw . +.It Cm rw +read-write +.It Cm direct +open with +.Dv O_DIRECT +option on the file +.El +.Pp Default is .Cm rw . .It Fl s Ar sectorsize diff --git a/sbin/ggate/ggatel/ggatel.c b/sbin/ggate/ggatel/ggatel.c index 246a419ecaaf..1cbb6af28b7e 100644 --- a/sbin/ggate/ggatel/ggatel.c +++ b/sbin/ggate/ggatel/ggatel.c @@ -43,7 +43,6 @@ #include #include -#include #include "ggate.h" @@ -52,6 +51,7 @@ static enum { UNSET, CREATE, DESTROY, LIST, RESCUE } action = UNSET; static const char *path = NULL; static int unit = G_GATE_UNIT_AUTO; static unsigned flags = 0; +static int direct_flag = 0; static int force = 0; static unsigned sectorsize = 0; static unsigned timeout = G_GATE_TIMEOUT; @@ -60,24 +60,30 @@ static void usage(void) { - fprintf(stderr, "usage: %s create [-v] [-o ] " + fprintf(stderr, "usage: %s create [-v] [-o option] ... " "[-s sectorsize] [-t timeout] [-u unit] \n", getprogname()); - fprintf(stderr, " %s rescue [-v] [-o ] <-u unit> " + fprintf(stderr, " %s rescue [-v] [-o option] ... <-u unit> " "\n", getprogname()); fprintf(stderr, " %s destroy [-f] <-u unit>\n", getprogname()); fprintf(stderr, " %s list [-v] [-u unit]\n", getprogname()); + fprintf(stderr, " option = {ro, wo, rw, direct}\n"); exit(EXIT_FAILURE); } static int g_gate_openflags(unsigned ggflags) { + int openflags = O_RDWR; if ((ggflags & G_GATE_FLAG_READONLY) != 0) - return (O_RDONLY); + openflags = O_RDONLY; else if ((ggflags & G_GATE_FLAG_WRITEONLY) != 0) - return (O_WRONLY); - return (O_RDWR); + openflags = O_WRONLY; + + if (direct_flag) + openflags |= O_DIRECT; + + return (openflags); } static void @@ -248,6 +254,8 @@ main(int argc, char *argv[]) flags = G_GATE_FLAG_WRITEONLY; else if (strcasecmp("rw", optarg) == 0) flags = 0; + else if (strcasecmp("direct", optarg) == 0) + direct_flag = 1; else { errx(EXIT_FAILURE, "Invalid argument for '-o' option."); diff --git a/sbin/ggate/shared/ggate.h b/sbin/ggate/shared/ggate.h index 0170df2dd1b6..78488a24c3fa 100644 --- a/sbin/ggate/shared/ggate.h +++ b/sbin/ggate/shared/ggate.h @@ -29,6 +29,7 @@ #ifndef _GGATE_H_ #define _GGATE_H_ +#include #include #include @@ -42,8 +43,8 @@ #define GGATE_MAGIC "GEOM_GATE " #define GGATE_VERSION 0 -#define GGATE_FLAG_RDONLY 0x0001 -#define GGATE_FLAG_WRONLY 0x0002 +#define GGATE_FLAG_RDONLY G_GATE_FLAG_READONLY +#define GGATE_FLAG_WRONLY G_GATE_FLAG_WRITEONLY /* * If neither the GGATE_FLAG_SEND nor the GGATE_FLAG_RECV flag is * set - this is initial connection. @@ -53,6 +54,8 @@ #define GGATE_FLAG_SEND 0x0004 #define GGATE_FLAG_RECV 0x0008 +#define GGATE_FLAG_DIRECT 0x0010 + #define GGATE_CMD_READ 0 #define GGATE_CMD_WRITE 1 #define GGATE_CMD_FLUSH 3