diff --git a/share/examples/puffs/dtfs/dtfs.c b/share/examples/puffs/dtfs/dtfs.c index c499ec3f3627..c201d5c1385f 100644 --- a/share/examples/puffs/dtfs/dtfs.c +++ b/share/examples/puffs/dtfs/dtfs.c @@ -1,4 +1,4 @@ -/* $NetBSD: dtfs.c,v 1.16 2007/03/20 18:30:30 pooka Exp $ */ +/* $NetBSD: dtfs.c,v 1.17 2007/04/11 21:07:54 pooka Exp $ */ /* * Copyright (c) 2006 Antti Kantee. All Rights Reserved. @@ -112,6 +112,7 @@ main(int argc, char *argv[]) } if (pflags & PUFFS_FLAG_OPDUMP) lflags |= PUFFSLOOP_NODAEMON; + pflags |= PUFFS_KFLAG_CANEXPORT; argc -= optind; argv += optind; @@ -123,6 +124,8 @@ main(int argc, char *argv[]) PUFFSOP_SET(pops, dtfs, fs, statvfs); PUFFSOP_SETFSNOP(pops, unmount); PUFFSOP_SETFSNOP(pops, sync); + PUFFSOP_SET(pops, dtfs, fs, fhtonode); + PUFFSOP_SET(pops, dtfs, fs, nodetofh); PUFFSOP_SET(pops, dtfs, fs, suspend); PUFFSOP_SET(pops, dtfs, node, lookup); @@ -144,6 +147,8 @@ main(int argc, char *argv[]) PUFFSOP_SET(pops, dtfs, node, inactive); PUFFSOP_SET(pops, dtfs, node, reclaim); + srandom(time(NULL)); /* for random generation numbers */ + if ((pu = puffs_mount(pops, argv[0], mntflags, FSNAME, &dtm, pflags, 0)) == NULL) err(1, "mount"); diff --git a/share/examples/puffs/dtfs/dtfs.h b/share/examples/puffs/dtfs/dtfs.h index 17bbb9460732..b3b99dd84657 100644 --- a/share/examples/puffs/dtfs/dtfs.h +++ b/share/examples/puffs/dtfs/dtfs.h @@ -1,4 +1,4 @@ -/* $NetBSD: dtfs.h,v 1.13 2007/04/10 13:32:02 pooka Exp $ */ +/* $NetBSD: dtfs.h,v 1.14 2007/04/11 21:07:54 pooka Exp $ */ /* * Copyright (c) 2006 Antti Kantee. All Rights Reserved. @@ -44,6 +44,7 @@ int dtfs_domount(struct puffs_usermount *); #define ROUNDUP(a,b) ((a) & ((b)-1)) #define BLOCKNUM(a,b) (((a) & ~((1<<(b))-1)) >> (b)) +struct dtfs_fid; struct dtfs_mount { ino_t dtm_nextfileid; /* running number for file id */ @@ -82,6 +83,15 @@ struct dtfs_dirent { LIST_ENTRY(dtfs_dirent) dfd_entries; }; +struct dtfs_fid { + struct puffs_node *dfid_addr; + + /* best^Wsome-effort extra sanity check */ + ino_t dfid_fileid; + u_long dfid_gen; +}; +#define DTFS_FIDSIZE (sizeof(struct dtfs_fid)) + struct puffs_node * dtfs_genfile(struct puffs_node *, const struct puffs_cn *, enum vtype); struct dtfs_file * dtfs_newdir(void); diff --git a/share/examples/puffs/dtfs/dtfs_subr.c b/share/examples/puffs/dtfs/dtfs_subr.c index b1020d308b05..1795653cf725 100644 --- a/share/examples/puffs/dtfs/dtfs_subr.c +++ b/share/examples/puffs/dtfs/dtfs_subr.c @@ -1,4 +1,4 @@ -/* $NetBSD: dtfs_subr.c,v 1.13 2007/04/01 10:55:38 pooka Exp $ */ +/* $NetBSD: dtfs_subr.c,v 1.14 2007/04/11 21:07:54 pooka Exp $ */ /* * Copyright (c) 2006 Antti Kantee. All Rights Reserved. @@ -64,7 +64,7 @@ dtfs_baseattrs(struct vattr *vap, enum vtype type, ino_t id) vap->va_fileid = id; vap->va_size = 0; vap->va_blocksize = getpagesize(); - vap->va_gen = 1; + vap->va_gen = random(); vap->va_flags = 0; vap->va_rdev = PUFFS_VNOVAL; vap->va_bytes = 0; diff --git a/share/examples/puffs/dtfs/dtfs_vfsops.c b/share/examples/puffs/dtfs/dtfs_vfsops.c index 7447462457f3..0ed1f3af3863 100644 --- a/share/examples/puffs/dtfs/dtfs_vfsops.c +++ b/share/examples/puffs/dtfs/dtfs_vfsops.c @@ -1,4 +1,4 @@ -/* $NetBSD: dtfs_vfsops.c,v 1.11 2007/01/26 23:02:05 pooka Exp $ */ +/* $NetBSD: dtfs_vfsops.c,v 1.12 2007/04/11 21:07:54 pooka Exp $ */ /* * Copyright (c) 2006 Antti Kantee. All Rights Reserved. @@ -142,6 +142,59 @@ dtfs_fs_statvfs(struct puffs_cc *pcc, struct statvfs *sbp, pid_t pid) } #undef ROUND +static void * +addrcmp(struct puffs_usermount *pu, struct puffs_node *pn, void *arg) +{ + + if (pn == arg) + return pn; + + return NULL; +} + +int +dtfs_fs_fhtonode(struct puffs_cc *pcc, void *fid, size_t fidsize, + void **fcookie, enum vtype *ftype, voff_t *fsize, dev_t *fdev) +{ + struct puffs_usermount *pu = puffs_cc_getusermount(pcc); + struct dtfs_fid *dfid; + struct puffs_node *pn; + + dfid = fid; + + pn = puffs_pn_nodewalk(pu, addrcmp, dfid->dfid_addr); + if (pn == NULL) + return EINVAL; + + if (pn->pn_va.va_fileid != dfid->dfid_fileid + || pn->pn_va.va_gen != dfid->dfid_gen) + return EINVAL; + + *fcookie = pn; + *ftype = pn->pn_va.va_type; + *fsize = pn->pn_va.va_size; + *fdev = pn->pn_va.va_rdev; + + return 0; +} + +int +dtfs_fs_nodetofh(struct puffs_cc *pcc, void *cookie, + void *fid, size_t *fidsize) +{ + struct puffs_node *pn = cookie; + struct dtfs_fid *dfid; + + memset(fid, 0xff, PUFFS_FHSIZE); + dfid = fid; + + dfid->dfid_addr = pn; + dfid->dfid_fileid = pn->pn_va.va_fileid; + dfid->dfid_gen = pn->pn_va.va_gen; + + return 0; +} + void dtfs_fs_suspend(struct puffs_cc *pcc, int status) { diff --git a/share/examples/puffs/dtfs/dtfs_vnops.c b/share/examples/puffs/dtfs/dtfs_vnops.c index 50a9d0f7a913..867cb65a8243 100644 --- a/share/examples/puffs/dtfs/dtfs_vnops.c +++ b/share/examples/puffs/dtfs/dtfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: dtfs_vnops.c,v 1.21 2007/04/10 13:32:02 pooka Exp $ */ +/* $NetBSD: dtfs_vnops.c,v 1.22 2007/04/11 21:07:54 pooka Exp $ */ /* * Copyright (c) 2006 Antti Kantee. All Rights Reserved. @@ -226,29 +226,39 @@ dtfs_node_rmdir(struct puffs_cc *pcc, void *opc, void *targ, int dtfs_node_readdir(struct puffs_cc *pcc, void *opc, - struct dirent *dent, const struct puffs_cred *pcr, off_t *readoff, - size_t *reslen) + struct dirent *dent, off_t *readoff, size_t *reslen, + const struct puffs_cred *pcr, + int *eofflag, off_t *cookies, size_t *ncookies) { struct puffs_node *pn = opc; struct puffs_node *pn_nth; struct dtfs_dirent *dfd_nth; + size_t maxcookies = *ncookies; if (pn->pn_va.va_type != VDIR) return ENOTDIR; dtfs_updatetimes(pn, 1, 0, 0); + *ncookies = 0; again: if (*readoff == DENT_DOT || *readoff == DENT_DOTDOT) { puffs_gendotdent(&dent, pn->pn_va.va_fileid, *readoff, reslen); + if (cookies) { + *(cookies++) = *readoff; + (*ncookies)++; + assert(*ncookies <= maxcookies); + } (*readoff)++; goto again; } for (;;) { dfd_nth = dtfs_dirgetnth(pn->pn_data, DENT_ADJ(*readoff)); - if (!dfd_nth) + if (!dfd_nth) { + *eofflag = 1; return 0; + } pn_nth = dfd_nth->dfd_node; if (!puffs_nextdent(&dent, dfd_nth->dfd_name, @@ -256,6 +266,11 @@ dtfs_node_readdir(struct puffs_cc *pcc, void *opc, puffs_vtype2dt(pn_nth->pn_va.va_type), reslen)) return 0; + if (cookies) { + *(cookies++) = *readoff; + (*ncookies)++; + assert(*ncookies <= maxcookies); + } (*readoff)++; } }