diff options
Diffstat (limited to 'libnetfs/netfs.h')
-rw-r--r-- | libnetfs/netfs.h | 431 |
1 files changed, 245 insertions, 186 deletions
diff --git a/libnetfs/netfs.h b/libnetfs/netfs.h index 836005ee..1dda718e 100644 --- a/libnetfs/netfs.h +++ b/libnetfs/netfs.h @@ -1,6 +1,6 @@ -/* +/* - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994,95,96,97,99,2000,02 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -23,22 +23,23 @@ #include <hurd/fshelp.h> #include <hurd/iohelp.h> #include <assert.h> -#include <argp.h> /* This library supports client-side network file system - implementations. It is analogous to the diskfs library provided for + implementations. It is analogous to the diskfs library provided for disk-based filesystems. */ +struct argp; + struct protid { struct port_info pi; - + /* User identification */ - struct netcred *credential; - + struct iouser *user; + /* Object this refers to */ struct peropen *po; - + /* Shared memory I/O information. */ memory_object_t shared_object; struct shared_io *mapped; @@ -47,34 +48,46 @@ struct protid /* One of these is created for each open */ struct peropen { - off_t filepointer; + loff_t filepointer; int lock_status; int refcnt; int openstat; - mach_port_t dotdotport; + struct node *np; + + /* The parent of the translator's root node. */ + mach_port_t root_parent; + + /* If this node is in a shadow tree, the parent of its root. */ + mach_port_t shadow_root_parent; + /* If in a shadow tree, its root node in this translator. */ + struct node *shadow_root; }; /* A unique one of these exists for each node currently in use. */ struct node { struct node *next, **prevp; - - /* Protocol specific stuff. */ + + /* Protocol specific stuff; defined by user. */ struct netnode *nn; - struct stat nn_stat; + /* The stat information for this particular node. */ + io_statbuf_t nn_stat; + /* The S_IPTRANS and S_IFMT bits here are examined instead of nn_stat.st_mode + to decide whether to do passive translator processing. Other bits + are ignored, so you can set this to nn_stat.st_mode if you want that. */ + mode_t nn_translated; - int istranslated; - struct mutex lock; - + + /* The number of references to this node. */ int references; - + mach_port_t sockaddr; - + int owner; - + struct transbox transbox; struct lock_box userlock; @@ -84,199 +97,231 @@ struct node struct dirmod *dirmod_reqs; }; +/* The user must define this variable. Set this to the name of the + filesystem server. */ +extern char *netfs_server_name; + +/* The user must define this variables. Set this to be the server + version number. */ +extern char *netfs_server_version; + /* The user must define this function. Make sure that NP->nn_stat is - filled with current information. CRED identifies the user - responsible for the operation. */ -error_t netfs_validate_stat (struct node *NP, struct netcred *cred); + filled with the most current information. CRED identifies the user + responsible for the operation. NP is locked. */ +error_t netfs_validate_stat (struct node *np, struct iouser *cred); /* The user must define this function. This should attempt a chmod - call for the user specified by CRED on node NODE, to change the - owner to UID and the group to GID. */ -error_t netfs_attempt_chown (struct netcred *cred, struct node *np, + call for the user specified by CRED on locked node NP, to change + the owner to UID and the group to GID. */ +error_t netfs_attempt_chown (struct iouser *cred, struct node *np, uid_t uid, uid_t gid); /* The user must define this function. This should attempt a chauthor - call for the user specified by CRED on node NODE, to change the - author to AUTHOR. */ -error_t netfs_attempt_chauthor (struct netcred *cred, struct node *np, + call for the user specified by CRED on locked node NP, thereby + changing the author to AUTHOR. */ +error_t netfs_attempt_chauthor (struct iouser *cred, struct node *np, uid_t author); /* The user must define this function. This should attempt a chmod - call for the user specified by CRED on node NODE, to change the - mode to MODE. Unlike the normal Unix and Hurd meaning of chmod, - this function is also used to attempt to change files into other - types. If such a transition is attempted which is impossible, then - return EOPNOTSUPP. - */ -error_t netfs_attempt_chmod (struct netcred *cred, struct node *np, + call for the user specified by CRED on locked node NODE, to change + the mode to MODE. Unlike the normal Unix and Hurd meaning of + chmod, this function is also used to attempt to change files into + other types. If such a transition is attempted which is + impossible, then return EOPNOTSUPP. */ +error_t netfs_attempt_chmod (struct iouser *cred, struct node *np, mode_t mode); -/* The user must define this function. Attempt to turn NODE (user CRED) - into a symlink with target NAME. */ -error_t netfs_attempt_mksymlink (struct netcred *cred, struct node *np, +/* The user must define this function. Attempt to turn locked node NP + (user CRED) into a symlink with target NAME. */ +error_t netfs_attempt_mksymlink (struct iouser *cred, struct node *np, char *name); /* The user must define this function. Attempt to turn NODE (user - CRED) into a device. TYPE is either S_IFBLK or S_IFCHR. */ -error_t netfs_attempt_mkdev (struct netcred *cred, struct node *np, + CRED) into a device. TYPE is either S_IFBLK or S_IFCHR. NP is + locked. */ +error_t netfs_attempt_mkdev (struct iouser *cred, struct node *np, mode_t type, dev_t indexes); -/* The user must define this function. Attempt to set the passive +/* The user may define this function. Attempt to set the passive translator record for FILE to ARGZ (of length ARGZLEN) for user - CRED. */ -error_t netfs_set_translator (struct netcred *cred, struct node *np, + CRED. NP is locked. */ +error_t netfs_set_translator (struct iouser *cred, struct node *np, char *argz, size_t argzlen); +/* The user may define this function (but should define it together + with netfs_set_translator). For locked node NODE with S_IPTRANS + set in its mode, look up the name of its translator. Store the + name into newly malloced storage, and return it in *ARGZ; set + *ARGZ_LEN to the total length. */ +error_t netfs_get_translator (struct node *node, char **argz, + size_t *argz_len); + /* The user must define this function. This should attempt a chflags - call for the user specified by CRED on node NODE, to change the - flags to FLAGS. */ -error_t netfs_attempt_chflags (struct netcred *cred, struct node *np, + call for the user specified by CRED on locked node NP, to change + the flags to FLAGS. */ +error_t netfs_attempt_chflags (struct iouser *cred, struct node *np, int flags); /* The user must define this function. This should attempt a utimes - call for the user specified by CRED on node NODE, to change the - atime to ATIME and the mtime to MTIME. */ -error_t netfs_attempt_utimes (struct netcred *cred, struct node *np, + call for the user specified by CRED on locked node NP, to change + the atime to ATIME and the mtime to MTIME. If ATIME or MTIME is + null, then set to the current time. */ +error_t netfs_attempt_utimes (struct iouser *cred, struct node *np, struct timespec *atime, struct timespec *mtime); /* The user must define this function. This should attempt to set the - size of the file NODE (for user CRED) to SIZE bytes long. */ -error_t netfs_attempt_set_size (struct netcred *cred, struct node *np, - off_t size); + size of the locked file NP (for user CRED) to SIZE bytes long. */ +error_t netfs_attempt_set_size (struct iouser *cred, struct node *np, + loff_t size); /* The user must define this function. This should attempt to fetch filesystem status information for the remote filesystem, for the - user CRED. */ -error_t netfs_attempt_statfs (struct netcred *cred, struct node *np, - struct statfs *st); - -/* The user must define this function. This should sync the file NP - completely to disk, for the user CRED. If WAIT is set, return - only after sync is completely finished. */ -error_t netfs_attempt_sync (struct netcred *cred, struct node *np, + user CRED. NP is locked. */ +error_t netfs_attempt_statfs (struct iouser *cred, struct node *np, + fsys_statfsbuf_t *st); + +/* The user must define this function. This should sync the locked + file NP completely to disk, for the user CRED. If WAIT is set, + return only after the sync is completely finished. */ +error_t netfs_attempt_sync (struct iouser *cred, struct node *np, int wait); /* The user must define this function. This should sync the entire - remote filesystem. If WAIT is set, return only after - sync is completely finished. */ -error_t netfs_attempt_syncfs (struct netcred *cred, int wait); - -/* The user must define this function. Lookup NAME in DIR for USER; - set *NP to the found name upon return. If the name was not found, - then return ENOENT. On any error, clear *NP. (*NP, if found, should - be locked, this call should unlock DIR no matter what.) */ -error_t netfs_attempt_lookup (struct netcred *user, struct node *dir, + remote filesystem. If WAIT is set, return only after the sync is + completely finished. */ +error_t netfs_attempt_syncfs (struct iouser *cred, int wait); + +/* The user must define this function. Lookup NAME in DIR (which is + locked) for USER; set *NP to the found name upon return. If the + name was not found, then return ENOENT. On any error, clear *NP. + (*NP, if found, should be locked and a reference to it generated. + This call should unlock DIR no matter what.) */ +error_t netfs_attempt_lookup (struct iouser *user, struct node *dir, char *name, struct node **np); -/* The user must define this function. Delete NAME in DIR for USER. */ -error_t netfs_attempt_unlink (struct netcred *user, struct node *dir, +/* The user must define this function. Delete NAME in DIR (which is + locked) for USER. */ +error_t netfs_attempt_unlink (struct iouser *user, struct node *dir, char *name); -/* Note that in this one call, neither of the specific nodes are locked. */ -error_t netfs_attempt_rename (struct netcred *user, struct node *fromdir, - char *fromname, struct node *todir, +/* The user must define this function. Attempt to rename the + directory FROMDIR to TODIR. Note that neither of the specific nodes + are locked. */ +error_t netfs_attempt_rename (struct iouser *user, struct node *fromdir, + char *fromname, struct node *todir, char *toname, int excl); /* The user must define this function. Attempt to create a new - directory named NAME in DIR for USER with mode MODE. */ -error_t netfs_attempt_mkdir (struct netcred *user, struct node *dir, + directory named NAME in DIR (which is locked) for USER with mode + MODE. */ +error_t netfs_attempt_mkdir (struct iouser *user, struct node *dir, char *name, mode_t mode); /* The user must define this function. Attempt to remove directory - named NAME in DIR for USER. */ -error_t netfs_attempt_rmdir (struct netcred *user, + named NAME in DIR (which is locked) for USER. */ +error_t netfs_attempt_rmdir (struct iouser *user, struct node *dir, char *name); /* The user must define this function. Create a link in DIR with name - NAME to FILE for USER. Note that neither DIR nor FILE are - locked. If EXCL is set, do not delete the target, but return EEXIST - if NAME is already found in DIR. */ -error_t netfs_attempt_link (struct netcred *user, struct node *dir, + NAME to FILE for USER. Note that neither DIR nor FILE are + locked. If EXCL is set, do not delete the target. Return EEXIST if + NAME is already found in DIR. */ +error_t netfs_attempt_link (struct iouser *user, struct node *dir, struct node *file, char *name, int excl); /* The user must define this function. Attempt to create an anonymous - file related to DIR for USER with MODE. Set *NP to the returned - file upon success. No matter what, unlock DIR. */ -error_t netfs_attempt_mkfile (struct netcred *user, struct node *dir, + file related to DIR (which is locked) for USER with MODE. Set *NP + to the returned file upon success. No matter what, unlock DIR. */ +error_t netfs_attempt_mkfile (struct iouser *user, struct node *dir, mode_t mode, struct node **np); /* The user must define this function. Attempt to create a file named - NAME in DIR for USER with MODE. Set *NP to the new node upon - return. On any error, clear *NP. *NP should be locked on success; - no matter what, unlock DIR before returning. */ -error_t netfs_attempt_create_file (struct netcred *user, struct node *dir, + NAME in DIR (which is locked) for USER with MODE. Set *NP to the + new node upon return. On any error, clear *NP. *NP should be + locked on success; no matter what, unlock DIR before returning. */ +error_t netfs_attempt_create_file (struct iouser *user, struct node *dir, char *name, mode_t mode, struct node **np); -/* The user must define this function. Read the contents of NP (a symlink), - for USER, into BUF. */ -error_t netfs_attempt_readlink (struct netcred *user, struct node *np, +/* The user must define this function. Read the contents of locked + node NP (a symlink), for USER, into BUF. */ +error_t netfs_attempt_readlink (struct iouser *user, struct node *np, char *buf); -/* The user must define this function. Node NP is being opened by USER, - with FLAGS. NEWNODE is nonzero if we just created this node. Return - an error if we should not permit the open to complete because of a - permission restriction. */ -error_t netfs_check_open_permissions (struct netcred *user, struct node *np, +/* The user must define this function. Locked node NP is being opened + by USER, with FLAGS. NEWNODE is nonzero if we just created this + node. Return an error if we should not permit the open to complete + because of a permission restriction. */ +error_t netfs_check_open_permissions (struct iouser *user, struct node *np, int flags, int newnode); -/* The user must define this function. Read from the file NP for user - CRED starting at OFFSET and continuing for up to *LEN bytes. Put - the data at DATA. Set *LEN to the amount successfully read upon - return. */ -error_t netfs_attempt_read (struct netcred *cred, struct node *np, - off_t offset, size_t *len, void *data); +/* The user must define this function. Read from the locked file NP + for user CRED starting at OFFSET and continuing for up to *LEN + bytes. Put the data at DATA. Set *LEN to the amount successfully + read upon return. */ +error_t netfs_attempt_read (struct iouser *cred, struct node *np, + loff_t offset, size_t *len, void *data); -/* The user must define this function. Write to the file NP for user - CRED starting at OFSET and continuing for up to *LEN bytes from - DATA. Set *LEN to the amount seccessfully written upon return. */ -error_t netfs_attempt_write (struct netcred *cred, struct node *np, - off_t offset, size_t *len, void *data); +/* The user must define this function. Write to the locked file NP + for user CRED starting at OFSET and continuing for up to *LEN bytes + from DATA. Set *LEN to the amount successfully written upon + return. */ +error_t netfs_attempt_write (struct iouser *cred, struct node *np, + loff_t offset, size_t *len, void *data); /* The user must define this function. Return the valid access types (bitwise OR of O_READ, O_WRITE, and O_EXEC) in *TYPES for - file NP and user CRED. */ -void netfs_report_access (struct netcred *cred, struct node *np, - int *types); - -/* The user must define this function. Malloc and fill two arrays with - the uids and gids from the specified credential. */ -void netfs_interpret_credential (struct netcred *cred, uid_t **uids, - int *nuids, uid_t **gids, int *ngids); - -/* The user must define this function. Return a (virtual or physical) - copy of CRED. */ -struct netcred *netfs_copy_credential (struct netcred *cred); - -/* The user must define this function. The specified credential is - not in use any more. */ -void netfs_drop_credential (struct netcred *cred); - -/* The user must define this function. Create a new credential - from the specified UID and GID arrays. */ -struct netcred *netfs_make_credential (uid_t *uids, int nuids, + locked file NP and user CRED. */ +error_t netfs_report_access (struct iouser *cred, struct node *np, + int *types); + +/* The user must define this function. Create a new user from the + specified UID and GID arrays. */ +struct iouser *netfs_make_user (uid_t *uids, int nuids, uid_t *gids, int ngids); -/* The user must define this function. Node NP is all done; free - all its associated storage. */ +/* The user must define this function. Node NP has no more references; + free all its associated storage. */ void netfs_node_norefs (struct node *np); -error_t netfs_get_dirents (struct netcred *, struct node *, int, int, char **, - mach_msg_type_number_t *, vm_size_t, int *); +/* The user must define this function. Fill the array *DATA of size + BUFSIZE with up to NENTRIES dirents from DIR (which is locked) + starting with entry ENTRY for user CRED. The number of entries in + the array is stored in *AMT and the number of bytes in *DATACNT. + If the supplied buffer is not large enough to hold the data, it + should be grown. */ +error_t netfs_get_dirents (struct iouser *cred, struct node *dir, + int entry, int nentries, char **data, + mach_msg_type_number_t *datacnt, + vm_size_t bufsize, int *amt); + +/* The user may define this function. For a full description, + see hurd/hurd_types.h. The default response indicates a network + store. If the supplied buffers are not large enough, they should + be grown as necessary. NP is locked. */ +error_t netfs_file_get_storage_info (struct iouser *cred, + struct node *np, + mach_port_t **ports, + mach_msg_type_name_t *ports_type, + mach_msg_type_number_t *num_ports, + int **ints, + mach_msg_type_number_t *num_ints, + loff_t **offsets, + mach_msg_type_number_t *num_offsets, + char **data, + mach_msg_type_number_t *data_len); /* Option parsing */ /* Parse and execute the runtime options in ARGZ & ARGZ_LEN. EINVAL is returned if some option is unrecognized. The default definition of this - routine will parse them using NETFS_RUNTIME_ARGP, which see. */ + routine will parse them using NETFS_RUNTIME_ARGP. */ error_t netfs_set_options (char *argz, size_t argz_len); -/* Return an argz string describing the current options. Fill *ARGZ - with a pointer to newly malloced storage holding the list and *LEN - to the length of that storage. The default definition of this routine - simply initializes *ARGZ and *ARGZ_LEN to 0 and calls - netfs_append_std_options. */ -error_t netfs_get_options (char **argz, size_t *argz_len); +/* Append to the malloced string *ARGZ of length *ARGZ_LEN a NUL-separated + list of the arguments to this translator. The default definition of this + routine simply calls netfs_append_std_options. */ +error_t netfs_append_args (char **argz, size_t *argz_len); /* If this is defined or set to a pointer to an argp structure, it will be used by the default netfs_set_options to handle runtime option parsing. @@ -300,24 +345,77 @@ extern const struct argp netfs_std_startup_argp; must already have a sane value). */ error_t netfs_append_std_options (char **argz, size_t *argz_len); +/* Definitions provided by user */ + +/* Maximum number of symlinks to follow before returning ELOOP. */ +extern int netfs_maxsymlinks; + /* Definitions provided by netfs. */ -struct node *netfs_make_node (struct netnode *); -mach_port_t netfs_startup (mach_port_t, int); +/* Given a netnode created by the user program, wraps it in a node + structure. The new node is not locked and has a single reference. + If an error occurs, NULL is returned. */ +struct node *netfs_make_node (struct netnode *); +/* Whenever node->references is to be touched, this lock must be + held. Cf. netfs_nrele, netfs_nput, netfs_nref and netfs_drop_node. */ extern spin_lock_t netfs_node_refcnt_lock; -extern int netfs_maxsymlinks; - +/* Normally called in main. This function sets up some of the netfs + server's internal state. */ void netfs_init (void); + +/* Starts the netfs server. Called after netfs_init. BOOTSTRAP is + the bootstrap port. FLAGS indicate how to open the underlying node + (Cf. hurd/fsys.defs). */ +mach_port_t netfs_startup (mach_port_t bootstrap, int flags); + +/* Normally called as the last function in main. The netfs server now + begins answering requests. This function never returns. */ void netfs_server_loop (void); -struct protid *netfs_make_protid (struct peropen *, struct netcred *); -struct peropen *netfs_make_peropen (struct node *, int, mach_port_t); -void netfs_drop_node (struct node *); + +/* Creates a new credential from USER which can be NULL on the peropen + PO. Returns NULL and sets errno on error. */ +struct protid *netfs_make_protid (struct peropen *po, struct iouser *user); + +/* Create and return a new peropen structure on node NP with open + flags FLAGS. The initial values for the root_parent, shadow_root, + and shadow_root_parent fields are copied from CONTEXT if it's + non-zero, otherwise zeroed. */ +struct peropen *netfs_make_peropen (struct node *, int, + struct peropen *context); + +/* Add a reference to node NP. Unless you already hold a reference, + NP must be locked. */ +void netfs_nref (struct node *np); + +/* Releases a node. Drops a reference to node NP, which must not be + locked by the caller. If this was the last reference, drops the + node. The node cannot be used again without first obtaining a + reference to it. */ +void netfs_nrele (struct node *np); + +/* Puts a node back. Drops a reference to the node NP, which must be + locked by the caller (this lock will be released by netfs_nput). + If this was the last reference, drops the node. The node cannot be + used again without first obtaining a reference to it. */ +void netfs_nput (struct node *np); + +/* Called internally when no more references to node NP exist. */ +void netfs_drop_node (struct node *np); + +/* Called internally when no more references to a protid exit. */ void netfs_release_protid (void *); + +/* Called internally when no more references to a protid exit. */ void netfs_release_peropen (struct peropen *); + +/* The netfs message demuxer. */ int netfs_demuxer (mach_msg_header_t *, mach_msg_header_t *); -error_t netfs_shutdown (int); + +/* Called to ask the filesystem to shutdown. If it returns, an error + occurred. FLAGS are passed to fsys_goaway. */ +error_t netfs_shutdown (int flags); extern struct port_class *netfs_protid_class; extern struct port_class *netfs_control_class; @@ -326,45 +424,6 @@ extern struct node *netfs_root_node; extern mach_port_t netfs_fsys_identity; extern auth_t netfs_auth_server_port; -extern inline void -netfs_nref (struct node *np) -{ - spin_lock (&netfs_node_refcnt_lock); - np->references++; - spin_unlock (&netfs_node_refcnt_lock); -} - -extern inline void -netfs_nrele (struct node *np) -{ - spin_lock (&netfs_node_refcnt_lock); - assert (np->references); - np->references--; - if (np->references == 0) - { - mutex_lock (&np->lock); - netfs_drop_node (np); - } - else - spin_unlock (&netfs_node_refcnt_lock); -} - -extern inline void -netfs_nput (struct node *np) -{ - spin_lock (&netfs_node_refcnt_lock); - assert (np->references); - np->references--; - if (np->references == 0) - netfs_drop_node (np); - else - { - spin_unlock (&netfs_node_refcnt_lock); - mutex_unlock (&np->lock); - } -} - - /* Mig gook. */ typedef struct protid *protid_t; |