Ejemplo n.º 1
0
Archivo: fs.c Proyecto: 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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
Archivo: null.c Proyecto: 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;
}
Ejemplo n.º 4
0
Archivo: null.c Proyecto: 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;
}
Ejemplo n.º 5
0
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);
}