/*---------------------------------------------------------------------------*/
/*nsmux.h*/
/*---------------------------------------------------------------------------*/
/*Definitions for filesystem proxy for namespace-based translator selection.*/
/*---------------------------------------------------------------------------*/
/*Based on the code of unionfs translator.*/
/*---------------------------------------------------------------------------*/
/*Copyright (C) 2001, 2002, 2005, 2008, 2009 Free Software Foundation,
  Inc.  Written by Sergiu Ivanov <unlimitedscolobb@gmail.com>.

  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 of the
  License, 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 __NSMUX_H__
#define __NSMUX_H__
/*---------------------------------------------------------------------------*/
#include <stddef.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/statfs.h>
#include <sys/time.h>
#include <hurd/ihash.h>
#include <hurd/iohelp.h>
/*---------------------------------------------------------------------------*/
#include "lib.h"
#include "node.h"
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*--------Macros-------------------------------------------------------------*/
/*The inode number for the root node*/
#define NSMUX_ROOT_INODE 1
/*---------------------------------------------------------------------------*/
/*Bits that are turned off after open*/
#define OPENONLY_STATE_MODES (O_CREAT | O_EXCL | O_NOLINK | O_NOTRANS)
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*--------Global Variables---------------------------------------------------*/
/*A mapped time value*/
/*Required for a very fast access to time*/
extern volatile struct mapped_time_value *maptime;
/*---------------------------------------------------------------------------*/
/*A port to the underlying node*/
extern mach_port_t underlying_node;
/*---------------------------------------------------------------------------*/
/*The stat information about the underlying node*/
extern io_statbuf_t underlying_node_stat;
/*---------------------------------------------------------------------------*/
/*The translator callbacks required by netfs_S_dir_lookup*/
extern fshelp_fetch_root_callback1_t _netfs_translator_callback1;
extern fshelp_fetch_root_callback2_t _netfs_translator_callback2;
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*--------Functions----------------------------------------------------------*/
/*Attempts to create a file named `name` in `dir` for `user` with mode `mode`*/
error_t
  netfs_attempt_create_file
  (struct iouser *user,
   struct node *dir, const char *name, mode_t mode, struct node **node);
/*---------------------------------------------------------------------------*/
/*Returns an error if the process of opening a file should not be allowed
	to complete because of insufficient permissions*/
error_t
  netfs_check_open_permissions
  (struct iouser *user, struct node *np, int flags, int newnode);
/*---------------------------------------------------------------------------*/
/*Attempts an utimes call for the user `cred` on node `node`*/
error_t
  netfs_attempt_utimes
  (struct iouser *cred,
   struct node *node, struct timespec *atime, struct timespec *mtime);
/*---------------------------------------------------------------------------*/
/*Returns the valid access types for file `node` and user `cred`*/
error_t
  netfs_report_access (struct iouser *cred, struct node *np, int *types);
/*---------------------------------------------------------------------------*/
/*Validates the stat data for the node*/
error_t netfs_validate_stat (struct node *np, struct iouser *cred);
/*---------------------------------------------------------------------------*/
/*Syncs `node` completely to disk*/
error_t netfs_attempt_sync (struct iouser *cred, struct node *node, int wait);
/*---------------------------------------------------------------------------*/
/*Fetches a directory*/
error_t
  netfs_get_dirents
  (struct iouser *cred,
   struct node *dir,
   int first_entry,
   int num_entries,
   char **data,
   mach_msg_type_number_t * data_len,
   vm_size_t max_data_len, int *data_entries);
/*---------------------------------------------------------------------------*/
/*Looks up `name` under `dir` for `user`*/
error_t
  netfs_attempt_lookup
  (struct iouser *user, struct node *dir, const char *name, struct node **node);
/*---------------------------------------------------------------------------*/
/*Performs an advanced lookup of file `name` under `dir`. If the
  lookup of the last component of the path is requested (`lastcomp` is
  1), it is not a directory and no translators are required (`name`
  does not contain ',,'), the function will simply open the required
  file and return the port in `file`. In other cases it will create a
  proxy node and return it in `node`.*/
error_t
  netfs_attempt_lookup_improved
  (struct iouser * user, struct node * dir, const char *name, int flags,
   int lastcomp, node_t ** node, file_t * file, int proxy);
/*---------------------------------------------------------------------------*/
/*Responds to the RPC dir_lookup*/
error_t
  netfs_S_dir_lookup
  (struct protid *diruser,
   const char *filename,
   int flags,
   mode_t mode,
   retry_type * do_retry,
   char *retry_name,
   mach_port_t * retry_port, mach_msg_type_number_t * retry_port_type);
/*---------------------------------------------------------------------------*/
/*Deletes `name` in `dir` for `user`*/
error_t
  netfs_attempt_unlink (struct iouser *user, struct node *dir, const char *name);
