diff options
Diffstat (limited to 'netfs-sample')
-rw-r--r-- | netfs-sample/README | 13 | ||||
-rwxr-xr-x | netfs-sample/build | 1 | ||||
-rw-r--r-- | netfs-sample/debug.h | 60 | ||||
-rw-r--r-- | netfs-sample/errors | 0 | ||||
-rw-r--r-- | netfs-sample/filtered | 0 | ||||
-rw-r--r-- | netfs-sample/filterfs.c | 1236 | ||||
-rw-r--r-- | netfs-sample/filterfs.h | 453 | ||||
-rw-r--r-- | netfs-sample/lib.c | 193 | ||||
-rw-r--r-- | netfs-sample/lib.h | 82 | ||||
-rw-r--r-- | netfs-sample/lnode.c | 305 | ||||
-rw-r--r-- | netfs-sample/lnode.h | 143 | ||||
-rw-r--r-- | netfs-sample/ncache.c | 221 | ||||
-rw-r--r-- | netfs-sample/ncache.h | 100 | ||||
-rw-r--r-- | netfs-sample/node.c | 803 | ||||
-rw-r--r-- | netfs-sample/node.h | 168 | ||||
-rw-r--r-- | netfs-sample/options.c | 255 | ||||
-rw-r--r-- | netfs-sample/options.h | 64 |
17 files changed, 0 insertions, 4097 deletions
diff --git a/netfs-sample/README b/netfs-sample/README deleted file mode 100644 index 112cce59..00000000 --- a/netfs-sample/README +++ /dev/null @@ -1,13 +0,0 @@ -FILTERFS TRANSLATOR - -WHAT'S THIS? -filterfs is a GNU/Hurd translator that filters the contents of the directory it -is set upon according to the result of execution of a given command. - -WHAT'S IT FOR? -This translator is intended as a preparatory exercise for the namespace-based -translator selection project (see http://www.bddebian.com/~wiki/community/gsoc/), -so it does not really have a stand-alone importance :-) - -DEVELOPER -Sergiu Ivanov <unlimitedscolobb@gmail.com> diff --git a/netfs-sample/build b/netfs-sample/build deleted file mode 100755 index 2555e2ca..00000000 --- a/netfs-sample/build +++ /dev/null @@ -1 +0,0 @@ -gcc -Wall -g -lnetfs -lfshelp -liohelp -lthreads -lports -lihash -lshouldbeinlibc -o filterfs filterfs.c node.c lnode.c ncache.c options.c lib.c 2>&1 | tee errors diff --git a/netfs-sample/debug.h b/netfs-sample/debug.h deleted file mode 100644 index 606d7e79..00000000 --- a/netfs-sample/debug.h +++ /dev/null @@ -1,60 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/*debug.h*/ -/*----------------------------------------------------------------------------*/ -/*Simple facilities for debugging messages*/ -/*----------------------------------------------------------------------------*/ -/*Based on the code of unionfs translator.*/ -/*----------------------------------------------------------------------------*/ -/*Copyright (C) 2001, 2002, 2005 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 __DEBUG_H__ -#define __DEBUG_H__ - -/*----------------------------------------------------------------------------*/ -#include <stdio.h> -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Macros--------------------------------------------------------------*/ -/*Print debug messages here*/ -#define DEBUG_OUTPUT "/var/tmp/filterfs.dbg" -/*----------------------------------------------------------------------------*/ -#ifdef DEBUG - /*Initializes the log*/ -# define INIT_LOG() filterfs_dbg = fopen(DEBUG_OUTPUT, "wt") - /*Closes the log*/ -# define CLOSE_LOG() fclose(filterfs_dbg) - /*Prints a debug message and flushes the debug output*/ -# define LOG_MSG(fmt, args...) {fprintf(filterfs_dbg, fmt"\n", ##args);\ - fflush(filterfs_dbg);} -#else - /*Remove requests for debugging output*/ -# define INIT_LOG() -# define CLOSE_LOG() -# define LOG_MSG(fmt, args...) -#endif /*DEBUG*/ -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Global Variables----------------------------------------------------*/ -/*The file to write debugging info to*/ -extern FILE * filterfs_dbg; -/*----------------------------------------------------------------------------*/ - -#endif /*__DEBUG_H__*/ diff --git a/netfs-sample/errors b/netfs-sample/errors deleted file mode 100644 index e69de29b..00000000 --- a/netfs-sample/errors +++ /dev/null diff --git a/netfs-sample/filtered b/netfs-sample/filtered deleted file mode 100644 index e69de29b..00000000 --- a/netfs-sample/filtered +++ /dev/null diff --git a/netfs-sample/filterfs.c b/netfs-sample/filterfs.c deleted file mode 100644 index d768e18b..00000000 --- a/netfs-sample/filterfs.c +++ /dev/null @@ -1,1236 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/*filter.c*/ -/*----------------------------------------------------------------------------*/ -/*The filtering translator*/ -/*----------------------------------------------------------------------------*/ -/*Based on the code of unionfs translator.*/ -/*----------------------------------------------------------------------------*/ -/*Copyright (C) 2001, 2002, 2005 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.*/ -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -#define _GNU_SOURCE 1 -/*----------------------------------------------------------------------------*/ -#include "filterfs.h" -/*----------------------------------------------------------------------------*/ -#include <error.h> -#include <argp.h> -#include <argz.h> -#include <hurd/netfs.h> -#include <fcntl.h> -/*----------------------------------------------------------------------------*/ -#include "debug.h" -#include "options.h" -#include "ncache.h" -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Macros--------------------------------------------------------------*/ -/*The state modes use in open*/ -#define OPENONLY_STATE_MODES (O_CREAT | O_EXCL | O_NOLINK | O_NOTRANS \ - | O_NONBLOCK) -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Global Variables----------------------------------------------------*/ -/*The name of the server*/ -char * netfs_server_name = "filterfs"; -/*----------------------------------------------------------------------------*/ -/*The version of the server*/ -char * netfs_server_version = "0.0"; -/*----------------------------------------------------------------------------*/ -/*The maximal length of a chain of symbolic links*/ -int netfs_maxsymlinks = 12; -/*----------------------------------------------------------------------------*/ -/*A port to the underlying node*/ -mach_port_t underlying_node; -/*----------------------------------------------------------------------------*/ -/*Status information for the underlying node*/ -io_statbuf_t underlying_node_stat; -/*----------------------------------------------------------------------------*/ -/*Mapped time used for updating node information*/ -volatile struct mapped_time_value * maptime; -/*----------------------------------------------------------------------------*/ -/*The filesystem ID*/ -pid_t fsid; -/*----------------------------------------------------------------------------*/ -/*The file to print debug messages to*/ -FILE * filterfs_dbg; -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------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, - char * name, - mode_t mode, - struct node ** node -) -{ - LOG_MSG("netfs_attempt_create_file"); - - /*Unlock `dir` and say that we can do nothing else here*/ - mutex_unlock(&dir->lock); - return EOPNOTSUPP; -}/*netfs_attempt_create_file*/ -/*----------------------------------------------------------------------------*/ -/*Return 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 -) -{ - LOG_MSG("netfs_check_open_permissions: '%s'", np->nn->lnode->name); - - error_t err = 0; - - /*Cheks user's permissions*/ - if(flags & O_READ) - err = fshelp_access(&np->nn_stat, S_IREAD, user); - if(!err && (flags & O_WRITE)) - err = fshelp_access(&np->nn_stat, S_IWRITE, user); - if(!err && (flags & O_EXEC)) - err = fshelp_access(&np->nn_stat, S_IEXEC, user); - - /*Return the result of the check*/ - return err; -}/*netfs_check_open_permissions*/ -/*----------------------------------------------------------------------------*/ -/*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 -) -{ - LOG_MSG("netfs_attempt_utimes"); - - error_t err = 0; - - /*See what information is to be updated*/ - int flags = TOUCH_CTIME; - - /*Check if the user is indeed the owner of the node*/ - err = fshelp_isowner(&node->nn_stat, cred); - - /*If the user is allowed to do utimes*/ - if(!err) - { - /*If atime is to be updated*/ - if(atime) - /*update the atime*/ - node->nn_stat.st_atim = *atime; - else - /*the current time will be set as the atime*/ - flags |= TOUCH_ATIME; - - /*If mtime is to be updated*/ - if(mtime) - /*update the mtime*/ - node->nn_stat.st_mtim = *mtime; - else - /*the current time will be set as mtime*/ - flags |= TOUCH_MTIME; - - /*touch the file*/ - fshelp_touch(&node->nn_stat, flags, maptime); - } - - /*Return the result of operations*/ - return err; -}/*netfs_attempt_utimes*/ -/*----------------------------------------------------------------------------*/ -/*Returns the valid access types for file `node` and user `cred`*/ -error_t -netfs_report_access -( - struct iouser * cred, - struct node * np, - int * types -) -{ - LOG_MSG("netfs_report_access"); - - /*No access at first*/ - *types = 0; - - /*Check the access and set the required bits*/ - if(fshelp_access(&np->nn_stat, S_IREAD, cred) == 0) - *types |= O_READ; - if(fshelp_access(&np->nn_stat, S_IWRITE, cred) == 0) - *types |= O_WRITE; - if(fshelp_access(&np->nn_stat, S_IEXEC, cred) == 0) - *types |= O_EXEC; - - /*Everything OK*/ - return 0; -}/*netfs_report_access*/ -/*----------------------------------------------------------------------------*/ -/*Validates the stat data for the node*/ -error_t -netfs_validate_stat -( - struct node * np, - struct iouser * cred -) -{ - LOG_MSG("netfs_validate_stat: '%s'", np->nn->lnode->name); - - error_t err = 0; - - /*If we are not at the root*/ - if(np != netfs_root_node) - { - /*If the node is not surely up-to-date*/ - if(!(np->nn->flags & FLAG_NODE_ULFS_UPTODATE)) - { - /*update it*/ - err = node_update(np); - } - - /*If no errors have yet occurred*/ - if(!err) - { - /*If the port to the file corresponding to `np` is valid*/ - if(np->nn->port != MACH_PORT_NULL) - { - /*We have a directory here (normally, only they maintain an open port). - Generally, our only concern is to maintain an open port in this case*/ - - /*attempt to stat this file*/ - err = io_stat(np->nn->port, &np->nn_stat); - - /*If stat information has been successfully obtained for the file*/ - if(!err) - /*duplicate the st_mode field of stat structure*/ - np->nn_translated = np->nn_stat.st_mode; - } - else - { - /*We, most probably, have something which is not a directory. Therefore - we will open the port and close it after the stat, so that additional - resources are not consumed.*/ - - /*the parent node of the current node*/ - node_t * dnp; - - /*obtain the parent node of the the current node*/ - err = ncache_node_lookup(np->nn->lnode->dir, &dnp); - - /*the lookup should never fail here*/ - assert(!err); - - /*open a port to the file we are interested in*/ - mach_port_t p = file_name_lookup_under - (dnp->nn->port, np->nn->lnode->name, 0, 0); - - /*put `dnp` back, since we don't need it any more*/ - netfs_nput(dnp); - - if(!p) - return EBADF; - - /*try to stat the node*/ - err = io_stat(p, &np->nn_stat); - - /*deallocate the port*/ - PORT_DEALLOC(p); - } - } - } - /*If we are at the root*/ - else - /*put the size of the node into the stat structure belonging to `np`*/ - node_get_size(np, (OFFSET_T *)&np->nn_stat.st_size); - - /*Return the result of operations*/ - return err; -}/*netfs_validate_stat*/ -/*----------------------------------------------------------------------------*/ -/*Syncs `node` completely to disk*/ -error_t -netfs_attempt_sync -( - struct iouser * cred, - struct node * node, - int wait -) -{ - LOG_MSG("netfs_attempt_sync"); - - /*Operation is not supported*/ - return EOPNOTSUPP; -}/*netfs_attempt_sync*/ -/*----------------------------------------------------------------------------*/ -/*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 -) -{ - LOG_MSG("netfs_get_dirents: '%s'", dir->nn->lnode->name); - - error_t err; - - /*Two pointers required for processing the list of dirents*/ - node_dirent_t * dirent_start, * dirent_current; - - /*The pointer to the beginning of the list of dirents*/ - node_dirent_t * dirent_list = NULL; - - /*The size of the current dirent*/ - size_t size = 0; - - /*The number of dirents added*/ - int count = 0; - - /*The dereferenced value of parameter `data`*/ - char * data_p; - - /*Takes into account the size of the given dirent*/ - int - bump_size - ( - const char * name - ) - { - /*If the required number of entries has not been listed yet*/ - if((num_entries == -1) || (count < num_entries)) - { - /*take the current size and take into account the length of the name*/ - size_t new_size = size + DIRENT_LEN(strlen(name)); - - /*If there is a limit for the received size and it has been exceeded*/ - if((max_data_len > 0) && (new_size > max_data_len)) - /*a new dirent cannot be added*/ - return 0; - - /*memorize the new size*/ - size = new_size; - - /*increase the number of dirents added*/ - ++count; - - /*everything is OK*/ - return 1; - } - else - { - /*dirents cannot be added*/ - return 0; - } - }/*bump_size*/ - - /*Adds a dirent to the list of dirents*/ - int - add_dirent - ( - const char * name, - ino_t ino, - int type - ) - { - /*If the required number of dirents has not been listed yet*/ - if((num_entries == -1) || (count < num_entries)) - { - /*create a new dirent*/ - struct dirent hdr; - - /*obtain the length of the name*/ - size_t name_len = strlen(name); - - /*compute the full size of the dirent*/ - size_t sz = DIRENT_LEN(name_len); - - /*If there is no room for this dirent*/ - if(sz > size) - /*stop*/ - return 0; - else - /*take into account the fact that a new dirent has just been added*/ - size -= sz; - - /*setup the dirent*/ - hdr.d_ino = ino; - hdr.d_reclen = sz; - hdr.d_type = type; - hdr.d_namlen = name_len; - - /*The following two lines of code reflect the old layout of - dirents in the memory. Now libnetfs expects the layout - identical to the layout provided by dir_readdir (see dir_entries_get)*/ - - /*copy the header of the dirent into the final block of dirents*/ - memcpy(data_p, &hdr, DIRENT_NAME_OFFS); - - /*copy the name of the dirent into the block of dirents*/ - strcpy(data_p + DIRENT_NAME_OFFS, name); - - /*This line is commented for the same reason as the two specifically - commented lines above.*/ - /*move the current pointer in the block of dirents*/ - data_p += sz; - - /*count the new dirent*/ - ++count; - - /*everything was OK, so say it*/ - return 1; - } - else - /*no [new] dirents allowed*/ - return 0; - }/*add_dirent*/ - - /*List the dirents for node `dir`*/ - err = node_entries_get(dir, &dirent_list); - - /*If listing was successful*/ - if(!err) - { - /*find the entry whose number is `first_entry`*/ - for - ( - dirent_start = dirent_list, count = 2; - dirent_start && (count < first_entry); - dirent_start = dirent_start->next, ++count - ); - - /*reset number of dirents added so far*/ - count = 0; - - /*make space for entries '.' and '..', if required*/ - if(first_entry == 0) - bump_size("."); - if(first_entry <= 1) - bump_size(".."); - - /*Go through all dirents*/ - for - ( - dirent_current = dirent_start; - dirent_current; - dirent_current = dirent_current->next - ) - /*If another dirent cannot be added succesfully*/ - if(bump_size(dirent_current->dirent->d_name) == 0) - /*stop here*/ - break; - - /*allocate the required space for dirents*/ - *data = mmap(0, size, PROT_READ | PROT_WRITE, MAP_ANON, 0, 0); - - /*check if any error occurred*/ - err = ((void *)*data == MAP_FAILED) ? (errno) : (0); - } - - /*If no errors have occurred so far*/ - if(!err) - { - /*obtain the pointer to the beginning of the block of dirents*/ - data_p = *data; - - /*fill the parameters with useful values*/ - *data_len = size; - *data_entries = count; - - /*reset the number of dirents added*/ - count = 0; - - /*add entries '.' and '..', if required*/ - if(first_entry == 0) - add_dirent(".", 2, DT_DIR); - if(first_entry <= 1) - add_dirent("..", 2, DT_DIR); - - /*Follow the list of dirents beginning with dirents_start*/ - for - ( - dirent_current = dirent_start; dirent_current; - dirent_current = dirent_current->next - ) - /*If the addition of the current dirent fails*/ - if - ( - add_dirent - (dirent_current->dirent->d_name, dirent_current->dirent->d_fileno, - dirent_current->dirent->d_type) == 0 - ) - /*stop adding dirents*/ - break; - } - - /*If the list of dirents has been allocated, free it*/ - if(dirent_list) - node_entries_free(dirent_list); - - /*The directory has been read right now, modify the access time*/ - fshelp_touch(&dir->nn_stat, TOUCH_ATIME, maptime); - - /*Return the result of listing the dirents*/ - return err; -}/*netfs_get_dirents*/ -/*----------------------------------------------------------------------------*/ -/*Looks up `name` under `dir` for `user`*/ -error_t -netfs_attempt_lookup -( - struct iouser * user, - struct node * dir, - char * name, - struct node ** node -) -{ - LOG_MSG("netfs_attempt_lookup: '%s'", name); - - error_t err = 0; - - /*If we are asked to fetch the current directory*/ - if(strcmp(name, ".") == 0) - { - /*add a reference to `dir` and put it into `node`*/ - netfs_nref(dir); - *node = dir; - - /*everything is OK*/ - return 0; - } - /*If we are asked to fetch the parent directory*/ - else if(strcmp(name, "..") == 0) - { - /*If the supplied node is not root*/ - if(dir->nn->lnode->dir) - { - /*The node corresponding to the parent directory must exist here*/ - assert(dir->nn->lnode->dir->node); - - /*put the parent node of `dir` into the result*/ - err = ncache_node_lookup(dir->nn->lnode->dir, node); - } - /*The supplied node is root*/ - else - { - /*this node is not included into our filesystem*/ - err = ENOENT; - *node = NULL; - } - - /*unlock the directory*/ - mutex_unlock(&dir->lock); - - /*stop here*/ - return err; - } - - /*Checks whether the given name satisfied the required property*/ - int - check_property - ( - const char * name - ) - { - /*If there is no property*/ - if(!property) - /*no filtering will be applied, any name is OK*/ - return 0; - - /*The number of occurrences of PROPERTY_PARAM in the property*/ - int param_entries_count = 0; - - /*The pointer to the current occurrence of PROPERTY_PARAM*/ - char * occurrence = strstr(property, PROPERTY_PARAM); - - /*Count the number of occurrences*/ - for(; occurrence; - occurrence = strstr(occurrence + 1, PROPERTY_PARAM), - ++param_entries_count); - - /*Compute the length of the property param*/ - size_t property_param_len = strlen(PROPERTY_PARAM); - - /*The length of the property*/ - size_t property_len = (property) ? (strlen(property)) : (0); - - /*Everything OK at first*/ - err = 0; - - /*Compute the length of the full name once*/ - size_t full_name_len = strlen(dir->nn->lnode->path) + 1 + strlen(name) + 1; - - /*Try to allocate the required space*/ - char * full_name = malloc(full_name_len); - if(!full_name) - { - err = ENOMEM; - return 0; - } - - /*Initialize `full_name` as a valid string*/ - full_name[0] = 0; - - /*Construct the full name*/ - strcpy(full_name, dir->nn->lnode->path); - strcat(full_name, "/"); - strcat(full_name, name); - - LOG_MSG("netfs_attempt_lookup: Applying filter to %s...", full_name); - - /*Compute the space required for the final filtering command*/ - size_t sz = property_len + (strlen(full_name) - property_param_len) - * param_entries_count; - - /*Try to allocate the space for the command*/ - char * cmd = malloc(sz); - if(!cmd) - { - free(full_name); - err = ENOMEM; - return 0; - } - - /*Initialize `cmd` as a valid string*/ - cmd[0] = 0; - - /*The current occurence of PROPERTY_PARAM in property*/ - char * p = strstr(property, PROPERTY_PARAM); - - /*The pointer to the current position in the property*/ - char * propp = property; - - /*While the command has not been constructed*/ - for(; p; p = strstr(propp, PROPERTY_PARAM)) - { - /*add the new part of the property to the command*/ - strncat(cmd, propp, p - propp); - - /*add the filename to the command*/ - strcat(cmd, full_name); - - /*LOG_MSG("\tcmd = '%s'", cmd);*/ - - /*advance the pointer in the property*/ - propp = p + property_param_len; - - /*LOG_MSG("\tpropp points at '%s'", propp);*/ - } - - /*Copy the rest of the property to the command*/ - strcat(cmd, propp); - - /*LOG_MSG("node_entries_get: The filtering command: '%s'.", cmd);*/ - - /*Execute the command*/ - int xcode = WEXITSTATUS(system(cmd)); - - /*Return the exit code of the command*/ - return xcode; - }/*check_property*/ - - /*If the given name does not satisfy the property*/ - if(check_property(name) != 0) - { - /*unlock the directory*/ - mutex_unlock(&dir->lock); - - /*no such file in the directory*/ - return ENOENT; - } - - /*Try to lookup the given file in the underlying directory*/ - mach_port_t p = file_name_lookup_under(dir->nn->port, name, 0, 0); - - /*If the lookup failed*/ - if(p == MACH_PORT_NULL) - { - /*unlock the directory*/ - mutex_unlock(&dir->lock); - - /*no such entry*/ - return ENOENT; - } - - /*Obtain the stat information about the file*/ - io_statbuf_t stat; - err = io_stat(p, &stat); - - /*Deallocate the obtained port*/ - PORT_DEALLOC(p); - - /*If this file is not a directory*/ - if(err || !S_ISDIR(stat.st_mode)) - { - /*do not set the port*/ - p = MACH_PORT_NULL; - } - else - { - /*lookup the port with the right to read the contents of the directory*/ - p = file_name_lookup_under(dir->nn->port, name, O_READ | O_DIRECTORY, 0); - if(p == MACH_PORT_NULL) - { - return EBADF; /*not enough rights?*/ - } - } - - /*The lnode corresponding to the entry we are supposed to fetch*/ - lnode_t * lnode; - - /*Finalizes the execution of this function*/ - void - finalize(void) - { - /*If some errors have occurred*/ - if(err) - { - /*the user should receive nothing*/ - *node = NULL; - - /*If there is some port, free it*/ - if(p != MACH_PORT_NULL) - PORT_DEALLOC(p); - } - /*If there is a node to return*/ - if(*node) - { - /*unlock the node*/ - mutex_unlock(&(*node)->lock); - - /*add the node to the cache*/ - ncache_node_add(*node); - } - - /*Unlock the mutexes in `dir`*/ - mutex_unlock(&dir->nn->lnode->lock); - mutex_unlock(&dir->lock); - }/*finalize*/ - - /*Try to find an lnode called `name` under the lnode corresponding to `dir`*/ - err = lnode_get(dir->nn->lnode, name, &lnode); - - /*If such an entry does not exist*/ - if(err == ENOENT) - { - /*create a new lnode with the supplied name*/ - err = lnode_create(name, &lnode); - if(err) - { - finalize(); - return err; - } - - /*install the new lnode into the directory*/ - lnode_install(dir->nn->lnode, lnode); - } - - /*Obtain the node corresponding to this lnode*/ - err = ncache_node_lookup(lnode, node); - - /*Remove an extra reference from the lnode*/ - lnode_ref_remove(lnode); - - /*If the lookup in the cache failed*/ - if(err) - { - /*stop*/ - finalize(); - return err; - } - - /*Store the port in the node*/ - (*node)->nn->port = p; - - /*Construct the full path to the node*/ - err = lnode_path_construct(lnode, NULL); - if(err) - { - finalize(); - return err; - } - - /*Now the node is up-to-date*/ - (*node)->nn->flags = FLAG_NODE_ULFS_UPTODATE; - - /*Return the result of performing the operations*/ - finalize(); - return err; -}/*netfs_attempt_lookup*/ -/*----------------------------------------------------------------------------*/ -/*Deletes `name` in `dir` for `user`*/ -error_t -netfs_attempt_unlink -( - struct iouser * user, - struct node * dir, - char * name -) -{ - LOG_MSG("netfs_attempt_unlink"); - - return 0; -}/*netfs_attempt_unlink*/ -/*----------------------------------------------------------------------------*/ -/*Attempts to rename `fromdir`/`fromname` to `todir`/`toname`*/ -error_t -netfs_attempt_rename -( - struct iouser * user, - struct node * fromdir, - char * fromname, - struct node * todir, - char * toname, - int excl -) -{ - LOG_MSG("netfs_attempt_rename"); - - /*Operation not supported*/ - return EOPNOTSUPP; -}/*netfs_attempt_rename*/ -/*----------------------------------------------------------------------------*/ -/*Attempts to create a new directory*/ -error_t -netfs_attempt_mkdir -( - struct iouser * user, - struct node * dir, - char * name, - mode_t mode -) -{ - LOG_MSG("netfs_attempt_mkdir"); - - return 0; -}/*netfs_attempt_mkdir*/ -/*----------------------------------------------------------------------------*/ -/*Attempts to remove directory `name` in `dir` for `user`*/ -error_t -netfs_attempt_rmdir -( - struct iouser * user, - struct node * dir, - char * name -) -{ - LOG_MSG("netfs_attempt_rmdir"); - - return 0; -}/*netfs_attempt_rmdir*/ -/*----------------------------------------------------------------------------*/ -/*Attempts to change the mode 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 -) -{ - LOG_MSG("netfs_attempt_chown"); - - /*Operation is not supported*/ - return EOPNOTSUPP; -}/*netfs_attempt_chown*/ -/*----------------------------------------------------------------------------*/ -/*Attempts to change the author of `node` to `author`*/ -error_t -netfs_attempt_chauthor -( - struct iouser * cred, - struct node * node, - uid_t author -) -{ - LOG_MSG("netfs_attempt_chauthor"); - - /*Operation is not supported*/ - return EOPNOTSUPP; -}/*netfs_attempt_chauthor*/ -/*----------------------------------------------------------------------------*/ -/*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 -) -{ - LOG_MSG("netfs_attempt_chmod"); - - /*Operation is not supported*/ - return EOPNOTSUPP; -}/*netfs_attempt_chmod*/ -/*----------------------------------------------------------------------------*/ -/*Attempts to turn `node` into a symlink targetting `name`*/ -error_t -netfs_attempt_mksymlink -( - struct iouser * cred, - struct node * node, - char * name -) -{ - LOG_MSG("netfs_attempt_mksymlink"); - - /*Operation is not supported*/ - return EOPNOTSUPP; -}/*netfs_attempt_mksymlink*/ -/*----------------------------------------------------------------------------*/ -/*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 -) -{ - LOG_MSG("netfs_attempt_mkdev"); - - /*Operation is not supported*/ - return EOPNOTSUPP; -}/*netfs_attempt_mkdev*/ -/*----------------------------------------------------------------------------*/ -/*Attempts to set the passive translator record for `file` passing `argz`*/ -error_t -netfs_set_translator -( - struct iouser * cred, - struct node * node, - char * argz, - size_t arglen -) -{ - LOG_MSG("netfs_set_translator"); - - /*Operation is not supported*/ - return EOPNOTSUPP; -}/*netfs_set_translator */ -/*----------------------------------------------------------------------------*/ -/*Attempts to call chflags for `node`*/ -error_t -netfs_attempt_chflags -( - struct iouser * cred, - struct node * node, - int flags -) -{ - LOG_MSG("netfs_attempt_chflags"); - - /*Operation is not supported*/ - return EOPNOTSUPP; -}/*netfs_attempt_chflags*/ -/*----------------------------------------------------------------------------*/ -/*Attempts to set the size of file `node`*/ -error_t -netfs_attempt_set_size -( - struct iouser * cred, - struct node * node, - loff_t size -) -{ - LOG_MSG("netfs_attempt_set_size"); - - /*Operation is not supported*/ - return EOPNOTSUPP; -}/*netfs_attempt_set_size*/ -/*----------------------------------------------------------------------------*/ -/*Fetches the filesystem status information*/ -error_t -netfs_attempt_statfs -( - struct iouser * cred, - struct node * node, - fsys_statfsbuf_t * st -) -{ - LOG_MSG("netfs_attempt_statfs"); - - /*Operation is not supported*/ - return EOPNOTSUPP; -}/*netfs_attempt_statfs*/ -/*----------------------------------------------------------------------------*/ -/*Syncs the filesystem*/ -error_t -netfs_attempt_syncfs -( - struct iouser * cred, - int wait -) -{ - LOG_MSG("netfs_attempt_syncfs"); - - /*Everythin OK*/ - return 0; -}/*netfs_attempt_syncfs*/ -/*----------------------------------------------------------------------------*/ -/*Creates a link in `dir` with `name` to `file`*/ -error_t -netfs_attempt_link -( - struct iouser * user, - struct node * dir, - struct node * file, - char * name, - int excl -) -{ - LOG_MSG("netfs_attempt_link"); - - /*Operation not supported*/ - return EOPNOTSUPP; -}/*netfs_attempt_link*/ -/*----------------------------------------------------------------------------*/ -/*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 -) -{ - LOG_MSG("netfs_attempt_mkfile"); - - /*Unlock the directory*/ - mutex_unlock(&dir->lock); - - /*Operation not supported*/ - return EOPNOTSUPP; -}/*netfs_attempt_mkfile*/ -/*----------------------------------------------------------------------------*/ -/*Reads the contents of symlink `node` into `buf`*/ -error_t -netfs_attempt_readlink -( - struct iouser * user, - struct node * node, - char * buf -) -{ - LOG_MSG("netfs_attempt_readlink"); - - /*Operation not supported (why?..)*/ - return EOPNOTSUPP; -}/*netfs_attempt_readlink*/ -/*----------------------------------------------------------------------------*/ -/*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 -) -{ - LOG_MSG("netfs_attempt_read"); - - error_t err = 0; - - /*If there is no port open for the current node*/ - if(np->nn->port == MACH_PORT_NULL) - { - /*the parent node of the current node*/ - node_t * dnp; - - /*obtain the parent node of the the current node*/ - err = ncache_node_lookup(np->nn->lnode->dir, &dnp); - - /*the lookup should never fail here*/ - assert(!err); - - /*open a port to the file we are interested in*/ - mach_port_t p = file_name_lookup_under - (dnp->nn->port, np->nn->lnode->name, O_READ, 0); - - /*put `dnp` back, since we don't need it any more*/ - netfs_nput(dnp); - - if(!p) - return EBADF; - - /*store the port in the node*/ - np->nn->port = p; - } - - /*Read the required data from the file*/ - err = io_read(np->nn->port, (char **)&data, len, offset, *len); - - /*Return the result of reading*/ - return err; -}/*netfs_attempt_read*/ -/*----------------------------------------------------------------------------*/ -/*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, - void * data -) -{ - LOG_MSG("netfs_attempt_write"); - - return 0; -}/*netfs_attempt_write*/ -/*----------------------------------------------------------------------------*/ -/*Frees all storage associated with the node*/ -void -netfs_node_norefs -( - struct node * np -) -{ - /*Destroy the node*/ - node_destroy(np); -}/*netfs_node_norefs*/ -/*----------------------------------------------------------------------------*/ -/*Entry point*/ -int -main -( - int argc, - char ** argv -) -{ - /*Start logging*/ - INIT_LOG(); - LOG_MSG(">> Starting initialization..."); - - /*The port on which this translator will be set upon*/ - mach_port_t bootstrap_port; - - error_t err = 0; - - /*Parse the command line arguments*/ - argp_parse(&argp_startup, argc, argv, ARGP_IN_ORDER, 0, 0); - LOG_MSG("Command line arguments parsed."); - - /*Try to create the root node*/ - err = node_create_root(&netfs_root_node); - if(err) - error(EXIT_FAILURE, err, "Failed to create the root node"); - LOG_MSG("Root node created."); - - /*Obtain the bootstrap port*/ - task_get_bootstrap_port(mach_task_self(), &bootstrap_port); - - /*Initialize the translator*/ - netfs_init(); - - /*Obtain a port to the underlying node*/ - underlying_node = netfs_startup(bootstrap_port, O_READ); - LOG_MSG("netfs initialization complete."); - - /*Initialize the root node*/ - err = node_init_root(netfs_root_node); - if(err) - error(EXIT_FAILURE, err, "Failed to initialize the root node"); - LOG_MSG("Root node initialized."); - LOG_MSG("\tRoot node address: 0x%lX", (unsigned long)netfs_root_node); - - /*Map the time for updating node information*/ - err = maptime_map(0, 0, &maptime); - if(err) - error(EXIT_FAILURE, err, "Failed to map the time"); - LOG_MSG("Time mapped."); - - /*Initialize the cache with the required number of nodes*/ - ncache_init(ncache_size); - LOG_MSG("Cache initialized."); - - /*Obtain stat information about the underlying node*/ - err = io_stat(underlying_node, &underlying_node_stat); - if(err) - error(EXIT_FAILURE, err, - "Cannot obtain stat information about the underlying node"); - LOG_MSG("Stat information for undelying node obtained."); - - /*Obtain the ID of the current process*/ - fsid = getpid(); - - /*Setup the stat information for the root node*/ - netfs_root_node->nn_stat = underlying_node_stat; - - netfs_root_node->nn_stat.st_ino = FILTERFS_ROOT_INODE; - netfs_root_node->nn_stat.st_fsid = fsid; - netfs_root_node->nn_stat.st_mode = S_IFDIR | (underlying_node_stat.st_mode - & ~S_IFMT & ~S_ITRANS); /*we are providing a translated directory*/ - - netfs_root_node->nn_translated = netfs_root_node->nn_stat.st_mode; - - /*If the underlying node is not a directory, enhance the permissions - of the root node of filterfs*/ - if(!S_ISDIR(underlying_node_stat.st_mode)) - { - /*can be read by owner*/ - if(underlying_node_stat.st_mode & S_IRUSR) - /*allow execution by the owner*/ - netfs_root_node->nn_stat.st_mode |= S_IXUSR; - /*can be read by group*/ - if(underlying_node_stat.st_mode & S_IRGRP) - /*allow execution by the group*/ - netfs_root_node->nn_stat.st_mode |= S_IXGRP; - /*can be read by others*/ - if(underlying_node_stat.st_mode & S_IROTH) - /*allow execution by the others*/ - netfs_root_node->nn_stat.st_mode |= S_IXOTH; - } - - /*Update the timestamps of the root node*/ - fshelp_touch - (&netfs_root_node->nn_stat, TOUCH_ATIME | TOUCH_MTIME | TOUCH_CTIME, - maptime); - - LOG_MSG(">> Initialization complete. Entering netfs server loop..."); - - /*Start serving clients*/ - for(;;) - netfs_server_loop(); -}/*main*/ -/*----------------------------------------------------------------------------*/ diff --git a/netfs-sample/filterfs.h b/netfs-sample/filterfs.h deleted file mode 100644 index 4470a7fb..00000000 --- a/netfs-sample/filterfs.h +++ /dev/null @@ -1,453 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/*filter.h*/ -/*----------------------------------------------------------------------------*/ -/*The definitions for the filtering translator*/ -/*----------------------------------------------------------------------------*/ -/*Based on the code of unionfs translator.*/ -/*----------------------------------------------------------------------------*/ -/*Copyright (C) 2001, 2002, 2005 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 __FILTERFS_H__ -#define __FILTERFS_H__ -/*----------------------------------------------------------------------------*/ -#include <stddef.h> -#include <stdlib.h> -#include <cthreads.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 for the root node*/ -#define FILTERFS_ROOT_INODE 1 -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Global Variables----------------------------------------------------*/ -/*A mapped time value for filterfs*/ -/*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; -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Structures----------------------------------------------------------*/ -/*A single entry in a directory*/ -struct filterfs_dir_entry - { - char * name; /*name of the entry*/ - size_t hv; /*hash value of NAME*/ - - struct node * node; /*the active node referred to by this node (may be 0)*/ - /*NETFS_NDOE_REFCNT_LOCK should be hel whule frobbing this*/ - - struct stat stat; /*status information*/ - - char * symlink_target; /*the name of the node this entry might refer to*/ - - time_t stat_timestamp; /*the moment at which the status information was retreieved*/ - - /*the directory to which this entry belongs*/ - struct filterfs_dir * dir; - - /*link to the entry in hash bucket and the address of the previous entry's - (or hashtable's) pointer to this entry*/ - /*If self_p is null, then this entry is deleted and awaiting - the final disposal*/ - struct filterfs_dir_entry * next, ** self_p; - - /*the next and the previous entries in the 'directory order'; 0 if there - are none*/ - struct filterfs_dir_entry * ordered_next, ** ordered_self_p; - - /*when the presence/absence of this file was last checked*/ - time_t name_timestamp; - - /*used for removing this entry*/ - hurd_ihash_locp_t inode_locp; - - /*a field for a negative result of lookup*/ - int noent : 1; - - /*a marker for gabage collecting*/ - int valid : 1; - };/*struct filterfs_dir_entry*/ -/*----------------------------------------------------------------------------*/ -/*A directory*/ -struct filterfs_dir - { - /*the number of entries in the hash table*/ - size_t num_entries; - - /*the number of entries that have nodes attached*/ - /*We keep an additional reference to our node if there is any, - to prevent it from going away*/ - size_t num_live_entries; - - /*the hash table for entries*/ - struct filterfs_dir_entry ** htable; - size_t htable_len; /*the lenght of the hash table*/ - - /*the list of entries in 'directory order'.*/ - /*The entries are listed in a linked list using the ordered_next - and ordered_self_p fields in each entry. Not all entries in htable - need to be in this list*/ - struct filterfs_dir_entry * ordered; - - /*the filesystem node corresponding to this directory*/ - struct node * node; - - /*the filesystem this directory is in*/ - struct filterfs * fs; - - /*when the presence/absence of this file was last checked*/ - time_t name_timestamp; - - /*used for removing this entry*/ - hurd_ihash_locp_t inode_locp; - - /*Stuff for detecting bulk stats (?)*/ - /*Might be reduntant for this project*/ - - /*the timestamp of the first sample in bulk_stat_count1, rounded to - BULK_STAT_PERIOD seconds*/ - time_t buld_stat_base_stamp; - - /*the number of stats done in the period - [bulk_stat_base_stamp, bulk_stat_base_stamp + BULK_STAT_PERIOD]*/ - unsigned bulk_stat_count_first_half; - - /*the number of stats done in the period - [bulk_stat_bast_stamp + BULK_STAT_PERIOD, - bulk_stat_bast_stamp + 2 * BULK_STAT_PERIOD]*/ - unsigned bulk_stat_count_second_half; - };/*struct filterfs_dir*/ -/*----------------------------------------------------------------------------*/ -/*A particular filesystem*/ -struct filterfs - { - /*the root of the filesystem*/ - struct node * root; - - /*inode numbers*/ - /*Assigned sequentially in the order of creation*/ - ino_t next_inode; - - /*the identifier of the filesystem (?)*/ - int fsid; - - /*a hash table mapping inode numbers to directory entries*/ - struct hurd_ihash inode_mappings; - - /*the lock for the hash table*/ - spin_lock_t inode_mappings_lock; - };/*struct filterfs*/ -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------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, - 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, - char * name, - struct node ** node - ); -/*----------------------------------------------------------------------------*/ -/*Deletes `name` in `dir` for `user`*/ -error_t -netfs_attempt_unlink - ( - struct iouser * user, - struct node * dir, - char * name - ); -/*----------------------------------------------------------------------------*/ -/*Attempts to rename `fromdir`/`fromname` to `todir`/`toname`*/ -error_t -netfs_attempt_rename - ( - struct iouser * user, - struct node * fromdir, - char * fromname, - struct node * todir, - char * toname, - int excl - ); -/*----------------------------------------------------------------------------*/ -/*Attempts to create a new directory*/ -error_t -netfs_attempt_mkdir - ( - struct iouser * user, - struct node * dir, - 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, - 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, - 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, - char * argz, - size_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, - 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, - void * data - ); -/*----------------------------------------------------------------------------*/ -/*Frees all storage associated with the node*/ -void -netfs_node_norefs - ( - struct node * np - ); -/*----------------------------------------------------------------------------*/ -#endif diff --git a/netfs-sample/lib.c b/netfs-sample/lib.c deleted file mode 100644 index aa0ff0be..00000000 --- a/netfs-sample/lib.c +++ /dev/null @@ -1,193 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/*lib.h*/ -/*----------------------------------------------------------------------------*/ -/*Basic routines for filesystem manipulations*/ -/*----------------------------------------------------------------------------*/ -/*Based on the code of unionfs translator.*/ -/*----------------------------------------------------------------------------*/ -/*Copyright (C) 2001, 2002, 2005 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.*/ -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -#define _GNU_SOURCE 1 -/*----------------------------------------------------------------------------*/ -#include <sys/mman.h> -/*----------------------------------------------------------------------------*/ -#include "lib.h" -#include "debug.h" -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Functions-----------------------------------------------------------*/ -/*Fetches directory entries for `dir`*/ -error_t -dir_entries_get - ( - file_t dir, - char ** dirent_data, /*the list of directory entries as returned - by dir_readdir*/ - size_t * dirent_data_size, /*the size of `dirent_data`*/ - struct dirent *** dirent_list /*the array of pointers to beginnings of - dirents in dirent_data*/ - ) - { - error_t err = 0; - - /*The data (array of dirents(?)) returned by dir_readdir*/ - char * data; - - /*The size of `data`*/ - size_t data_size; - - /*The number of entries in `data`*/ - int entries_num; - - /*Try to read the contents of the specified directory*/ - err = dir_readdir(dir, &data, &data_size, 0, -1, 0, &entries_num); - if(err) - return err; - - /*Create a new list of dirents*/ - struct dirent ** list; - - /*Allocate the memory for the list of dirents and for the - finalizing element*/ - list = malloc(sizeof(struct dirent *) * (entries_num + 1)); - - /*If memory allocation has failed*/ - if(!list) - { - /*free the result of dir_readdir*/ - munmap(data, data_size); - - /*return the corresponding error*/ - return ENOMEM; - } - - /*The current directory entry*/ - struct dirent * dp; - - int i; - - /*Go through every element of the list of dirents*/ - for - ( - i = 0, dp = (struct dirent *)data; - i < entries_num; - ++i, dp = (struct dirent *)((char *)dp + dp->d_reclen)) - /*copy the current value into the list*/ - *(list + i) = dp; - - /*Nullify the last element of the list*/ - *(list + i) = NULL; - - /*Copy the required values in the parameters*/ - *dirent_data = data; - *dirent_data_size = data_size; - *dirent_list = list; - - /*Return success*/ - return err; - }/*dir_entries_get*/ -/*----------------------------------------------------------------------------*/ -/*Lookup `name` under `dir` (or cwd, if `dir` is invalid)*/ -error_t -file_lookup - ( - file_t dir, - char * name, - int flags0, /*try to open with these flags first*/ - int flags1, /*try to open with these flags, if `flags0` fail*/ - int mode, /*if the file is to be created, create it with this mode*/ - file_t * port, /*store the port to the looked up file here*/ - io_statbuf_t * stat /*store the stat information here*/ - ) - { - error_t err = 0; - - /*The port to the looked up file*/ - file_t p; - - /*The stat information about the looked up file*/ - io_statbuf_t s; - - /*Performs a lookup under 'dir' or in cwd, if `dir` is invalid*/ - file_t - do_file_lookup - ( - file_t dir, - char * name, /*lookup this file*/ - int flags, /*lookup the file with these flags*/ - int mode /*if a new file is to be created, create it with this mode*/ - ) - { - /*The result of lookup*/ - file_t p; - - /*If `dir` is a valid port*/ - if(dir != MACH_PORT_NULL) - /*try to lookup `name` under `dir`*/ - p = file_name_lookup_under(dir, name, flags, mode); - else - /*lookup `name` under current cwd*/ - p = file_name_lookup(name, flags, mode); - - /*Return the result of the lookup*/ - return p; - }/*do_file_lookup*/ - - /*Lookup `name` under the suggested `dir`*/ - p = do_file_lookup(dir, name, flags0, mode); - - /*If the lookup failed*/ - if(p == MACH_PORT_NULL) - /*try to lookup for `name` using alternative flags `flags1`*/ - p = do_file_lookup(dir, name, flags1, mode); - - /*If the port is valid*/ - if(p != MACH_PORT_NULL) - { - /*If stat information is required*/ - if(stat) - { - /*obtain stat information for `p`*/ - err = io_stat(p, &s); - if(err) - PORT_DEALLOC(p); - } - } - else - /*copy `errno` into `err`*/ - err = errno; - - /*If no errors have happened during lookup*/ - if(!err) - { - /*copy the resulting port into *`port`*/ - *port = p; - - /*fill in the receiver for stat information, if requried*/ - if(stat) - *stat = s; - } - - /*Return the result of performing operations*/ - return err; - }/*file_lookup*/ -/*----------------------------------------------------------------------------*/ diff --git a/netfs-sample/lib.h b/netfs-sample/lib.h deleted file mode 100644 index 6335efcf..00000000 --- a/netfs-sample/lib.h +++ /dev/null @@ -1,82 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/*lib.h*/ -/*----------------------------------------------------------------------------*/ -/*Declarations of basic routines for filesystem manipulations*/ -/*----------------------------------------------------------------------------*/ -/*Based on the code of unionfs translator.*/ -/*----------------------------------------------------------------------------*/ -/*Copyright (C) 2001, 2002, 2005 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 __LIB_H__ -#define __LIB_H__ - -/*----------------------------------------------------------------------------*/ -#define __USE_FILE_OFFSET64 -/*----------------------------------------------------------------------------*/ -#include <hurd.h> -#include <dirent.h> -#include <stddef.h> -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Macros--------------------------------------------------------------*/ -/*Alignment of directory entries*/ -#define DIRENT_ALIGN 4 -/*----------------------------------------------------------------------------*/ -/*The offset of the directory name in the directory entry structure*/ -#define DIRENT_NAME_OFFS offsetof(struct dirent, d_name) -/*----------------------------------------------------------------------------*/ -/*Computes the length of the structure before the name + the name + 0, - all padded to DIRENT_ALIGN*/ -#define DIRENT_LEN(name_len)\ - ((DIRENT_NAME_OFFS + (name_len) + 1 + DIRENT_ALIGN - 1) &\ - ~(DIRENT_ALIGN - 1)) -/*----------------------------------------------------------------------------*/ -/*Deallocate the given port for the current task*/ -#define PORT_DEALLOC(p) (mach_port_deallocate(mach_task_self(), (p))) -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Functions-----------------------------------------------------------*/ -/*Fetches directory entries for `dir`*/ -error_t -dir_entries_get - ( - file_t dir, - char ** dirent_data, /*the list of directory entries as returned - by dir_readdir*/ - size_t * dirent_data_size, /*the size of `dirent_data`*/ - struct dirent *** dirent_list /*the array of pointers to beginnings of - dirents in dirent_data*/ - ); -/*----------------------------------------------------------------------------*/ -/*Lookup `name` under `dir` (or cwd, if `dir` is invalid)*/ -error_t -file_lookup - ( - file_t dir, - char * name, - int flags0, /*try to open with these flags first*/ - int flags1, /*try to open with these flags, if `flags0` fail*/ - int mode, /*if the file is to be created, create it with this mode*/ - file_t * port, /*store the port to the looked up file here*/ - io_statbuf_t * stat /*store the stat information here*/ - ); -/*----------------------------------------------------------------------------*/ -#endif /*__LIB_H__*/ diff --git a/netfs-sample/lnode.c b/netfs-sample/lnode.c deleted file mode 100644 index 33394ed0..00000000 --- a/netfs-sample/lnode.c +++ /dev/null @@ -1,305 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/*lnode.c*/ -/*----------------------------------------------------------------------------*/ -/*Implementation of policies of management of 'light nodes'*/ -/*----------------------------------------------------------------------------*/ -/*Based on the code of unionfs translator.*/ -/*----------------------------------------------------------------------------*/ -/*Copyright (C) 2001, 2002, 2005 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.*/ -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -#define _GNU_SOURCE -/*----------------------------------------------------------------------------*/ -#include "lnode.h" -#include "debug.h" -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Functions-----------------------------------------------------------*/ -/*Adds a reference to the `lnode` (which must be locked)*/ -void -lnode_ref_add - ( - lnode_t * node - ) - { - /*Increment the number of references*/ - ++node->references; - }/*lnode_ref_add*/ -/*----------------------------------------------------------------------------*/ -/*Removes a reference from `node` (which must be locked). If that was the last - reference, destroy the node*/ -void -lnode_ref_remove - ( - lnode_t * node - ) - { - /*Fail if the node is not referenced by anybody*/ - assert(node->references); - - /*Decrement the number of references to `node`*/ - --node->references; - - /*If there are no references remaining*/ - if(node->references == 0) - { - /*uninstall the node from the directory it is in and destroy it*/ - lnode_uninstall(node); - lnode_destroy(node); - } - else - /*simply unlock the node*/ - mutex_unlock(&node->lock); - }/*lnode_ref_remove*/ -/*----------------------------------------------------------------------------*/ -/*Creates a new lnode with `name`; the new node is locked and contains - a single reference*/ -error_t -lnode_create - ( - char * name, - lnode_t ** node /*put the result here*/ - ) - { - /*Allocate the memory for the node*/ - lnode_t * node_new = malloc(sizeof(lnode_t)); - - /*If the memory has not been allocated*/ - if(!node_new) - { - /*stop*/ - return ENOMEM; - } - - /*The copy of the name*/ - char * name_cp = NULL; - - /*If the name exists*/ - if(name) - { - /*duplicate it*/ - name_cp = strdup(name); - - /*If the name has not been duplicated*/ - if(!name_cp) - { - /*free the node*/ - free(node_new); - - /*stop*/ - return ENOMEM; - } - } - - /*Setup the new node*/ - memset(node_new, 0, sizeof(lnode_t)); - node_new->name = name_cp; - node_new->name_len = (name_cp) ? (strlen(name_cp)) : (0); - - /*Setup one reference to this lnode*/ - node_new->references = 1; - - /*Initialize the mutex and acquire a lock on this lnode*/ - mutex_init(&node_new->lock); - mutex_lock(&node_new->lock); - - /*Store the result in the second parameter*/ - *node = node_new; - - /*Return success*/ - return 0; - }/*lnode_create*/ -/*----------------------------------------------------------------------------*/ -/*Destroys the given lnode*/ -void -lnode_destroy - ( - lnode_t * node /*destroy this*/ - ) - { - /*Destroy the name of the node*/ - free(node->name); - - /*Destroy the node itself*/ - free(node); - }/*lnode_destroy*/ -/*----------------------------------------------------------------------------*/ -/*Constructs the full path for the given lnode and stores the result both in - the parameter and inside the lnode (the same string, actually)*/ -error_t -lnode_path_construct - ( - lnode_t * node, - char ** path /*store the path here*/ - ) - { - error_t err = 0; - - /*The final path*/ - char * p; - - /*The final length of the path*/ - int p_len = 0; - - /*A temporary pointer to an lnode*/ - lnode_t * n; - - /*While the root node of the filterfs filesystem has not been reached*/ - for(n = node; n && n->dir; n = n->dir) - /*add the length of the name of `n` to `p_len` make some space for - the delimiter '/', if we are not approaching the root node*/ - /*p_len += n->name_len + ((n->dir->dir) ? (1) : (0));*/ - /*There is some path to our root node, so we will anyway have to - add a '/'*/ - p_len += n->name_len + 1; - - /*Include the space for the path to the root node of the filterfs - (n is now the root of the filesystem)*/ - p_len += strlen(n->path) + 1; - - /*Try to allocate the space for the string*/ - p = malloc(p_len * sizeof(char)); - if(!p) - err = ENOMEM; - /*If memory allocation has been successful*/ - else - { - /*put a terminal 0 at the end of the path*/ - p[--p_len] = 0; - - /*While the root node of the filterfs filesystem has not been reached*/ - for(n = node; n && n->dir; n = n->dir) - { - /*compute the position where the name of `n` is to be inserted*/ - p_len -= n->name_len; - - /*copy the name of the node into the path (omit the terminal 0)*/ - strncpy(p + p_len, n->name, n->name_len); - - /*If we are not at the root node of the filterfs filesystem, add the - separator*/ - /*if(n->dir->dir) - p[--p_len] = '/';*/ - /*we anyway have to add the separator slash*/ - p[--p_len] = '/'; - } - - /*put the path to the root node at the beginning of the first path - (n is at the root now)*/ - strncpy(p, n->path, strlen(n->path)); - - /*destroy the former path in lnode, if it exists*/ - if(node->path) - free(node->path); - - /*store the new path inside the lnode*/ - node->path = p; - - /*store the path in the parameter*/ - if(path) - *path = p; - } - - /*Return the result of operations*/ - return err; - }/*lnode_path_construct*/ -/*----------------------------------------------------------------------------*/ -/*Gets a light node by its name, locks it and increments its refcount*/ -error_t -lnode_get - ( - lnode_t * dir, /*search here*/ - char * name, /*search for this name*/ - lnode_t ** node /*put the result here*/ - ) - { - error_t err = 0; - - /*The pointer to the required lnode*/ - lnode_t * n; - - /*Find `name` among the names of entries in `dir`*/ - for(n = dir->entries; n && (strcmp(n->name, name) != 0); n = n->next); - - /*If the search has been successful*/ - if(n) - { - /*lock the node*/ - mutex_lock(&n->lock); - - /*increment the refcount of the found lnode*/ - lnode_ref_add(n); - - /*put a pointer to `n` into the parameter*/ - *node = n; - } - else - err = ENOENT; - - /*Return the result of operations*/ - return err; - }/*lnode_get*/ -/*----------------------------------------------------------------------------*/ -/*Install the lnode into the lnode tree: add a reference to `dir` (which must - be locked)*/ -void -lnode_install - ( - lnode_t * dir, /*install here*/ - lnode_t * node /*install this*/ - ) - { - /*Install `node` into the list of entries in `dir`*/ - node->next = dir->entries; - node->prevp = &dir->entries; /*this node is the first on the list*/ - if(dir->entries) - dir->entries->prevp = &node->next; /*here `prevp` gets the value - corresponding to its meaning*/ - dir->entries = node; - - /*Add a new reference to dir*/ - lnode_ref_add(dir); - - /*Setup the `dir` link in node*/ - node->dir = dir; - }/*lnode_install*/ -/*----------------------------------------------------------------------------*/ -/*Unistall the node from the node tree; remove a reference from the lnode - containing `node`*/ -void -lnode_uninstall - ( - lnode_t * node - ) - { - /*Remove a reference from the parent*/ - lnode_ref_remove(node->dir); - - /*Make the next pointer in the previous element point to the element, - which follows `node`*/ - *node->prevp = node->next; - - /*If the current node is not the last one, connect the list after removal - of the current node*/ - if(node->next) - node->next->prevp = &node->next; - }/*lnode_uninstall*/ -/*----------------------------------------------------------------------------*/ diff --git a/netfs-sample/lnode.h b/netfs-sample/lnode.h deleted file mode 100644 index 7c42c8d4..00000000 --- a/netfs-sample/lnode.h +++ /dev/null @@ -1,143 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/*lnode.h*/ -/*----------------------------------------------------------------------------*/ -/*Management of cheap 'light nodes'*/ -/*----------------------------------------------------------------------------*/ -/*Based on the code of unionfs translator.*/ -/*----------------------------------------------------------------------------*/ -/*Copyright (C) 2001, 2002, 2005 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 __LNODE_H__ -#define __LNODE_H__ - -/*----------------------------------------------------------------------------*/ -#include <error.h> -#include <hurd/netfs.h> -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*A candy synonym for the fundamental libnetfs node*/ -typedef struct node node_t; -/*----------------------------------------------------------------------------*/ -/*The light node*/ -struct lnode - { - /*the name of the lnode*/ - char * name; - - /*the length of the name; `name` does not change, and this value is used - quite often, therefore calculate it just once*/ - size_t name_len; - - /*the full path to the lnode*/ - char * path; - - /*the associated flags*/ - int flags; - - /*the number of references to this lnode*/ - int references; - - /*the reference to the real node*/ - node_t * node; - - /*the next lnode and the pointer to this lnode from the previous one*/ - struct lnode * next, **prevp; - - /*the lnode (directory) in which this node is contained*/ - struct lnode * dir; - - /*the beginning of the list of entries contained in this lnode (directory)*/ - struct lnode * entries; - - /*a lock*/ - struct mutex lock; - };/*struct lnode*/ -/*----------------------------------------------------------------------------*/ -typedef struct lnode lnode_t; -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Functions-----------------------------------------------------------*/ -/*Adds a reference to the `lnode` (which must be locked)*/ -void -lnode_ref_add - ( - lnode_t * node - ); -/*----------------------------------------------------------------------------*/ -/*Removes a reference from `node` (which must be locked). If that was the last - reference, destroy the node*/ -void -lnode_ref_remove - ( - lnode_t * node - ); -/*----------------------------------------------------------------------------*/ -/*Creates a new lnode with `name`; the new node is locked and contains - a single reference*/ -error_t -lnode_create - ( - char * name, - lnode_t ** node /*put the result here*/ - ); -/*----------------------------------------------------------------------------*/ -/*Destroys the given lnode*/ -void -lnode_destroy - ( - lnode_t * node /*destroy this*/ - ); -/*----------------------------------------------------------------------------*/ -/*Constructs the full path for the given lnode and stores the result both in - the parameter and inside the lnode (the same string, actually)*/ -error_t -lnode_path_construct - ( - lnode_t * node, - char ** path /*store the path here*/ - ); -/*----------------------------------------------------------------------------*/ -/*Gets a light node by its name, locks it and increments its refcount*/ -error_t -lnode_get - ( - lnode_t * dir, /*search here*/ - char * name, /*search for this name*/ - lnode_t ** node /*put the result here*/ - ); -/*----------------------------------------------------------------------------*/ -/*Install the lnode into the lnode tree: add a reference to `dir` (which must - be locked)*/ -void -lnode_install - ( - lnode_t * dir, /*install here*/ - lnode_t * node /*install this*/ - ); -/*----------------------------------------------------------------------------*/ -/*Unistall the node from the node tree; remove a reference from the lnode*/ -void -lnode_uninstall - ( - lnode_t * node - ); -/*----------------------------------------------------------------------------*/ -#endif /*__LNODE_H__*/ diff --git a/netfs-sample/ncache.c b/netfs-sample/ncache.c deleted file mode 100644 index 12462d31..00000000 --- a/netfs-sample/ncache.c +++ /dev/null @@ -1,221 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/*ncache.h*/ -/*----------------------------------------------------------------------------*/ -/*The implementation of the cache of nodes*/ -/*----------------------------------------------------------------------------*/ -/*Based on the code of unionfs translator.*/ -/*----------------------------------------------------------------------------*/ -/*Copyright (C) 2001, 2002, 2005 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.*/ -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -#define _GNU_SOURCE 1 -/*----------------------------------------------------------------------------*/ -#include "ncache.h" -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Global Variables----------------------------------------------------*/ -/*The global cache chain*/ -ncache_t ncache; -/*----------------------------------------------------------------------------*/ -/*Cache size (may be overwritten by the user)*/ -int ncache_size = NCACHE_SIZE; -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Functions-----------------------------------------------------------*/ -/*Initializes the node cache*/ -void -ncache_init - ( - int size_max - ) - { - /*Reset the LRU and MRU ends of the list*/ - ncache.mru = ncache.lru = NULL; - - /*Set the maximal size according to the parameter*/ - ncache.size_max = size_max; - - /*The cache is empty so far; remark that*/ - ncache.size_current = 0; - - /*Init the lock*/ - mutex_init(&ncache.lock); - }/*ncache_init*/ -/*----------------------------------------------------------------------------*/ -/*Looks up the lnode and stores the result in `node`; creates a new entry - in the cache if the lookup fails*/ -error_t -ncache_node_lookup - ( - lnode_t * lnode, /*search for this*/ - node_t ** node /*put the result here*/ - ) - { - error_t err = 0; - - /*Obtain the pointer to the node corresponding to `lnode`*/ - node_t * n = lnode->node; - - /*If a node has already been created for the given lnode*/ - if(n != NULL) - { - /*count a new reference to 'n'*/ - netfs_nref(n); - } - else - { - /*create a new node for the given lnode and store the result in `n`*/ - err = node_create(lnode, &n); - } - - /*If no errors have occurred during the previous operations*/ - if(!err) - { - /*lock the mutex in the looked up node*/ - mutex_lock(&n->lock); - - /*store the lookup result in `node`*/ - *node = n; - } - - /*Return the result of operations*/ - return err; - }/*ncache_node_lookup*/ -/*----------------------------------------------------------------------------*/ -/*Removes the given node from the cache*/ -static -void -ncache_node_remove - ( - node_t * node - ) - { - /*Obtain the pointer to the netnode (this contains the information - specific of us)*/ - struct netnode * nn = node->nn; - - /*If there exists a successor of this node in the cache chain*/ - if(nn->ncache_next) - /*remove the reference in the successor*/ - nn->ncache_next->nn->ncache_prev = nn->ncache_prev; - /*If there exists a predecessor of this node in the cache chain*/ - if(nn->ncache_prev) - /*remove the reference in the predecessor*/ - nn->ncache_prev->nn->ncache_next = nn->ncache_next; - - /*If the node was located at the MRU end of the list*/ - if(ncache.mru == node) - /*shift the MRU end to the next node*/ - ncache.mru = nn->ncache_next; - /*If the node was located at the LRU end of the list*/ - if(ncache.lru == node) - /*shift the LRU end to the previous node*/ - ncache.lru = nn->ncache_prev; - - /*Invalidate the references inside the node*/ - nn->ncache_next = nn->ncache_prev = NULL; - - /*Count the removal of a node*/ - --ncache.size_current; - }/*ncache_node_remove*/ -/*----------------------------------------------------------------------------*/ -/*Resets the node cache*/ -void -ncache_reset(void) - { - /*The node being currently deleted*/ - node_t * node; - - /*Acquire a lock on the cache*/ - mutex_lock(&ncache.lock); - - /*Remove the whole cache chain*/ - for(node = ncache.mru; node != NULL; ncache_node_remove(node), node = ncache.mru); - - /*Release the lock*/ - mutex_unlock(&ncache.lock); - }/*ncache_reset*/ -/*----------------------------------------------------------------------------*/ -/*Adds the given node to the cache*/ -void -ncache_node_add - ( - node_t * node /*the node to add*/ - ) - { - /*Acquire a lock on the cache*/ - mutex_lock(&ncache.lock); - - /*If there already are some nodes in the cache and it is enabled*/ - if((ncache.size_max > 0) || (ncache.size_current > 0)) - { - /*If the node to be added is not at the MRU end already*/ - if(ncache.mru != node) - { - /*If the node is correctly integrated in the cache*/ - if((node->nn->ncache_next != NULL) && (node->nn->ncache_prev != NULL)) - /*remove the old entry*/ - ncache_node_remove(node); - else - /*add a new reference to the node*/ - netfs_nref(node); - - /*put the node at the MRU end of the cache chain*/ - node->nn->ncache_next = ncache.mru; - node->nn->ncache_prev = NULL; - - /*setup the pointer in the old MRU end, if it exists*/ - if(ncache.mru != NULL) - ncache.mru->nn->ncache_prev = node; - - /*setup the LRU end of the cache chain, if it did not exist previously*/ - if(ncache.lru == NULL) - ncache.lru = node; - - /*shift the MRU end to the new node*/ - ncache.mru = node; - - /*count the addition*/ - ++ncache.size_current; - } - } - - /*While the size of the cache is exceeding the maximal size*/ - node_t * old_lru; - for - ( - old_lru = ncache.lru; - ncache.size_current > ncache.size_max; - old_lru = ncache.lru - ) - { - /*remove the current LRU end of the list from the cache*/ - ncache_node_remove(old_lru); - - /*release the reference to the node owned by this thread*/ - netfs_nrele(old_lru); - } - - /*Release the lock on the cache*/ - mutex_unlock(&ncache.lock); - }/*ncache_node_add*/ -/*----------------------------------------------------------------------------*/ diff --git a/netfs-sample/ncache.h b/netfs-sample/ncache.h deleted file mode 100644 index 124d514e..00000000 --- a/netfs-sample/ncache.h +++ /dev/null @@ -1,100 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/*ncache.h*/ -/*----------------------------------------------------------------------------*/ -/*The cache of nodes*/ -/*----------------------------------------------------------------------------*/ -/*Based on the code of unionfs translator.*/ -/*----------------------------------------------------------------------------*/ -/*Copyright (C) 2001, 2002, 2005 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 __NCACHE_H__ -#define __NCACHE_H__ - -/*----------------------------------------------------------------------------*/ -#include <error.h> -#include <hurd/netfs.h> -/*----------------------------------------------------------------------------*/ -#include "node.h" -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Macros--------------------------------------------------------------*/ -/*The default maximal cache size*/ -#define NCACHE_SIZE 256 -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*A cache chain*/ -struct ncache - { - /*the MRU end of the cache chain*/ - node_t * mru; - - /*the LRU end of the cache chain*/ - node_t * lru; - - /*the maximal number of nodes to cache*/ - int size_max; - - /*the current length of the cache chain*/ - int size_current; - - /*a lock*/ - struct mutex lock; - };/*struct ncache*/ -/*----------------------------------------------------------------------------*/ -typedef struct ncache ncache_t; -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Global Variables----------------------------------------------------*/ -/*The cache size (may be overwritten by the user)*/ -extern int cache_size; -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Functions-----------------------------------------------------------*/ -/*Initializes the node cache*/ -void -ncache_init - ( - int size_max - ); -/*----------------------------------------------------------------------------*/ -/*Looks up the lnode and stores the result in `node`; creates a new entry - in the cache if the lookup fails*/ -error_t -ncache_node_lookup - ( - lnode_t * lnode, /*search for this*/ - node_t ** node /*put the result here*/ - ); -/*----------------------------------------------------------------------------*/ -/*Resets the node cache*/ -void -ncache_reset(void); -/*----------------------------------------------------------------------------*/ -/*Adds the given node to the cache*/ -void -ncache_node_add - ( - node_t * node /*the node to add*/ - ); -/*----------------------------------------------------------------------------*/ -#endif /*__NCACHE_H__*/ diff --git a/netfs-sample/node.c b/netfs-sample/node.c deleted file mode 100644 index 602660b6..00000000 --- a/netfs-sample/node.c +++ /dev/null @@ -1,803 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/*node.c*/ -/*----------------------------------------------------------------------------*/ -/*Implementation of node management strategies*/ -/*----------------------------------------------------------------------------*/ -/*Based on the code of unionfs translator.*/ -/*----------------------------------------------------------------------------*/ -/*Copyright (C) 2001, 2002, 2005 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.*/ -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -#define _GNU_SOURCE 1 -/*----------------------------------------------------------------------------*/ -#include <stdlib.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/mman.h> -#include <stdio.h> -/*----------------------------------------------------------------------------*/ -#include "debug.h" -#include "node.h" -#include "options.h" -#include "lib.h" -#include "filterfs.h" -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Global Variables----------------------------------------------------*/ -/*The lock protecting the underlying filesystem*/ -struct mutex ulfs_lock = MUTEX_INITIALIZER; -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Functions-----------------------------------------------------------*/ -/*Derives a new node from `lnode` and adds a reference to `lnode`*/ -error_t -node_create -( - lnode_t * lnode, - node_t ** node /*store the result here*/ -) -{ - error_t err = 0; - - /*Create a new netnode*/ - netnode_t * netnode_new = malloc(sizeof(netnode_t)); - - /*If the memory could not be allocated*/ - if(netnode_new == NULL) - err = ENOMEM; - else - { - /*create a new node from the netnode*/ - node_t * node_new = netfs_make_node(netnode_new); - - /*If the creation failed*/ - if(node_new == NULL) - { - /*set the error code*/ - err = ENOMEM; - - /*destroy the netnode created above*/ - free(netnode_new); - - /*stop*/ - return err; - } - - /*link the lnode to the new node*/ - lnode->node = node_new; - lnode_ref_add(lnode); - - /*setup the references in the newly created node*/ - node_new->nn->lnode = lnode; - node_new->nn->flags = 0; - node_new->nn->ncache_next = node_new->nn->ncache_prev = NULL; - - /*store the result of creation in the second parameter*/ - *node = node_new; - } - - /*Return the result of operations*/ - return err; -}/*node_create*/ -/*----------------------------------------------------------------------------*/ -/*Destroys the specified node and removes a light reference from the - associated light node*/ -void -node_destroy -( - node_t * np -) -{ - /*Die if the node does not belong to node cache*/ - assert(!np->nn->ncache_next || !np->nn->ncache_prev); - - /*Destroy the port to the underlying filesystem allocated to the node*/ - PORT_DEALLOC(np->nn->port); - - /*Lock the lnode corresponding to the current node*/ - mutex_lock(&np->nn->lnode->lock); - - /*Orphan the light node*/ - np->nn->lnode->node = NULL; - - /*Remove a reference from the lnode*/ - lnode_ref_remove(np->nn->lnode); - - /*Free the netnode and the node itself*/ - free(np->nn); - free(np); -}/*node_destroy*/ -/*----------------------------------------------------------------------------*/ -/*Creates the root node and the corresponding lnode*/ -error_t -node_create_root -( - node_t ** root_node /*store the result here*/ -) -{ - /*Try to create a new lnode*/ - lnode_t * lnode; - error_t err = lnode_create(NULL, &lnode); - - /*Stop, if the creation failed*/ - if(err) - return err; - - /*Try to derive the node corresponding to `lnode`*/ - node_t * node; - err = node_create(lnode, &node); - - /*If the operation failed*/ - if(err) - { - /*destroy the created lnode*/ - lnode_destroy(lnode); - - /*stop*/ - return err; - } - - /*Release the lock on the lnode*/ - mutex_unlock(&lnode->lock); - - /*Store the result in the parameter*/ - *root_node = node; - - /*Return the result*/ - return err; -}/*node_create_root*/ -/*----------------------------------------------------------------------------*/ -/*Initializes the port to the underlying filesystem for the root node*/ -error_t -node_init_root -( - node_t * node /*the root node*/ -) -{ - error_t err = 0; - - /*Acquire a lock for operations on the underlying filesystem*/ - mutex_lock(&ulfs_lock); - - /*Open the port to the directory specified in `dir`*/ - node->nn->port = file_name_lookup(dir, O_READ | O_DIRECTORY, 0); - - /*If the directory could not be opened*/ - if(node->nn->port == MACH_PORT_NULL) - { - /*set the error code accordingly*/ - err = errno; - LOG_MSG("node_init_root: Could not open the port for %s.", dir); - - /*release the lock and stop*/ - mutex_unlock(&ulfs_lock); - return err; - } - - LOG_MSG("node_init_root: Port for %s opened successfully.", dir); - LOG_MSG("\tPort: 0x%lX", (unsigned long)node->nn->port); - - /*Stat the root node*/ - err = io_stat(node->nn->port, &node->nn_stat); - if(err) - { - /*deallocate the port*/ - PORT_DEALLOC(node->nn->port); - - LOG_MSG("node_init_root: Could not stat the root node."); - - /*unlock the mutex and exit*/ - mutex_unlock(&ulfs_lock); - return err; - } - - /*Set the path to the corresponding lnode to `dir`*/ - node->nn->lnode->path = strdup(dir); - if(!node->nn->lnode->path) - { - /*deallocate the port*/ - PORT_DEALLOC(node->nn->port); - - /*unlock the mutex*/ - mutex_unlock(&ulfs_lock); - - LOG_MSG("node_init_root: Could not strdup the directory."); - return ENOMEM; - } - - /*The current position in dir*/ - char * p = dir + strlen(dir); - - /*Go through the path from end to beginning*/ - for(; p >= dir; --p) - { - /*If the current character is a '/'*/ - if(*p == '/') - { - /*If p is not the first character*/ - if(p > dir) - { - /*if this slash is escaped, skip it*/ - if(*(p - 1) == '\\') - continue; - } - - /*advance the pointer to the first character after the slash*/ - ++p; - - /*stop*/ - break; - } - } - - LOG_MSG("node_init_root: The name of root node is %s.", p); - - /*Set the name of the lnode to the last element in the path to dir*/ - node->nn->lnode->name = strdup(p); - /*If the name of the node could not be duplicated*/ - if(!node->nn->lnode->name) - { - /*free the name of the path to the node and deallocate teh port*/ - free(node->nn->lnode->path); - PORT_DEALLOC(node->nn->port); - - /*unlock the mutex*/ - mutex_unlock(&ulfs_lock); - - LOG_MSG("node_init_root: Could not strdup the name of the root node."); - return ENOMEM; - } - - /*Compute the length of the name of the root node*/ - node->nn->lnode->name_len = strlen(p); - - /*Release the lock for operations on the undelying filesystem*/ - mutex_unlock(&ulfs_lock); - - /*Return the result of operations*/ - return err; -}/*node_init_root*/ -/*----------------------------------------------------------------------------*/ -/*Frees a list of dirents*/ -void -node_entries_free -( - node_dirent_t * dirents /*free this*/ -) -{ - /*The current and the next elements*/ - node_dirent_t * dirent, * dirent_next; - - /*Go through all elements of the list*/ - for(dirent = dirents; dirent; dirent = dirent_next) - { - /*store the next element*/ - dirent_next = dirent->next; - - /*free the dirent stored in the current element of the list*/ - free(dirent->dirent); - - /*free the current element*/ - free(dirent); - } -}/*node_entries_free*/ -/*----------------------------------------------------------------------------*/ -/*Reads the directory entries from `node`, which must be locked*/ -error_t -node_entries_get -( - node_t * node, - node_dirent_t ** dirents /*store the result here*/ -) -{ - error_t err = 0; - - /*Obtain the path to the current node*/ - char * path_to_node = node->nn->lnode->path; - - /*The number of PROPERTY_PARAMs in the property*/ - int param_entries_count = 0; - - /*The length of the property*/ - size_t property_len = (property) ? (strlen(property)) : (0); - - /*The length of PROPERTY_PARAM*/ - size_t property_param_len = strlen(PROPERTY_PARAM); - - /*The full name and the filtering command*/ - char * full_name = NULL, * cmd = NULL; - - /*The lengths of the full name and the filtering command in chunks*/ - size_t full_name_size = 1, cmd_size = 1; - - /*If some property was indeed specified*/ - if(property_len != 0) - { - /*the pointer to the current occurrence of PROPERTY_PARAM*/ - char * occurrence = strstr(property, PROPERTY_PARAM); - - /*count the number of occurrences*/ - for(; occurrence; - occurrence = strstr(occurrence + 1, PROPERTY_PARAM), - ++param_entries_count); - - /*try allocate the memory for the fullname and the filtering command*/ - full_name = malloc(full_name_size * STRING_CHUNK); - if(!full_name) - return ENOMEM; - - cmd = malloc(cmd_size * STRING_CHUNK); - if(!cmd) - { - free(full_name); - return ENOMEM; - } - } - - /*Obtain the length of the path*/ - size_t pathlen = strlen(path_to_node); - - /*Checks if the given file satisfies the property. Zero value means that - the entry must be filtered out*/ - int - check_property - ( - const char * name /*the name of the file*/ - ) - { - /*If there is no property*/ - if(!property) - /*no filtering will be applied, any name is OK*/ - return 0; - - /*Everything OK at first*/ - err = 0; - - /*Compute the length of the full name once*/ - size_t full_name_len = pathlen + 1 + strlen(name) + 1; - - /*See how much space (in chunks) is required for the full name*/ - int chunks = full_name_size; - for(; full_name_len > chunks * STRING_CHUNK; ++chunks); - - /*If more memory is requied*/ - if(chunks > full_name_size) - { - /*free the old full name*/ - free(full_name); - - /*try to allocate the new memory*/ - full_name = malloc(chunks * STRING_CHUNK); - if(!full_name) - { - err = ENOMEM; - free(cmd); /*the string for the command is definitely allocated here*/ - return 0; - } - - /*store the new size*/ - full_name_size = chunks; - } - - /*Initialize `full_name` as a valid string*/ - full_name[0] = 0; - - /*Construct the full name*/ - strcpy(full_name, path_to_node); - strcat(full_name, "/"); - strcat(full_name, name); - - /*LOG_MSG("node_entries_get: Applying filter to %s...", full_name);*/ - - /*Compute the space required for the final filtering command*/ - size_t sz = property_len + (strlen(full_name) - property_param_len) - * param_entries_count; - - /*See how much space (in chunks) is required for the command*/ - for(chunks = cmd_size; sz > chunks * STRING_CHUNK; ++chunks); - - /*If more memory is requied*/ - if(chunks > cmd_size) - { - /*free the old command*/ - free(cmd); - - /*try to allocate the new memory*/ - cmd = malloc(chunks * STRING_CHUNK); - if(!cmd) - { - err = ENOMEM; - free(full_name); /*the string for the full name is - definitely allocated here*/ - return 0; - } - - /*store the new size*/ - cmd_size = chunks; - } - - /*Initialize `cmd` as a valid string*/ - cmd[0] = 0; - - /*The current occurence of PROPERTY_PARAM in property*/ - char * p = strstr(property, PROPERTY_PARAM); - - /*The pointer to the current position in the property*/ - char * propp = property; - - /*While the command has not been constructed*/ - for(; p; p = strstr(propp, PROPERTY_PARAM)) - { - /*add the new part of the property to the command*/ - strncat(cmd, propp, p - propp); - - /*add the filename to the command*/ - strcat(cmd, full_name); - - /*LOG_MSG("\tcmd = '%s'", cmd);*/ - - /*advance the pointer in the property*/ - propp = p + property_param_len; - - /*LOG_MSG("\tpropp points at '%s'", propp);*/ - } - - /*Copy the rest of the property to the command*/ - strcat(cmd, propp); - - /*LOG_MSG("node_entries_get: The filtering command: '%s'.", cmd);*/ - - /*Execute the command*/ - int xcode = WEXITSTATUS(system(cmd)); - - /*Return the exit code of the command*/ - return xcode; - }/*check_property*/ - - /*The list of dirents*/ - struct dirent ** dirent_list, **dirent; - - /*The head of the list of dirents*/ - node_dirent_t * node_dirent_list = NULL; - - /*The size of the array of pointers to dirent*/ - size_t dirent_data_size; - - /*The array of dirents*/ - char * dirent_data; - - /*Obtain the directory entries for the given node*/ - err = dir_entries_get - (node->nn->port, &dirent_data, &dirent_data_size, &dirent_list); - if(err) - { - return err; - } - - /*The new entry in the list*/ - node_dirent_t * node_dirent_new; - - /*The new dirent*/ - struct dirent * dirent_new; - - /*LOG_MSG("node_entries_get: Getting entries for %p", node);*/ - - /*The name of the current dirent*/ - char * name; - - /*The length of the current name*/ - size_t name_len; - - /*The size of the current dirent*/ - size_t size; - - /*The exit code of property*/ - int good; - - /*Go through all elements of the list of pointers to dirent*/ - for(dirent = dirent_list; *dirent; ++dirent) - { - /*obtain the name of the current dirent*/ - name = &((*dirent)->d_name[0]); - - /*If the current dirent is either '.' or '..', skip it*/ - if((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0)) - continue; - - /*check if the current dirent has the property*/ - good = check_property(name); - if(err) - break; - - /*If the current entry is not good, skip it*/ - if(good != 0) - continue; - - /*obtain the length of the current name*/ - name_len = strlen(name); - - /*obtain the length of the current dirent*/ - size = DIRENT_LEN(name_len); - - /*create a new list element*/ - node_dirent_new = malloc(sizeof(node_dirent_t)); - if(!node_dirent_new) - { - err = ENOMEM; - break; - } - - /*create a new dirent*/ - dirent_new = malloc(size); - if(!dirent_new) - { - free(node_dirent_new); - err = ENOMEM; - break; - } - - /*fill the dirent with information*/ - dirent_new->d_ino = (*dirent)->d_ino; - dirent_new->d_type = (*dirent)->d_type; - dirent_new->d_reclen = size; - strcpy((char *)dirent_new + DIRENT_NAME_OFFS, name); - - /*add the dirent to the list*/ - node_dirent_new->dirent = dirent_new; - node_dirent_new->next = node_dirent_list; - node_dirent_list = node_dirent_new; - } - - /*If something went wrong in the loop*/ - if(err) - /*free the list of dirents*/ - node_entries_free(node_dirent_list); - else - /*store the list of dirents in the second parameter*/ - *dirents = node_dirent_list; - - /*Free the list of pointers to dirent*/ - free(dirent_list); - - /*Free the results of listing the dirents*/ - munmap(dirent_data, dirent_data_size); - - /*Free the full name and the command (if these are present at all)*/ - if(full_name) - free(full_name); - if(cmd) - free(cmd); - - /*Return the result of operations*/ - return err; -}/*node_entries_get*/ -/*----------------------------------------------------------------------------*/ -/*Makes sure that all ports to the underlying filesystem of `node` are up to - date*/ -error_t -node_update -( - node_t * node -) -{ - error_t err = 0; - - /*The full path to this node*/ - char * path; - - /*Stat information for `node`*/ - io_statbuf_t stat; - - /*The port to the file corresponding to `node`*/ - file_t port; - - /*If the specified node is the root node or if it must not be updated*/ - if(NODE_IS_ROOT(node) || (node->nn->flags & FLAG_NODE_ULFS_FIXED)) - /*do nothing*/ - return err; /*return 0; actually*/ - - /*Gain exclusive access to the root node of the filesystem*/ - mutex_lock(&netfs_root_node->lock); - - /*Construct the full path to `node`*/ - err = lnode_path_construct(node->nn->lnode, &path); - if(err) - { - mutex_unlock(&netfs_root_node->lock); - return err; - } - - /*Deallocate `node`'s port to the underlying filesystem*/ - if(node->nn->port) - PORT_DEALLOC(node->nn->port); - - /*Try to lookup the file for `node` in its untranslated version*/ - err = file_lookup - ( - netfs_root_node->nn->port, path, O_READ | O_NOTRANS, O_NOTRANS, - 0, &port, &stat - ); - if(err) - { - node->nn->port = MACH_PORT_NULL; - err = 0; /*failure (?)*/ - return err; - } - - /*If the node looked up is actually the root node of filterfs filesystem*/ - if - ( - (stat.st_ino == underlying_node_stat.st_ino) - && (stat.st_fsid == underlying_node_stat.st_fsid) - ) - /*set `err` accordingly*/ - err = ELOOP; - else - { - /*deallocate the obtained port*/ - PORT_DEALLOC(port); - - /*obtain the translated version of the required node*/ - err = file_lookup - (netfs_root_node->nn->port, path, O_READ, 0, 0, &port, &stat); - } - - /*If there have been errors*/ - if(err) - /*reset the port*/ - port = MACH_PORT_NULL; - - /*Store the port in the node*/ - node->nn->port = port; - - /*Remove the flag about the invalidity of the current node and set the - flag that the node is up-to-date*/ - node->nn->flags &= ~FLAG_NODE_INVALIDATE; - node->nn->flags |= FLAG_NODE_ULFS_UPTODATE; - - /*Release the lock on the root node of filterfs filesystem*/ - mutex_unlock(&netfs_root_node->lock); - - /*Return the result of operations*/ - return err; -}/*node_update*/ -/*----------------------------------------------------------------------------*/ -/*Computes the size of the given directory*/ -error_t -node_get_size -( - node_t * dir, - OFFSET_T * off -) -{ - error_t err = 0; - - /*The final size*/ - size_t size = 0; - - /*The number of directory entries*/ - /*int count = 0;*/ - - /*The the node in the directory entries list from which we start counting*/ - /*node_dirent_t * dirent_start = NULL;*/ - - /*The currently analyzed dirent*/ - node_dirent_t * dirent_current = NULL; - - /*The pointer to the beginning of the list of dirents*/ - node_dirent_t * dirent_list = NULL; - - /*The first entry we have to analyze*/ - /*int first_entry = 2;*/ - - /*Takes into consideration the name of the current dirent*/ - void - bump_size - ( - const char * name - ) - { - /*Increment the current size by the size of the current dirent*/ - size += DIRENT_LEN(strlen(name)); - - /*Count the current dirent*/ - /*++count;*/ - }/*bump_size*/ - - /*Obtain the list of entries in the current directory*/ - err = node_entries_get(dir, &dirent_list); - if(err) - return err; - - /*Obtain the pointer to the dirent which has the number first_entry*/ - /*Actually, the first element of the list*/ - /*This code is included in unionfs, but it's completely useless here*/ - /*for - ( - dirent_start = dirent_list, count = 2; - dirent_start && count < first_entry; - dirent_start = dirent_start->next, ++count - );*/ - - /*Reset the count*/ - /*count = 0;*/ - - /*Make space for '.' and '..' entries*/ - /*This code is included in unionfs, but it's completely useless here*/ - /*if(first_entry == 0) - bump_size("."); - if(first_entry <= 1) - bump_size("..");*/ - - /*See how much space is required for the node*/ - for - ( - dirent_current = dirent_list/*dirent_start*/; dirent_current; - dirent_current = dirent_current->next - ) - bump_size(dirent_current->dirent->d_name); - - /*Free the list of dirents*/ - node_entries_free(dirent_list); - - /*Return the size*/ - *off = size; - return 0; -}/*node_get_size*/ -/*----------------------------------------------------------------------------*/ -/*Remove the file called `name` under `dir`*/ -error_t -node_unlink_file -( - node_t * dir, - char * name -) -{ - error_t err = 0; - - /*The port to the file which will be unlinked*/ - mach_port_t p; - - /*Stat information about the file which will be unlinked*/ - io_statbuf_t stat; - - /*If port corresponding to `dir` is invalid*/ - if(dir->nn->port == MACH_PORT_NULL) - /*stop with an error*/ - return ENOENT; /*FIXME: Is the return value indeed meaningful here?*/ - - /*Attempt to lookup the specified file*/ - err = file_lookup(dir->nn->port, name, O_NOTRANS, O_NOTRANS, 0, &p, &stat); - if(err) - return err; - - /*Deallocate the obtained port*/ - PORT_DEALLOC(p); - - /*Unlink file `name` under `dir`*/ - err = dir_unlink(dir->nn->port, name); - if(err) - return err; - - return err; -}/*node_unlink_file*/ -/*----------------------------------------------------------------------------*/ diff --git a/netfs-sample/node.h b/netfs-sample/node.h deleted file mode 100644 index dcd618d4..00000000 --- a/netfs-sample/node.h +++ /dev/null @@ -1,168 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/*node.h*/ -/*----------------------------------------------------------------------------*/ -/*Node management. Also see lnode.h*/ -/*----------------------------------------------------------------------------*/ -/*Based on the code of unionfs translator.*/ -/*----------------------------------------------------------------------------*/ -/*Copyright (C) 2001, 2002, 2005 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 __NODE_H__ -#define __NODE_H__ - -/*----------------------------------------------------------------------------*/ -#include <error.h> -#include <sys/stat.h> -#include <hurd/netfs.h> -/*----------------------------------------------------------------------------*/ -#include "lnode.h" -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Macros--------------------------------------------------------------*/ -/*Checks whether the give node is the root of the filterfs filesystem*/ -#define NODE_IS_ROOT(n) (((n)->nn->lnode->dir) ? (0) : (1)) -/*----------------------------------------------------------------------------*/ -/*Node flags*/ -#define FLAG_NODE_ULFS_FIXED 0x00000001 /*this node should not be updated*/ -#define FLAG_NODE_INVALIDATE 0x00000002 /*this node must be updated*/ -#define FLAG_NODE_ULFS_UPTODATE 0x00000004 /*this node has just been updated*/ -/*----------------------------------------------------------------------------*/ -/*The type of offset corresponding to the current platform*/ -#ifdef __USE_FILE_OFFSET64 -# define OFFSET_T __off64_t -#else -# define OFFSET_T __off_t -#endif /*__USE_FILE_OFFSET64*/ -/*----------------------------------------------------------------------------*/ -/*The size of a chunk of a string (for a small optimization in checking - the property)*/ -#define STRING_CHUNK 256 -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*The user-defined node for libnetfs*/ -struct netnode - { - /*the reference to the corresponding light node*/ - lnode_t * lnode; - - /*the flags associated with this node (might be not required)*/ - int flags; - - /*a port to the underlying filesystem*/ - file_t port; - - /*the neighbouring entries in the cache*/ - node_t * ncache_prev, * ncache_next; - };/*struct netnode*/ -/*----------------------------------------------------------------------------*/ -typedef struct netnode netnode_t; -/*----------------------------------------------------------------------------*/ -/*A list element containing directory entry*/ -struct node_dirent - { - /*the directory entry*/ - struct dirent * dirent; - - /*the next element*/ - struct node_dirent * next; - };/*struct node_dirent*/ -/*----------------------------------------------------------------------------*/ -typedef struct node_dirent node_dirent_t; -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Global Variables----------------------------------------------------*/ -/*The lock protecting the underlying filesystem*/ -extern struct mutex ulfs_lock; -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Functions-----------------------------------------------------------*/ -/*Derives a new node from `lnode` and adds a reference to `lnode`*/ -error_t -node_create - ( - lnode_t * lnode, - node_t ** node /*store the result here*/ - ); -/*----------------------------------------------------------------------------*/ -/*Destroys the specified node and removes a light reference from the - associated light node*/ -void -node_destroy - ( - node_t * np - ); -/*----------------------------------------------------------------------------*/ -/*Creates the root node and the corresponding lnode*/ -error_t -node_create_root - ( - node_t ** root_node /*store the result here*/ - ); -/*----------------------------------------------------------------------------*/ -/*Initializes the port to the underlying filesystem for the root node*/ -error_t -node_init_root - ( - node_t * node /*the root node*/ - ); -/*----------------------------------------------------------------------------*/ -/*Frees a list of dirents*/ -void -node_entries_free - ( - node_dirent_t * dirents /*free this*/ - ); -/*----------------------------------------------------------------------------*/ -/*Reads the directory entries from `node`, which must be locked*/ -error_t -node_entries_get - ( - node_t * node, - node_dirent_t ** dirents /*store the result here*/ - ); -/*----------------------------------------------------------------------------*/ -/*Makes sure that all ports to the underlying filesystem of `node` are up to - date*/ -error_t -node_update - ( - node_t * node - ); -/*----------------------------------------------------------------------------*/ -/*Computes the size of the given directory*/ -error_t -node_get_size - ( - node_t * dir, - OFFSET_T * off - ); -/*----------------------------------------------------------------------------*/ -/*Remove the file called `name` under `dir`*/ -error_t -node_unlink_file - ( - node_t * dir, - char * name - ); -/*----------------------------------------------------------------------------*/ -#endif /*__NODE_H__*/ diff --git a/netfs-sample/options.c b/netfs-sample/options.c deleted file mode 100644 index c39d3f2b..00000000 --- a/netfs-sample/options.c +++ /dev/null @@ -1,255 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/*options.h*/ -/*----------------------------------------------------------------------------*/ -/*Definitions for parsing the command line switches*/ -/*----------------------------------------------------------------------------*/ -/*Based on the code of unionfs translator.*/ -/*----------------------------------------------------------------------------*/ -/*Copyright (C) 2001, 2002, 2005 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.*/ -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -#define _GNU_SOURCE 1 -/*----------------------------------------------------------------------------*/ -#include <argp.h> -#include <error.h> -/*----------------------------------------------------------------------------*/ -#include "debug.h" -#include "options.h" -#include "ncache.h" -#include "node.h" -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Macros--------------------------------------------------------------*/ -/*Short documentation for argp*/ -#define ARGS_DOC "DIR" -#define DOC "Shows the contents of DIR filtered according to PROPERTY.\ - If DIR is not specified, ~/ is assumed." -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Forward Declarations------------------------------------------------*/ -/*Argp parser function for the common options*/ -static -error_t -argp_parse_common_options - ( - int key, - char * arg, - struct argp_state * state - ); -/*----------------------------------------------------------------------------*/ -/*Argp parser function for the startup options*/ -static -error_t -argp_parse_startup_options - ( - int key, - char * arg, - struct argp_state * state - ); -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Global Variables----------------------------------------------------*/ -/*This variable is set to a non-zero value after the parsing of starup options - is finished*/ -/*Whenever the argument parser is later called to modify the - options of filterfs the root node will be initialized accordingly directly - by the parser*/ -static int parsing_startup_options_finished; -/*----------------------------------------------------------------------------*/ -/*Argp options common to both the runtime and the startup parser*/ -static const struct argp_option argp_common_options[] = - { - {OPT_LONG_CACHE_SIZE, OPT_CACHE_SIZE, "SIZE", 0, - "The maximal number of nodes in the node cache"}, - {OPT_LONG_PROPERTY, OPT_PROPERTY, "PROPERTY", 0, - "The command which will act as a filter"} - }; -/*----------------------------------------------------------------------------*/ -/*Argp options only meaningful for startupp parsing*/ -static const struct argp_option argp_startup_options[] = - { - {0} - }; -/*----------------------------------------------------------------------------*/ -/*Argp parser for only the common options*/ -static const struct argp argp_parser_common_options = - {argp_common_options, argp_parse_common_options, 0, 0, 0}; -/*----------------------------------------------------------------------------*/ -/*Argp parser for only the startup options*/ -static const struct argp argp_parser_startup_options = - {argp_startup_options, argp_parse_startup_options, 0, 0, 0}; -/*----------------------------------------------------------------------------*/ -/*The list of children parsers for runtime arguments*/ -static const struct argp_child argp_children_runtime[] = - { - {&argp_parser_common_options}, - {&netfs_std_runtime_argp}, - {0} - }; -/*----------------------------------------------------------------------------*/ -/*The list of children parsers for startup arguments*/ -static const struct argp_child argp_children_startup[] = - { - {&argp_parser_startup_options}, - {&argp_parser_common_options}, - {&netfs_std_startup_argp}, - {0} - }; -/*----------------------------------------------------------------------------*/ -/*The version of the server for argp*/ -const char * argp_program_version = "0.0"; -/*----------------------------------------------------------------------------*/ -/*The arpg parser for runtime arguments*/ -struct argp argp_runtime = - {0, 0, 0, 0, argp_children_runtime}; -/*----------------------------------------------------------------------------*/ -/*The argp parser for startup arguments*/ -struct argp argp_startup = - {0, 0, ARGS_DOC, DOC, argp_children_startup}; -/*----------------------------------------------------------------------------*/ -/*The filtering command*/ -char * property = NULL; -/*----------------------------------------------------------------------------*/ -/*The directory to filter*/ -char * dir = NULL; -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Functions-----------------------------------------------------------*/ -/*Argp parser function for the common options*/ -static -error_t -argp_parse_common_options - ( - int key, - char * arg, - struct argp_state * state - ) - { - error_t err = 0; - - /*Go through the possible options*/ - switch(key) - { - case OPT_CACHE_SIZE: - { - /*store the new cache-size*/ - ncache_size = strtol(arg, NULL, 10); - - break; - } - case OPT_PROPERTY: - { - /*try to duplicate the filtering command*/ - property = strdup(arg); - if(!property) - error(EXIT_FAILURE, ENOMEM, "Could not strdup the property"); - - break; - } - case ARGP_KEY_ARG: /*the directory to filter*/ - { - /*try to duplicate the directory name*/ - dir = strdup(arg); - if(!dir) - error(EXIT_FAILURE, ENOMEM, "argp_parse_common_options: " - "Could not strdup the directory"); - - /*fill all trailing spaces with 0*/ - int i = strlen(dir) - 1; - /*for(i = strlen(dir) - 1; (i >= 0) && (dir[i] == ' '); dir[i--] = 0);*/ - /*the original filename may contain spaces*/ - - /*If the last non blank symbol is a '/' and it's not the only one*/ - if((dir[i] == '/') && (i != 0)) - /*put 0 instead*/ - dir[i] = 0; - - LOG_MSG("argp_parse_common_options: Filtering the directory %s.", dir); - - break; - } - case ARGP_KEY_END: - { - /*If parsing of startup options has not finished*/ - if(!parsing_startup_options_finished) - { - /*reset the cache*/ - ncache_reset(); - - /*If the directory has not been specified*/ - if(!dir) - { - /*assume the directory to be the home directory*/ - ; - - /*FIXME: The default directory is /var/tmp*/ - dir = "/var/tmp"; - } - - /*set the flag that the startup options have already been parsed*/ - parsing_startup_options_finished = 1; - } - else - { -/*TODO: Take care of runtime calls modifying the property*/ - } - } - /*If the option could not be recognized*/ - default: - { - /*set the error code*/ - err = ARGP_ERR_UNKNOWN; - } - } - - /*Return the result*/ - return err; - }/*argp_parse_common_options*/ -/*----------------------------------------------------------------------------*/ -/*Argp parser function for the startup options*/ -static -error_t -argp_parse_startup_options - ( - int key, - char * arg, - struct argp_state * state - ) - { - /*Do nothing in a beautiful way*/ - error_t err = 0; - - switch(key) - { - default: - { - err = ARGP_ERR_UNKNOWN; - - break; - } - } - - return err; - }/*argp_parse_startup_options*/ -/*----------------------------------------------------------------------------*/ diff --git a/netfs-sample/options.h b/netfs-sample/options.h deleted file mode 100644 index 0f917bb0..00000000 --- a/netfs-sample/options.h +++ /dev/null @@ -1,64 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/*options.h*/ -/*----------------------------------------------------------------------------*/ -/*Declarations for parsing the command line switches*/ -/*----------------------------------------------------------------------------*/ -/*Based on the code of unionfs translator.*/ -/*----------------------------------------------------------------------------*/ -/*Copyright (C) 2001, 2002, 2005 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 __OPTIONS_H__ -#define __OPTIONS_H__ - -/*----------------------------------------------------------------------------*/ -/*--------Macros--------------------------------------------------------------*/ -/*The possible short options*/ -#define OPT_CACHE_SIZE 'c' -/*the property according to which filtering will be performed*/ -#define OPT_PROPERTY 'p' -/*----------------------------------------------------------------------------*/ -/*The corresponding long options*/ -#define OPT_LONG_CACHE_SIZE "cache-size" -#define OPT_LONG_PROPERTY "property" -/*----------------------------------------------------------------------------*/ -/*Makes a long option out of option name*/ -#define OPT_LONG(o) "--"o -/*----------------------------------------------------------------------------*/ -/*The substring of the property which shall be replaced by the filename*/ -#define PROPERTY_PARAM "{}" -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*--------Global Variables----------------------------------------------------*/ -/*The argp parser for startup arguments*/ -extern struct argp argp_startup; -/*----------------------------------------------------------------------------*/ -/*The argp parser for rutime arguments*/ -extern struct argp argp_runtime; -/*----------------------------------------------------------------------------*/ -/*The number of nodes in cache (see ncache.{c,h})*/ -extern int ncache_size; -/*----------------------------------------------------------------------------*/ -/*The filtering command*/ -extern char * property; -/*----------------------------------------------------------------------------*/ -/*The directory to filter*/ -extern char * dir; -/*----------------------------------------------------------------------------*/ -#endif /*__OPTIONS_H__*/ |