Module Name: src Committed By: manu Date: Wed Apr 18 00:57:22 UTC 2012
Modified Files: src/lib/libperfuse: ops.c perfuse.c perfuse_priv.h subr.c src/lib/libpuffs: dispatcher.c pnode.c puffs.3 puffs.h puffs_ops.3 puffs_priv.h Log Message: - When using PUFFS_KFLAG_CACHE_FS_TTL, do not use puffs_node to carry attribute and TTL fora newly created node. Instead extend puffs_newinfo and add puffs_newinfo_setva() and puffs_newinfo_setttl() - Remove node_mk_common_final in libperfuse. It used to set uid/gid for a newly created vnode but has been made redundant along time ago since uid and gid are properly set in FUSE header. - In libperfuse, check for corner case where opc = 0 on INACTIVE and RECLAIM (how is it possible? Check for it to avoid a crash anyway) - In libperfuse, make sure we unlimit RLIMIT_AS and RLIMIT_DATA so that we do notrun out of memory because the kernel is lazy at reclaiming vnodes. - In libperfuse, cleanup style of perfuse_destroy_pn() To generate a diff of this commit: cvs rdiff -u -r1.53 -r1.54 src/lib/libperfuse/ops.c cvs rdiff -u -r1.27 -r1.28 src/lib/libperfuse/perfuse.c cvs rdiff -u -r1.28 -r1.29 src/lib/libperfuse/perfuse_priv.h cvs rdiff -u -r1.17 -r1.18 src/lib/libperfuse/subr.c cvs rdiff -u -r1.39 -r1.40 src/lib/libpuffs/dispatcher.c cvs rdiff -u -r1.11 -r1.12 src/lib/libpuffs/pnode.c cvs rdiff -u -r1.51 -r1.52 src/lib/libpuffs/puffs.3 cvs rdiff -u -r1.120 -r1.121 src/lib/libpuffs/puffs.h cvs rdiff -u -r1.29 -r1.30 src/lib/libpuffs/puffs_ops.3 cvs rdiff -u -r1.44 -r1.45 src/lib/libpuffs/puffs_priv.h 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.53 src/lib/libperfuse/ops.c:1.54 --- src/lib/libperfuse/ops.c:1.53 Sun Apr 8 15:13:06 2012 +++ src/lib/libperfuse/ops.c Wed Apr 18 00:57:21 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ops.c,v 1.53 2012/04/08 15:13:06 manu Exp $ */ +/* $NetBSD: ops.c,v 1.54 2012/04/18 00:57:21 manu Exp $ */ /*- * Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved. @@ -34,7 +34,7 @@ #include <sysexits.h> #include <syslog.h> #include <puffs.h> -#include <sys/socket.h> +#include <sys/cdefs.h> #include <sys/socket.h> #include <sys/extattr.h> #include <sys/time.h> @@ -48,9 +48,12 @@ extern int perfuse_diagflags; #if 0 static void print_node(const char *, puffs_cookie_t); #endif +#ifdef PUFFS_KFLAG_CACHE_FS_TTL +static void perfuse_newinfo_setttl(struct puffs_newinfo *, + struct fuse_entry_out *, struct fuse_attr_out *); +#else /* PUFFS_KFLAG_CACHE_FS_TTL */ static void set_expire(puffs_cookie_t, struct fuse_entry_out *, struct fuse_attr_out *); -#ifndef PUFFS_KFLAG_CACHE_FS_TTL static int attr_expired(puffs_cookie_t); static int entry_expired(puffs_cookie_t); #endif /* PUFFS_KFLAG_CACHE_FS_TTL */ @@ -63,11 +66,10 @@ static void fuse_attr_to_vap(struct perf static int node_lookup_dir_nodot(struct puffs_usermount *, puffs_cookie_t, char *, size_t, struct puffs_node **); static int node_lookup_common(struct puffs_usermount *, puffs_cookie_t, - const char *, const struct puffs_cred *, struct puffs_node **); + struct puffs_newinfo *, const char *, const struct puffs_cred *, + struct puffs_node **); static int node_mk_common(struct puffs_usermount *, puffs_cookie_t, struct puffs_newinfo *, const struct puffs_cn *pcn, perfuse_msg_t *); -static int node_mk_common_final(struct puffs_usermount *, puffs_cookie_t, - struct puffs_node *, const struct puffs_cn *pcn); static uint64_t readdir_last_cookie(struct fuse_dirent *, size_t); static ssize_t fuse_to_dirent(struct puffs_usermount *, puffs_cookie_t, struct fuse_dirent *, size_t); @@ -336,12 +338,48 @@ fuse_attr_to_vap(struct perfuse_state *p return; } +#ifdef PUFFS_KFLAG_CACHE_FS_TTL +static void perfuse_newinfo_setttl(struct puffs_newinfo *pni, + struct fuse_entry_out *feo, struct fuse_attr_out *fao) +{ +#ifdef PERFUSE_DEBUG + 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__); +#endif /* PERFUSE_DEBUG */ + + if (fao != NULL) { + struct timespec va_ttl; + + va_ttl.tv_sec = fao->attr_valid; + va_ttl.tv_nsec = fao->attr_valid_nsec; + + puffs_newinfo_setvattl(pni, &va_ttl); + } + + if (feo != NULL) { + struct timespec va_ttl; + struct timespec cn_ttl; + + va_ttl.tv_sec = feo->attr_valid; + va_ttl.tv_nsec = feo->attr_valid_nsec; + cn_ttl.tv_sec = feo->entry_valid; + cn_ttl.tv_nsec = feo->entry_valid_nsec; + + puffs_newinfo_setvattl(pni, &va_ttl); + puffs_newinfo_setcnttl(pni, &cn_ttl); + } + + return; +} +#else /* PUFFS_KFLAG_CACHE_FS_TTL */ static void set_expire(puffs_cookie_t opc, struct fuse_entry_out *feo, struct fuse_attr_out *fao) { struct puffs_node *pn = (struct puffs_node *)opc; -#ifndef PUFFS_KFLAG_CACHE_FS_TTL struct perfuse_node_data *pnd = PERFUSE_NODE_DATA(opc); struct timespec entry_ts; struct timespec attr_ts; @@ -349,7 +387,6 @@ set_expire(puffs_cookie_t opc, struct fu if (clock_gettime(CLOCK_REALTIME, &now) != 0) DERR(EX_OSERR, "clock_gettime failed"); -#endif /* PUFFS_KFLAG_CACHE_FS_TTL */ if ((feo == NULL) && (fao == NULL)) DERRX(EX_SOFTWARE, "%s: feo and fao NULL", __func__); @@ -358,12 +395,6 @@ set_expire(puffs_cookie_t opc, struct fu DERRX(EX_SOFTWARE, "%s: feo and fao != NULL", __func__); if (feo != NULL) { -#ifdef PUFFS_KFLAG_CACHE_FS_TTL - pn->pn_cn_ttl.tv_sec = feo->entry_valid; - pn->pn_cn_ttl.tv_nsec = feo->entry_valid_nsec; - pn->pn_va_ttl.tv_sec = feo->attr_valid; - pn->pn_va_ttl.tv_nsec = feo->attr_valid_nsec; -#else /* PUFFS_KFLAG_CACHE_FS_TTL */ entry_ts.tv_sec = (time_t)feo->entry_valid; entry_ts.tv_nsec = (long)feo->entry_valid_nsec; @@ -373,25 +404,18 @@ set_expire(puffs_cookie_t opc, struct fu attr_ts.tv_nsec = (long)feo->attr_valid_nsec; timespecadd(&now, &attr_ts, &pnd->pnd_attr_expire); -#endif /* PUFFS_KFLAG_CACHE_FS_TTL */ } if (fao != NULL) { -#ifdef PUFFS_KFLAG_CACHE_FS_TTL - pn->pn_va_ttl.tv_sec = fao->attr_valid; - pn->pn_va_ttl.tv_nsec = fao->attr_valid_nsec; -#else /* PUFFS_KFLAG_CACHE_FS_TTL */ 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); -#endif /* PUFFS_KFLAG_CACHE_FS_TTL */ } return; } -#ifndef PUFFS_KFLAG_CACHE_FS_TTL static int attr_expired(puffs_cookie_t opc) { @@ -451,12 +475,13 @@ node_lookup_dir_nodot(struct puffs_userm return 0; } - return node_lookup_common(pu, opc, name, NULL, pnp); + return node_lookup_common(pu, opc, NULL, name, NULL, pnp); } static int node_lookup_common(struct puffs_usermount *pu, puffs_cookie_t opc, - const char *path, const struct puffs_cred *pcr, struct puffs_node **pnp) + struct puffs_newinfo *pni, const char *path, + const struct puffs_cred *pcr, struct puffs_node **pnp) { struct perfuse_state *ps; struct perfuse_node_data *oldpnd; @@ -543,14 +568,12 @@ node_lookup_common(struct puffs_usermoun feo = GET_OUTPAYLOAD(ps, pm, fuse_entry_out); + pn = NULL; if (oldpnd != NULL) { if (oldpnd->pnd_nodeid == feo->nodeid) { oldpnd->pnd_fuse_nlookup++; oldpnd->pnd_puffs_nlookup++; - *pnp = oldpnd->pnd_pn; - - ps->ps_destroy_msg(pm); - return 0; + pn = oldpnd->pnd_pn; } else { oldpnd->pnd_flags |= PND_REMOVED; #ifdef PERFUSE_DEBUG @@ -563,12 +586,16 @@ node_lookup_common(struct puffs_usermoun } } - pn = perfuse_new_pn(pu, path, opc); - PERFUSE_NODE_DATA(pn)->pnd_nodeid = feo->nodeid; + if (pn == NULL) { + pn = perfuse_new_pn(pu, path, opc); + 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); +#ifndef PUFFS_KFLAG_CACHE_FS_TTL set_expire((puffs_cookie_t)pn, feo, NULL); +#endif /* PUFFS_KFLAG_CACHE_FS_TTL */ *pnp = pn; @@ -579,6 +606,17 @@ node_lookup_common(struct puffs_usermoun (void *)opc, pn, feo->nodeid, path); #endif + if (pni != NULL) { +#ifdef PUFFS_KFLAG_CACHE_FS_TTL + puffs_newinfo_setva(pni, &pn->pn_va); + perfuse_newinfo_setttl(pni, feo, NULL); +#endif /* PUFFS_KFLAG_CACHE_FS_TTL */ + puffs_newinfo_setcookie(pni, pn); + puffs_newinfo_setvtype(pni, pn->pn_va.va_type); + puffs_newinfo_setsize(pni, (voff_t)pn->pn_va.va_size); + puffs_newinfo_setrdev(pni, pn->pn_va.va_rdev); + } + ps->ps_destroy_msg(pm); return 0; @@ -615,9 +653,15 @@ node_mk_common(struct puffs_usermount *p 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 PUFFS_KFLAG_CACHE_FS_TTL + puffs_newinfo_setva(pni, &pn->pn_va); + perfuse_newinfo_setttl(pni, feo, NULL); +#else + set_expire((puffs_cookie_t)pn, feo, NULL); +#endif + #ifdef PERFUSE_DEBUG if (perfuse_diagflags & PDF_FILENAME) @@ -627,61 +671,11 @@ node_mk_common(struct puffs_usermount *p PERFUSE_NODE_DATA(pn)->pnd_flags, feo->nodeid); #endif ps->ps_destroy_msg(pm); - - return node_mk_common_final(pu, opc, pn, pcn); -} - -/* - * Common final code for methods that create objects: - * perfuse_node_mkdir via node_mk_common - * perfuse_node_mknod via node_mk_common - * perfuse_node_symlink via node_mk_common - * perfuse_node_create - */ -static int -node_mk_common_final(struct puffs_usermount *pu, puffs_cookie_t opc, - struct puffs_node *pn, const struct puffs_cn *pcn) -{ - struct perfuse_state *ps; - perfuse_msg_t *pm; - struct fuse_setattr_in *fsi; - struct fuse_attr_out *fao; - int error; - - ps = puffs_getspecific(pu); - - /* - * Set owner and group. The kernel cannot create a file - * on its own (puffs_cred_getuid would return -1), right? - */ - if (puffs_cred_getuid(pcn->pcn_cred, &pn->pn_va.va_uid) != 0) - DERRX(EX_SOFTWARE, "puffs_cred_getuid fails in %s", __func__); - if (puffs_cred_getgid(pcn->pcn_cred, &pn->pn_va.va_gid) != 0) - DERRX(EX_SOFTWARE, "puffs_cred_getgid fails in %s", __func__); - - pm = ps->ps_new_msg(pu, (puffs_cookie_t)pn, - FUSE_SETATTR, sizeof(*fsi), pcn->pcn_cred); - fsi = GET_INPAYLOAD(ps, pm, fuse_setattr_in); - fsi->uid = pn->pn_va.va_uid; - fsi->gid = pn->pn_va.va_gid; - fsi->valid = FUSE_FATTR_UID|FUSE_FATTR_GID; - - if ((error = xchg_msg(pu, (puffs_cookie_t)pn, pm, - sizeof(*fao), wait_reply)) != 0) - return error; - - 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 - */ + + /* Parents is now dirty */ PERFUSE_NODE_DATA(opc)->pnd_flags |= PND_DIRTY; - ps->ps_destroy_msg(pm); - - return 0; + return 0; } static uint64_t @@ -1168,11 +1162,20 @@ perfuse_node_lookup(struct puffs_usermou /* * Special case for .. */ - if (strcmp(pcn->pcn_name, "..") == 0) + if (strcmp(pcn->pcn_name, "..") == 0) { pn = PERFUSE_NODE_DATA(opc)->pnd_parent; - else - error = node_lookup_common(pu, (puffs_cookie_t)opc, +#ifdef PUFFS_KFLAG_CACHE_FS_TTL + puffs_newinfo_setva(pni, &pn->pn_va); + /* XXX cannot call perfuse_newinfo_setttl */ +#endif /* PUFFS_KFLAG_CACHE_FS_TTL */ + puffs_newinfo_setcookie(pni, pn); + puffs_newinfo_setvtype(pni, pn->pn_va.va_type); + puffs_newinfo_setsize(pni, (voff_t)pn->pn_va.va_size); + puffs_newinfo_setrdev(pni, pn->pn_va.va_rdev); + } else { + error = node_lookup_common(pu, (puffs_cookie_t)opc, pni, pcn->pcn_name, pcn->pcn_cred, &pn); + } if (error != 0) return error; @@ -1222,11 +1225,6 @@ perfuse_node_lookup(struct puffs_usermou */ PERFUSE_NODE_DATA(pn)->pnd_flags &= ~PND_RECLAIMED; - puffs_newinfo_setcookie(pni, pn); - puffs_newinfo_setvtype(pni, pn->pn_va.va_type); - puffs_newinfo_setsize(pni, (voff_t)pn->pn_va.va_size); - puffs_newinfo_setrdev(pni, pn->pn_va.va_rdev); - return error; } @@ -1255,7 +1253,7 @@ perfuse_node_create(struct puffs_usermou */ ps = puffs_getspecific(pu); if (ps->ps_flags & PS_NO_CREAT) { - error = node_lookup_common(pu, opc, pcn->pcn_name, + error = node_lookup_common(pu, opc, NULL, pcn->pcn_name, pcn->pcn_cred, &pn); if (error == 0) return EEXIST; @@ -1264,7 +1262,7 @@ perfuse_node_create(struct puffs_usermou if (error != 0) return error; - error = node_lookup_common(pu, opc, pcn->pcn_name, + error = node_lookup_common(pu, opc, NULL, pcn->pcn_name, pcn->pcn_cred, &pn); if (error != 0) return error; @@ -1331,9 +1329,14 @@ perfuse_node_create(struct puffs_usermou 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 PUFFS_KFLAG_CACHE_FS_TTL + puffs_newinfo_setva(pni, &pn->pn_va); + perfuse_newinfo_setttl(pni, feo, NULL); +#else /* PUFFS_KFLAG_CACHE_FS_TTL */ + set_expire((puffs_cookie_t)pn, feo, NULL); +#endif /* PUFFS_KFLAG_CACHE_FS_TTL */ #ifdef PERFUSE_DEBUG if (perfuse_diagflags & (PDF_FH|PDF_FILENAME)) @@ -1346,7 +1349,7 @@ perfuse_node_create(struct puffs_usermou ps->ps_destroy_msg(pm); - return node_mk_common_final(pu, opc, pn, pcn); + return 0; } @@ -1576,6 +1579,14 @@ int perfuse_node_getattr(struct puffs_usermount *pu, puffs_cookie_t opc, struct vattr *vap, const struct puffs_cred *pcr) { + return perfuse_node_getattr_ttl(pu, opc, vap, pcr, NULL); +} + +int +perfuse_node_getattr_ttl(struct puffs_usermount *pu, puffs_cookie_t opc, + struct vattr *vap, const struct puffs_cred *pcr, + struct timespec *va_ttl) +{ perfuse_msg_t *pm = NULL; struct perfuse_state *ps; struct perfuse_node_data *pnd = PERFUSE_NODE_DATA(opc); @@ -1645,7 +1656,15 @@ perfuse_node_getattr(struct puffs_usermo * not available from filesystem. */ fuse_attr_to_vap(ps, vap, &fao->attr); + +#ifdef PUFFS_KFLAG_CACHE_FS_TTL + if (va_ttl != NULL) { + va_ttl->tv_sec = fao->attr_valid; + va_ttl->tv_nsec = fao->attr_valid_nsec; + } +#else /* PUFFS_KFLAG_CACHE_FS_TTL */ set_expire(opc, NULL, fao); +#endif /* PUFFS_KFLAG_CACHE_FS_TTL */ ps->ps_destroy_msg(pm); out: @@ -1660,6 +1679,15 @@ int perfuse_node_setattr(struct puffs_usermount *pu, puffs_cookie_t opc, const struct vattr *vap, const struct puffs_cred *pcr) { + return perfuse_node_setattr_ttl(pu, opc, + __UNCONST(vap), pcr, NULL); +} + +int +perfuse_node_setattr_ttl(struct puffs_usermount *pu, puffs_cookie_t opc, + struct vattr *vap, const struct puffs_cred *pcr, + struct timespec *va_ttl) +{ perfuse_msg_t *pm; uint64_t fh; struct perfuse_state *ps; @@ -1860,7 +1888,16 @@ perfuse_node_setattr(struct puffs_usermo #endif fuse_attr_to_vap(ps, old_va, &fao->attr); + +#ifdef PUFFS_KFLAG_CACHE_FS_TTL + if (va_ttl != NULL) { + va_ttl->tv_sec = fao->attr_valid; + va_ttl->tv_nsec = fao->attr_valid_nsec; + (void)memcpy(vap, old_va, sizeof(*vap)); + } +#else /* PUFFS_KFLAG_CACHE_FS_TTL */ set_expire(opc, NULL, fao); +#endif /* PUFFS_KFLAG_CACHE_FS_TTL */ ps->ps_destroy_msg(pm); @@ -2582,6 +2619,9 @@ perfuse_node_reclaim(struct puffs_usermo struct puffs_node *pn; struct puffs_node *pn_root; + if (opc == 0) + return 0; + ps = puffs_getspecific(pu); pnd = PERFUSE_NODE_DATA(opc); @@ -2689,6 +2729,9 @@ perfuse_node_inactive(struct puffs_userm struct perfuse_node_data *pnd; int error; + if (opc == 0) + return 0; + ps = puffs_getspecific(pu); pnd = PERFUSE_NODE_DATA(opc); Index: src/lib/libperfuse/perfuse.c diff -u src/lib/libperfuse/perfuse.c:1.27 src/lib/libperfuse/perfuse.c:1.28 --- src/lib/libperfuse/perfuse.c:1.27 Sun Apr 8 15:13:06 2012 +++ src/lib/libperfuse/perfuse.c Wed Apr 18 00:57:22 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: perfuse.c,v 1.27 2012/04/08 15:13:06 manu Exp $ */ +/* $NetBSD: perfuse.c,v 1.28 2012/04/18 00:57:22 manu Exp $ */ /*- * Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved. @@ -397,17 +397,18 @@ perfuse_init(struct perfuse_callbacks *p /* * perfused can grow quite large, let assume there's enough ram ... */ - if (getrlimit(RLIMIT_DATA, &rl) < 0) { - DERR(EX_OSERR, "%s: getrlimit failed: %s", __func__, + rl.rlim_cur = RLIM_INFINITY; + rl.rlim_max = RLIM_INFINITY; + + if (setrlimit(RLIMIT_DATA, &rl) < 0) { + DERR(EX_OSERR, "%s: setrlimit failed: %s", __func__, + strerror(errno)); + } + + if (setrlimit(RLIMIT_AS, &rl) < 0) { + DERR(EX_OSERR, "%s: setrlimit failed: %s", __func__, strerror(errno)); - } else { - rl.rlim_cur = rl.rlim_max; - if (setrlimit(RLIMIT_DATA, &rl) < 0) { - DERR(EX_OSERR, "%s: setrlimit failed: %s", __func__, - strerror(errno)); - } } - ps = init_state(); ps->ps_owner_uid = pmi->pmi_uid; @@ -485,25 +486,12 @@ perfuse_init(struct perfuse_callbacks *p PUFFSOP_SET(pops, perfuse, node, listextattr); PUFFSOP_SET(pops, perfuse, node, deleteextattr); #endif /* PUFFS_EXTNAMELEN */ +#ifdef PUFFS_KFLAG_CACHE_FS_TTL + PUFFSOP_SET(pops, perfuse, node, getattr_ttl); + PUFFSOP_SET(pops, perfuse, node, setattr_ttl); +#endif /* PUFFS_KFLAG_CACHE_FS_TTL */ /* - * We used to have PUFFS_KFLAG_WTCACHE here, which uses the - * page cache (highly desirable to get mmap(2)), but still sends - * all writes to the filesystem. In fact it does not send the - * data written, but the pages that contain it. - * - * There is a nasty bug hidden somewhere, possibly in libpuffs' - * VOP_FSYNC, which sends an asynchronous PUFFS_SETATTR that - * update file size. When writes are in progress, it will cause - * the file to be truncated and we get a zero-filled chunk at the - * beginning of a page. Removing PUFFS_KFLAG_WTCACHE fixes that - * problem. - * - * The other consequences are that changes will not be propagated - * 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. In later * NetBSD releases we use the alternative PUFFS_KFLAG_CACHE_FS_TTL, Index: src/lib/libperfuse/perfuse_priv.h diff -u src/lib/libperfuse/perfuse_priv.h:1.28 src/lib/libperfuse/perfuse_priv.h:1.29 --- src/lib/libperfuse/perfuse_priv.h:1.28 Sun Apr 8 15:13:06 2012 +++ src/lib/libperfuse/perfuse_priv.h Wed Apr 18 00:57:22 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: perfuse_priv.h,v 1.28 2012/04/08 15:13:06 manu Exp $ */ +/* $NetBSD: perfuse_priv.h,v 1.29 2012/04/18 00:57:22 manu Exp $ */ /*- * Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved. @@ -254,6 +254,12 @@ int perfuse_node_listextattr(struct puff int, size_t *, uint8_t *, size_t *, int, const struct puffs_cred *); int perfuse_node_deleteextattr(struct puffs_usermount *, puffs_cookie_t, int, const char *, const struct puffs_cred *); +int perfuse_node_getattr_ttl(struct puffs_usermount *, + puffs_cookie_t, struct vattr *, const struct puffs_cred *, + struct timespec *); +int perfuse_node_setattr_ttl(struct puffs_usermount *, + puffs_cookie_t, struct vattr *, const struct puffs_cred *, + struct timespec *); struct perfuse_trace *perfuse_trace_begin(struct perfuse_state *, puffs_cookie_t, perfuse_msg_t *); Index: src/lib/libperfuse/subr.c diff -u src/lib/libperfuse/subr.c:1.17 src/lib/libperfuse/subr.c:1.18 --- src/lib/libperfuse/subr.c:1.17 Wed Mar 21 10:10:36 2012 +++ src/lib/libperfuse/subr.c Wed Apr 18 00:57:22 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: subr.c,v 1.17 2012/03/21 10:10:36 matt Exp $ */ +/* $NetBSD: subr.c,v 1.18 2012/04/18 00:57:22 manu Exp $ */ /*- * Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved. @@ -90,18 +90,15 @@ perfuse_destroy_pn(struct puffs_node *pn { struct perfuse_node_data *pnd; - pnd = PERFUSE_NODE_DATA(pn); - - if (pnd->pnd_parent != NULL) { - struct perfuse_node_data *parent_pnd; + if ((pnd = puffs_pn_getpriv(pn)) != NULL) { + if (pnd->pnd_parent != NULL) { + struct perfuse_node_data *parent_pnd; - parent_pnd = PERFUSE_NODE_DATA(pnd->pnd_parent); - TAILQ_REMOVE(&parent_pnd->pnd_children, pnd, pnd_next); - } + parent_pnd = PERFUSE_NODE_DATA(pnd->pnd_parent); + TAILQ_REMOVE(&parent_pnd->pnd_children, pnd, pnd_next); - if ((pnd = puffs_pn_getpriv(pn)) != NULL) { - if (pnd->pnd_parent != NULL) PERFUSE_NODE_DATA(pnd->pnd_parent)->pnd_childcount--; + } if (pnd->pnd_dirent != NULL) free(pnd->pnd_dirent); @@ -114,9 +111,6 @@ perfuse_destroy_pn(struct puffs_node *pn if (!TAILQ_EMPTY(&pnd->pnd_pcq)) DERRX(EX_SOFTWARE, "%s: non empty pnd_pcq", __func__); - - if (pnd == NULL) - DERRX(EX_SOFTWARE, "%s: pnd == NULL ???", __func__); #endif /* PERFUSE_DEBUG */ free(pnd); Index: src/lib/libpuffs/dispatcher.c diff -u src/lib/libpuffs/dispatcher.c:1.39 src/lib/libpuffs/dispatcher.c:1.40 --- src/lib/libpuffs/dispatcher.c:1.39 Sun Apr 8 15:07:45 2012 +++ src/lib/libpuffs/dispatcher.c Wed Apr 18 00:57:22 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: dispatcher.c,v 1.39 2012/04/08 15:07:45 manu Exp $ */ +/* $NetBSD: dispatcher.c,v 1.40 2012/04/18 00:57:22 manu Exp $ */ /* * Copyright (c) 2006, 2007, 2008 Antti Kantee. All Rights Reserved. @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #if !defined(lint) -__RCSID("$NetBSD: dispatcher.c,v 1.39 2012/04/08 15:07:45 manu Exp $"); +__RCSID("$NetBSD: dispatcher.c,v 1.40 2012/04/18 00:57:22 manu Exp $"); #endif /* !lint */ #include <sys/types.h> @@ -52,26 +52,6 @@ __RCSID("$NetBSD: dispatcher.c,v 1.39 20 static void dispatch(struct puffs_cc *); -static void -update_fs_ttl(struct puffs_usermount *pu, puffs_cookie_t opc, - struct vattr *rvap, - struct timespec *va_ttl, struct timespec *cn_ttl) -{ - struct puffs_node *pn = NULL; - - pn = PU_CMAP(pu, opc); - - (void)memcpy(rvap, &pn->pn_va, sizeof(*rvap)); - - va_ttl->tv_sec = pn->pn_va_ttl.tv_sec; - va_ttl->tv_nsec = pn->pn_va_ttl.tv_nsec; - - if (cn_ttl != NULL) { - cn_ttl->tv_sec = pn->pn_cn_ttl.tv_sec; - cn_ttl->tv_nsec = pn->pn_cn_ttl.tv_nsec; - } -} - /* for our eyes only */ void puffs__ml_dispatch(struct puffs_usermount *pu, struct puffs_framebuf *pb) @@ -222,6 +202,9 @@ dispatch(struct puffs_cc *pcc) pni.pni_vtype = &auxt->pvfsr_vtype; pni.pni_size = &auxt->pvfsr_size; pni.pni_rdev = &auxt->pvfsr_rdev; + pni.pni_va = NULL; + pni.pni_va_ttl = NULL; + pni.pni_cn_ttl = NULL; error = pops->puffs_fs_fhtonode(pu, auxt->pvfsr_data, auxt->pvfsr_dsize, &pni); @@ -288,6 +271,9 @@ dispatch(struct puffs_cc *pcc) pni.pni_vtype = &auxt->pvnr_vtype; pni.pni_size = &auxt->pvnr_size; pni.pni_rdev = &auxt->pvnr_rdev; + pni.pni_va = &auxt->pvnr_va; + pni.pni_va_ttl = &auxt->pvnr_va_ttl; + pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; if (buildpath) { error = puffs_path_pcnbuild(pu, &pcn, opcookie); @@ -315,13 +301,6 @@ dispatch(struct puffs_cc *pcc) &pcn.pcn_po_full); } } - - if ((error == 0) && PUFFS_USE_FS_TTL(pu)) - update_fs_ttl(pu, auxt->pvnr_newnode, - &auxt->pvnr_va, - &auxt->pvnr_va_ttl, - &auxt->pvnr_cn_ttl); - break; } @@ -341,6 +320,9 @@ dispatch(struct puffs_cc *pcc) memset(&pni, 0, sizeof(pni)); pni.pni_cookie = &auxt->pvnr_newnode; + pni.pni_va = &auxt->pvnr_va; + pni.pni_va_ttl = &auxt->pvnr_va_ttl; + pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; if (buildpath) { error = puffs_path_pcnbuild(pu, &pcn, opcookie); @@ -362,12 +344,6 @@ dispatch(struct puffs_cc *pcc) } } - if ((error == 0) && PUFFS_USE_FS_TTL(pu)) - update_fs_ttl(pu, auxt->pvnr_newnode, - &auxt->pvnr_va, - &auxt->pvnr_va_ttl, - &auxt->pvnr_cn_ttl); - break; } @@ -387,6 +363,9 @@ dispatch(struct puffs_cc *pcc) memset(&pni, 0, sizeof(pni)); pni.pni_cookie = &auxt->pvnr_newnode; + pni.pni_va = &auxt->pvnr_va; + pni.pni_va_ttl = &auxt->pvnr_va_ttl; + pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; if (buildpath) { error = puffs_path_pcnbuild(pu, &pcn, opcookie); @@ -408,12 +387,6 @@ dispatch(struct puffs_cc *pcc) } } - if ((error == 0) && PUFFS_USE_FS_TTL(pu)) - update_fs_ttl(pu, auxt->pvnr_newnode, - &auxt->pvnr_va, - &auxt->pvnr_va_ttl, - &auxt->pvnr_cn_ttl); - break; } @@ -467,27 +440,24 @@ dispatch(struct puffs_cc *pcc) struct puffs_vnmsg_getattr *auxt = auxbuf; PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); - if (pops->puffs_node_getattr == NULL) { - error = EOPNOTSUPP; - break; - } - - error = pops->puffs_node_getattr(pu, - opcookie, &auxt->pvnr_va, pcr); + if (PUFFS_USE_FS_TTL(pu)) { + if (pops->puffs_node_getattr_ttl == NULL) { + error = EOPNOTSUPP; + break; + } - if ((error == 0) && PUFFS_USE_FS_TTL(pu)) { - struct puffs_node *pn; + error = pops->puffs_node_getattr_ttl(pu, + opcookie, &auxt->pvnr_va, pcr, + &auxt->pvnr_va_ttl); + } else { + if (pops->puffs_node_getattr == NULL) { + error = EOPNOTSUPP; + break; + } - pn = PU_CMAP(pu, opcookie); - auxt->pvnr_va_ttl = pn->pn_va_ttl; + error = pops->puffs_node_getattr(pu, + opcookie, &auxt->pvnr_va, pcr); } - - if ((error == 0) && PUFFS_USE_FS_TTL(pu)) - update_fs_ttl(pu, opcookie, - &auxt->pvnr_va, - &auxt->pvnr_va_ttl, - NULL); - break; } @@ -496,19 +466,24 @@ dispatch(struct puffs_cc *pcc) struct puffs_vnmsg_setattr *auxt = auxbuf; PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); - if (pops->puffs_node_setattr == NULL) { - error = EOPNOTSUPP; - break; - } + if (PUFFS_USE_FS_TTL(pu)) { + if (pops->puffs_node_setattr_ttl == NULL) { + error = EOPNOTSUPP; + break; + } - error = pops->puffs_node_setattr(pu, - opcookie, &auxt->pvnr_va, pcr); + error = pops->puffs_node_setattr_ttl(pu, + opcookie, &auxt->pvnr_va, pcr, + &auxt->pvnr_va_ttl); + } else { + if (pops->puffs_node_setattr == NULL) { + error = EOPNOTSUPP; + break; + } - if ((error == 0) && PUFFS_USE_FS_TTL(pu)) - update_fs_ttl(pu, opcookie, - &auxt->pvnr_va, - &auxt->pvnr_va_ttl, - NULL); + error = pops->puffs_node_setattr(pu, + opcookie, &auxt->pvnr_va, pcr); + } break; } @@ -684,6 +659,9 @@ dispatch(struct puffs_cc *pcc) memset(&pni, 0, sizeof(pni)); pni.pni_cookie = &auxt->pvnr_newnode; + pni.pni_va = &auxt->pvnr_va; + pni.pni_va_ttl = &auxt->pvnr_va_ttl; + pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; if (buildpath) { error = puffs_path_pcnbuild(pu, &pcn, opcookie); @@ -705,12 +683,6 @@ dispatch(struct puffs_cc *pcc) } } - if ((error == 0) && PUFFS_USE_FS_TTL(pu)) - update_fs_ttl(pu, auxt->pvnr_newnode, - &auxt->pvnr_va, - &auxt->pvnr_va_ttl, - &auxt->pvnr_cn_ttl); - break; } @@ -747,6 +719,9 @@ dispatch(struct puffs_cc *pcc) memset(&pni, 0, sizeof(pni)); pni.pni_cookie = &auxt->pvnr_newnode; + pni.pni_va = &auxt->pvnr_va; + pni.pni_va_ttl = &auxt->pvnr_va_ttl; + pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; if (buildpath) { error = puffs_path_pcnbuild(pu, &pcn, opcookie); @@ -769,12 +744,6 @@ dispatch(struct puffs_cc *pcc) } } - if ((error == 0) && PUFFS_USE_FS_TTL(pu)) - update_fs_ttl(pu, auxt->pvnr_newnode, - &auxt->pvnr_va, - &auxt->pvnr_va_ttl, - &auxt->pvnr_cn_ttl); - break; } Index: src/lib/libpuffs/pnode.c diff -u src/lib/libpuffs/pnode.c:1.11 src/lib/libpuffs/pnode.c:1.12 --- src/lib/libpuffs/pnode.c:1.11 Sun Apr 8 15:07:45 2012 +++ src/lib/libpuffs/pnode.c Wed Apr 18 00:57:22 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: pnode.c,v 1.11 2012/04/08 15:07:45 manu Exp $ */ +/* $NetBSD: pnode.c,v 1.12 2012/04/18 00:57:22 manu Exp $ */ /* * Copyright (c) 2006 Antti Kantee. All Rights Reserved. @@ -27,7 +27,7 @@ #include <sys/cdefs.h> #if !defined(lint) -__RCSID("$NetBSD: pnode.c,v 1.11 2012/04/08 15:07:45 manu Exp $"); +__RCSID("$NetBSD: pnode.c,v 1.12 2012/04/18 00:57:22 manu Exp $"); #endif /* !lint */ #include <sys/types.h> @@ -136,19 +136,6 @@ puffs_pn_getmnt(struct puffs_node *pn) return pn->pn_mnt; } -struct timespec * -puffs_pn_getvattl(struct puffs_node *pn) -{ - return &pn->pn_va_ttl; -} - -struct timespec * -puffs_pn_getcnttl(struct puffs_node *pn) -{ - return &pn->pn_cn_ttl; -} - - /* convenience / shortcut */ void * puffs_pn_getmntspecific(struct puffs_node *pn) @@ -187,3 +174,27 @@ puffs_newinfo_setrdev(struct puffs_newin *pni->pni_rdev = rdev; } + +void +puffs_newinfo_setva(struct puffs_newinfo *pni, struct vattr *va) +{ + + (void)memcpy(pni->pni_va, va, sizeof(struct vattr)); +} + +void +puffs_newinfo_setvattl(struct puffs_newinfo *pni, struct timespec *va_ttl) +{ + + pni->pni_va_ttl->tv_sec = va_ttl->tv_sec; + pni->pni_va_ttl->tv_nsec = va_ttl->tv_nsec; +} + +void +puffs_newinfo_setcnttl(struct puffs_newinfo *pni, struct timespec *cn_ttl) +{ + + pni->pni_cn_ttl->tv_sec = cn_ttl->tv_sec; + pni->pni_cn_ttl->tv_nsec = cn_ttl->tv_nsec; +} + Index: src/lib/libpuffs/puffs.3 diff -u src/lib/libpuffs/puffs.3:1.51 src/lib/libpuffs/puffs.3:1.52 --- src/lib/libpuffs/puffs.3:1.51 Sun Apr 8 16:09:55 2012 +++ src/lib/libpuffs/puffs.3 Wed Apr 18 00:57:22 2012 @@ -1,4 +1,4 @@ -.\" $NetBSD: puffs.3,v 1.51 2012/04/08 16:09:55 wiz Exp $ +.\" $NetBSD: puffs.3,v 1.52 2012/04/18 00:57:22 manu Exp $ .\" .\" Copyright (c) 2006, 2007, 2008 Antti Kantee. All rights reserved. .\" @@ -237,15 +237,22 @@ Especially if the file system uses the a is a good idea to define this flag. .It Dv PUFFS_KFLAG_CACHE_FS_TTL Enforce name and attribute caches based on file system-supplied TTL. -In lookup, create, mknod, mkdir, symlink, getattr, and setattr, -the file system must update the attributes and their TTL through -.Fn puffs_pn_getvap -and -.Fn puffs_pn_getvattl . -.Pp -In lookup, create, mknod, mkdir, and symlink, -the name TTL must be updated through -.Fn puffs_pn_getcnttl . +In lookup, create, mknod, mkdir, and symlink, the file system must +update the node attributes, their TTL, and the node name TTL through +.Fn puffs_newinfo_setva , +.Fn puffs_newinfo_setvattl +and +.Fn puffs_newinfo_setcnttl . +.Pp +Additionally, +.Fn puffs_node_getattr_ttl +and +.Fn puffs_node_setattr_ttl +will be called instead of +.Fn puffs_node_getattr +and +.Fn puffs_node_setattr . + .It Dv PUFFS_FLAG_OPDUMP This option makes the framework dump a textual representation of each operation before executing it. Index: src/lib/libpuffs/puffs.h diff -u src/lib/libpuffs/puffs.h:1.120 src/lib/libpuffs/puffs.h:1.121 --- src/lib/libpuffs/puffs.h:1.120 Sun Apr 8 15:07:45 2012 +++ src/lib/libpuffs/puffs.h Wed Apr 18 00:57:22 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: puffs.h,v 1.120 2012/04/08 15:07:45 manu Exp $ */ +/* $NetBSD: puffs.h,v 1.121 2012/04/18 00:57:22 manu Exp $ */ /* * Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved. @@ -89,9 +89,6 @@ struct puffs_node { LIST_ENTRY(puffs_node) pn_entries; LIST_HEAD(,puffs_kcache)pn_cacheinfo; /* PUFFS_KFLAG_CACHE */ - - struct timespec pn_cn_ttl; /* PUFFS_FLAG_CACHE_FS_TTL */ - struct timespec pn_va_ttl; /* PUFFS_FLAG_CACHE_FS_TTL */ }; #define PUFFS_NODE_REMOVED 0x01 /* not on entry list */ @@ -236,8 +233,14 @@ struct puffs_ops { int, size_t *, uint8_t *, size_t *, int, const struct puffs_cred *); int (*puffs_node_deleteextattr)(struct puffs_usermount *, puffs_cookie_t, int, const char *, const struct puffs_cred *); + int (*puffs_node_getattr_ttl)(struct puffs_usermount *, + puffs_cookie_t, struct vattr *, const struct puffs_cred *, + struct timespec *); + int (*puffs_node_setattr_ttl)(struct puffs_usermount *, + puffs_cookie_t, struct vattr *, const struct puffs_cred *, + struct timespec *); - void *puffs_ops_spare[32]; + void *puffs_ops_spare[30]; }; typedef int (*pu_pathbuild_fn)(struct puffs_usermount *, @@ -384,7 +387,14 @@ enum { int, const struct puffs_cred *); \ int fsname##_node_deleteextattr(struct puffs_usermount *, \ puffs_cookie_t, int, const char *, \ - const struct puffs_cred *); + const struct puffs_cred *); \ + int fsname##_node_getattr_ttl(struct puffs_usermount *, \ + puffs_cookie_t, struct vattr *, const struct puffs_cred *, \ + struct timespec *); \ + int fsname##_node_setattr_ttl(struct puffs_usermount *, \ + puffs_cookie_t, struct vattr *, const struct puffs_cred *, \ + struct timespec *); + #define PUFFSOP_INIT(ops) \ ops = malloc(sizeof(struct puffs_ops)); \ @@ -494,6 +504,9 @@ void puffs_newinfo_setcookie(struct puff void puffs_newinfo_setvtype(struct puffs_newinfo *, enum vtype); void puffs_newinfo_setsize(struct puffs_newinfo *, voff_t); void puffs_newinfo_setrdev(struct puffs_newinfo *, dev_t); +void puffs_newinfo_setva(struct puffs_newinfo *, struct vattr *); +void puffs_newinfo_setvattl(struct puffs_newinfo *, struct timespec *); +void puffs_newinfo_setcnttl(struct puffs_newinfo *, struct timespec *); void *puffs_pn_getmntspecific(struct puffs_node *); Index: src/lib/libpuffs/puffs_ops.3 diff -u src/lib/libpuffs/puffs_ops.3:1.29 src/lib/libpuffs/puffs_ops.3:1.30 --- src/lib/libpuffs/puffs_ops.3:1.29 Mon Jul 4 08:07:30 2011 +++ src/lib/libpuffs/puffs_ops.3 Wed Apr 18 00:57:22 2012 @@ -1,4 +1,4 @@ -.\" $NetBSD: puffs_ops.3,v 1.29 2011/07/04 08:07:30 manu Exp $ +.\" $NetBSD: puffs_ops.3,v 1.30 2012/04/18 00:57:22 manu Exp $ .\" .\" Copyright (c) 2007 Antti Kantee. All rights reserved. .\" @@ -103,6 +103,16 @@ .Fa "const struct puffs_cred *pcr" .Fc .Ft int +.Fo puffs_node_getattr_ttl +.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "struct vattr *vap" +.Fa "const struct puffs_cred *pcr" "struct timespec *va_ttl" +.Fc +.Ft int +.Fo puffs_node_setattr_ttl +.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "const struct vattr *vap" +.Fa "const struct puffs_cred *pcr" "struct timespec *va_ttl" +.Fc +.Ft int .Fo puffs_node_poll .Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int *events" .Fc @@ -225,6 +235,12 @@ .Fn puffs_newinfo_setsize "struct puffs_newinfo *pni" "voff_t size" .Ft void .Fn puffs_newinfo_setrdev "struct puffs_newinfo *pni" "dev_t rdev" +.Ft void +.Fn puffs_newinfo_setva "struct puffs_newinfo *pni" "struct vattr *vap" +.Ft void +.Fn puffs_newinfo_setvattl "struct puffs_newinfo *pni" "struct timespec *va_ttl" +.Ft void +.Fn puffs_newinfo_setcnttl "struct puffs_newinfo *pni" "struct timespec *cn_ttl" .Sh DESCRIPTION The operations .Nm puffs @@ -370,6 +386,18 @@ If the located entry is a block device o the dev_t for the entry should be set using .Fn puffs_newinfo_setrdev . .Pp +If +.Fn puffs_init +was called with +.Dv PUFFS_KFLAG_CACHE_FS_TTL +then +.Fn puffs_newinfo_setva , +.Fn puffs_newinfo_setvattl , +and +.Fn puffs_newinfo_setcnttl +can be called to specify the new node attributes, cached attributes +time to live, and cached name timeto live. +.Pp The type of operation is found from .Va pcn-\*[Gt]pcn_nameiop : .Bl -tag -width XNAMEI_LOOKUPX @@ -478,6 +506,11 @@ The attributes of the node specified by .Fa opc must be copied to the space pointed by .Fa va . +.It Fn puffs_node_getattr_ttl "pu" "opc" "va" "pcr" "va_ttl" +Same as +.Fn puffs_node_getattr +with cached attribute time to live specified in +.Fa va_ttl .It Fn puffs_node_setattr "pu" "opc" "va" "pcr" The attributes for the node specified by .Fa opc @@ -488,6 +521,11 @@ Only fields of which contain a value different from .Dv PUFFS_VNOVAL (typecast to the field's type!) contain a valid value. +.It Fn puffs_node_setattr_ttl "pu" "opc" "va" "pcr" "va_ttl" +Same as +.Fn puffs_node_setattr +with cached attribute time to live specified in +.Fa va_ttl .It Fn puffs_node_poll "pu" "opc" "events" Poll for events on node .Ar opc . @@ -788,6 +826,46 @@ This call is valid only for and .Fn fhtovp producing device type nodes. +.It Fn puffs_newinfo_setva pni vap +Set the attributes for newly created vnode. This call is valid for +.Fn lookup , +.Fn create , +.Fn mkdir , +.Fn mknod , +and +.Fn symlink , +if +.Fn puffs_init +vas called with +.Dv PUFFS_KFLAG_CACHE_FS_TTL +flag set. +.It Fn puffs_newinfo_setvattl pni va_ttl +Set cached attribute time to live for newly created vnode. +This call is valid for +.Fn lookup , +.Fn create , +.Fn mkdir , +.Fn mknod , +and +.Fn symlink , +if +.Fn puffs_init +vas called with +.Dv PUFFS_KFLAG_CACHE_FS_TTL +flag set. +.It Fn puffs_newinfo_setcnttl pni cn_ttl +Set cached name time to live for newly created vnode. This call is valid for +.Fn lookup , +.Fn create , +.Fn mkdir , +.Fn mknod , +and +.Fn symlink , +if +.Fn puffs_init +vas called with +.Dv PUFFS_KFLAG_CACHE_FS_TTL +flag set. .El .Sh SEE ALSO .Xr puffs 3 , Index: src/lib/libpuffs/puffs_priv.h diff -u src/lib/libpuffs/puffs_priv.h:1.44 src/lib/libpuffs/puffs_priv.h:1.45 --- src/lib/libpuffs/puffs_priv.h:1.44 Mon Jun 20 09:11:17 2011 +++ src/lib/libpuffs/puffs_priv.h Wed Apr 18 00:57:22 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: puffs_priv.h,v 1.44 2011/06/20 09:11:17 mrg Exp $ */ +/* $NetBSD: puffs_priv.h,v 1.45 2012/04/18 00:57:22 manu Exp $ */ /* * Copyright (c) 2006, 2007, 2008 Antti Kantee. All Rights Reserved. @@ -199,6 +199,9 @@ struct puffs_newinfo { enum vtype *pni_vtype; voff_t *pni_size; dev_t *pni_rdev; + struct vattr *pni_va; + struct timespec *pni_va_ttl; + struct timespec *pni_cn_ttl; }; #define PUFFS_MAKEKCRED(to, from) \