// -*-c++-*- /* $Id: sfsrocd.h,v 1.25 2002/01/11 16:33:18 fubob Exp $ */ /* * * Copyright (C) 2000, 2001 Kevin Fu (fubob@mit.edu) * Copyright (C) 1998, 2000 David Mazieres (dm@uun.org) * Copyright (C) 1999 Frans Kaashoek (kaashoek@mit.edu) * * 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 * */ #ifndef _SFSROCD_H_ #define _SFSROCD_H_ 1 #include "arpc.h" #include "nfs3_prot.h" #include "sfscd_prot.h" #include "sfsmisc.h" #include "sfsro_prot.h" #include "qhash.h" #include "itree.h" #include "crypt.h" #include "list.h" #include "sfsclient.h" #include "nfstrans.h" #include "cache.h" #include "qhash.h" // Profiling for development struct cache_stat { u_int32_t namec_hit; u_int32_t namec_miss; u_int32_t namec_tot; u_int32_t directoryc_hit; u_int32_t directoryc_miss; u_int32_t directoryc_tot; u_int32_t iblockc_hit; u_int32_t iblockc_miss; u_int32_t iblockc_tot; u_int32_t blockc_hit; u_int32_t blockc_miss; u_int32_t blockc_tot; }; extern cache_stat cstat; #ifdef MAINTAINER extern const bool sfsrocd_noverify; extern const bool sfsrocd_nocache; extern const bool sfsrocd_cache_stat; #else /* !MAINTAINER */ enum { sfsrocd_noverify = 0, sfsrocd_nocache = 0, sfsrocd_cache_stat = 0 }; #endif /* !MAINTAINER */ class filesys; typedef callback >::ref cb_nfs_fh3_t; typedef callback >::ref cb_fattr3_t; typedef callback::ref cb_str_t; typedef callback >::ref cb_sfsro_data_t; typedef callback >::ref cb_sfsro_inode_t; typedef callback >::ref cb_sfsro_directory_t; typedef callback > >::ref cb_rpc_bytes_t; typedef callback >::ref cb_sfsro_indirect_t; typedef callback >::ref cb_ptr_sfs_hash_t; typedef callback >::ref cb_sfs_hash_t; // callbacks that include NFS error conditions #if 0 typedef callback, nfsstat3 stat>::ref cb_stat_nfs_fh3_t; typedef callback, nfsstat3 stat>::ref cb_stat_fattr3_t; #endif /* Rep invariant: no name cache entry can have a partially filled name_dat. The fh, ip, and fa must be set before adding to cache */ struct name_dat { const ref fh; ref ip; ref fa; name_dat (const ref fhfh, ref ipip, ref fafa) : fh (fhfh), ip (ipip), fa (fafa) { } }; typedef callback >::ref cb_ref_name_dat_t; typedef callback >::ref cb_ptr_name_dat_t; /* SFSRO directory info */ struct dir_dat { ref cookieverf; ref reply; ref nd; dir_dat (ref cv, ref dl, ref ndnd) : cookieverf (cv), reply (dl), nd (ndnd) { } }; typedef callback >::ref cb_dir_dat_t; struct qhash_nnstr_ret { typedef str type; typedef str const_type; static type ret (str *v) { return v ? *v : str (NULL); } static const_type const_ret (const str *v) { return v ? *v : str (NULL); } }; // Name cache maps pathnames to name_dat typedef cache, 512> namec_t; /* FH translation table Note for fhtt, we use a qhash_nnstr_ret so that we can return str's rather than str *'s from the lookup. useful for anything refcounted. */ typedef qhash, equals, qhash_nnstr_ret> fhtt_t; class getdata { /* Functions that communicate directly with SFSRO servers. Should only be called from the filesys class Representation: SFSRO file handles and SFSRO blocks of raw data */ public: getdata (ref fsinfo, ref sfsroc) : fsi (fsinfo), sfsroc (sfsroc) { memcpy (IV, fsi->v1->info.iv.base (), SFSRO_IVSIZE); } /* Request blocks from SFSRO server and verify integrity */ // void operator() (cb_sfsro_data_t cb, ref fh); /* jj said I could do this, but "don't blame me, asshole." */ void fetch (cb_sfsro_data_t cb, ref fh); private: ref fsi; ptr sfsroc; // IV to modify the message space such that if a particular collision // is found for SHA1, this does not necessary imply a collision in SFSRO. // Our IV is the ASCII hostID. char IV[SFSRO_IVSIZE]; void fetch1 (cb_sfsro_data_t cb, ref fh, sfsro_datares *res, clnt_stat err); }; class filesys { /* Functions to convert raw SFSRO blocks into data structures like directories, file blocks, inodes, and indirect blocks. Representation: SFSRO structures and SFSRO file handles. */ public: filesys (ref fsinfo, ref sfsroc) : fsi (fsinfo) { gd = New refcounted (fsinfo, sfsroc); } inline void getdirectory (cb_sfsro_directory_t cb, ptr fh); inline void getfiledata (cb_rpc_bytes_t cb, ptr fh); inline void getinode (cb_sfsro_inode_t cb, ptr fh); inline void getindir (cb_sfsro_indirect_t cb, ptr fh); /* given a file's inode, return the b'th block or NULL if not exist */ void getblock (cb_ptr_sfs_hash_t cb, ref ip, uint64 b); private: ref fsi; ptr gd; cache, 512> iblockc; // Indirect block cache cache, 512> directoryc; // Directory block cache cache >, 64> blockc; // file data buffer cache void getdirectory1 (cb_sfsro_directory_t cb, ref fh, ref data); void getfiledata1 (cb_rpc_bytes_t cb, ref fh, ref data); void getinode1 (cb_sfsro_inode_t cb, ref fh, ref data); void getindir1 (cb_sfsro_indirect_t cb, ref fh, ref data); void single_indirectres (cb_ptr_sfs_hash_t cb, size_t i, ref ip, ref indirect); void double_indirectres (cb_ptr_sfs_hash_t cb, size_t i, ref ip, ref indirect); void triple_indirectres (cb_ptr_sfs_hash_t cb, size_t i, ref ip, ref indirect); }; class pathtrans { /* Functions to converts pathnames (the file handle representation internal to the "server" class) to inodes and NFS file handles. Is called only by self and functions in server class. */ public: pathtrans (ref fhttfhtt, ref namecnamec, ref fsfs, ref fh) : fhtt (fhttfhtt), namec (namecnamec), fs (fsfs), rootrofh (fh) { // rnd.getbytes (nfs_fh3_IV, SFSRO_IVSIZE); // for debugging, use a constant IV for now. bzero (nfs_fh3_IV, SFSRO_IVSIZE); } void nd (cb_ptr_name_dat_t cb, str file_path); void nfsfh (nfs_fh3 *nfh, str file_path); void lookup (cb_ptr_name_dat_t cb, ptr dir_nd, str dir_path, str filename); private: ref fhtt; ref namec; ref fs; ref rootrofh; char nfs_fh3_IV[SFSRO_IVSIZE]; void add_entry (cb_ptr_name_dat_t cb, str file_path, ref fh, ref ip); void nd1 (cb_ptr_name_dat_t cb, ref > suffix, str dir_path, ptr dir_nd); void lookup1 (cb_ptr_name_dat_t cb, ptr dir_nd, str dir_path, str filename); void lookup2 (cb_ptr_name_dat_t cb, ptr dir_nd, str dir_path, str filename, uint64 blocknum, ptr dir); }; class nfstrans { /* Translate from NFS FHs to other structures of a similar level of abstraction. */ public: nfstrans (ref fhttfhtt, ref ptpt) : fhtt (fhttfhtt), pt (ptpt) { } inline str path (ref nfh) { return (*fhtt)[*nfh]; } inline void nd (cb_ptr_name_dat_t cb, ref nfh) { pt->nd (cb, path (nfh)); } inline void close (ref nfh) { fhtt->remove (*nfh); } private: ref fhtt; // FH translation table ref pt; }; class server : public sfsserver { protected: server (const sfsserverargs &a) // : sfsserver (a), x (a.p->x) { } : sfsserver (a) { } private: ptr pt; ptr nt; ptr fs; // ref x; /* High level functions. */ void dispatch (nfscall *sbp); void dispatch_helper (nfscall *sbp, ref nfh, ptr nd); bool setrootfh (const sfs_fsinfo *fsi); void expired (); /* These functions reply to NFS. Representation: NFS structures */ void nfsproc3_getattrres (nfscall *sbp, ptr nd); void nfsproc3_lookupres (nfscall *sbp, nfsstat3 status, ptr obj_nfh, ptr obj_nd, ptr dir_nd); void nfsproc3_accessres (nfscall *sbp, uint32 ac, nfsstat3 status, ptr nd); void nfsproc3_readlinkres (nfscall *sbp, ptr nd); void nfsproc3_readres (nfscall *sbp, uint32 count, uint64 start, bool eof, nfsstat3 status, ptr > data, ptr nd); void nfsproc3_readdirres (nfscall *sbp, uint64 cookie, uint32 count, nfsstat3 status, ptr dir, ptr dir_nfh, ptr nd); void nfsproc3_readdirplusres (nfscall *sbp, uint64 cookie, uint32 count, nfsstat3 status, ptr dir, ptr dir_nfh, ptr nd); void nfsproc3_fsstatres (nfscall *sbp, ptr nd); void nfsproc3_fsinfores (nfscall *sbp, ptr nd); /* Intermediate callbacks. */ void nfsproc3_lookup1 (nfscall *sbp, str dir_path, str filename, ref dir_nd, ref dir_nfh, ptr obj_nd); void nfsproc3_lookup2 (nfscall *sbp, str dir_path, str filename, ref dir_nfh, ptr obj_nd, ref dir_fa); void nfsproc3_access1 (nfscall *sbp, uint32 access_req, ref nd, ref nfh, ref ip); void nfsproc3_readlink1 (nfscall *sbp, ref nd, ref nfh, ref ip); void nfsproc3_read1 (nfscall *sbp, ref nd, uint64 offset, uint32 count); void nfsproc3_read2 (nfscall *sbp, ref nd, uint64 offset, uint32 count, ref > fdat); void nfsproc3_readdir1 (nfscall *sbp, ref dir_nfh, ref nd, uint64 cookie, /* cookieverf3 &cv, */ uint32 count); void nfsproc3_readdir2 (nfscall *sbp, uint64 cookie, ref dir_nfh, ref nd, uint32 count, ptr dir); void nfsproc3_readdirplus1 (nfscall *sbp, ref dir_nfh, ref nd, uint64 cookie, /* cookieverf3 &cv, */ uint32 count); /* Functions to help the nfsproc3_foo procedures */ }; #define DIR_OFFSET(cookie) ((cookie) >> 40) #define DIR_BLOCK(cookie) ((cookie) & INT64 (0x000000FFFFFFFFFF)) #define DIR_COOKIE(offset, block) (((uint64)(offset) << 40) | (uint64)(block)) #endif /* _SFSROCD_H_ */