/*---------------------------------------------------------------------------*/
/*Attempts to rename `fromdir`/`fromname` to `todir`/`toname`*/
error_t
  netfs_attempt_rename
  (struct iouser *user,
   struct node *fromdir,
   const char *fromname, struct node *todir, const char *toname, int excl);
/*---------------------------------------------------------------------------*/
/*Attempts to create a new directory*/
error_t
  netfs_attempt_mkdir
  (struct iouser *user, struct node *dir, const char *name, mode_t mode);
/*---------------------------------------------------------------------------*/
/*Attempts to remove directory `name` in `dir` for `user`*/
error_t
  netfs_attempt_rmdir (struct iouser *user, struct node *dir, const char *name);
/*---------------------------------------------------------------------------*/
/*Attempts to change the owner of `node` for user `cred` to `uid`:`gid`*/
error_t
  netfs_attempt_chown
  (struct iouser *cred, struct node *node, uid_t uid, uid_t gid);
/*---------------------------------------------------------------------------*/
/*Attempts to change the author of `node` to `author`*/
error_t
  netfs_attempt_chauthor
  (struct iouser *cred, struct node *node, uid_t author);
/*---------------------------------------------------------------------------*/
/*Attempts to change the mode of `node` to `mode` for `cred`*/
error_t
  netfs_attempt_chmod (struct iouser *user, struct node *node, mode_t mode);
/*---------------------------------------------------------------------------*/
/*Attempts to turn `node` into a symlink targetting `name`*/
error_t
  netfs_attempt_mksymlink
  (struct iouser *cred, struct node *node, const char *name);
/*---------------------------------------------------------------------------*/
/*Attempts to turn `node` into a device; type can be either S_IFBLK or S_IFCHR*/
error_t
  netfs_attempt_mkdev
  (struct iouser *cred, struct node *node, mode_t type, dev_t indexes);
/*---------------------------------------------------------------------------*/
/*Attempts to set the passive translator record for `file` passing `argz`*/
error_t
  netfs_set_translator
  (struct iouser *cred, struct node *node, const char *argz, mach_msg_type_number_t arglen);
/*---------------------------------------------------------------------------*/
/*Attempts to call chflags for `node`*/
error_t
  netfs_attempt_chflags (struct iouser *cred, struct node *node, int flags);
/*---------------------------------------------------------------------------*/
/*Attempts to set the size of file `node`*/
error_t
  netfs_attempt_set_size
  (struct iouser *cred, struct node *node, loff_t size);
/*---------------------------------------------------------------------------*/
/*Fetches the filesystem status information*/
error_t
  netfs_attempt_statfs
  (struct iouser *cred, struct node *node, fsys_statfsbuf_t * st);
/*---------------------------------------------------------------------------*/
/*Syncs the filesystem*/
error_t netfs_attempt_syncfs (struct iouser *cred, int wait);
/*---------------------------------------------------------------------------*/
/*Creates a link in `dir` with `name` to `file`*/
error_t
  netfs_attempt_link
  (struct iouser *user,
   struct node *dir, struct node *file, const char *name, int excl);
/*---------------------------------------------------------------------------*/
/*Attempts to create an anonymous file related to `dir` with `mode`*/
error_t
  netfs_attempt_mkfile
  (struct iouser *user, struct node *dir, mode_t mode, struct node **node);
/*---------------------------------------------------------------------------*/
/*Reads the contents of symlink `node` into `buf`*/
error_t
  netfs_attempt_readlink (struct iouser *user, struct node *node, char *buf);
/*---------------------------------------------------------------------------*/
/*Reads from file `node` up to `len` bytes from `offset` into `data`*/
error_t
  netfs_attempt_read
  (struct iouser *cred,
   struct node *np, loff_t offset, size_t * len, void *data);
/*---------------------------------------------------------------------------*/
/*Writes to file `node` up to `len` bytes from offset from `data`*/
error_t
  netfs_attempt_write
  (struct iouser *cred,
   struct node *node, loff_t offset, size_t * len, const void *data);
/*---------------------------------------------------------------------------*/
/*Frees all storage associated with the node*/
void netfs_node_norefs (struct node *np);
/*---------------------------------------------------------------------------*/
/*Implements file_get_translator_cntl as described in <hurd/fs.defs>
  (according to diskfs_S_file_get_translator_cntl)*/
kern_return_t
  netfs_S_file_get_translator_cntl
  (struct protid *user, mach_port_t * cntl, mach_msg_type_name_t * cntltype);
/*---------------------------------------------------------------------------*/
/* Shutdown the filesystem; flags are as for fsys_goaway. */
error_t
netfs_shutdown (int flags);
/*---------------------------------------------------------------------------*/
#endif /*__NSMUX_H__*/
