Index: cpukit/ChangeLog
===================================================================
--- cpukit/ChangeLog	(revision babf5758c41e00b1a477b63ae1e55056a668ff1e)
+++ cpukit/ChangeLog	(revision 624867bc09632b9c98235073f9a1b4f130233c47)
@@ -1,2 +1,11 @@
+2005-02-09	Eric Norum <norum@aps.anl.gov>
+
+	* libfs/Makefile.am, libfs/src/imfs/imfs.h, libfs/src/imfs/imfs_eval.c,
+	libfs/src/imfs/imfs_fchmod.c, libfs/src/imfs/imfs_handlers_memfile.c,
+	libfs/src/imfs/imfs_init.c, libfs/src/imfs/imfs_initsupp.c,
+	libfs/src/imfs/imfs_load_tar.c, libfs/src/imfs/linearfile.c,
+	libfs/src/imfs/memfile.c, libfs/src/imfs/miniimfs_init.c: Add
+	'copy-on-write' semantics to rtems_tarfs_load().
+
 2005-02-08	Ralf Corsepius <ralf.corsepius@rtems.org>
 
Index: cpukit/libfs/Makefile.am
===================================================================
--- cpukit/libfs/Makefile.am	(revision babf5758c41e00b1a477b63ae1e55056a668ff1e)
+++ cpukit/libfs/Makefile.am	(revision 624867bc09632b9c98235073f9a1b4f130233c47)
@@ -22,5 +22,5 @@
     src/imfs/imfs_unlink.c src/imfs/imfs_unmount.c src/imfs/imfs_utime.c \
     src/imfs/imfs_ntype.c src/imfs/imfs_stat.c src/imfs/imfs_getchild.c \
-    src/imfs/memfile.c src/imfs/linearfile.c src/imfs/deviceio.c \
+    src/imfs/memfile.c src/imfs/deviceio.c \
     src/imfs/imfs_handlers_device.c src/imfs/imfs_handlers_directory.c \
     src/imfs/imfs_handlers_link.c src/imfs/imfs_handlers_memfile.c \
Index: cpukit/libfs/src/imfs/imfs.h
===================================================================
--- cpukit/libfs/src/imfs/imfs.h	(revision babf5758c41e00b1a477b63ae1e55056a668ff1e)
+++ cpukit/libfs/src/imfs/imfs.h	(revision 624867bc09632b9c98235073f9a1b4f130233c47)
@@ -203,5 +203,4 @@
 typedef struct {
   ino_t                             ino_count;
-  rtems_filesystem_file_handlers_r *linearfile_handlers;
   rtems_filesystem_file_handlers_r *memfile_handlers;
   rtems_filesystem_file_handlers_r *directory_handlers;
@@ -238,5 +237,4 @@
 extern rtems_filesystem_file_handlers_r       IMFS_device_handlers;
 extern rtems_filesystem_file_handlers_r       IMFS_link_handlers;
-extern rtems_filesystem_file_handlers_r       IMFS_linearfile_handlers;
 extern rtems_filesystem_file_handlers_r       IMFS_memfile_handlers;
 extern rtems_filesystem_operations_table      IMFS_ops;
@@ -259,5 +257,4 @@
    rtems_filesystem_mount_table_entry_t *mt_entry,
    rtems_filesystem_operations_table    *op_table,
-   rtems_filesystem_file_handlers_r     *linearfile_handlers,
    rtems_filesystem_file_handlers_r     *memfile_handlers,
    rtems_filesystem_file_handlers_r     *directory_handlers
@@ -417,16 +414,4 @@
 );
 
-int linearfile_read(
-  rtems_libio_t *iop,             /* IN  */
-  void          *buffer,          /* IN  */
-  uint32_t       count            /* IN  */
-);
-
-int linearfile_lseek(
-  rtems_libio_t        *iop,        /* IN  */
-  off_t                 offset,     /* IN  */
-  int                   whence      /* IN  */
-);
-
 int memfile_open(
   rtems_libio_t *iop,             /* IN  */
Index: cpukit/libfs/src/imfs/imfs_eval.c
===================================================================
--- cpukit/libfs/src/imfs/imfs_eval.c	(revision babf5758c41e00b1a477b63ae1e55056a668ff1e)
+++ cpukit/libfs/src/imfs/imfs_eval.c	(revision 624867bc09632b9c98235073f9a1b4f130233c47)
@@ -53,5 +53,5 @@
       break;
     case IMFS_LINEAR_FILE:
-      loc->handlers = fs_info->linearfile_handlers;
+      loc->handlers = fs_info->memfile_handlers;
       break;
     case IMFS_MEMORY_FILE:
Index: cpukit/libfs/src/imfs/imfs_fchmod.c
===================================================================
--- cpukit/libfs/src/imfs/imfs_fchmod.c	(revision babf5758c41e00b1a477b63ae1e55056a668ff1e)
+++ cpukit/libfs/src/imfs/imfs_fchmod.c	(revision 624867bc09632b9c98235073f9a1b4f130233c47)
@@ -57,23 +57,4 @@
     rtems_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)) )
