diff options
Diffstat (limited to 'c/src/libfs/src/imfs')
-rw-r--r-- | c/src/libfs/src/imfs/imfs.h | 4 | ||||
-rw-r--r-- | c/src/libfs/src/imfs/imfs_fchmod.c | 19 | ||||
-rw-r--r-- | c/src/libfs/src/imfs/imfs_handlers_memfile.c | 8 | ||||
-rw-r--r-- | c/src/libfs/src/imfs/imfs_load_tar.c | 62 | ||||
-rw-r--r-- | c/src/libfs/src/imfs/memfile.c | 43 |
5 files changed, 108 insertions, 28 deletions
diff --git a/c/src/libfs/src/imfs/imfs.h b/c/src/libfs/src/imfs/imfs.h index 2b2d84806f..ad18284d93 100644 --- a/c/src/libfs/src/imfs/imfs.h +++ b/c/src/libfs/src/imfs/imfs.h @@ -130,7 +130,7 @@ typedef struct { #define IMFS_HARD_LINK RTEMS_FILESYSTEM_HARD_LINK #define IMFS_SYM_LINK RTEMS_FILESYSTEM_SYM_LINK #define IMFS_MEMORY_FILE RTEMS_FILESYSTEM_MEMORY_FILE -#define IMFS_LINEAR_FILE (RTEMS_FILESYSTEM_MEMORY_FILE + 1) +#define IMFS_LINEAR_FILE (IMFS_MEMORY_FILE + 1) #define IMFS_NUMBER_OF_TYPES (IMFS_LINEAR_FILE + 1) @@ -264,7 +264,7 @@ int IMFS_fsunmount( rtems_filesystem_mount_table_entry_t *mt_entry ); -int rtems_tarfs_mount( +int rtems_tarfs_load( char *mountpoint, unsigned char *addr, unsigned long length diff --git a/c/src/libfs/src/imfs/imfs_fchmod.c b/c/src/libfs/src/imfs/imfs_fchmod.c index 02ac934854..d360a1543a 100644 --- a/c/src/libfs/src/imfs/imfs_fchmod.c +++ b/c/src/libfs/src/imfs/imfs_fchmod.c @@ -44,6 +44,25 @@ int IMFS_fchmod( if ( mode & (~ (S_IRWXU | S_IRWXG | S_IRWXO ) ) ) set_errno_and_return_minus_one( EPERM ); + /* + * If we make a linear-file writeable, construct a block file + * from it first. + */ + if ( (jnode->type == IMFS_LINEAR_FILE) && + (mode & (S_IWUSR | S_IWGRP | S_IWOTH)) ) + { + unsigned32 count = jnode->info.linearfile.size; + const unsigned char *buffer = jnode->info.linearfile.direct; + + jnode->type = IMFS_MEMORY_FILE; + jnode->info.file.size = 0; + jnode->info.file.indirect = 0; + jnode->info.file.doubly_indirect = 0; + jnode->info.file.triply_indirect = 0; + if (IMFS_memfile_write(jnode, 0, buffer, count) == -1) + return(-1); + } + jnode->st_mode &= ~(S_IRWXU | S_IRWXG | S_IRWXO); jnode->st_mode |= mode; diff --git a/c/src/libfs/src/imfs/imfs_handlers_memfile.c b/c/src/libfs/src/imfs/imfs_handlers_memfile.c index eb2ab47b39..2de3aaeb4e 100644 --- a/c/src/libfs/src/imfs/imfs_handlers_memfile.c +++ b/c/src/libfs/src/imfs/imfs_handlers_memfile.c @@ -22,18 +22,18 @@ rtems_filesystem_file_handlers_r IMFS_linearfile_handlers = { memfile_open, memfile_close, - linearfile_read, + memfile_read, NULL, /* write */ memfile_ioctl, - linearfile_lseek, + memfile_lseek, IMFS_stat, - NULL, /* chmod */ + IMFS_fchmod, NULL, /* ftruncate */ NULL, /* fpathconf */ IMFS_fdatasync, /* fsync */ IMFS_fdatasync, IMFS_fcntl, - NULL /* rmnod */ + memfile_rmnod }; rtems_filesystem_file_handlers_r IMFS_memfile_handlers = { diff --git a/c/src/libfs/src/imfs/imfs_load_tar.c b/c/src/libfs/src/imfs/imfs_load_tar.c index 7dc7df8a61..ede0c6ad89 100644 --- a/c/src/libfs/src/imfs/imfs_load_tar.c +++ b/c/src/libfs/src/imfs/imfs_load_tar.c @@ -4,13 +4,10 @@ * Directories from the TAR file are created as usual in the IMFS. * File entries are created as IMFS_LINEAR_FILE nodes with their nods * pointing to addresses in the TAR image. - * - * $Id$ - * *************************************************************************/ #include <rtems.h> -#include <rtems/libio.h> +#include <rtems/libio_.h> #include <string.h> #include <chain.h> #include <imfs.h> @@ -110,9 +107,9 @@ compute_tar_header_checksum(char *bufr) /************************************************************************** - * rtems_tarfs_mount + * rtems_tarfs_load * - * Here we create the mountpoint directory and mount the tarfs at + * Here we create the mountpoint directory and load the tarfs at * that node. Once the IMFS has been mounted, we work through the * tar image and perform as follows: * - For directories, simply call mkdir(). The IMFS creates nodes as @@ -121,9 +118,9 @@ compute_tar_header_checksum(char *bufr) * create_node. *************************************************************************/ int -rtems_tarfs_mount(char *mountpoint, - unsigned char *tar_image, - unsigned long tar_size) +rtems_tarfs_load(char *mountpoint, + unsigned char *tar_image, + unsigned long tar_size) { rtems_filesystem_location_info_t root_loc; rtems_filesystem_location_info_t loc; @@ -133,6 +130,7 @@ rtems_tarfs_mount(char *mountpoint, int hdr_chksum; unsigned char linkflag; unsigned long file_size; + unsigned long file_mode; int offset; unsigned long nblocks; IMFS_jnode_t *node; @@ -143,6 +141,9 @@ rtems_tarfs_mount(char *mountpoint, if (status != 0) return(-1); + if (root_loc.ops != &IMFS_ops) + return(-1); + /*********************************************************************** * Create an IMFS node structure pointing to tar image memory. **********************************************************************/ @@ -164,9 +165,10 @@ rtems_tarfs_mount(char *mountpoint, filename[MAX_NAME_FIELD_SIZE] = '\0'; linkflag = hdr_ptr[156]; + file_mode = octal2ulong(&hdr_ptr[100], 8); file_size = octal2ulong(&hdr_ptr[124], 12); - hdr_chksum = (int)octal2ulong(&hdr_ptr[148], 8); + if (compute_tar_header_checksum(hdr_ptr) != hdr_chksum) break; @@ -179,15 +181,19 @@ rtems_tarfs_mount(char *mountpoint, if (linkflag == LF_DIR) { strcpy(full_filename, mountpoint); - strcat(full_filename, "/"); + if (full_filename[strlen(full_filename)-1] != '/') + strcat(full_filename, "/"); strcat(full_filename, filename); mkdir(full_filename, S_IRWXU | S_IRWXG | S_IRWXO); } - else if (linkflag == LF_NORMAL) + /****************************************************************** + * Create a LINEAR_FILE node if no user write permission. + *****************************************************************/ + else if ((linkflag == LF_NORMAL) && + ((file_mode & 0200) == 0000)) { const char *name; - loc = root_loc; if (IMFS_evaluate_for_make(filename, &loc, &name) == 0) { @@ -202,6 +208,36 @@ rtems_tarfs_mount(char *mountpoint, nblocks = (((file_size) + 511) & ~511) / 512; offset += 512 * nblocks; } + /****************************************************************** + * Create a regular MEMORY_FILE if write permission exists. + *****************************************************************/ + else if ((linkflag == LF_NORMAL) && + ((file_mode & 0200) == 0200)) + { + int fd; + int n, left, ptr; + + strcpy(full_filename, mountpoint); + if (full_filename[strlen(full_filename)-1] != '/') + strcat(full_filename, "/"); + strcat(full_filename, filename); + + fd = creat(full_filename, S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP); + if (fd != -1) + { + left = file_size; + ptr = offset; + while ((n = write(fd, &tar_image[ptr], left)) > 0) + { + left -= n; + ptr += n; + } + close(fd); + } + + nblocks = (((file_size) + 511) & ~511) / 512; + offset += 512 * nblocks; + } } return(status); diff --git a/c/src/libfs/src/imfs/memfile.c b/c/src/libfs/src/imfs/memfile.c index 890f2aebc1..cfbf5dd110 100644 --- a/c/src/libfs/src/imfs/memfile.c +++ b/c/src/libfs/src/imfs/memfile.c @@ -197,10 +197,16 @@ int memfile_lseek( the_jnode = iop->file_info; - if (IMFS_memfile_extend( the_jnode, iop->offset )) - set_errno_and_return_minus_one( ENOSPC ); + if (the_jnode->type == IMFS_LINEAR_FILE) { + if (iop->offset > the_jnode->info.linearfile.size) + iop->offset = the_jnode->info.linearfile.size; + } + else { /* Must be a block file (IMFS_MEMORY_FILE). */ + if (IMFS_memfile_extend( the_jnode, iop->offset )) + set_errno_and_return_minus_one( ENOSPC ); - iop->size = the_jnode->info.file.size; + iop->size = the_jnode->info.file.size; + } return iop->offset; } @@ -499,8 +505,6 @@ int IMFS_memfile_remove( if ( info->triply_indirect ) { for ( i=0 ; i<IMFS_MEMFILE_BLOCK_SLOTS ; i++ ) { p = (block_p *) info->triply_indirect[i]; - if (!p) /* ensure we have a valid pointer */ - break; for ( j=0 ; j<IMFS_MEMFILE_BLOCK_SLOTS ; j++ ) { if ( p[j] ) { memfile_free_blocks_in_table( (block_p **)&p[j], to_free); @@ -554,8 +558,10 @@ MEMFILE_STATIC int IMFS_memfile_read( if ( !the_jnode ) set_errno_and_return_minus_one( EIO ); - assert( the_jnode->type == IMFS_MEMORY_FILE ); - if ( the_jnode->type != IMFS_MEMORY_FILE ) + assert( the_jnode->type == IMFS_MEMORY_FILE || + the_jnode->type == IMFS_LINEAR_FILE ); + if ( the_jnode->type != IMFS_MEMORY_FILE && + the_jnode->type != IMFS_LINEAR_FILE ) set_errno_and_return_minus_one( EIO ); /* @@ -575,6 +581,25 @@ MEMFILE_STATIC int IMFS_memfile_read( set_errno_and_return_minus_one( EINVAL ); /* + * Linear files (as created from a tar file are easier to handle + * than block files). + */ + if (the_jnode->type == IMFS_LINEAR_FILE) { + unsigned char *file_ptr; + + file_ptr = (unsigned char *)the_jnode->info.linearfile.direct; + + if (my_length > (the_jnode->info.linearfile.size - start)) + my_length = the_jnode->info.linearfile.size - start; + + memcpy(dest, &file_ptr[start], my_length); + + IMFS_update_atime( the_jnode ); + + return my_length; + } + + /* * If the last byte we are supposed to read is past the end of this * in memory file, then shorten the length to read. */ @@ -1090,8 +1115,8 @@ int memfile_rmnod( /* * Free memory associated with a memory file. */ - - IMFS_memfile_remove( the_jnode ); + if (the_jnode->type != IMFS_LINEAR_FILE) + IMFS_memfile_remove( the_jnode ); free( the_jnode ); } |