예제 #1
0
파일: srv.c 프로젝트: ericvh/npfs-dirtab
static Npfcall *
np_auth(Npreq *req, Npfcall *tc)
{
	Npconn *conn;
	Npfid *afid;
	Npfcall *rc;

	rc = NULL;
	conn = req->conn;
	afid = np_fid_find(conn, tc->afid);
	if (afid) {
		np_werror(Einuse, EIO);
		goto done;
	}

	afid = np_fid_create(conn, tc->afid, NULL);
	if (!afid) {
		np_werror(Enomem, ENOMEM);
		goto done;
	}

	if (conn->srv->auth)
		rc = (*conn->srv->auth->auth)(afid, &tc->uname, &tc->aname);
	else
		np_werror(Enoauth, EIO);

	afid->type = Qtauth;
done:
	np_fid_decref(afid);
	return rc;
}
예제 #2
0
파일: srv.c 프로젝트: ericvh/npfs-dirtab
static Npfcall *
np_attach(Npreq *req, Npfcall *tc)
{
	Npconn *conn;
	Npfid *fid, *afid;
	Npfcall *rc;

	rc = NULL;
	conn = req->conn;
	afid = NULL;

	/* the fid that the connecting client wants to call root  */
	fid = np_fid_find(conn, tc->fid);

	/* if this fid exists then report error  */
	if (fid) {
		np_werror(Einuse, EIO);
		goto done;
	}

	/* create a fid structure for the root   */
	fid = np_fid_create(conn, tc->fid, NULL);
	if (!fid) {
		np_werror(Enomem, ENOMEM);
		goto done;
	} else 
	  /* maintain a reference count for fid   */
		np_fid_incref(fid);

	req->fid = fid;
	afid = np_fid_find(conn, tc->afid);
	if (!afid) {
		if (tc->afid!=NOFID) {
			np_werror(Eunknownfid, EIO);
			goto done;
		}

		if (!afid->type&Qtauth) {
			np_werror(Ebadusefid, EIO);
			goto done;
		}
	} else 
		np_fid_incref(afid);

	if (conn->srv->auth) {
		rc = (*conn->srv->auth->attach)(afid, &tc->uname, &tc->aname);
		if (rc)
			goto done;
	}

	rc = (*conn->srv->attach)(fid, afid, &tc->uname, &tc->aname);

done:
	np_fid_decref(fid);
	np_fid_decref(afid);
	return rc;
}
예제 #3
0
파일: srv.c 프로젝트: ericvh/npfs-dirtab
static Npfcall *
np_walk(Npreq *req, Npfcall *tc)
{
	int i;
	Npconn *conn;
	Npfid *fid, *newfid;
	Npfcall *rc;
	Npqid wqids[MAXWELEM];

	rc = NULL;
	conn = req->conn;
	newfid = NULL;
	fid = np_fid_find(conn, tc->fid);
	if (!fid) {
		np_werror(Eunknownfid, EIO);
		goto done;
	} else 
		np_fid_incref(fid);

	req->fid = fid;
	if (!fid->type&Qtdir) {
		np_werror(Enotdir, ENOTDIR);
		goto done;
	}

	if (fid->omode != (u16) ~0) {
		np_werror(Ebadusefid, EIO);
		goto done;
	}

	if (tc->nwname > MAXWELEM) {
		np_werror(Etoomanywnames, EIO);
		goto done;
	}

	if (tc->fid != tc->newfid) {
		newfid = np_fid_find(conn, tc->newfid);
		if (newfid) {
			np_werror(Einuse, EIO);
			goto done;
		}
		newfid = np_fid_create(conn, tc->newfid, NULL);
		if (!newfid) {
			np_werror(Enomem, ENOMEM);
			goto done;
		}

		if (!(*conn->srv->clone)(fid, newfid))
			goto done;

		newfid->user = fid->user;
		newfid->type = fid->type;
	} else
		newfid = fid;

	np_fid_incref(newfid);
	for(i = 0; i < tc->nwname;) {
		if (!(*conn->srv->walk)(newfid, &tc->wnames[i], &wqids[i]))
			break;

		newfid->type = wqids[i].type;
		i++;

		if (i<(tc->nwname) && !newfid->type&Qtdir)
			break;
	}

	if (i==0 && tc->nwname!=0)
		goto done;

	np_werror(NULL, 0);
	if (tc->fid != tc->newfid)
		np_fid_incref(newfid);
	rc = np_create_rwalk(i, wqids);

done:
	np_fid_decref(fid);
	np_fid_decref(newfid);
	return rc;
}
예제 #4
0
/* Look up operation's fid and assign it to req->fid.
 * This is done before the request is handed off to a worker, with
 * the plan of using fid data in scheduling work.
 * The fid refcount is incremented here, then decremented in
 * np_process_request ().
 */
