예제 #1
0
int
sysctlfs_fs_fhtonode(struct puffs_usermount *pu, void *fid, size_t fidsize,
	struct puffs_newinfo *pni)
{
	struct puffs_pathobj po;
	struct puffs_node *pn;
	struct sfsnode *sfs;
	struct sfsfid *sfid;

	sfid = fid;

	po.po_len = sfid->len;
	po.po_path = &sfid->path;

	pn = getnode(pu, &po, 0);
	if (pn == NULL)
		return EINVAL;
	sfs = pn->pn_data;

	puffs_newinfo_setcookie(pni, pn);
	if (ISADIR(sfs))
		puffs_newinfo_setvtype(pni, VDIR);
	else
		puffs_newinfo_setvtype(pni, VREG);

	return 0;
}
예제 #2
0
파일: dtfs_vnops.c 프로젝트: 2asoft/freebsd
int
dtfs_node_lookup(struct puffs_usermount *pu, void *opc,
	struct puffs_newinfo *pni, const struct puffs_cn *pcn)
{
	struct puffs_node *pn_dir = opc;
	struct dtfs_file *df = DTFS_CTOF(opc);
	struct dtfs_dirent *dfd;
	extern int straightflush;
	int rv;

	/* parent dir? */
	if (PCNISDOTDOT(pcn)) {
		if (df->df_dotdot == NULL)
			return ENOENT;

		assert(df->df_dotdot->pn_va.va_type == VDIR);
		puffs_newinfo_setcookie(pni, df->df_dotdot);
		puffs_newinfo_setvtype(pni, df->df_dotdot->pn_va.va_type);

		return 0;
	}

	dfd = dtfs_dirgetbyname(df, pcn->pcn_name, pcn->pcn_namelen);
	if (dfd) {
		if ((pcn->pcn_flags & NAMEI_ISLASTCN) &&
		    (pcn->pcn_nameiop == NAMEI_DELETE)) {
			rv = puffs_access(VDIR, pn_dir->pn_va.va_mode,
			    pn_dir->pn_va.va_uid, pn_dir->pn_va.va_gid,
			    PUFFS_VWRITE, pcn->pcn_cred);
			if (rv)
				return rv;
		}
		puffs_newinfo_setcookie(pni, dfd->dfd_node);
		puffs_newinfo_setvtype(pni, dfd->dfd_node->pn_va.va_type);
		puffs_newinfo_setsize(pni, dfd->dfd_node->pn_va.va_size);
		puffs_newinfo_setrdev(pni, dfd->dfd_node->pn_va.va_rdev);

		if (straightflush)
			puffs_flush_pagecache_node(pu, dfd->dfd_node);

		return 0;
	}

	if ((pcn->pcn_flags & NAMEI_ISLASTCN)
	    && (pcn->pcn_nameiop == NAMEI_CREATE ||
	        pcn->pcn_nameiop == NAMEI_RENAME)) {
		rv = puffs_access(VDIR, pn_dir->pn_va.va_mode,
		    pn_dir->pn_va.va_uid, pn_dir->pn_va.va_gid,
		    PUFFS_VWRITE, pcn->pcn_cred);
		if (rv)
			return rv;
	}

	return ENOENT;
}
예제 #3
0
int
sysctlfs_node_lookup(struct puffs_usermount *pu, void *opc,
	struct puffs_newinfo *pni, const struct puffs_cn *pcn)
{
	struct puffs_cn *p2cn = __UNCONST(pcn); /* XXX: fix the interface */
	struct sysctlnode sn[SFS_NODEPERDIR];
	struct sysctlnode qnode;
	struct puffs_node *pn_dir = opc;
	struct puffs_node *pn_new;
	struct sfsnode *sfs_dir = pn_dir->pn_data, *sfs_new;
	SfsName *sname = PCNPATH(pcn);
	size_t sl, i;
	int nodetype;

	assert(ISADIR(sfs_dir));

	/*
	 * If we're looking for dotdot, we already have the entire pathname
	 * in sname, courtesy of pathbuild, so we can skip this step.
	 */
	if (!PCNISDOTDOT(pcn)) {
		memset(&qnode, 0, sizeof(qnode));
		sl = SFS_NODEPERDIR * sizeof(struct sysctlnode);
		qnode.sysctl_flags = SYSCTL_VERSION;
		(*sname)[PCNPLEN(pcn)] = CTL_QUERY;

		if (sysctl(*sname, PCNPLEN(pcn) + 1, sn, &sl,
		    &qnode, sizeof(qnode)) == -1)
			return ENOENT;

		for (i = 0; i < sl / sizeof(struct sysctlnode); i++)
			if (strcmp(sn[i].sysctl_name, pcn->pcn_name) == 0)
				break;
		if (i == sl / sizeof(struct sysctlnode))
			return ENOENT;

		(*sname)[PCNPLEN(pcn)] = sn[i].sysctl_num;
		p2cn->pcn_po_full.po_len++;
		nodetype = sn[i].sysctl_flags;
	} else
		nodetype = CTLTYPE_NODE;

