#IFNDEF NFS_H
#DEFINE NFS_H

#include "fsutil.h"
#include "fsfile.h"
#include "persifs.h"

class nfs
{
 public:
  void dispatch(nfscall *nc);
 
 protected:
  nfs(ref<FS>);

 private:
  void nfs3_getattr(nfscall *nc);
  void nfs3_getattr_on_load(nfscall *nc, cbe, ref<fsfile>);
  void nfs3_getattr_on_getAttr(nfscall *nc, ref<fsfile>, fattr3);
  void nfs3_getattr_error(nfscall *nc);

  void nfs3_setattr(nfscall *nc);
  void nfs3_setattr_on_load(nfscall *nc, cbe, ref<fsfile>);
  void nfs3_setattr_on_getAttr(nfscall *nc, ref<fsfile>, cbe, fattr3);
  void nfs3_setattr_on_setAttr(nfscall *nc, ref<fsfile>, fattr3, cbe, fattr3);
  void nfs3_setattr_error(nfscall *nc);

  void nfs3_lookup(nfscall *nc);
  void nfs3_lookup_on_load(nfscall *nc, ref<fsfile>, cbe);
  void nfs3_lookup_on_dirLoad(nfscall *nc, ref<fsfile>, cbe, ref<fsdir>);
  void nfs3_lookup_on_lookup(nfscall *nc, cbe, ref<dirEntry>);
  void nfs3_lookup_error(nfscall *nc, int);

  void nfs3_access(nfscall *nc);
  void nfs3_access_on_load(nfscall *nc, cbe, ref<fsfile>);
  void nfs3_access_on_getAttr(nfscall *nc, ref<fsfile>, cbe, fattr3);
  void nfs3_access_error(nfscall *nc);

  void nfs3_read(nfscall *nc);
  void nfs3_read_on_load(nfscall *nc, cbe, ref<fsfile>);
  void nfs3_read_on_read(nfscall *nc, cbe, str);
  void nfs3_read_error(nfscall *nc);

  void nfs3_write(nfscall *nc);
  void nfs3_write_on_load(nfscall *nc, cbe, ref<fsfile>);
  void nfs3_write_on_getAttr(nfscall *nc, ref<fsfile>, cbe, fattr3);
  void nfs3_write_on_write(nfscall *nc, ref<fsfile>, fattr3, uint64, cbe);
  void nfs3_write_on_final(nfscall *nc, fattr3, uint64, fattr3);
  void nfs3_write_error(nfscall *nc);

  void nfs3_create(nfscall *nc);
  void nfs3_create_on_load(nfscall *nc, cbe, ref<fsfile>);
  void nfs3_create_on_getAttr(nfscall *nc, ref<fsfile>, cbe, fattr3);
  void nfs3_create_on_dirLoad(nfscall *nc, ref<fsfile>, fattr3, cbe, ref<fsdir>);
  void nfs3_create_on_lookup(nfscall *nc, ref<fsfile>, fattr3, ref<fsdir>, cbe, ref<fsdirEntry>);
  void nfs3_create_on_create(nfscall *nc, ref<fsfile>, fattr3, ref<fsdir>, cbe, ref<fsfile>);
  void nfs3_create_on_add(nfscall *nc, ref<fsfile>, fattr3, ref<fsdir>, cbe, ref<fsdirEntry>);
  void nfs3_create_final(nfscall *nc, inumber, fattr3, fattr3);
  void nfs3_create_error(nfscall *nc);

  void nfs3_mkdir(nfscall *nc);
  void nfs3_mkdir_on_load(nfscall *nc, cbe, ref<fsfile>);
  void nfs3_mkdir_on_load(nfscall *nc, ref<fsfile>, cbe, fattr3);
  void nfs3_mkdir_on_dirLoad(nfscall *nc, ref<fsfile>, fattr3, cbe, ref<fsdir>);
  void nfs3_mkdir_on_lookup(nfscall *nc, ref<fsfile>, ref<fsdir>, fattr3, cbe, ref<fsdirEntry>);
  void nfs3_mkdir_on_create(nfscall *nc, ref<fsfile>, ref<fsdir>, fattr3, cbe, ref<fsdir>);
  void nfs3_mkdir_on_add(nfscall *nc, ref<fsfile>, ref<fsdir>, fattr3, cbe, ref<fsdirEntry>);
  void nfs3_mkdir_on_final(nfscall *nc, inumber, fattr3, fattr3);
  void nfs3_mkdir_error(nfscall *nc);

  void nfs3_remove(nfscall *nc);
  void nfs3_remove_on_load(nfscall *nc, cbe, ref<fsfile>);
  void nfs3_remove_on_getAttr(nfscall *nc, ref<fsfile>, cbe, fattr3);
  void nfs3_remove_on_dirLoad(nfscall *nc, ref<fsfile>, fattr3, cbe, ref<fsdir>);
  void nfs3_remove_on_remove(nfscall *nc, ref<fsfile>, fattr3, ref<fsdir>, cbe);
  void nfs3_remove_final(nfscall *nc, fattr3, fattr3);
  void nfs3_remove_error(nfscall *nc);
  void nfs3_readdir(nfscall *nc);
  void nfs3_readdir_on_load(nfscall *nc, cbe, ref<fsfile>);
  void nfs3_readdir_on_dirLoad(nfscall *nc, cbe, ref<fsdir>);
  void nfs3_readdir_error(nfscall *nc);

  void nfs3_fsstat(nfscall *nc);

  void nfs3_fsinfo(nfscall *nc);

}
