static void test_rwalk (void) { Npfcall *fc, *fc2; struct p9_qid wqids [P9_MAXWELEM] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, { 10, 11, 12 }, { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, { 10, 11, 12 }, { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, { 10, 11, 12 }, { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, { 10, 11, 12 }, }; int i; assert (P9_MAXWELEM == 16); if (!(fc = np_create_rwalk (P9_MAXWELEM, wqids))) msg_exit ("out of memory in %s", __FUNCTION__); fc2 = _rcv_buf (fc, P9_RWALK, __FUNCTION__); assert (fc->u.rwalk.nwqid == P9_MAXWELEM); assert (fc->u.rwalk.nwqid == fc2->u.rwalk.nwqid); for (i = 0; i < P9_MAXWELEM; i++) { assert (fc->u.rwalk.wqids[i].type == fc2->u.rwalk.wqids[i].type); assert (fc->u.rwalk.wqids[i].version == fc2->u.rwalk.wqids[i].version); assert (fc->u.rwalk.wqids[i].path == fc2->u.rwalk.wqids[i].path); } free (fc); free (fc2); }
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; }
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; }