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; }
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; }
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; }
/* 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; } }
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; }