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) \