Module Name: src Committed By: manu Date: Sun Oct 30 05:11:37 UTC 2011
Modified Files: src/lib/libperfuse: ops.c perfuse.c perfuse_if.h perfuse_priv.h subr.c Log Message: - 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 To generate a diff of this commit: cvs rdiff -u -r1.42 -r1.43 src/lib/libperfuse/ops.c cvs rdiff -u -r1.22 -r1.23 src/lib/libperfuse/perfuse.c \ src/lib/libperfuse/perfuse_priv.h cvs rdiff -u -r1.16 -r1.17 src/lib/libperfuse/perfuse_if.h cvs rdiff -u -r1.13 -r1.14 src/lib/libperfuse/subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libperfuse/ops.c diff -u src/lib/libperfuse/ops.c:1.42 src/lib/libperfuse/ops.c:1.43 --- src/lib/libperfuse/ops.c:1.42 Sat Sep 10 10:06:10 2011 +++ src/lib/libperfuse/ops.c Sun Oct 30 05:11:37 2011 @@ -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 @@ perfuse_node_close_common(pu, opc, mode) #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 @@ xchg_msg(pu, opc, pm, len, wait) #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 @@ fuse_attr_to_vap(ps, vap, fa) 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 @@ node_lookup_dir_nodot(pu, opc, name, nam 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 @@ node_lookup_dir_nodot(pu, opc, name, nam } /* - * 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); + if (strncmp(name, "..", namelen) == 0) { + *pnp = PERFUSE_NODE_DATA(opc)->pnd_parent; + return 0; + } - return error; + return node_lookup_common(pu, opc, name, NULL, pnp); } static int @@ -363,13 +424,16 @@ node_lookup_common(pu, opc, path, pcr, p 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 @@ node_lookup_common(pu, opc, path, pcr, p /* * 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 @@ node_lookup_common(pu, opc, path, pcr, p 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); + set_expire((puffs_cookie_t)pn, feo, NULL); - if (pnp != NULL) - *pnp = pn; + *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 @@ node_mk_common(pu, opc, pni, pcn, pm) 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__); pn = perfuse_new_pn(pu, pcn->pcn_name, 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); + set_expire((puffs_cookie_t)pn, feo, NULL); puffs_newinfo_setcookie(pni, pn); #ifdef PERFUSE_DEBUG if (perfuse_diagflags & PDF_FILENAME) DPRINTF("%s: opc = %p, file = \"%s\", flags = 0x%x " - "ino = %"PRId64"\n", + "nodeid = 0x%"PRIx64"\n", __func__, (void *)pn, pcn->pcn_name, PERFUSE_NODE_DATA(pn)->pnd_flags, feo->nodeid); #endif @@ -530,6 +636,7 @@ node_mk_common_final(pu, opc, pn, pcn) fao = GET_OUTPAYLOAD(ps, pm, fuse_attr_out); fuse_attr_to_vap(ps, &pn->pn_va, &fao->attr); + set_expire((puffs_cookie_t)pn, NULL, fao); /* * The parent directory needs a sync @@ -624,17 +731,16 @@ fuse_to_dirent(pu, opc, fd, fd_len) /* * Filesystem was mounted without -o use_ino * Perform a lookup to find it. - * XXX still broken */ if (fd->ino == PERFUSE_UNKNOWN_INO) { struct puffs_node *pn; if (node_lookup_dir_nodot(pu, opc, fd->name, - fd->namelen, &pn) != 0) - DERRX(EX_SOFTWARE, - "node_lookup_dir_nodot failed"); - - fd->ino = PERFUSE_NODE_DATA(pn)->pnd_ino; + fd->namelen, &pn) != 0) { + DWARNX("node_lookup_dir_nodot failed"); + } else { + fd->ino = pn->pn_va.va_fileid; + } } dents->d_fileno = fd->ino; @@ -645,7 +751,7 @@ fuse_to_dirent(pu, opc, fd, fd_len) #ifdef PERFUSE_DEBUG if (perfuse_diagflags & PDF_READDIR) - DPRINTF("%s: translated \"%s\" ino = %"PRId64"\n", + DPRINTF("%s: translated \"%s\" ino = %"PRIu64"\n", __func__, dents->d_name, dents->d_fileno); #endif @@ -1196,8 +1302,8 @@ perfuse_node_create(pu, opc, pni, pcn, v feo = GET_OUTPAYLOAD(ps, pm, fuse_entry_out); foo = (struct fuse_open_out *)(void *)(feo + 1); - 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__); /* * Save the file handle and inode in node private data @@ -1205,19 +1311,21 @@ perfuse_node_create(pu, opc, pni, pcn, v */ pn = perfuse_new_pn(pu, name, opc); perfuse_new_fh((puffs_cookie_t)pn, foo->fh, FWRITE); - 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); + set_expire((puffs_cookie_t)pn, feo, NULL); puffs_newinfo_setcookie(pni, pn); #ifdef PERFUSE_DEBUG if (perfuse_diagflags & (PDF_FH|PDF_FILENAME)) DPRINTF("%s: opc = %p, file = \"%s\", flags = 0x%x " - "ino = %"PRId64", wfh = 0x%"PRIx64"\n", + "nodeid = 0x%"PRIx64", wfh = 0x%"PRIx64"\n", __func__, (void *)pn, pcn->pcn_name, - PERFUSE_NODE_DATA(pn)->pnd_flags, feo->nodeid, foo->fh); + PERFUSE_NODE_DATA(pn)->pnd_flags, feo->nodeid, + foo->fh); #endif ps->ps_destroy_msg(pm); @@ -1383,9 +1491,9 @@ perfuse_node_open(pu, opc, mode, pcr) #ifdef PERFUSE_DEBUG if (perfuse_diagflags & (PDF_FH|PDF_FILENAME)) DPRINTF("%s: opc = %p, file = \"%s\", " - "ino = %"PRId64", %s%sfh = 0x%"PRIx64"\n", + "nodeid = 0x%"PRIx64", %s%sfh = 0x%"PRIx64"\n", __func__, (void *)opc, perfuse_node_path(opc), - pnd->pnd_ino, mode & FREAD ? "r" : "", + pnd->pnd_nodeid, mode & FREAD ? "r" : "", mode & FWRITE ? "w" : "", foo->fh); #endif @@ -1485,12 +1593,12 @@ perfuse_node_getattr(pu, opc, vap, pcr) struct vattr *vap; const struct puffs_cred *pcr; { - perfuse_msg_t *pm; + perfuse_msg_t *pm = NULL; struct perfuse_state *ps; struct perfuse_node_data *pnd = PERFUSE_NODE_DATA(opc); struct fuse_getattr_in *fgi; struct fuse_attr_out *fao; - int error; + int error = 0; if (pnd->pnd_flags & PND_REMOVED) return ENOENT; @@ -1503,6 +1611,16 @@ perfuse_node_getattr(pu, opc, vap, pcr) pnd->pnd_flags |= PND_INRESIZE; ps = puffs_getspecific(pu); + + /* + * Check for cached attributes + * This still require serialized access to size. + */ + if (!attr_expired(opc)) { + (void)memcpy(vap, puffs_pn_getvap((struct puffs_node *)opc), + sizeof(*vap)); + goto out; + } /* * FUSE_GETATTR_FH must be set in fgi->flags @@ -1537,17 +1655,16 @@ perfuse_node_getattr(pu, opc, vap, pcr) #endif /* - * The message from filesystem has a cache timeout - * XXX this is ignored yet, is that right? - * - * We also set birthtime, flags, filerev,vaflags to 0. + * We set birthtime, flags, filerev,vaflags to 0. * This seems the best bet, since the information is * not available from filesystem. */ fuse_attr_to_vap(ps, vap, &fao->attr); + set_expire(opc, NULL, fao); out: - ps->ps_destroy_msg(pm); + if (pm != NULL) + ps->ps_destroy_msg(pm); pnd->pnd_flags &= ~PND_INRESIZE; (void)dequeue_requests(ps, opc, PCQ_RESIZE, DEQUEUE_ALL); @@ -1762,6 +1879,8 @@ perfuse_node_setattr(pu, opc, vap, pcr) #endif fuse_attr_to_vap(ps, old_va, &fao->attr); + set_expire(opc, NULL, fao); + out: if (pm != NULL) ps->ps_destroy_msg(pm); @@ -1806,9 +1925,9 @@ perfuse_node_poll(pu, opc, events) #ifdef PERFUSE_DEBUG if (perfuse_diagflags & PDF_FH) - DPRINTF("%s: opc = %p, ino = %"PRId64", fh = 0x%"PRIx64"\n", + DPRINTF("%s: opc = %p, nodeid = 0x%"PRIx64", fh = 0x%"PRIx64"\n", __func__, (void *)opc, - PERFUSE_NODE_DATA(opc)->pnd_ino, fpi->fh); + PERFUSE_NODE_DATA(opc)->pnd_nodeid, fpi->fh); #endif if ((error = xchg_msg(pu, opc, pm, sizeof(*fpo), wait_reply)) != 0) goto out; @@ -1917,9 +2036,9 @@ perfuse_node_fsync(pu, opc, pcr, flags, #ifdef PERFUSE_DEBUG if (perfuse_diagflags & PDF_FH) - DPRINTF("%s: opc = %p, ino = %"PRId64", fh = 0x%"PRIx64"\n", + DPRINTF("%s: opc = %p, nodeid = 0x%"PRIx64", fh = 0x%"PRIx64"\n", __func__, (void *)opc, - PERFUSE_NODE_DATA(opc)->pnd_ino, ffi->fh); + PERFUSE_NODE_DATA(opc)->pnd_nodeid, ffi->fh); #endif if ((error = xchg_msg(pu, opc, pm, @@ -2023,8 +2142,8 @@ perfuse_node_remove(pu, opc, targ, pcn) #ifdef PERFUSE_DEBUG if (perfuse_diagflags & PDF_FILENAME) - DPRINTF("%s: remove nodeid = %"PRId64" file = \"%s\"\n", - __func__, PERFUSE_NODE_DATA(targ)->pnd_ino, + DPRINTF("%s: remove nodeid = 0x%"PRIx64" file = \"%s\"\n", + __func__, PERFUSE_NODE_DATA(targ)->pnd_nodeid, pcn->pcn_name); #endif out: @@ -2058,7 +2177,7 @@ perfuse_node_link(pu, opc, targ, pcn) pm = ps->ps_new_msg(pu, opc, FUSE_LINK, len, pcn->pcn_cred); fli = GET_INPAYLOAD(ps, pm, fuse_link_in); - fli->oldnodeid = PERFUSE_NODE_DATA(pn)->pnd_ino; + fli->oldnodeid = PERFUSE_NODE_DATA(pn)->pnd_nodeid; (void)strlcpy((char *)(void *)(fli + 1), name, len - sizeof(*fli)); error = xchg_msg(pu, opc, pm, UNSPEC_REPLY_LEN, wait_reply); @@ -2116,7 +2235,7 @@ perfuse_node_rename(pu, opc, src, pcn_sr len = sizeof(*fri) + oldname_len + newname_len; pm = ps->ps_new_msg(pu, opc, FUSE_RENAME, len, pcn_targ->pcn_cred); fri = GET_INPAYLOAD(ps, pm, fuse_rename_in); - fri->newdir = PERFUSE_NODE_DATA(targ_dir)->pnd_ino; + fri->newdir = PERFUSE_NODE_DATA(targ_dir)->pnd_nodeid; np = (char *)(void *)(fri + 1); (void)strlcpy(np, oldname, oldname_len); np += oldname_len; @@ -2154,12 +2273,12 @@ perfuse_node_rename(pu, opc, src, pcn_sr #ifdef PERFUSE_DEBUG if (perfuse_diagflags & PDF_FILENAME) - DPRINTF("%s: nodeid = %"PRId64" file = \"%s\" renamed \"%s\" " - "nodeid = %"PRId64" -> nodeid = %"PRId64" \"%s\"\n", - __func__, PERFUSE_NODE_DATA(src)->pnd_ino, + DPRINTF("%s: nodeid = 0x%"PRIx64" file = \"%s\" renamed \"%s\" " + "nodeid = 0x%"PRIx64" -> nodeid = 0x%"PRIx64" \"%s\"\n", + __func__, PERFUSE_NODE_DATA(src)->pnd_nodeid, pcn_src->pcn_name, pcn_targ->pcn_name, - PERFUSE_NODE_DATA(opc)->pnd_ino, - PERFUSE_NODE_DATA(targ_dir)->pnd_ino, + PERFUSE_NODE_DATA(opc)->pnd_nodeid, + PERFUSE_NODE_DATA(targ_dir)->pnd_nodeid, perfuse_node_path(targ_dir)); #endif @@ -2250,8 +2369,8 @@ perfuse_node_rmdir(pu, opc, targ, pcn) #ifdef PERFUSE_DEBUG if (perfuse_diagflags & PDF_FILENAME) - DPRINTF("%s: remove nodeid = %"PRId64" file = \"%s\"\n", - __func__, PERFUSE_NODE_DATA(targ)->pnd_ino, + DPRINTF("%s: remove nodeid = 0x%"PRIx64" file = \"%s\"\n", + __func__, PERFUSE_NODE_DATA(targ)->pnd_nodeid, perfuse_node_path(targ)); #endif out: @@ -2368,9 +2487,9 @@ perfuse_node_readdir(pu, opc, dent, read #ifdef PERFUSE_DEBUG if (perfuse_diagflags & PDF_FH) - DPRINTF("%s: opc = %p, ino = %"PRId64", rfh = 0x%"PRIx64"\n", + DPRINTF("%s: opc = %p, nodeid = 0x%"PRIx64", rfh = 0x%"PRIx64"\n", __func__, (void *)opc, - PERFUSE_NODE_DATA(opc)->pnd_ino, fh); + PERFUSE_NODE_DATA(opc)->pnd_nodeid, fh); #endif pnd->pnd_all_fd = NULL; @@ -2542,7 +2661,7 @@ perfuse_node_reclaim(pu, opc) /* * Never forget the root. */ - if (pnd->pnd_ino == FUSE_ROOT_ID) + if (pnd->pnd_nodeid == FUSE_ROOT_ID) return 0; pnd->pnd_flags |= PND_RECLAIMED; @@ -2550,7 +2669,7 @@ perfuse_node_reclaim(pu, opc) #ifdef PERFUSE_DEBUG if (perfuse_diagflags & PDF_RECLAIM) DPRINTF("%s (nodeid %"PRId64") reclaimed\n", - perfuse_node_path(opc), pnd->pnd_ino); + perfuse_node_path(opc), pnd->pnd_nodeid); #endif pn_root = puffs_getroot(pu); @@ -2564,7 +2683,7 @@ perfuse_node_reclaim(pu, opc) if (perfuse_diagflags & PDF_RECLAIM) DPRINTF("%s (nodeid %"PRId64") is %sreclaimed, " "has childcount %d %s%s%s%s, pending ops:%s%s%s\n", - perfuse_node_path((puffs_cookie_t)pn), pnd->pnd_ino, + perfuse_node_path((puffs_cookie_t)pn), pnd->pnd_nodeid, pnd->pnd_flags & PND_RECLAIMED ? "" : "not ", pnd->pnd_childcount, pnd->pnd_flags & PND_OPEN ? "open " : "not open", @@ -2755,9 +2874,9 @@ perfuse_node_advlock(pu, opc, id, op, fl #ifdef PERFUSE_DEBUG if (perfuse_diagflags & PDF_FH) - DPRINTF("%s: opc = %p, ino = %"PRId64", fh = 0x%"PRIx64"\n", + DPRINTF("%s: opc = %p, nodeid = 0x%"PRIx64", fh = 0x%"PRIx64"\n", __func__, (void *)opc, - PERFUSE_NODE_DATA(opc)->pnd_ino, fli->fh); + PERFUSE_NODE_DATA(opc)->pnd_nodeid, fli->fh); #endif if ((error = xchg_msg(pu, opc, pm, UNSPEC_REPLY_LEN, wait_reply)) != 0) @@ -2860,8 +2979,8 @@ perfuse_node_read(pu, opc, buf, offset, #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 error = xchg_msg(pu, opc, pm, UNSPEC_REPLY_LEN, wait_reply); @@ -3006,9 +3125,9 @@ perfuse_node_write(pu, opc, buf, offset, #ifdef PERFUSE_DEBUG if (perfuse_diagflags & PDF_FH) - DPRINTF("%s: opc = %p, ino = %"PRId64", " + DPRINTF("%s: opc = %p, nodeid = 0x%"PRIx64", " "fh = 0x%"PRIx64"\n", __func__, - (void *)opc, pnd->pnd_ino, fwi->fh); + (void *)opc, pnd->pnd_nodeid, fwi->fh); #endif if ((error = xchg_msg(pu, opc, pm, sizeof(*fwo), wait_reply)) != 0) Index: src/lib/libperfuse/perfuse.c diff -u src/lib/libperfuse/perfuse.c:1.22 src/lib/libperfuse/perfuse.c:1.23 --- src/lib/libperfuse/perfuse.c:1.22 Sun Oct 23 05:01:00 2011 +++ src/lib/libperfuse/perfuse.c Sun Oct 30 05:11:37 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: perfuse.c,v 1.22 2011/10/23 05:01:00 manu Exp $ */ +/* $NetBSD: perfuse.c,v 1.23 2011/10/30 05:11:37 manu Exp $ */ /*- * Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved. @@ -511,8 +511,11 @@ perfuse_init(pc, pmi) * immediatly to the filesystem, and we get a huge performance gain * because much less requests are sent. A test case for the above * mentioned bug got its execution time slashed by factor 50. + * + * PUFFS_KFLAG_NOCACHE_NAME is required so that we can see changes + * done by other machines in networked filesystems. */ - puffs_flags = 0; + puffs_flags = PUFFS_KFLAG_NOCACHE_NAME; if (perfuse_diagflags & PDF_PUFFS) puffs_flags |= PUFFS_FLAG_OPDUMP; @@ -526,7 +529,7 @@ perfuse_init(pc, pmi) * Setup filesystem root */ pn_root = perfuse_new_pn(pu, "", NULL); - PERFUSE_NODE_DATA(pn_root)->pnd_ino = FUSE_ROOT_ID; + PERFUSE_NODE_DATA(pn_root)->pnd_nodeid = FUSE_ROOT_ID; PERFUSE_NODE_DATA(pn_root)->pnd_parent = pn_root; puffs_setroot(pu, pn_root); ps->ps_fsid = pn_root->pn_va.va_fsid; @@ -541,6 +544,7 @@ perfuse_init(pc, pmi) puffs_vattr_null(&pn_root->pn_va); pn_root->pn_va.va_type = VDIR; pn_root->pn_va.va_mode = 0755; + pn_root->pn_va.va_fileid = FUSE_ROOT_ID; ps->ps_root = pn_root; @@ -616,11 +620,11 @@ perfuse_mainloop(pu) /* ARGSUSED0 */ uint64_t -perfuse_get_ino(pu, opc) +perfuse_get_nodeid(pu, opc) struct puffs_usermount *pu; puffs_cookie_t opc; { - return PERFUSE_NODE_DATA(opc)->pnd_ino; + return PERFUSE_NODE_DATA(opc)->pnd_nodeid; } int Index: src/lib/libperfuse/perfuse_priv.h diff -u src/lib/libperfuse/perfuse_priv.h:1.22 src/lib/libperfuse/perfuse_priv.h:1.23 --- src/lib/libperfuse/perfuse_priv.h:1.22 Fri Sep 9 15:45:28 2011 +++ src/lib/libperfuse/perfuse_priv.h Sun Oct 30 05:11:37 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: perfuse_priv.h,v 1.22 2011/09/09 15:45:28 manu Exp $ */ +/* $NetBSD: perfuse_priv.h,v 1.23 2011/10/30 05:11:37 manu Exp $ */ /*- * Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved. @@ -92,7 +92,7 @@ struct perfuse_cc_queue { struct perfuse_node_data { uint64_t pnd_rfh; uint64_t pnd_wfh; - uint64_t pnd_ino; /* inode */ + uint64_t pnd_nodeid; /* nodeid, this is not inode */ uint64_t pnd_nlookup; /* vnode refcount */ uint64_t pnd_lock_owner; struct dirent *pnd_dirent; /* native buffer for readdir */ @@ -121,6 +121,8 @@ struct perfuse_node_data { puffs_cookie_t pnd_pn; char pnd_name[MAXPATHLEN]; /* node name */ TAILQ_HEAD(,perfuse_node_data) pnd_children; + struct timespec pnd_entry_expire; + struct timespec pnd_attr_expire; }; #define PERFUSE_NODE_DATA(opc) \ Index: src/lib/libperfuse/perfuse_if.h diff -u src/lib/libperfuse/perfuse_if.h:1.16 src/lib/libperfuse/perfuse_if.h:1.17 --- src/lib/libperfuse/perfuse_if.h:1.16 Fri Sep 9 15:45:28 2011 +++ src/lib/libperfuse/perfuse_if.h Sun Oct 30 05:11:37 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: perfuse_if.h,v 1.16 2011/09/09 15:45:28 manu Exp $ */ +/* $NetBSD: perfuse_if.h,v 1.17 2011/10/30 05:11:37 manu Exp $ */ /*- * Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved. @@ -35,6 +35,7 @@ #define FUSE_COMMFD_ENV "_FUSE_COMMFD" #define PERFUSE_MOUNT_MAGIC "noFuseRq" #define PERFUSE_UNKNOWN_INO 0xffffffff +#define PERFUSE_UNKNOWN_NODEID 0xffffffff /* * Diagnostic flags. This global is used only for DPRINTF/DERR/DWARN @@ -199,7 +200,7 @@ struct puffs_usermount *perfuse_init(str void perfuse_setspecific(struct puffs_usermount *, void *); void *perfuse_getspecific(struct puffs_usermount *); uint64_t perfuse_next_unique(struct puffs_usermount *); -uint64_t perfuse_get_ino(struct puffs_usermount *, puffs_cookie_t); +uint64_t perfuse_get_nodeid(struct puffs_usermount *, puffs_cookie_t); int perfuse_inloop(struct puffs_usermount *); const char *perfuse_opname(int); void perfuse_fs_init(struct puffs_usermount *); Index: src/lib/libperfuse/subr.c diff -u src/lib/libperfuse/subr.c:1.13 src/lib/libperfuse/subr.c:1.14 --- src/lib/libperfuse/subr.c:1.13 Sat Aug 13 23:12:15 2011 +++ src/lib/libperfuse/subr.c Sun Oct 30 05:11:37 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: subr.c,v 1.13 2011/08/13 23:12:15 christos Exp $ */ +/* $NetBSD: subr.c,v 1.14 2011/10/30 05:11:37 manu Exp $ */ /*- * Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved. @@ -66,7 +66,7 @@ perfuse_new_pn(pu, name, parent) (void)memset(pnd, 0, sizeof(*pnd)); pnd->pnd_rfh = FUSE_UNKNOWN_FH; pnd->pnd_wfh = FUSE_UNKNOWN_FH; - pnd->pnd_ino = PERFUSE_UNKNOWN_INO; + pnd->pnd_nodeid = PERFUSE_UNKNOWN_NODEID; pnd->pnd_nlookup = 1; pnd->pnd_parent = parent; pnd->pnd_pn = (puffs_cookie_t)pn;