From d19415873fb6b6197d77916758593c9897a0cb69 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 12 Jan 2001 13:44:12 +0000 Subject: 2001-01-12 Jake Janovetz * src/imfs/imfs.h, src/imfs/imfs_creat.c, src/imfs/imfs_debug.c, src/imfs/imfs_eval.c, src/imfs/imfs_fchmod.c, src/imfs/imfs_handlers_memfile.c, src/imfs/imfs_init.c, src/imfs/imfs_initsupp.c, src/imfs/imfs_stat.c, src/imfs/memfile.c, src/imfs/miniimfs_init.c: Final developmental update to "tarfs". When rtems_tarfs_load() is called, it checks the permissions on each file. If there is write permission, it just creates a standard file using "creat()" and therefore, uses the IMFS MEMORY_FILE. If there is no write permission, it creates a LINEAR_FILE node with the appropriate properties. If the permission is ever changed to writeable, IMFS_fchmod converts it to a regular memory file. --- cpukit/libfs/ChangeLog | 14 ++++++ cpukit/libfs/src/imfs/imfs.h | 4 +- cpukit/libfs/src/imfs/imfs_fchmod.c | 19 ++++++++ cpukit/libfs/src/imfs/imfs_handlers_memfile.c | 8 ++-- cpukit/libfs/src/imfs/imfs_load_tar.c | 62 +++++++++++++++++++++------ cpukit/libfs/src/imfs/memfile.c | 43 +++++++++++++++---- 6 files changed, 122 insertions(+), 28 deletions(-) (limited to 'cpukit') diff --git a/cpukit/libfs/ChangeLog b/cpukit/libfs/ChangeLog index b275ae611d..1911559167 100644 --- a/cpukit/libfs/ChangeLog +++ b/cpukit/libfs/ChangeLog @@ -1,3 +1,17 @@ +2001-01-12 Jake Janovetz + + * src/imfs/imfs.h, src/imfs/imfs_creat.c, src/imfs/imfs_debug.c, + src/imfs/imfs_eval.c, src/imfs/imfs_fchmod.c, + src/imfs/imfs_handlers_memfile.c, src/imfs/imfs_init.c, + src/imfs/imfs_initsupp.c, src/imfs/imfs_stat.c, src/imfs/memfile.c, + src/imfs/miniimfs_init.c: Final developmental update to "tarfs". + When rtems_tarfs_load() is called, it checks the permissions + on each file. If there is write permission, it just creates a + standard file using "creat()" and therefore, uses the IMFS MEMORY_FILE. + If there is no write permission, it creates a LINEAR_FILE node + with the appropriate properties. If the permission is ever changed + to writeable, IMFS_fchmod converts it to a regular memory file. + 2000-12-12 Jake Janovetz * src/imfs/linearfile.c, src/imfs/imfs_load_tar.c: New files. diff --git a/cpukit/libfs/src/imfs/imfs.h b/cpukit/libfs/src/imfs/imfs.h index 2b2d84806f..ad18284d93 100644 --- a/cpukit/libfs/src/imfs/imfs.h +++ b/cpukit/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/cpukit/libfs/src/imfs/imfs_fchmod.c b/cpukit/libfs/src/imfs/imfs_fchmod.c index 02ac934854..d360a1543a 100644 --- a/cpukit/libfs/src/imfs/imfs_fchmod.c +++ b/cpukit/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/cpukit/libfs/src/imfs/imfs_handlers_memfile.c b/cpukit/libfs/src/imfs/imfs_handlers_memfile.c index eb2ab47b39..2de3aaeb4e 100644 --- a/cpukit/libfs/src/imfs/imfs_handlers_memfile.c +++ b/cpukit/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/cpukit/libfs/src/imfs/imfs_load_tar.c b/cpukit/libfs/src/imfs/imfs_load_tar.c index 7dc7df8a61..ede0c6ad89 100644 --- a/cpukit/libfs/src/imfs/imfs_load_tar.c +++ b/cpukit/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 -#include +#include #include #include #include @@ -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) { @@ -199,6 +205,36 @@ rtems_tarfs_mount(char *mountpoint, node->info.linearfile.direct = &tar_image[offset]; } + 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; } diff --git a/cpukit/libfs/src/imfs/memfile.c b/cpukit/libfs/src/imfs/memfile.c index 890f2aebc1..cfbf5dd110 100644 --- a/cpukit/libfs/src/imfs/memfile.c +++ b/cpukit/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 ; itriply_indirect[i]; - if (!p) /* ensure we have a valid pointer */ - break; for ( j=0 ; jtype == 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 ); /* @@ -574,6 +580,25 @@ MEMFILE_STATIC int IMFS_memfile_read( if ( !my_length ) 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 ); } -- cgit v1.2.3