diff options
author | Chris Johns <chrisj@rtems.org> | 2010-05-31 13:56:37 +0000 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2010-05-31 13:56:37 +0000 |
commit | 29e92b090c8bc35745aa5c89231ce806bcb11e57 (patch) | |
tree | a253c33b1654609acfbd5216797976dce3b0748f /cpukit/libcsupport/src/mount.c | |
parent | 2010-05-31 Joel Sherrill <joel.sherrilL@OARcorp.com> (diff) | |
download | rtems-29e92b090c8bc35745aa5c89231ce806bcb11e57.tar.bz2 |
2010-05-31 Chris Johns <chrisj@rtems.org>
* libcsupport/Makefile.am: Add mount-mgr.c.
* libcsupport/src/mount-mgr.c: New.
* include/rtems/fs.h: Added rtems_filesystem_location_mount.
* libcsupport/include/rtems/libio.h, libcsupport/src/mount.c: New
mount interface. It is similar to Linux.
* libcsupport/include/rtems/libio_.h: Remove the
init_fs_mount_table call.
* libcsupport/src/base_fs.c: Remove init_fs_mount_table_call. Use
the new mount call. Remove setting the root node in the global
pathloc. Mount does this now.
* libcsupport/src/privateenv.c: Remove the hack to set the root
mount table entry in the environment.
* libcsupport/src/unmount.cL Free the target string.
* libblock/src/bdpart-mount.c: New mount API.
* libfs/src/devfs/devfs.h, libfs/src/devfs/devfs_init.c,
libfs/src/dosfs/dosfs.h, libfs/src/dosfs/msdos.h,
libfs/src/dosfs/msdos_init.c, libfs/src/imfs/imfs.h,
libfs/src/imfs/imfs_eval.c, libfs/src/imfs/imfs_init.c,
libfs/src/imfs/miniimfs_init.c,
libfs/src/nfsclient/src/librtemsNfs.h,
libfs/src/rfs/rtems-rfs-rtems.c, libfs/src/rfs/rtems-rfs.h,
libnetworking/lib/ftpfs.c, libnetworking/rtems/ftpfs.h,
libnetworking/rtems/tftp.h: New mount_h API.
* libfs/src/devfs/devfs_eval.c: Local include of extern ops.
* libfs/src/nfsclient/src/nfs.c: New mount API. Removed the mount
me call and fixed the initialisation to happen when mounting.
* libmisc/Makefile.am, libmisc/shell/shellconfig.h: Remove mount
filesystem files.
* libmisc/fsmount/fsmount.c, libmisc/fsmount/fsmount.h: Updated to
the new mount table values.
* libmisc/shell/main_mount_ftp.c,
libmisc/shell/main_mount_msdos.c, libmisc/shell/main_mount_rfs.c,
libmisc/shell/main_mount_tftp.c: Removed.
* libmisc/shell/main_mount.c: Use the new mount API. Also access
the file system table for the file system types.
* libnetworking/lib/tftpDriver.c: Updated to the new mount
API. Fixed to allow mounting from any mount point. Also can now
have more than file system mounted.
* sapi/include/confdefs.h: Add file system configuration support.
Diffstat (limited to 'cpukit/libcsupport/src/mount.c')
-rw-r--r-- | cpukit/libcsupport/src/mount.c | 287 |
1 files changed, 172 insertions, 115 deletions
diff --git a/cpukit/libcsupport/src/mount.c b/cpukit/libcsupport/src/mount.c index d21a084be0..3e3c47166d 100644 --- a/cpukit/libcsupport/src/mount.c +++ b/cpukit/libcsupport/src/mount.c @@ -33,24 +33,72 @@ #include <rtems/libio_.h> -rtems_chain_control rtems_filesystem_mount_table_control; +/* + * External defined by confdefs.h or the user. + */ +extern const rtems_filesystem_table_t configuration_filesystem_table[]; /* - * Prototypes that probably should be somewhere else. + * Points to a list of filesystems added at runtime. */ +rtems_chain_control *rtems_filesystem_table; -int init_fs_mount_table( void ); -static bool Is_node_fs_root( - rtems_filesystem_location_info_t *loc -); +/* + * Mount table list. + */ +rtems_chain_control rtems_filesystem_mount_table_control; +bool rtems_filesystem_mount_table_control_init; +/* + * Default pathconfs. + */ +const rtems_filesystem_limits_and_options_t rtems_filesystem_default_pathconf = { + 5, /* link_max: count */ + 128, /* max_canon: max formatted input line size */ + 7, /* max_input: max input line size */ + 255, /* name_max: max name */ + 255, /* path_max: max path */ + 1024, /* pipe_buf: pipe buffer size */ + 0, /* posix_async_io: async IO supported on fs, 0=no, 1=yes */ + 0 , /* posix_chown_restrictions: can chown: 0=no, 1=yes */ + 1, /* posix_no_trunc: error on filenames > max name, 0=no, 1=yes */ + 0, /* posix_prio_io: priority IO, 0=no, 1=yes */ + 0, /* posix_sync_io: file can be sync'ed, 0=no, 1=yes */ + 0 /* posix_vdisable: special char processing, 0=no, 1=yes */ +}; /* - * XXX + * Is_node_fs_root + * + * This routine will run through the entries that currently exist in the + * mount table chain. For each entry in the mount table chain it will + * compare the mount tables root node to the node describing the selected + * mount point. If any match is found true is returned else false is + * returned. + * */ -#define FOUND 0 -#define NOT_FOUND -1 +static bool Is_node_fs_root( + rtems_filesystem_location_info_t *loc +) +{ + rtems_chain_node *the_node; + rtems_filesystem_mount_table_entry_t *the_mount_entry; + + /* + * For each mount table entry + */ + if ( rtems_filesystem_mount_table_control_init ) { + for ( the_node = rtems_chain_first( &rtems_filesystem_mount_table_control ); + !rtems_chain_is_tail( &rtems_filesystem_mount_table_control, the_node ); + the_node = rtems_chain_next( the_node ) ) { + the_mount_entry = (rtems_filesystem_mount_table_entry_t *) the_node; + if ( the_mount_entry->mt_fs_root.node_access == loc->node_access ) + return true; + } + } + return false; +} /* * mount @@ -68,27 +116,25 @@ static bool Is_node_fs_root( */ int mount( - rtems_filesystem_mount_table_entry_t **mt_entry, - const rtems_filesystem_operations_table *fs_ops, - rtems_filesystem_options_t options, - const char *device, - const char *mount_point -) + const char *source, + const char *target, + const char *filesystemtype, + rtems_filesystem_options_t options, + const void *data + ) { + const rtems_filesystem_table_t *entry; rtems_filesystem_location_info_t loc; - rtems_filesystem_mount_table_entry_t *temp_mt_entry = NULL; + rtems_filesystem_mount_table_entry_t *mt_entry = NULL; rtems_filesystem_location_info_t *loc_to_free = NULL; size_t size; -/* XXX add code to check for required operations */ - /* - * Is there a file system operations table? + * If mount is ever called we allocate the mount table control structure. */ - - if ( fs_ops == NULL ) { - errno = EINVAL; - return -1; + if ( !rtems_filesystem_mount_table_control_init ) { + rtems_filesystem_mount_table_control_init = true; + rtems_chain_initialize_empty ( &rtems_filesystem_mount_table_control ); } /* @@ -101,45 +147,88 @@ int mount( return -1; } - /* Do they support being mounted at all ? */ - if ( !fs_ops->fsmount_me_h ) { - errno = ENOTSUP; - goto cleanup_and_bail; + /* + * Check the type. + */ + if (!filesystemtype) { + errno = EINVAL; + return -1; } + if (strlen(filesystemtype) >= 128) { + errno = EINVAL; + return -1; + } + + /* + * Check the configuration table filesystems then check any runtime added + * file systems. + */ + entry = &configuration_filesystem_table[0]; + while (entry->type) { + if (strcmp (filesystemtype, entry->type) == 0) + break; + ++entry; + } + + if (!entry->type) { + entry = NULL; + if (rtems_filesystem_table) { + rtems_chain_node *the_node; + for (the_node = rtems_chain_first(rtems_filesystem_table); + !rtems_chain_is_tail(rtems_filesystem_table, the_node); + the_node = rtems_chain_next(the_node)) { + entry = &(((rtems_filesystem_table_node_t*) the_node)->entry); + if (strcmp (filesystemtype, entry->type) == 0) + break; + entry = NULL; + } + } + } + if (!entry) + { + errno = EINVAL; + return -1; + } + /* * Allocate a mount table entry */ - size = sizeof(rtems_filesystem_mount_table_entry_t); - if ( device ) - size += strlen( device ) + 1; - temp_mt_entry = malloc( size ); - - if ( !temp_mt_entry ) { - errno = ENOMEM; - return -1; - } - - temp_mt_entry->mt_fs_root.mt_entry = temp_mt_entry; - temp_mt_entry->options = options; - if ( device ) { - temp_mt_entry->dev = - (char *)temp_mt_entry + sizeof( rtems_filesystem_mount_table_entry_t ); - strcpy( temp_mt_entry->dev, device ); - } else - temp_mt_entry->dev = 0; + size = sizeof(rtems_filesystem_mount_table_entry_t); + if ( source ) + size += strlen( source ) + 1; + + mt_entry = malloc( size ); + if ( !mt_entry ) { + errno = ENOMEM; + return -1; + } + + memset( mt_entry, 0, size ); + + mt_entry->mt_fs_root.mt_entry = mt_entry; + mt_entry->type = entry->type; + mt_entry->options = options; + mt_entry->pathconf_limits_and_options = rtems_filesystem_default_pathconf; + + if ( source ) { + mt_entry->dev = + (char *)mt_entry + sizeof( rtems_filesystem_mount_table_entry_t ); + strcpy( mt_entry->dev, source ); + } else + mt_entry->dev = 0; /* * The mount_point should be a directory with read/write/execute * permissions in the existing tree. */ - if ( mount_point ) { + if ( target ) { if ( rtems_filesystem_evaluate_path( - mount_point, strlen( mount_point ), RTEMS_LIBIO_PERMS_RWX, &loc, true ) == -1 ) + target, strlen( target ), RTEMS_LIBIO_PERMS_RWX, &loc, true ) == -1 ) goto cleanup_and_bail; loc_to_free = &loc; @@ -179,11 +268,11 @@ int mount( * traverse the tree. */ - temp_mt_entry->mt_point_node.node_access = loc.node_access; - temp_mt_entry->mt_point_node.handlers = loc.handlers; - temp_mt_entry->mt_point_node.ops = loc.ops; - temp_mt_entry->mt_point_node.mt_entry = loc.mt_entry; - + mt_entry->mt_point_node.node_access = loc.node_access; + mt_entry->mt_point_node.handlers = loc.handlers; + mt_entry->mt_point_node.ops = loc.ops; + mt_entry->mt_point_node.mt_entry = loc.mt_entry; + /* * This link to the parent is only done when we are dealing with system * below the base file system @@ -194,31 +283,45 @@ int mount( goto cleanup_and_bail; } - if ( loc.ops->mount_h( temp_mt_entry ) ) { + if ( loc.ops->mount_h( mt_entry ) ) { goto cleanup_and_bail; } + + mt_entry->target = strdup( target ); } else { /* + * Do we already have a base file system ? + */ + if ( !rtems_chain_is_empty( &rtems_filesystem_mount_table_control ) ) { + errno = EINVAL; + goto cleanup_and_bail; + } + + /* * This is a mount of the base file system --> The * mt_point_node.node_access will be set to null to indicate that this * is the root of the entire file system. */ - temp_mt_entry->mt_fs_root.node_access = NULL; - temp_mt_entry->mt_fs_root.handlers = NULL; - temp_mt_entry->mt_fs_root.ops = NULL; + mt_entry->mt_fs_root.node_access = NULL; + mt_entry->mt_fs_root.handlers = NULL; + mt_entry->mt_fs_root.ops = NULL; + + mt_entry->mt_point_node.node_access = NULL; + mt_entry->mt_point_node.handlers = NULL; + mt_entry->mt_point_node.ops = NULL; + mt_entry->mt_point_node.mt_entry = NULL; - temp_mt_entry->mt_point_node.node_access = NULL; - temp_mt_entry->mt_point_node.handlers = NULL; - temp_mt_entry->mt_point_node.ops = NULL; - temp_mt_entry->mt_point_node.mt_entry = NULL; + mt_entry->target = "/"; } - if ( fs_ops->fsmount_me_h( temp_mt_entry ) ) { - /* try to undo the mount operation */ - if ( loc.ops->unmount_h ) { - loc.ops->unmount_h( temp_mt_entry ); + if ( entry->mount_h( mt_entry, data ) ) { + /* + * Try to undo the mount operation + */ + if ( loc.ops->unmount_h ) { + loc.ops->unmount_h( mt_entry ); } goto cleanup_and_bail; } @@ -226,18 +329,18 @@ int mount( /* * Add the mount table entry to the mount table chain */ - rtems_chain_append( &rtems_filesystem_mount_table_control, - &temp_mt_entry->Node ); + &mt_entry->Node ); - if ( mt_entry ) - *mt_entry = temp_mt_entry; + if ( !target ) + rtems_filesystem_root = mt_entry->mt_fs_root; return 0; cleanup_and_bail: - free( temp_mt_entry ); + free( (void*) mt_entry->target ); + free( mt_entry ); if ( loc_to_free ) rtems_filesystem_freenode( loc_to_free ); @@ -245,49 +348,3 @@ cleanup_and_bail: return -1; } - - -/* - * init_fs_mount_table - * - * This routine will initialize the chain control element that manages the - * mount table chain. - */ - -int init_fs_mount_table(void) -{ - rtems_chain_initialize_empty ( &rtems_filesystem_mount_table_control ); - return 0; -} - -/* - * Is_node_fs_root - * - * This routine will run through the entries that currently exist in the - * mount table chain. For each entry in the mount table chain it will - * compare the mount tables root node to the node describing the selected - * mount point. If any match is found true is returned else false is - * returned. - * - */ - -static bool Is_node_fs_root( - rtems_filesystem_location_info_t *loc -) -{ - rtems_chain_node *the_node; - rtems_filesystem_mount_table_entry_t *the_mount_entry; - - /* - * For each mount table entry - */ - - for ( the_node = rtems_filesystem_mount_table_control.first; - !rtems_chain_is_tail( &rtems_filesystem_mount_table_control, the_node ); - the_node = the_node->next ) { - the_mount_entry = (rtems_filesystem_mount_table_entry_t *) the_node; - if ( the_mount_entry->mt_fs_root.node_access == loc->node_access ) - return true; - } - return false; -} |