// -*- c++ -*- /* $Id: sfsrwsd.h,v 1.48 2001/07/18 03:02:18 dm Exp $ */ /* * * Copyright (C) 1998 David Mazieres (dm@uun.org) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * */ #include "qhash.h" #include "arpc.h" #include "vec.h" #include "getfh3.h" #include "sfsmisc.h" #include "crypt.h" #include "rabin.h" #include "seqno.h" #include "nfstrans.h" #include "sfsserv.h" #define FATTR3 fattr3exp typedef callback::ref cbb; inline bool operator== (const nfs_fh3 &a, const nfs_fh3 &b) { return a.data.size () == b.data.size () && !memcmp (a.data.base (), b.data.base (), b.data.size ()); } inline bool operator!= (const nfs_fh3 &a, const nfs_fh3 &b) { return !(a == b); } struct hashfh3 { hashfh3 () {} hash_t operator() (const nfs_fh3 &fh) const { const u_int32_t *s = reinterpret_cast (fh.data.base ()); const u_int32_t *e = s + (fh.data.size () >> 2); u_int32_t val = 0; while (s < e) val ^= *s++; return val; } }; struct filesys { str host; ptr c; filesys *parent; str path_root; // Local path corresponding to root str path_mntpt; // Mountpoint relative to exported namespace nfs_fh3 fh_root; // NFS File handle of root nfs_fh3 fh_mntpt; // NFS File handle of mount point u_int64_t fsid; // fsid of root u_int64_t fileid_root; // fileid of root u_int64_t fileid_root_dd; // fileid of root/.. u_int64_t fileid_mntpt; // fileid of mntpt u_int64_t fileid_mntpt_dd; // fileid of mntpt/.. enum { ANON_READ = 1, ANON_READWRITE = 3, }; u_int options; // Any of the above options ihash_entry mphl; typedef qhash inotab_t; typedef ihash mp3tab_t; mp3tab_t &mp3tab; inotab_t *inotab; filesys () : mp3tab (*New mp3tab_t), inotab (New inotab_t) {} }; class erraccum; struct synctab; class filesrv { public: struct reqstate { ptr c; u_int32_t fsno; bool rootfh; }; sfs_servinfo servinfo; sfs_hash hostid; ptr sk; ptr authxprt; ptr authclnt; vec fstab; blowfish fhkey; sfs_fsinfo fsinfo; u_int leasetime; private: typedef callback::ref cb_t; cb_t::ptr cb; struct getattr_state { int nleft; bool ok; }; PRIVDEST ~filesrv (); // No deleting /* Initialization functions */ int path2fsidx (str path, size_t nfs); void gotroot (ref ea, int i, ptr ni, str err); void gotroots (bool ok); void gotrootattr (ref ea, int i, const nfs_fh3 *fhp, const FATTR3 *attr, str err); void gotmp (ref ea, int i, const nfs_fh3 *fhp, const FATTR3 *attr, str err); void gotmps (bool ok); void gotrdres (ref, ref res, int i, bool mp, clnt_stat stat); void gotdds (bool ok); void fixrdres (void *res, filesys *fsp, bool rootfh); void fixrdplusres (void *res, filesys *fsp, bool rootfh); int fhsubst (bool *substp, filesys *pfsp, nfs_fh3 *fhp, u_int32_t *fsnop); size_t getfsno (const filesys *fsp) const { #ifdef CHECK_BOUNDS assert (fstab.base () <= fsp && fsp < fstab.lim ()); #endif /*CHECK_BOUNDS*/ return fsp - fstab.base (); } public: synctab *const st; void init (cb_t cb); bool fixarg (svccb *sbp, reqstate *fsnop); bool fixres (svccb *sbp, void *res, reqstate *fsnop); bool getauthclnt (); filesrv (); }; extern int sfssfd; class client : public virtual refcount, public sfsserv { filesrv *fsrv; ptr nfssrv; static u_int64_t nextgen (); void fail (); void nfs3dispatch (svccb *); void nfs3reply (svccb *sbp, void *res, filesrv::reqstate rqs, clnt_stat err); void renamecb_1 (svccb *sbp, void *res, filesrv::reqstate rqs, clnt_stat err); void renamecb_2 (svccb *sbp, rename3res *rres, filesrv::reqstate rqs, lookup3res *ares, clnt_stat err); protected: client (ref x); ~client (); ptr doconnect (const sfs_connectarg *, sfs_servinfo *); public: ptr nfscbc; const u_int64_t generation; ihash_entry glink; void sfs_getfsinfo (svccb *sbp); static void launch (ref x) { vNew refcounted (x); } filesrv *getfilesrv () const { return fsrv; } }; extern ihash clienttab; synctab *synctab_alloc (); void synctab_free (synctab *st); void dolease (filesrv *fsrv, u_int64_t cgen, u_int32_t fsno, xattr *xp); void doleases (filesrv *fsrv, u_int64_t cgen, u_int32_t fsno, svccb *sbp, void *res); bool fh3tosfs (nfs_fh3 *); bool fh3tonfs (nfs_fh3 *); void client_accept (ptr x); extern filesrv *defsrv; template inline str stat2str (T xstat, clnt_stat stat) { if (stat) return strbuf () << stat; else if (xstat) return strbuf () << xstat; else return NULL; }