Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libperfuse - performance improvement for read, readdir a...
details: https://anonhg.NetBSD.org/src/rev/b3ea66bbed98
branches: trunk
changeset: 757735:b3ea66bbed98
user: manu <manu%NetBSD.org@localhost>
date: Mon Sep 20 07:00:21 2010 +0000
description:
- performance improvement for read, readdir and write. Now we use
SOCK_DGRAM, we can send many pages at once without hitting any bug
- when creating a file, it is open for FUSE, but not for the kernel.
If the kernel does not do a subsequent open, we have a leak. We fight
against this by trying to close such file that the kernel left unopen
for some time.
- some code refactoring to make message exchange debug easier (more to come)
diffstat:
lib/libperfuse/ops.c | 250 +++++++++++++++++++++++++----------------
lib/libperfuse/perfuse.c | 23 ++-
lib/libperfuse/perfuse_priv.h | 48 +++++---
lib/libperfuse/subr.c | 49 +++++++-
4 files changed, 241 insertions(+), 129 deletions(-)
diffs (truncated from 943 to 300 lines):
diff -r 3bcd98e17ef5 -r b3ea66bbed98 lib/libperfuse/ops.c
--- a/lib/libperfuse/ops.c Mon Sep 20 06:54:06 2010 +0000
+++ b/lib/libperfuse/ops.c Mon Sep 20 07:00:21 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ops.c,v 1.15 2010/09/15 01:51:43 manu Exp $ */
+/* $NetBSD: ops.c,v 1.16 2010/09/20 07:00:21 manu Exp $ */
/*-
* Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
@@ -43,7 +43,8 @@
extern int perfuse_diagflags;
-static int node_close_common(struct puffs_usermount *, puffs_cookie_t, int);
+static int xchg_msg(struct puffs_usermount *, puffs_cookie_t,
+ perfuse_msg_t *, size_t, enum perfuse_xchg_pb_reply);
static int no_access(puffs_cookie_t, const struct puffs_cred *, mode_t);
static void fuse_attr_to_vap(struct perfuse_state *,
struct vattr *, struct fuse_attr *);
@@ -94,8 +95,8 @@
#define IFTOVT(mode) (iftovt_tab[((mode) & S_IFMT) >> 12])
#define VTTOIF(indx) (vttoif_tab[(int)(indx)])
-static int
-node_close_common(pu, opc, mode)
+int
+perfuse_node_close_common(pu, opc, mode)
struct puffs_usermount *pu;
puffs_cookie_t opc;
int mode;
@@ -148,7 +149,8 @@
__func__, (void *)opc, pnd->pnd_ino, fri->fh);
#endif
- if ((error = XCHG_MSG(ps, pu, pm, NO_PAYLOAD_REPLY_LEN)) != 0)
+ if ((error = xchg_msg(pu, opc, pm,
+ NO_PAYLOAD_REPLY_LEN, wait_reply)) != 0)
goto out;
ps->ps_destroy_msg(pm);
@@ -163,6 +165,30 @@
return error;
}
+/* ARGSUSED1 */
+static int
+xchg_msg(pu, opc, pm, len, wait)
+ struct puffs_usermount *pu;
+ puffs_cookie_t opc;
+ perfuse_msg_t *pm;
+ size_t len;
+ enum perfuse_xchg_pb_reply wait;
+{
+ struct perfuse_state *ps;
+ int error;
+
+ ps = puffs_getspecific(pu);
+
+#ifdef PERFUSE_DEBUG
+ if ((perfuse_diagflags & PDF_FUSE) && (opc != 0))
+ DPRINTF("file = \"%s\"\n",
+ (char *)PNPATH((struct puffs_node *)opc));
+#endif
+ error = ps->ps_xchg_msg(pu, pm, len, wait);
+
+ return error;
+}
+
static int
no_access(opc, pcr, mode)
puffs_cookie_t opc;
@@ -285,7 +311,7 @@
pm = ps->ps_new_msg(pu, opc, FUSE_LOOKUP, len, NULL);
(void)strlcpy(_GET_INPAYLOAD(ps, pm, char *), path, len);
- if ((error = XCHG_MSG(ps, pu, pm, sizeof(*feo))) != 0)
+ if ((error = xchg_msg(pu, opc, pm, sizeof(*feo), wait_reply)) != 0)
goto out;
feo = GET_OUTPAYLOAD(ps, pm, fuse_entry_out);
@@ -327,7 +353,7 @@
ps = puffs_getspecific(pu);
- if ((error = XCHG_MSG(ps, pu, pm, sizeof(*feo))) != 0)
+ if ((error = xchg_msg(pu, opc, pm, sizeof(*feo), wait_reply)) != 0)
goto out;
feo = GET_OUTPAYLOAD(ps, pm, fuse_entry_out);
@@ -357,7 +383,8 @@
/*
* A fuse_attr_out is returned, but we ignore it.
*/
- error = XCHG_MSG(ps, pu, pm, sizeof(struct fuse_attr_out));
+ error = xchg_msg(pu, (puffs_cookie_t)pn,
+ pm, sizeof(struct fuse_attr_out), wait_reply);
/*
* The parent directory needs a sync
@@ -604,9 +631,6 @@
ps = perfuse_getspecific(pu);
#endif
- /*
- * XXX Add a lock he day we go multithreaded
- */
pnd = PERFUSE_NODE_DATA(opc);
pcq.pcq_type = type;
pcq.pcq_cc = puffs_cc_getcc(pu);
@@ -644,9 +668,6 @@
struct perfuse_node_data *pnd;
int dequeued;
- /*
- * XXX Add a lock he day we go multithreaded
- */
pnd = PERFUSE_NODE_DATA(opc);
dequeued = 0;
TAILQ_FOREACH(pcq, &pnd->pnd_pcq, pcq_next) {
@@ -684,7 +705,7 @@
int error;
ps = puffs_getspecific(pu);
-
+
if (puffs_mount(pu, ps->ps_target, ps->ps_mountflags, ps->ps_root) != 0)
DERR(EX_OSERR, "puffs_mount failed");
@@ -702,7 +723,7 @@
fii->max_readahead = 32 * PAGE_SIZE;
fii->flags = (FUSE_ASYNC_READ|FUSE_POSIX_LOCKS|FUSE_ATOMIC_O_TRUNC);
- if ((error = XCHG_MSG(ps, pu, pm, sizeof(*fio))) != 0)
+ if ((error = xchg_msg(pu, 0, pm, sizeof(*fio), wait_reply)) != 0)
DERRX(EX_SOFTWARE, "init message exchange failed (%d)", error);
fio = GET_OUTPAYLOAD(ps, pm, fuse_init_out);
@@ -729,7 +750,7 @@
opc = (puffs_cookie_t)puffs_getroot(pu);
pm = ps->ps_new_msg(pu, opc, FUSE_DESTROY, 0, NULL);
- if ((error = XCHG_MSG(ps, pu, pm, UNSPEC_REPLY_LEN)) != 0) {
+ if ((error = xchg_msg(pu, opc, pm, UNSPEC_REPLY_LEN, wait_reply)) != 0){
DWARN("unmount %s", ps->ps_target);
if (!(flags & MNT_FORCE))
goto out;
@@ -759,7 +780,7 @@
opc = (puffs_cookie_t)puffs_getroot(pu);
pm = ps->ps_new_msg(pu, opc, FUSE_STATFS, 0, NULL);
- if ((error = XCHG_MSG(ps, pu, pm, sizeof(*fso))) != 0)
+ if ((error = xchg_msg(pu, opc, pm, sizeof(*fso), wait_reply)) != 0)
goto out;
fso = GET_OUTPAYLOAD(ps, pm, fuse_statfs_out);
@@ -964,10 +985,17 @@
opc = (puffs_cookie_t)pn;
- error = perfuse_node_open(pu, opc, FREAD|FWRITE, pcn->pcn_cred);
+ error = perfuse_node_open(pu, opc, FWRITE, pcn->pcn_cred);
if (error != 0)
return error;
+ /*
+ * This node has been open in the filesystem,
+ * but not by the kernel. We will have to close
+ * it on our own to avoid a leak
+ */
+ PERFUSE_NODE_DATA(opc)->pnd_flags |= PND_OPENFS;
+
return 0;
}
@@ -989,7 +1017,7 @@
(void)strlcpy((char*)(void *)(fci + 1), name, namelen);
len = sizeof(*feo) + sizeof(*foo);
- if ((error = XCHG_MSG(ps, pu, pm, len)) != 0)
+ if ((error = xchg_msg(pu, opc, pm, len, wait_reply)) != 0)
goto out;
feo = GET_OUTPAYLOAD(ps, pm, fuse_entry_out);
@@ -1002,7 +1030,7 @@
* so that we can reuse it later
*/
pn = perfuse_new_pn(pu, opc);
- perfuse_new_fh((puffs_cookie_t)pn, foo->fh, FWRITE);
+ perfuse_new_fh(pu, (puffs_cookie_t)pn, foo->fh, FWRITE);
PERFUSE_NODE_DATA(pn)->pnd_ino = feo->nodeid;
#ifdef PERFUSE_DEBUG
@@ -1020,6 +1048,14 @@
* The parent directory needs a sync
*/
PERFUSE_NODE_DATA(opc)->pnd_flags |= PND_DIRTY;
+
+ /*
+ * This node has been open in the filesystem,
+ * but not by the kernel. We will have to close
+ * it on our own to avoid a leak
+ */
+ PERFUSE_NODE_DATA(pn)->pnd_flags |= PND_OPENFS;
+
out:
ps->ps_destroy_msg(pm);
@@ -1113,6 +1149,14 @@
pn = (struct puffs_node *)opc;
if (puffs_pn_getvap(pn)->va_type == VDIR) {
+ /*
+ * We may open removed files, but it seems much more
+ * troublesome to open removed directories. glusterfs says
+ * "OPENDIR (null) (fuse_loc_fill() failed)"
+ */
+ if (pnd->pnd_flags & PND_REMOVED)
+ return ENOENT;
+
op = FUSE_OPENDIR;
pmode = PUFFS_VREAD|PUFFS_VEXEC;
} else {
@@ -1143,10 +1187,20 @@
* Do not open twice, and do not reopen for reading
* if we already have write handle.
*/
- if ((mode & FREAD) && (pnd->pnd_flags & PND_RFH))
+ if (((mode & FREAD) && (pnd->pnd_flags & PND_RFH)) ||
+ ((mode & FWRITE) && (pnd->pnd_flags & PND_WFH))) {
+ /*
+ * If the file was created, it was open for
+ * the filesystem but not for the kernel. This
+ * is not the case anymore, therefore we cleanup
+ * the flag to avoid an unwanted cleanup close
+ * after PERFUSE_OPENFS_TIMEOUT.
+ */
+ pnd->pnd_flags &= ~PND_OPENFS;
+
return 0;
- if ((mode & FWRITE) && (pnd->pnd_flags & PND_WFH))
- return 0;
+ }
+
/*
* Convert PUFFS mode to FUSE mode: convert FREAD/FWRITE
@@ -1160,16 +1214,16 @@
foi->flags = fmode;
foi->unused = 0;
- if ((error = XCHG_MSG(ps, pu, pm, sizeof(*foo))) != 0)
+ if ((error = xchg_msg(pu, opc, pm, sizeof(*foo), wait_reply)) != 0)
goto out;
foo = GET_OUTPAYLOAD(ps, pm, fuse_open_out);
-
+
/*
* Save the file handle in node private data
* so that we can reuse it later
*/
- perfuse_new_fh((puffs_cookie_t)pn, foo->fh, mode);
+ perfuse_new_fh(pu, (puffs_cookie_t)pn, foo->fh, mode);
#ifdef PERFUSE_DEBUG
if (perfuse_diagflags & PDF_FH)
@@ -1180,6 +1234,7 @@
pnd->pnd_ino, mode & FREAD ? "r" : "",
mode & FWRITE ? "w" : "", foo->fh);
#endif
+
out:
ps->ps_destroy_msg(pm);
@@ -1210,7 +1265,7 @@
* therefore postpone the close operation at reclaim time.
*/
if (puffs_pn_getvap(pn)->va_type != VREG)
- return node_close_common(pu, opc, flags);
+ return perfuse_node_close_common(pu, opc, flags);
return 0;
}
@@ -1243,7 +1298,7 @@
fai = GET_INPAYLOAD(ps, pm, fuse_access_in);
fai->mask = mode;
- error = XCHG_MSG(ps, pu, pm, NO_PAYLOAD_REPLY_LEN);
+ error = xchg_msg(pu, opc, pm, NO_PAYLOAD_REPLY_LEN, wait_reply);
ps->ps_destroy_msg(pm);
}
@@ -1266,7 +1321,8 @@
"fh = 0x%"PRIx64"\n", __func__, (void *)opc,
PERFUSE_NODE_DATA(opc)->pnd_ino, fgi->fh);
#endif
- if ((error = XCHG_MSG(ps, pu, pm, sizeof(*fao))) != 0) {
+ if ((error = xchg_msg(pu, opc, pm,
+ sizeof(*fao), wait_reply)) != 0) {
ps->ps_destroy_msg(pm);
Home |
Main Index |
Thread Index |
Old Index