Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libperfuse - Fix the confusion between fileno (opaque FU...
details: https://anonhg.NetBSD.org/src/rev/05eea3ad8a1f
branches: trunk
changeset: 770709:05eea3ad8a1f
user: manu <manu%NetBSD.org@localhost>
date: Sun Oct 30 05:11:37 2011 +0000
description:
- Fix the confusion between fileno (opaque FUSE reference) and inode
numbers. fileno must be used when exchanging FUSE messages.
- Do not use kernel name cache anymore, as it caused modification from
other machines to be invisible.
- Honour name and attribute cache directive from FUSE filesystem
diffstat:
lib/libperfuse/ops.c | 311 +++++++++++++++++++++++++++++------------
lib/libperfuse/perfuse.c | 14 +-
lib/libperfuse/perfuse_if.h | 5 +-
lib/libperfuse/perfuse_priv.h | 6 +-
lib/libperfuse/subr.c | 4 +-
5 files changed, 233 insertions(+), 107 deletions(-)
diffs (truncated from 750 to 300 lines):
diff -r 7eca6a009ece -r 05eea3ad8a1f lib/libperfuse/ops.c
--- a/lib/libperfuse/ops.c Sun Oct 30 01:57:40 2011 +0000
+++ b/lib/libperfuse/ops.c Sun Oct 30 05:11:37 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ops.c,v 1.42 2011/09/10 10:06:10 tron Exp $ */
+/* $NetBSD: ops.c,v 1.43 2011/10/30 05:11:37 manu Exp $ */
/*-
* Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved.
@@ -44,6 +44,10 @@
extern int perfuse_diagflags;
+static void set_expire(puffs_cookie_t, struct fuse_entry_out *,
+ struct fuse_attr_out *);
+static int attr_expired(puffs_cookie_t);
+static int entry_expired(puffs_cookie_t);
static int xchg_msg(struct puffs_usermount *, puffs_cookie_t,
perfuse_msg_t *, size_t, enum perfuse_xchg_pb_reply);
static int mode_access(puffs_cookie_t, const struct puffs_cred *, mode_t);
@@ -153,8 +157,8 @@
#ifdef PERFUSE_DEBUG
if (perfuse_diagflags & PDF_FH)
- DPRINTF("%s: opc = %p, ino = %"PRId64", fh = 0x%"PRIx64"\n",
- __func__, (void *)opc, pnd->pnd_ino, fri->fh);
+ DPRINTF("%s: opc = %p, nodeid = 0x%"PRIx64", fh = 0x%"PRIx64"\n",
+ __func__, (void *)opc, pnd->pnd_nodeid, fri->fh);
#endif
if ((error = xchg_msg(pu, opc, pm,
@@ -193,8 +197,9 @@
#ifdef PERFUSE_DEBUG
if ((perfuse_diagflags & PDF_FILENAME) && (opc != 0))
- DPRINTF("file = \"%s\" flags = 0x%x\n",
- perfuse_node_path(opc),
+ DPRINTF("file = \"%s\", ino = %"PRIu64" flags = 0x%x\n",
+ perfuse_node_path(opc),
+ ((struct puffs_node *)opc)->pn_va.va_fileid,
PERFUSE_NODE_DATA(opc)->pnd_flags);
#endif
if (pnd)
@@ -309,6 +314,74 @@
return;
}
+static void
+set_expire(opc, feo, fao)
+ puffs_cookie_t opc;
+ struct fuse_entry_out *feo;
+ struct fuse_attr_out *fao;
+{
+ struct perfuse_node_data *pnd = PERFUSE_NODE_DATA(opc);
+ struct timespec entry_ts;
+ struct timespec attr_ts;
+ struct timespec now;
+
+ if ((feo == NULL) && (fao == NULL))
+ DERRX(EX_SOFTWARE, "%s: feo and fao NULL", __func__);
+
+ if ((feo != NULL) && (fao != NULL))
+ DERRX(EX_SOFTWARE, "%s: feo and fao != NULL", __func__);
+
+ if (clock_gettime(CLOCK_REALTIME, &now) != 0)
+ DERR(EX_OSERR, "clock_gettime failed");
+
+ if (feo != NULL) {
+ entry_ts.tv_sec = (time_t)feo->entry_valid;
+ entry_ts.tv_nsec = (long)feo->entry_valid_nsec;
+
+ timespecadd(&now, &entry_ts, &pnd->pnd_entry_expire);
+
+ attr_ts.tv_sec = (time_t)feo->attr_valid;
+ attr_ts.tv_nsec = (long)feo->attr_valid_nsec;
+
+ timespecadd(&now, &attr_ts, &pnd->pnd_attr_expire);
+ }
+
+ if (fao != NULL) {
+ attr_ts.tv_sec = (time_t)fao->attr_valid;
+ attr_ts.tv_nsec = (long)fao->attr_valid_nsec;
+
+ timespecadd(&now, &attr_ts, &pnd->pnd_attr_expire);
+ }
+
+ return;
+}
+
+static int
+attr_expired(opc)
+ puffs_cookie_t opc;
+{
+ struct perfuse_node_data *pnd = PERFUSE_NODE_DATA(opc);
+ struct timespec now;
+
+ if (clock_gettime(CLOCK_REALTIME, &now) != 0)
+ DERR(EX_OSERR, "clock_gettime failed");
+
+ return timespeccmp(&pnd->pnd_attr_expire, &now, <);
+}
+
+static int
+entry_expired(opc)
+ puffs_cookie_t opc;
+{
+ struct perfuse_node_data *pnd = PERFUSE_NODE_DATA(opc);
+ struct timespec now;
+
+ if (clock_gettime(CLOCK_REALTIME, &now) != 0)
+ DERR(EX_OSERR, "clock_gettime failed");
+
+ return timespeccmp(&pnd->pnd_entry_expire, &now, <);
+}
+
/*
* Lookup name in directory opc
@@ -323,12 +396,8 @@
size_t namelen;
struct puffs_node **pnp;
{
- char *path;
- struct puffs_node *dpn = (struct puffs_node *)opc;
- int error;
-
/*
- * is easy as we already know it
+ * "dot" is easy as we already know it
*/
if (strncmp(name, ".", namelen) == 0) {
*pnp = (struct puffs_node *)opc;
@@ -336,22 +405,14 @@
}
/*
- * For .. we just forget the name part
+ * "dotdot" is also known
*/
- if (strncmp(name, "..", namelen) == 0)
- namelen = 0;
-
- namelen = PNPLEN(dpn) + 1 + namelen + 1;
- if ((path = malloc(namelen)) == NULL)
- DERR(EX_OSERR, "%s: malloc failed", __func__);
- (void)snprintf(path, namelen, "%s/%s",
- perfuse_node_path((puffs_cookie_t)dpn), name);
-
- error = node_lookup_common(pu, opc, path, NULL, pnp);
-
- free(path);
-
- return error;
+ if (strncmp(name, "..", namelen) == 0) {
+ *pnp = PERFUSE_NODE_DATA(opc)->pnd_parent;
+ return 0;
+ }
+
+ return node_lookup_common(pu, opc, name, NULL, pnp);
}
static int
@@ -363,13 +424,16 @@
struct puffs_node **pnp;
{
struct perfuse_state *ps;
- struct perfuse_node_data *pnd;
+ struct perfuse_node_data *oldpnd;
perfuse_msg_t *pm;
struct fuse_entry_out *feo;
struct puffs_node *pn;
size_t len;
int error;
+ if (pnp == NULL)
+ DERRX(EX_SOFTWARE, "pnp must be != NULL");
+
ps = puffs_getspecific(pu);
#ifdef PERFUSE_DEBUG
@@ -380,24 +444,27 @@
/*
* Is the node already known?
*/
- TAILQ_FOREACH(pnd, &PERFUSE_NODE_DATA(opc)->pnd_children, pnd_next) {
- if ((pnd->pnd_flags & PND_REMOVED) ||
- (strcmp(pnd->pnd_name, path) != 0))
+ TAILQ_FOREACH(oldpnd, &PERFUSE_NODE_DATA(opc)->pnd_children, pnd_next) {
+ if ((oldpnd->pnd_flags & PND_REMOVED) ||
+ (strcmp(oldpnd->pnd_name, path) != 0))
continue;
- /*
- * We have a match
- */
- if (pnp != NULL)
- *pnp = (struct puffs_node *)(pnd->pnd_pn);
-
#ifdef PERFUSE_DEBUG
if (perfuse_diagflags & PDF_FILENAME)
DPRINTF("%s: opc = %p, file = \"%s\" found "
- "cookie = %p, ino = %"PRId64" for \"%s\"\n",
+ "cookie = %p, nodeid = 0x%"PRIx64" for \"%s\"\n",
__func__, (void *)opc, perfuse_node_path(opc),
- (void *)pnd->pnd_pn, pnd->pnd_ino, path);
+ (void *)oldpnd->pnd_pn, oldpnd->pnd_nodeid,
+ path);
#endif
+ break;
+ }
+
+ /*
+ * Check for cached name
+ */
+ if ((oldpnd != NULL) && !entry_expired(oldpnd->pnd_pn)) {
+ *pnp = oldpnd->pnd_pn;
return 0;
}
@@ -406,26 +473,64 @@
pm = ps->ps_new_msg(pu, opc, FUSE_LOOKUP, len, pcr);
(void)strlcpy(_GET_INPAYLOAD(ps, pm, char *), path, len);
- if ((error = xchg_msg(pu, opc, pm, sizeof(*feo), wait_reply)) != 0)
+ error = xchg_msg(pu, opc, pm, sizeof(*feo), wait_reply);
+
+ switch (error) {
+ case 0:
+ break;
+ case ENOENT:
+ if (oldpnd != NULL) {
+ oldpnd->pnd_flags |= PND_REMOVED;
+#ifdef PERFUSE_DEBUG
+ if (perfuse_diagflags & PDF_FILENAME)
+ DPRINTF("%s: opc = %p nodeid = 0x%"PRIx64" "
+ "file = \"%s\" removed\n", __func__,
+ oldpnd->pnd_pn, oldpnd->pnd_nodeid,
+ oldpnd->pnd_name);
+#endif
+ }
+ /* FALLTHROUGH */
+ default:
goto out;
+ /* NOTREACHED */
+ break;
+ }
feo = GET_OUTPAYLOAD(ps, pm, fuse_entry_out);
+ if (oldpnd != NULL) {
+ if (oldpnd->pnd_nodeid == feo->nodeid) {
+ oldpnd->pnd_nlookup++;
+ *pnp = oldpnd->pnd_pn;
+ goto out;
+ } else {
+ oldpnd->pnd_flags |= PND_REMOVED;
+#ifdef PERFUSE_DEBUG
+ if (perfuse_diagflags & PDF_FILENAME)
+ DPRINTF("%s: opc = %p nodeid = 0x%"PRIx64" "
+ "file = \"%s\" replaced\n", __func__,
+ oldpnd->pnd_pn, oldpnd->pnd_nodeid,
+ oldpnd->pnd_name);
+#endif
+ }
+ }
+
pn = perfuse_new_pn(pu, path, opc);
- PERFUSE_NODE_DATA(pn)->pnd_ino = feo->nodeid;
+ PERFUSE_NODE_DATA(pn)->pnd_nodeid = feo->nodeid;
fuse_attr_to_vap(ps, &pn->pn_va, &feo->attr);
pn->pn_va.va_gen = (u_long)(feo->generation);
-
- if (pnp != NULL)
- *pnp = pn;
+ set_expire((puffs_cookie_t)pn, feo, NULL);
+
+ *pnp = pn;
#ifdef PERFUSE_DEBUG
if (perfuse_diagflags & PDF_FILENAME)
- DPRINTF("%s: opc = %p, looked up opc = %p, ino = %"PRId64" "
- "file = \"%s\"\n", __func__, (void *)opc, pn,
- feo->nodeid, path);
+ DPRINTF("%s: opc = %p, looked up opc = %p, "
+ "nodeid = 0x%"PRIx64" file = \"%s\"\n", __func__,
+ (void *)opc, pn, feo->nodeid, path);
#endif
+
out:
ps->ps_destroy_msg(pm);
@@ -458,21 +563,22 @@
goto out;
feo = GET_OUTPAYLOAD(ps, pm, fuse_entry_out);
- if (feo->nodeid == PERFUSE_UNKNOWN_INO)
- DERRX(EX_SOFTWARE, "%s: no ino", __func__);
+ if (feo->nodeid == PERFUSE_UNKNOWN_NODEID)
+ DERRX(EX_SOFTWARE, "%s: no nodeid", __func__);
Home |
Main Index |
Thread Index |
Old Index