static void
np_preprocess_request(Npreq *req)
{
	Npfcall *tc = req->tcall;
	Npconn *conn = req->conn;

	switch (tc->type) {
		case P9_TSTATFS:
			req->fid = np_fid_find (conn, tc->u.tstatfs.fid);
			break;
		case P9_TLOPEN:
			req->fid = np_fid_find (conn, tc->u.tlopen.fid);
			break;
		case P9_TLCREATE:
			req->fid = np_fid_find (conn, tc->u.tlcreate.fid);
			break;
		case P9_TSYMLINK:
			req->fid = np_fid_find (conn, tc->u.tsymlink.fid);
			break;
		case P9_TMKNOD:
			req->fid = np_fid_find (conn, tc->u.tmknod.fid);
			break;
		case P9_TRENAME:
			req->fid = np_fid_find (conn, tc->u.trename.fid);
			break;
		case P9_TREADLINK:
			req->fid = np_fid_find (conn, tc->u.treadlink.fid);
			break;
		case P9_TGETATTR:
			req->fid = np_fid_find (conn, tc->u.tgetattr.fid);
			break;
		case P9_TSETATTR:
			req->fid = np_fid_find (conn, tc->u.tsetattr.fid);
			break;
		case P9_TXATTRWALK:
			req->fid = np_fid_find (conn, tc->u.txattrwalk.fid);
			break;
		case P9_TXATTRCREATE:
			req->fid = np_fid_find (conn, tc->u.txattrcreate.fid);
			break;
		case P9_TREADDIR:
			req->fid = np_fid_find (conn, tc->u.treaddir.fid);
			break;
		case P9_TFSYNC:
			req->fid = np_fid_find (conn, tc->u.tfsync.fid);
			break;
		case P9_TLOCK:
			req->fid = np_fid_find (conn, tc->u.tlock.fid);
			break;
		case P9_TGETLOCK:
			req->fid = np_fid_find (conn, tc->u.tgetlock.fid);
			break;
		case P9_TLINK:
			req->fid = np_fid_find (conn, tc->u.tlink.dfid);
			break;
		case P9_TMKDIR:
			req->fid = np_fid_find (conn, tc->u.tmkdir.fid);
			break;
		case P9_TVERSION:
			break;
		case P9_TAUTH:
			req->fid = np_fid_create (conn, tc->u.tauth.afid);
			if (!req->fid)
				break;
			req->fid->aname = np_strdup (&tc->u.tauth.aname);
			if (!req->fid->aname)
				np_fid_decref (&req->fid);
			/* XXX leave fid->tpool NULL for now as auth
			 * can be handled in the default thread pool
			 * without risk of deadlock.
			 */
			break;
		case P9_TATTACH:
			req->fid = np_fid_create (conn, tc->u.tattach.fid);
			if (!req->fid)
				break;
			req->fid->aname = np_strdup (&tc->u.tattach.aname);
			if (!req->fid->aname)
				np_fid_decref (&req->fid);
			/* Here we select the tpool that will handle this
			 * request and requests on fids walked from this fid.
			 */
			np_tpool_select (req);
			break;
		case P9_TFLUSH:
			break;
		case P9_TWALK:
			req->fid = np_fid_find (conn, tc->u.twalk.fid);
			break;
		case P9_TREAD:
			req->fid = np_fid_find (conn, tc->u.tread.fid);
			break;
		case P9_TWRITE:
			req->fid = np_fid_find (conn, tc->u.twrite.fid);
			break;
		case P9_TCLUNK:
			req->fid = np_fid_find (conn, tc->u.tclunk.fid);
			break;
		case P9_TREMOVE:
			req->fid = np_fid_find (conn, tc->u.tremove.fid);
			break;
		case P9_TRENAMEAT:
			req->fid = np_fid_find (conn,
						tc->u.trenameat.olddirfid);
			break;
		case P9_TUNLINKAT:
			req->fid = np_fid_find (conn, tc->u.tunlinkat.dirfid);
			break;
		default:
			break;
	}
}
예제 #5
0
Npfcall *
np_walk(Npreq *req, Npfcall *tc)
{
	int i;
	Npconn *conn = req->conn;
	Npfid *fid = req->fid;
	Npfid *newfid = NULL;
	Npfcall *rc = NULL;
	Npqid wqids[P9_MAXWELEM];

	if (!fid) {
		np_uerror (EIO);
		goto done;
	}
#if 0
	if (!(fid->type & P9_QTDIR)) {
		np_uerror(ENOTDIR);
		goto done;
	}
#endif
	/* FIXME: error if fid has been opened */
	if (tc->u.twalk.nwname > P9_MAXWELEM) {
		np_uerror(EIO);
		goto done;
	}

	if (tc->u.twalk.fid != tc->u.twalk.newfid) {
		newfid = np_fid_find(conn, tc->u.twalk.newfid);
		if (newfid) {
			np_uerror(EIO);
			goto done;
		}
		newfid = np_fid_create(conn, tc->u.twalk.newfid, NULL);
		if (!newfid)
			goto done;
		if (fid->type & P9_QTTMP) {
			if (!np_ctl_clone (fid, newfid))
				goto done;
		} else {
			if (!conn->srv->clone)
				goto done;
			if (!(*conn->srv->clone)(fid, newfid))
				goto done;
		}
		np_user_incref(fid->user);
		newfid->user = fid->user;
		np_tpool_incref(fid->tpool);
		newfid->tpool = fid->tpool;
		newfid->type = fid->type;
		if (!(newfid->aname = strdup (fid->aname))) {
			np_uerror (ENOMEM);
			goto done;
		}
	} else
		newfid = fid;

	np_fid_incref(newfid);
	if (!(newfid->type & P9_QTTMP)) {
		if (np_setfsid (req, newfid->user, -1) < 0)
			goto done;
	}
	for(i = 0; i < tc->u.twalk.nwname;) {
		if (newfid->type & P9_QTTMP) {
			if (!np_ctl_walk (newfid, &tc->u.twalk.wnames[i],
					  &wqids[i]))
				break;
		} else {
			if (!conn->srv->walk) {
				np_uerror (ENOSYS);
				break;
			}
			if (!(*conn->srv->walk)(newfid, &tc->u.twalk.wnames[i],
						&wqids[i]))
				break;
		}
		newfid->type = wqids[i].type;
		i++;
		if (i<(tc->u.twalk.nwname) && !(newfid->type & P9_QTDIR))
			break;
	}

	if (i==0 && tc->u.twalk.nwname!=0)
		goto done;

	np_uerror(0);
	if (tc->u.twalk.fid != tc->u.twalk.newfid)
		np_fid_incref(newfid);
	rc = np_create_rwalk(i, wqids);

done:
	np_fid_decref(newfid);
	return rc;
}