/*ARGSUSED*/ int puffs_null_node_getattr(struct puffs_usermount *pu, puffs_cookie_t opc, struct vattr *va, const struct puffs_cred *pcred) { struct puffs_node *pn = opc; struct stat sb; if (lstat(PNPATH(pn), &sb) == -1) return errno; puffs_stat2vattr(va, &sb); return 0; }
static int makenode(struct puffs_usermount *pu, struct puffs_newinfo *pni, const struct puffs_cn *pcn, const struct vattr *va, int regular) { struct puffs_node *pn; struct stat sb; int rv; if ((rv = processvattr(PCNPATH(pcn), va, regular)) != 0) return rv; pn = puffs_pn_new(pu, NULL); if (!pn) return ENOMEM; puffs_setvattr(&pn->pn_va, va); if (lstat(PCNPATH(pcn), &sb) == -1) return errno; puffs_stat2vattr(&pn->pn_va, &sb); puffs_newinfo_setcookie(pni, pn); return 0; }
int puffs_null_node_lookup(struct puffs_usermount *pu, puffs_cookie_t opc, struct puffs_newinfo *pni, const struct puffs_cn *pcn) { struct puffs_node *pn = opc, *pn_res; struct stat sb; int rv; assert(pn->pn_va.va_type == VDIR); /* * Note to whoever is copypasting this: you must first check * if the node is there and only then do nodewalk. Alternatively * you could make sure that you don't return unlinked/rmdir'd * nodes in some other fashion */ rv = lstat(PCNPATH(pcn), &sb); if (rv) return errno; /* XXX2: nodewalk is a bit too slow here */ pn_res = puffs_pn_nodewalk(pu, inodecmp, &sb.st_ino); if (pn_res == NULL) { pn_res = puffs_pn_new(pu, NULL); if (pn_res == NULL) return ENOMEM; puffs_stat2vattr(&pn_res->pn_va, &sb); } puffs_newinfo_setcookie(pni, pn_res); puffs_newinfo_setvtype(pni, pn_res->pn_va.va_type); puffs_newinfo_setsize(pni, (off_t)pn_res->pn_va.va_size); puffs_newinfo_setrdev(pni, pn_res->pn_va.va_rdev); return 0; }
int main(int argc, char *argv[]) { struct puffs_usermount *pu; struct puffs_ops *pops; struct puffs_pathobj *po_root; struct puffs_node *pn_root; struct stat sb; int mntflags, pflags; int ch; int detach; setprogname(argv[0]); if (argc < 3) usage(); pflags = mntflags = 0; detach = 1; while ((ch = getopt(argc, argv, "o:s")) != -1) { switch (ch) { case 'o': getmntopts(optarg, puffsmopts, &mntflags, &pflags); break; case 's': detach = 0; break; } } pflags |= PUFFS_FLAG_BUILDPATH; argv += optind; argc -= optind; if (pflags & PUFFS_FLAG_OPDUMP) detach = 0; if (argc != 2) usage(); if (lstat(argv[0], &sb) == -1) err(1, "stat %s", argv[0]); if ((sb.st_mode & S_IFDIR) == 0) errx(1, "%s is not a directory", argv[0]); PUFFSOP_INIT(pops); puffs_null_setops(pops); if ((pu = puffs_init(pops, argv[0], "pnullfs", NULL, pflags)) == NULL) err(1, "init"); pn_root = puffs_pn_new(pu, NULL); if (pn_root == NULL) err(1, "puffs_pn_new"); puffs_setroot(pu, pn_root); puffs_setfhsize(pu, 0, PUFFS_FHFLAG_PASSTHROUGH); po_root = puffs_getrootpathobj(pu); if (po_root == NULL) err(1, "getrootpathobj"); po_root->po_path = argv[0]; po_root->po_len = strlen(argv[0]); puffs_stat2vattr(&pn_root->pn_va, &sb); if (detach) if (puffs_daemon(pu, 1, 1) == -1) err(1, "puffs_daemon"); if (puffs_mount(pu, argv[1], mntflags, pn_root) == -1) err(1, "puffs_mount"); if (puffs_mainloop(pu) == -1) err(1, "mainloop"); return 0; }