	pn_new = getnode(pu, &p2cn->pcn_po_full, nodetype);
	sfs_new = pn_new->pn_data;

	puffs_newinfo_setcookie(pni, pn_new);
	if (ISADIR(sfs_new))
		puffs_newinfo_setvtype(pni, VDIR);
	else
		puffs_newinfo_setvtype(pni, VREG);

	return 0;
}
예제 #4
0
파일: fs.c 프로젝트: glk/puffs
int
psshfs_fs_fhtonode(struct puffs_usermount *pu, void *fid, size_t fidsize,
	struct puffs_newinfo *pni)
{
	struct psshfs_ctx *pctx = puffs_getspecific(pu);
	struct psshfs_fid *pf = fid;
	struct puffs_node *pn = pf->node;
	struct psshfs_node *psn;
	int rv;

	if (pf->mounttime != pctx->mounttime)
		return EINVAL;
	if (pn == 0)
		return EINVAL;
	psn = pn->pn_data;
	if ((psn->stat & PSN_HASFH) == 0)
		return EINVAL;

	/* update node attributes */
	rv = getnodeattr(pu, pn);
	if (rv)
		return EINVAL;

	puffs_newinfo_setcookie(pni, pn);
	puffs_newinfo_setvtype(pni, pn->pn_va.va_type);
	puffs_newinfo_setsize(pni, pn->pn_va.va_size);

	return 0;
}
예제 #5
0
파일: null.c 프로젝트: glk/puffs
/*ARGSUSED*/
int
puffs_null_fs_fhtonode(struct puffs_usermount *pu, void *fid, size_t fidsize,
	struct puffs_newinfo *pni)
{
	struct puffs_node *pn_res;

	if (fidsize != sizeof(struct fid))
		return EINVAL;

	pn_res = puffs_pn_nodewalk(pu, fhcmp, fid);
	if (pn_res == NULL)
		return ENOENT;

	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;
}
예제 #6
0
파일: null.c 프로젝트: glk/puffs
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;
}
예제 #7
0
파일: node.c 프로젝트: ryo/netbsd-src
int
puffs9p_node_lookup(struct puffs_usermount *pu, void *opc, struct puffs_newinfo *pni,
	const struct puffs_cn *pcn)
{
	AUTOVAR(pu);
	struct vattr va;
	struct puffs_node *pn, *pn_dir = opc;
	struct p9pnode *p9n_dir = pn_dir->pn_data;
	p9ptag_t tfid = NEXTFID(p9p);
	struct qid9p newqid;
	uint16_t nqid;

	p9pbuf_put_1(pb, P9PROTO_T_WALK);
	p9pbuf_put_2(pb, tag);
	p9pbuf_put_4(pb, p9n_dir->fid_base);
	p9pbuf_put_4(pb, tfid);
	p9pbuf_put_2(pb, 1);
	p9pbuf_put_str(pb, pcn->pcn_name);
	GETRESPONSE(pb);

	rv = proto_expect_walk_nqids(pb, &nqid);
	if (rv) {
		rv = ENOENT;
		goto out;
	}
	if (nqid != 1) {
		rv = EPROTO;
		goto out;
	}
	if ((rv = proto_getqid(pb, &newqid)))
		goto out;

	/* we get the parent vers in walk(?)  compensate */
	p9pbuf_recycleout(pb);
	tag = NEXTTAG(p9p);
	p9pbuf_put_1(pb, P9PROTO_T_STAT);
	p9pbuf_put_2(pb, tag);
	p9pbuf_put_4(pb, tfid);
	GETRESPONSE(pb);
	if ((rv = proto_expect_stat(pb, &va)) != 0) {
		proto_cc_clunkfid(pu, tfid, 0);
		rv = ENOENT;
		goto out;
	}
	if (newqid.qidpath != va.va_fileid) {
		proto_cc_clunkfid(pu, tfid, 0);
		rv = EPROTO;
		goto out;
	}
	newqid.qidvers = va.va_gen;

	pn = puffs_pn_nodewalk(pu, nodecmp, &newqid);
	if (pn == NULL)
		pn = newp9pnode_qid(pu, &newqid, tfid);
	else
		proto_cc_clunkfid(pu, tfid, 0);
	/* assert pn */
	memcpy(&pn->pn_va, &va, sizeof(va));

	puffs_newinfo_setcookie(pni, pn);
	puffs_newinfo_setvtype(pni, pn->pn_va.va_type);
	puffs_newinfo_setsize(pni, pn->pn_va.va_size);
	puffs_newinfo_setrdev(pni, pn->pn_va.va_rdev);

 out:
	RETURN(rv);
}