aboutsummaryrefslogtreecommitdiffstats
path: root/main/nfs-utils/0002-mountd-talk-to-kernel-using-file-descriptors-instead.patch
diff options
context:
space:
mode:
Diffstat (limited to 'main/nfs-utils/0002-mountd-talk-to-kernel-using-file-descriptors-instead.patch')
-rw-r--r--main/nfs-utils/0002-mountd-talk-to-kernel-using-file-descriptors-instead.patch650
1 files changed, 0 insertions, 650 deletions
diff --git a/main/nfs-utils/0002-mountd-talk-to-kernel-using-file-descriptors-instead.patch b/main/nfs-utils/0002-mountd-talk-to-kernel-using-file-descriptors-instead.patch
deleted file mode 100644
index 1a50cf28b4..0000000000
--- a/main/nfs-utils/0002-mountd-talk-to-kernel-using-file-descriptors-instead.patch
+++ /dev/null
@@ -1,650 +0,0 @@
-From 0b6eff3dc8fecff610264209d458ab9ca2344440 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
-Date: Thu, 2 Oct 2014 15:23:29 +0300
-Subject: [PATCH v2 2/5] mountd: talk to kernel using file descriptors instead
- of FILE
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Timo Teräs <timo.teras@iki.fi>
----
- utils/mountd/cache.c | 343 +++++++++++++++++++++++++++------------------------
- 1 file changed, 183 insertions(+), 160 deletions(-)
-
-diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
-index 663a52a..c23d384 100644
---- a/utils/mountd/cache.c
-+++ b/utils/mountd/cache.c
-@@ -61,15 +61,13 @@ enum nfsd_fsid {
- * Record is terminated with newline.
- *
- */
--static int cache_export_ent(char *domain, struct exportent *exp, char *p);
-+static int cache_export_ent(char *buf, int buflen, char *domain, struct exportent *exp, char *path);
-
- #define INITIAL_MANAGED_GROUPS 100
-
--char *lbuf = NULL;
--int lbuflen = 0;
- extern int use_ipaddr;
-
--static void auth_unix_ip(FILE *f)
-+static void auth_unix_ip(int f)
- {
- /* requests are
- * class IP-ADDR
-@@ -78,23 +76,26 @@ static void auth_unix_ip(FILE *f)
- *
- * "nfsd" IP-ADDR expiry domainname
- */
-- char *cp;
- char class[20];
- char ipaddr[INET6_ADDRSTRLEN + 1];
- char *client = NULL;
- struct addrinfo *tmp = NULL;
-- if (readline(fileno(f), &lbuf, &lbuflen) != 1)
-- return;
-+ char buf[RPC_CHAN_BUF_SIZE], *bp;
-+ int blen;
-+
-+ blen = read(f, buf, sizeof(buf));
-+ if (blen <= 0 || buf[blen-1] != '\n') return;
-+ buf[blen-1] = 0;
-
-- xlog(D_CALL, "auth_unix_ip: inbuf '%s'", lbuf);
-+ xlog(D_CALL, "auth_unix_ip: inbuf '%s'", buf);
-
-- cp = lbuf;
-+ bp = buf;
-
-- if (qword_get(&cp, class, 20) <= 0 ||
-+ if (qword_get(&bp, class, 20) <= 0 ||
- strcmp(class, "nfsd") != 0)
- return;
-
-- if (qword_get(&cp, ipaddr, sizeof(ipaddr) - 1) <= 0)
-+ if (qword_get(&bp, ipaddr, sizeof(ipaddr) - 1) <= 0)
- return;
-
- tmp = host_pton(ipaddr);
-@@ -113,16 +114,20 @@ static void auth_unix_ip(FILE *f)
- freeaddrinfo(ai);
- }
- }
-- qword_print(f, "nfsd");
-- qword_print(f, ipaddr);
-- qword_printtimefrom(f, DEFAULT_TTL);
-+ bp = buf; blen = sizeof(buf);
-+ qword_add(&bp, &blen, "nfsd");
-+ qword_add(&bp, &blen, ipaddr);
-+ qword_adduint(&bp, &blen, time(0) + DEFAULT_TTL);
- if (use_ipaddr) {
- memmove(ipaddr + 1, ipaddr, strlen(ipaddr) + 1);
- ipaddr[0] = '$';
-- qword_print(f, ipaddr);
-+ qword_add(&bp, &blen, ipaddr);
- } else if (client)
-- qword_print(f, *client?client:"DEFAULT");
-- qword_eol(f);
-+ qword_add(&bp, &blen, *client?client:"DEFAULT");
-+ qword_addeol(&bp, &blen);
-+ if (blen <= 0 || write(f, buf, bp - buf) != bp - buf)
-+ xlog(L_ERROR, "auth_unix_ip: error writing reply");
-+
- xlog(D_CALL, "auth_unix_ip: client %p '%s'", client, client?client: "DEFAULT");
-
- free(client);
-@@ -130,7 +135,7 @@ static void auth_unix_ip(FILE *f)
-
- }
-
--static void auth_unix_gid(FILE *f)
-+static void auth_unix_gid(int f)
- {
- /* Request are
- * uid
-@@ -144,7 +149,8 @@ static void auth_unix_gid(FILE *f)
- gid_t *more_groups;
- int ngroups;
- int rv, i;
-- char *cp;
-+ char buf[RPC_CHAN_BUF_SIZE], *bp;
-+ int blen;
-
- if (groups_len == 0) {
- groups = malloc(sizeof(gid_t) * INITIAL_MANAGED_GROUPS);
-@@ -156,11 +162,12 @@ static void auth_unix_gid(FILE *f)
-
- ngroups = groups_len;
-
-- if (readline(fileno(f), &lbuf, &lbuflen) != 1)
-- return;
-+ blen = read(f, buf, sizeof(buf));
-+ if (blen <= 0 || buf[blen-1] != '\n') return;
-+ buf[blen-1] = 0;
-
-- cp = lbuf;
-- if (qword_get_uint(&cp, &uid) != 0)
-+ bp = buf;
-+ if (qword_get_uint(&bp, &uid) != 0)
- return;
-
- pw = getpwuid(uid);
-@@ -180,15 +187,19 @@ static void auth_unix_gid(FILE *f)
- }
- }
- }
-- qword_printuint(f, uid);
-- qword_printtimefrom(f, DEFAULT_TTL);
-+
-+ bp = buf; blen = sizeof(buf);
-+ qword_adduint(&bp, &blen, uid);
-+ qword_adduint(&bp, &blen, time(0) + DEFAULT_TTL);
- if (rv >= 0) {
-- qword_printuint(f, ngroups);
-+ qword_adduint(&bp, &blen, ngroups);
- for (i=0; i<ngroups; i++)
-- qword_printuint(f, groups[i]);
-+ qword_adduint(&bp, &blen, groups[i]);
- } else
-- qword_printuint(f, 0);
-- qword_eol(f);
-+ qword_adduint(&bp, &blen, 0);
-+ qword_addeol(&bp, &blen);
-+ if (blen <= 0 || write(f, buf, bp - buf) != bp - buf)
-+ xlog(L_ERROR, "auth_unix_gid: error writing reply");
- }
-
- #if USE_BLKID
-@@ -659,14 +670,13 @@ static struct addrinfo *lookup_client_addr(char *dom)
- return ret;
- }
-
--static void nfsd_fh(FILE *f)
-+static void nfsd_fh(int f)
- {
- /* request are:
- * domain fsidtype fsid
- * interpret fsid, find export point and options, and write:
- * domain fsidtype fsid expiry path
- */
-- char *cp;
- char *dom;
- int fsidtype;
- int fsidlen;
-@@ -678,24 +688,27 @@ static void nfsd_fh(FILE *f)
- nfs_export *exp;
- int i;
- int dev_missing = 0;
-+ char buf[RPC_CHAN_BUF_SIZE], *bp;
-+ int blen;
-
-- if (readline(fileno(f), &lbuf, &lbuflen) != 1)
-- return;
-+ blen = read(f, buf, sizeof(buf));
-+ if (blen <= 0 || buf[blen-1] != '\n') return;
-+ buf[blen-1] = 0;
-
-- xlog(D_CALL, "nfsd_fh: inbuf '%s'", lbuf);
-+ xlog(D_CALL, "nfsd_fh: inbuf '%s'", buf);
-
-- cp = lbuf;
-+ bp = buf;
-
-- dom = malloc(strlen(cp));
-+ dom = malloc(blen);
- if (dom == NULL)
- return;
-- if (qword_get(&cp, dom, strlen(cp)) <= 0)
-+ if (qword_get(&bp, dom, blen) <= 0)
- goto out;
-- if (qword_get_int(&cp, &fsidtype) != 0)
-+ if (qword_get_int(&bp, &fsidtype) != 0)
- goto out;
- if (fsidtype < 0 || fsidtype > 7)
- goto out; /* unknown type */
-- if ((fsidlen = qword_get(&cp, fsid, 32)) <= 0)
-+ if ((fsidlen = qword_get(&bp, fsid, 32)) <= 0)
- goto out;
- if (parse_fsid(fsidtype, fsidlen, fsid, &parsed))
- goto out;
-@@ -796,12 +809,13 @@ static void nfsd_fh(FILE *f)
- }
-
- if (found)
-- if (cache_export_ent(dom, found, found_path) < 0)
-+ if (cache_export_ent(buf, sizeof(buf), dom, found, found_path) < 0)
- found = 0;
-
-- qword_print(f, dom);
-- qword_printint(f, fsidtype);
-- qword_printhex(f, fsid, fsidlen);
-+ bp = buf; blen = sizeof(buf);
-+ qword_add(&bp, &blen, dom);
-+ qword_addint(&bp, &blen, fsidtype);
-+ qword_addhex(&bp, &blen, fsid, fsidlen);
- /* The fsid -> path lookup can be quite expensive as it
- * potentially stats and reads lots of devices, and some of those
- * might have spun-down. The Answer is not likely to
-@@ -810,20 +824,21 @@ static void nfsd_fh(FILE *f)
- * timeout. Maybe this should be configurable on the command
- * line.
- */
-- qword_printint(f, 0x7fffffff);
-+ qword_addint(&bp, &blen, 0x7fffffff);
- if (found)
-- qword_print(f, found_path);
-- qword_eol(f);
-- out:
-+ qword_add(&bp, &blen, found_path);
-+ qword_addeol(&bp, &blen);
-+ if (blen <= 0 || write(f, buf, bp - buf) != bp - buf)
-+ xlog(L_ERROR, "nfsd_fh: error writing reply");
-+out:
- if (found_path)
- free(found_path);
- freeaddrinfo(ai);
- free(dom);
- xlog(D_CALL, "nfsd_fh: found %p path %s", found, found ? found->e_path : NULL);
-- return;
- }
-
--static void write_fsloc(FILE *f, struct exportent *ep)
-+static void write_fsloc(char **bp, int *blen, struct exportent *ep)
- {
- struct servers *servers;
-
-@@ -833,20 +848,20 @@ static void write_fsloc(FILE *f, struct exportent *ep)
- servers = replicas_lookup(ep->e_fslocmethod, ep->e_fslocdata);
- if (!servers)
- return;
-- qword_print(f, "fsloc");
-- qword_printint(f, servers->h_num);
-+ qword_add(bp, blen, "fsloc");
-+ qword_addint(bp, blen, servers->h_num);
- if (servers->h_num >= 0) {
- int i;
- for (i=0; i<servers->h_num; i++) {
-- qword_print(f, servers->h_mp[i]->h_host);
-- qword_print(f, servers->h_mp[i]->h_path);
-+ qword_add(bp, blen, servers->h_mp[i]->h_host);
-+ qword_add(bp, blen, servers->h_mp[i]->h_path);
- }
- }
-- qword_printint(f, servers->h_referral);
-+ qword_addint(bp, blen, servers->h_referral);
- release_replicas(servers);
- }
-
--static void write_secinfo(FILE *f, struct exportent *ep, int flag_mask)
-+static void write_secinfo(char **bp, int *blen, struct exportent *ep, int flag_mask)
- {
- struct sec_entry *p;
-
-@@ -857,45 +872,52 @@ static void write_secinfo(FILE *f, struct exportent *ep, int flag_mask)
- return;
- }
- fix_pseudoflavor_flags(ep);
-- qword_print(f, "secinfo");
-- qword_printint(f, p - ep->e_secinfo);
-+ qword_add(bp, blen, "secinfo");
-+ qword_addint(bp, blen, p - ep->e_secinfo);
- for (p = ep->e_secinfo; p->flav; p++) {
-- qword_printint(f, p->flav->fnum);
-- qword_printint(f, p->flags & flag_mask);
-+ qword_addint(bp, blen, p->flav->fnum);
-+ qword_addint(bp, blen, p->flags & flag_mask);
- }
-
- }
-
--static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *exp)
-+static int dump_to_cache(int f, char *buf, int buflen, char *domain, char *path, struct exportent *exp)
- {
-- qword_print(f, domain);
-- qword_print(f, path);
-+ char *bp = buf;
-+ int blen = buflen;
-+ time_t now = time(0);
-+
-+ qword_add(&bp, &blen, domain);
-+ qword_add(&bp, &blen, path);
- if (exp) {
- int different_fs = strcmp(path, exp->e_path) != 0;
- int flag_mask = different_fs ? ~NFSEXP_FSID : ~0;
-
-- qword_printtimefrom(f, exp->e_ttl);
-- qword_printint(f, exp->e_flags & flag_mask);
-- qword_printint(f, exp->e_anonuid);
-- qword_printint(f, exp->e_anongid);
-- qword_printint(f, exp->e_fsid);
-- write_fsloc(f, exp);
-- write_secinfo(f, exp, flag_mask);
-- if (exp->e_uuid == NULL || different_fs) {
-- char u[16];
-- if (uuid_by_path(path, 0, 16, u)) {
-- qword_print(f, "uuid");
-- qword_printhex(f, u, 16);
-- }
-- } else {
-- char u[16];
-- get_uuid(exp->e_uuid, 16, u);
-- qword_print(f, "uuid");
-- qword_printhex(f, u, 16);
-- }
-+ qword_adduint(&bp, &blen, now + exp->e_ttl);
-+ qword_addint(&bp, &blen, exp->e_flags & flag_mask);
-+ qword_addint(&bp, &blen, exp->e_anonuid);
-+ qword_addint(&bp, &blen, exp->e_anongid);
-+ qword_addint(&bp, &blen, exp->e_fsid);
-+ write_fsloc(&bp, &blen, exp);
-+ write_secinfo(&bp, &blen, exp, flag_mask);
-+ if (exp->e_uuid == NULL || different_fs) {
-+ char u[16];
-+ if (uuid_by_path(path, 0, 16, u)) {
-+ qword_add(&bp, &blen, "uuid");
-+ qword_addhex(&bp, &blen, u, 16);
-+ }
-+ } else {
-+ char u[16];
-+ get_uuid(exp->e_uuid, 16, u);
-+ qword_add(&bp, &blen, "uuid");
-+ qword_addhex(&bp, &blen, u, 16);
-+ }
- } else
-- qword_printtimefrom(f, DEFAULT_TTL);
-- return qword_eol(f);
-+ qword_adduint(&bp, &blen, now + DEFAULT_TTL);
-+ qword_addeol(&bp, &blen);
-+ if (blen <= 0) return -1;
-+ if (write(f, buf, bp - buf) != bp - buf) return -1;
-+ return 0;
- }
-
- static nfs_export *
-@@ -1245,27 +1267,27 @@ static struct exportent *lookup_junction(char *dom, const char *pathname,
- return exp;
- }
-
--static void lookup_nonexport(FILE *f, char *dom, char *path,
-+static void lookup_nonexport(int f, char *buf, int buflen, char *dom, char *path,
- struct addrinfo *ai)
- {
- struct exportent *eep;
-
- eep = lookup_junction(dom, path, ai);
-- dump_to_cache(f, dom, path, eep);
-+ dump_to_cache(f, buf, buflen, dom, path, eep);
- if (eep == NULL)
- return;
- exportent_release(eep);
- free(eep);
- }
- #else /* !HAVE_NFS_PLUGIN_H */
--static void lookup_nonexport(FILE *f, char *dom, char *path,
-+static void lookup_nonexport(int f, char *buf, int buflen, char *dom, char *path,
- struct addrinfo *UNUSED(ai))
- {
-- dump_to_cache(f, dom, path, NULL);
-+ dump_to_cache(f, buf, buflen, dom, path, NULL);
- }
- #endif /* !HAVE_NFS_PLUGIN_H */
-
--static void nfsd_export(FILE *f)
-+static void nfsd_export(int f)
- {
- /* requests are:
- * domain path
-@@ -1273,26 +1295,28 @@ static void nfsd_export(FILE *f)
- * domain path expiry flags anonuid anongid fsid
- */
-
-- char *cp;
- char *dom, *path;
- nfs_export *found = NULL;
- struct addrinfo *ai = NULL;
-+ char buf[RPC_CHAN_BUF_SIZE], *bp;
-+ int blen;
-
-- if (readline(fileno(f), &lbuf, &lbuflen) != 1)
-- return;
-+ blen = read(f, buf, sizeof(buf));
-+ if (blen <= 0 || buf[blen-1] != '\n') return;
-+ buf[blen-1] = 0;
-
-- xlog(D_CALL, "nfsd_export: inbuf '%s'", lbuf);
-+ xlog(D_CALL, "nfsd_export: inbuf '%s'", buf);
-
-- cp = lbuf;
-- dom = malloc(strlen(cp));
-- path = malloc(strlen(cp));
-+ bp = buf;
-+ dom = malloc(blen);
-+ path = malloc(blen);
-
- if (!dom || !path)
- goto out;
-
-- if (qword_get(&cp, dom, strlen(lbuf)) <= 0)
-+ if (qword_get(&bp, dom, blen) <= 0)
- goto out;
-- if (qword_get(&cp, path, strlen(lbuf)) <= 0)
-+ if (qword_get(&bp, path, blen) <= 0)
- goto out;
-
- auth_reload();
-@@ -1306,14 +1330,14 @@ static void nfsd_export(FILE *f)
- found = lookup_export(dom, path, ai);
-
- if (found) {
-- if (dump_to_cache(f, dom, path, &found->m_export) < 0) {
-+ if (dump_to_cache(f, buf, sizeof(buf), dom, path, &found->m_export) < 0) {
- xlog(L_WARNING,
- "Cannot export %s, possibly unsupported filesystem"
- " or fsid= required", path);
-- dump_to_cache(f, dom, path, NULL);
-+ dump_to_cache(f, buf, sizeof(buf), dom, path, NULL);
- }
- } else
-- lookup_nonexport(f, dom, path, ai);
-+ lookup_nonexport(f, buf, sizeof(buf), dom, path, ai);
-
- out:
- xlog(D_CALL, "nfsd_export: found %p path %s", found, path ? path : NULL);
-@@ -1325,15 +1349,14 @@ static void nfsd_export(FILE *f)
-
- struct {
- char *cache_name;
-- void (*cache_handle)(FILE *f);
-- FILE *f;
-- char vbuf[RPC_CHAN_BUF_SIZE];
-+ void (*cache_handle)(int f);
-+ int f;
- } cachelist[] = {
-- { "auth.unix.ip", auth_unix_ip, NULL, ""},
-- { "auth.unix.gid", auth_unix_gid, NULL, ""},
-- { "nfsd.export", nfsd_export, NULL, ""},
-- { "nfsd.fh", nfsd_fh, NULL, ""},
-- { NULL, NULL, NULL, ""}
-+ { "auth.unix.ip", auth_unix_ip, -1 },
-+ { "auth.unix.gid", auth_unix_gid, -1 },
-+ { "nfsd.export", nfsd_export, -1 },
-+ { "nfsd.fh", nfsd_fh, -1 },
-+ { NULL, NULL, -1 }
- };
-
- extern int manage_gids;
-@@ -1350,11 +1373,7 @@ void cache_open(void)
- if (!manage_gids && cachelist[i].cache_handle == auth_unix_gid)
- continue;
- sprintf(path, "/proc/net/rpc/%s/channel", cachelist[i].cache_name);
-- cachelist[i].f = fopen(path, "r+");
-- if (cachelist[i].f != NULL) {
-- setvbuf(cachelist[i].f, cachelist[i].vbuf, _IOLBF,
-- RPC_CHAN_BUF_SIZE);
-- }
-+ cachelist[i].f = open(path, O_RDWR);
- }
- }
-
-@@ -1366,8 +1385,8 @@ void cache_set_fds(fd_set *fdset)
- {
- int i;
- for (i=0; cachelist[i].cache_name; i++) {
-- if (cachelist[i].f)
-- FD_SET(fileno(cachelist[i].f), fdset);
-+ if (cachelist[i].f >= 0)
-+ FD_SET(cachelist[i].f, fdset);
- }
- }
-
-@@ -1380,11 +1399,11 @@ int cache_process_req(fd_set *readfds)
- int i;
- int cnt = 0;
- for (i=0; cachelist[i].cache_name; i++) {
-- if (cachelist[i].f != NULL &&
-- FD_ISSET(fileno(cachelist[i].f), readfds)) {
-+ if (cachelist[i].f >= 0 &&
-+ FD_ISSET(cachelist[i].f, readfds)) {
- cnt++;
- cachelist[i].cache_handle(cachelist[i].f);
-- FD_CLR(fileno(cachelist[i].f), readfds);
-+ FD_CLR(cachelist[i].f, readfds);
- }
- }
- return cnt;
-@@ -1397,14 +1416,14 @@ int cache_process_req(fd_set *readfds)
- * % echo $domain $path $[now+DEFAULT_TTL] $options $anonuid $anongid $fsid > /proc/net/rpc/nfsd.export/channel
- */
-
--static int cache_export_ent(char *domain, struct exportent *exp, char *path)
-+static int cache_export_ent(char *buf, int buflen, char *domain, struct exportent *exp, char *path)
- {
-- int err;
-- FILE *f = fopen("/proc/net/rpc/nfsd.export/channel", "w");
-- if (!f)
-- return -1;
-+ int f, err;
-+
-+ f = open("/proc/net/rpc/nfsd.export/channel", O_WRONLY);
-+ if (f < 0) return -1;
-
-- err = dump_to_cache(f, domain, exp->e_path, exp);
-+ err = dump_to_cache(f, buf, buflen, domain, exp->e_path, exp);
- if (err) {
- xlog(L_WARNING,
- "Cannot export %s, possibly unsupported filesystem or"
-@@ -1445,13 +1464,13 @@ static int cache_export_ent(char *domain, struct exportent *exp, char *path)
- continue;
- dev = stb.st_dev;
- path[l] = 0;
-- dump_to_cache(f, domain, path, exp);
-+ dump_to_cache(f, buf, buflen, domain, path, exp);
- path[l] = c;
- }
- break;
- }
-
-- fclose(f);
-+ close(f);
- return err;
- }
-
-@@ -1462,27 +1481,25 @@ static int cache_export_ent(char *domain, struct exportent *exp, char *path)
- */
- int cache_export(nfs_export *exp, char *path)
- {
-- char buf[INET6_ADDRSTRLEN];
-- int err;
-- FILE *f;
-+ char ip[INET6_ADDRSTRLEN];
-+ char buf[RPC_CHAN_BUF_SIZE], *bp;
-+ int blen, f;
-
-- f = fopen("/proc/net/rpc/auth.unix.ip/channel", "w");
-- if (!f)
-+ f = open("/proc/net/rpc/auth.unix.ip/channel", O_WRONLY);
-+ if (f < 0)
- return -1;
-
--
-- qword_print(f, "nfsd");
-- qword_print(f,
-- host_ntop(get_addrlist(exp->m_client, 0), buf, sizeof(buf)));
-- qword_printtimefrom(f, exp->m_export.e_ttl);
-- qword_print(f, exp->m_client->m_hostname);
-- err = qword_eol(f);
--
-- fclose(f);
--
-- err = cache_export_ent(exp->m_client->m_hostname, &exp->m_export, path)
-- || err;
-- return err;
-+ bp = buf, blen = sizeof(buf);
-+ qword_add(&bp, &blen, "nfsd");
-+ qword_add(&bp, &blen, host_ntop(get_addrlist(exp->m_client, 0), ip, sizeof(ip)));
-+ qword_adduint(&bp, &blen, time(0) + exp->m_export.e_ttl);
-+ qword_add(&bp, &blen, exp->m_client->m_hostname);
-+ qword_addeol(&bp, &blen);
-+ if (blen <= 0 || write(f, buf, bp - buf) != bp - buf) blen = -1;
-+ close(f);
-+ if (blen < 0) return -1;
-+
-+ return cache_export_ent(buf, sizeof(buf), exp->m_client->m_hostname, &exp->m_export, path);
- }
-
- /**
-@@ -1501,27 +1518,33 @@ int cache_export(nfs_export *exp, char *path)
- struct nfs_fh_len *
- cache_get_filehandle(nfs_export *exp, int len, char *p)
- {
-- FILE *f = fopen("/proc/fs/nfsd/filehandle", "r+");
-- char buf[200];
-- char *bp = buf;
-- int failed;
- static struct nfs_fh_len fh;
-+ char buf[RPC_CHAN_BUF_SIZE], *bp;
-+ int blen, f;
-+
-+ f = open("/proc/fs/nfsd/filehandle", O_RDWR);
-+ if (f < 0) {
-+ f = open("/proc/fs/nfs/filehandle", O_RDWR);
-+ if (f < 0) return NULL;
-+ }
-
-- if (!f)
-- f = fopen("/proc/fs/nfs/filehandle", "r+");
-- if (!f)
-+ bp = buf, blen = sizeof(buf);
-+ qword_add(&bp, &blen, exp->m_client->m_hostname);
-+ qword_add(&bp, &blen, p);
-+ qword_addint(&bp, &blen, len);
-+ qword_addeol(&bp, &blen);
-+ if (blen <= 0 || write(f, buf, bp - buf) != bp - buf) {
-+ close(f);
- return NULL;
-+ }
-+ bp = buf;
-+ blen = read(f, buf, sizeof(buf));
-+ close(f);
-
-- qword_print(f, exp->m_client->m_hostname);
-- qword_print(f, p);
-- qword_printint(f, len);
-- failed = qword_eol(f);
--
-- if (!failed)
-- failed = (fgets(buf, sizeof(buf), f) == NULL);
-- fclose(f);
-- if (failed)
-+ if (blen <= 0 || buf[blen-1] != '\n')
- return NULL;
-+ buf[blen-1] = 0;
-+
- memset(fh.fh_handle, 0, sizeof(fh.fh_handle));
- fh.fh_size = qword_get(&bp, (char *)fh.fh_handle, NFS3_FHSIZE);
- return &fh;
---
-2.1.2
-