-  {
-    uint32_t   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;
Index: cpukit/libfs/src/imfs/imfs_handlers_memfile.c
===================================================================
--- cpukit/libfs/src/imfs/imfs_handlers_memfile.c	(revision babf5758c41e00b1a477b63ae1e55056a668ff1e)
+++ cpukit/libfs/src/imfs/imfs_handlers_memfile.c	(revision 624867bc09632b9c98235073f9a1b4f130233c47)
@@ -24,21 +24,4 @@
  */
 
-rtems_filesystem_file_handlers_r IMFS_linearfile_handlers = {
-  memfile_open,
-  memfile_close,
-  memfile_read,
-  NULL,                /* write */
-  memfile_ioctl,
-  memfile_lseek,
-  IMFS_stat,
-  IMFS_fchmod,
-  NULL,                /* ftruncate */
-  NULL,                /* fpathconf */
-  IMFS_fdatasync,      /* fsync */
-  IMFS_fdatasync,
-  IMFS_fcntl,
-  memfile_rmnod
-};
-
 rtems_filesystem_file_handlers_r IMFS_memfile_handlers = {
   memfile_open,
Index: cpukit/libfs/src/imfs/imfs_init.c
===================================================================
--- cpukit/libfs/src/imfs/imfs_init.c	(revision babf5758c41e00b1a477b63ae1e55056a668ff1e)
+++ cpukit/libfs/src/imfs/imfs_init.c	(revision 624867bc09632b9c98235073f9a1b4f130233c47)
@@ -64,5 +64,4 @@
      temp_mt_entry,
      &IMFS_ops,
-     &IMFS_linearfile_handlers,
      &IMFS_memfile_handlers,
      &IMFS_directory_handlers
Index: cpukit/libfs/src/imfs/imfs_initsupp.c
===================================================================
--- cpukit/libfs/src/imfs/imfs_initsupp.c	(revision babf5758c41e00b1a477b63ae1e55056a668ff1e)
+++ cpukit/libfs/src/imfs/imfs_initsupp.c	(revision 624867bc09632b9c98235073f9a1b4f130233c47)
@@ -38,5 +38,4 @@
   rtems_filesystem_mount_table_entry_t *temp_mt_entry,
    rtems_filesystem_operations_table    *op_table,
-   rtems_filesystem_file_handlers_r     *linearfile_handlers,
    rtems_filesystem_file_handlers_r     *memfile_handlers,
    rtems_filesystem_file_handlers_r     *directory_handlers
@@ -79,5 +78,4 @@
 
   fs_info->ino_count             = 1;
-  fs_info->linearfile_handlers   = linearfile_handlers;
   fs_info->memfile_handlers      = memfile_handlers;
   fs_info->directory_handlers    = directory_handlers;
Index: cpukit/libfs/src/imfs/imfs_load_tar.c
===================================================================
--- cpukit/libfs/src/imfs/imfs_load_tar.c	(revision babf5758c41e00b1a477b63ae1e55056a668ff1e)
+++ cpukit/libfs/src/imfs/imfs_load_tar.c	(revision 624867bc09632b9c98235073f9a1b4f130233c47)
@@ -26,4 +26,5 @@
 #include <rtems/imfs.h>
 #include <rtems/untar.h>
+#include <rtems/tar.h>
 
 /**************************************************************************
@@ -142,8 +143,7 @@
       }
       /******************************************************************
-       * Create a LINEAR_FILE node if no user write permission.
+       * Create a LINEAR_FILE node
        *****************************************************************/
-      else if ((linkflag == REGTYPE) &&
-               ((file_mode & 0200) == 0000))
+      else if (linkflag == REGTYPE)
       {
          const char  *name;
@@ -153,39 +153,9 @@
          {
             node = IMFS_create_node(&loc,
-                                    IMFS_LINEAR_FILE, (char *)name,
-                                    (S_IRUSR | S_IRGRP | S_IROTH) | S_IFREG,
-                                    NULL);
+                        IMFS_LINEAR_FILE, (char *)name,
+                        (file_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFREG,
+                        NULL);
             node->info.linearfile.size   = file_size;
             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 == REGTYPE) &&
-               ((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);
          }
 
Index: ukit/libfs/src/imfs/linearfile.c
===================================================================
--- cpukit/libfs/src/imfs/linearfile.c	(revision babf5758c41e00b1a477b63ae1e55056a668ff1e)
+++ 	(revision )
@@ -1,115 +1,0 @@
-/*
- *  IMFS Linear File Handlers
- *
- *  This file contains the set of handlers used to process operations on
- *  IMFS linear memory file nodes.  Linear memory files are contiguous
- *  blocks of memory created from a TAR or other filesystem image.
- *  The blocks are nonwriteable and nonresizeable.
- *
- *  COPYRIGHT (c) 1989-1999.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.com/license/LICENSE.
- *
- *  $Id$
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-#include <errno.h>
-
-#include <rtems.h>
-#include <rtems/libio.h>
-#include "imfs.h"
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
-
-/*
- * linearfile_read
- *
- *  This routine processes the read() system call.
- */
-
-int linearfile_read(
-  rtems_libio_t *iop,
-  void          *buffer,
-  uint32_t       count
-)
-{
-  IMFS_jnode_t   *the_jnode;
-  unsigned char  *dest;
-  unsigned char  *file_ptr;
-  int            file_offset;
-
-
-  the_jnode = iop->file_info;
-
-  /*
-   *  Perform internal consistency checks
-   */
-
-  assert( the_jnode );
-  if ( !the_jnode )
-    rtems_set_errno_and_return_minus_one( EIO );
-
-  assert( the_jnode->type == IMFS_LINEAR_FILE );
-  if ( the_jnode->type != IMFS_LINEAR_FILE )
-    rtems_set_errno_and_return_minus_one( EIO );
-
-  /*
-   *  Error checks on arguments
-   */
-
-  dest = (unsigned char *)buffer;
-  assert( dest );
-  if ( !dest )
-    rtems_set_errno_and_return_minus_one( EINVAL );
-
-  /*
-   *  Perform a simple memory copy.
-   */
-
-  if (count == 0)
-     return(0);
-
-  the_jnode = iop->file_info;
-  file_ptr    = (unsigned char *)the_jnode->info.linearfile.direct;
-  file_offset = (unsigned long)iop->offset;
-
-  if (count > (the_jnode->info.linearfile.size - file_offset))
-     count = the_jnode->info.linearfile.size - file_offset;
-
-  memcpy(dest, &file_ptr[file_offset], count);
-
-  return(count);
-}
-
-
-/*
- *  linearfile_lseek
- *
- *  This routine processes the lseek() system call.
- */
-
-int linearfile_lseek(
-  rtems_libio_t   *iop,
-  off_t            offset,
-  int              whence
-)
-{
-  IMFS_jnode_t   *the_jnode;
-
-  the_jnode = iop->file_info;
-
-  if (iop->offset > the_jnode->info.linearfile.size)
-    iop->offset = the_jnode->info.linearfile.size;
-
-  return iop->offset;
-}
Index: cpukit/libfs/src/imfs/memfile.c
===================================================================
--- cpukit/libfs/src/imfs/memfile.c	(revision babf5758c41e00b1a477b63ae1e55056a668ff1e)
+++ cpukit/libfs/src/imfs/memfile.c	(revision 624867bc09632b9c98235073f9a1b4f130233c47)
@@ -100,4 +100,21 @@
   the_jnode = iop->file_info;
 
+  /*
+   * Perform 'copy on write' for linear files
+   */
+  if ((iop->flags & (LIBIO_FLAGS_WRITE | LIBIO_FLAGS_APPEND))
+   && (the_jnode->type == IMFS_LINEAR_FILE)) {
+    uint32_t   count = the_jnode->info.linearfile.size;
+    const unsigned char *buffer = the_jnode->info.linearfile.direct;
+
+    the_jnode->type = IMFS_MEMORY_FILE;
+    the_jnode->info.file.size            = 0;
+    the_jnode->info.file.indirect        = 0;
+    the_jnode->info.file.doubly_indirect = 0;
+    the_jnode->info.file.triply_indirect = 0;
+    if ((count != 0)
+     && (IMFS_memfile_write(the_jnode, 0, buffer, count) == -1))
+        return -1;
+  }
   if (iop->flags & LIBIO_FLAGS_APPEND)
     iop->offset = the_jnode->info.file.size;
Index: cpukit/libfs/src/imfs/miniimfs_init.c
===================================================================
--- cpukit/libfs/src/imfs/miniimfs_init.c	(revision babf5758c41e00b1a477b63ae1e55056a668ff1e)
+++ cpukit/libfs/src/imfs/miniimfs_init.c	(revision 624867bc09632b9c98235073f9a1b4f130233c47)
@@ -64,5 +64,4 @@
       temp_mt_entry,
       &miniIMFS_ops,
-      &rtems_filesystem_null_handlers,  /* for linearfiles */
       &rtems_filesystem_null_handlers,  /* for memfiles */
       &rtems_filesystem_null_handlers   /* for directories */
