summaryrefslogtreecommitdiffstats
path: root/cpukit/include/rtems/rfs
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2017-12-23 18:18:56 +1100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-01-25 08:45:26 +0100
commit2afb22b7e1ebcbe40373ff7e0efae7d207c655a9 (patch)
tree44759efe9374f13200a97e96d91bd9a2b7e5ce2a /cpukit/include/rtems/rfs
parentMAINTAINERS: Add myself to Write After Approval. (diff)
downloadrtems-2afb22b7e1ebcbe40373ff7e0efae7d207c655a9.tar.bz2
Remove make preinstall
A speciality of the RTEMS build system was the make preinstall step. It copied header files from arbitrary locations into the build tree. The header files were included via the -Bsome/build/tree/path GCC command line option. This has at least seven problems: * The make preinstall step itself needs time and disk space. * Errors in header files show up in the build tree copy. This makes it hard for editors to open the right file to fix the error. * There is no clear relationship between source and build tree header files. This makes an audit of the build process difficult. * The visibility of all header files in the build tree makes it difficult to enforce API barriers. For example it is discouraged to use BSP-specifics in the cpukit. * An introduction of a new build system is difficult. * Include paths specified by the -B option are system headers. This may suppress warnings. * The parallel build had sporadic failures on some hosts. This patch removes the make preinstall step. All installed header files are moved to dedicated include directories in the source tree. Let @RTEMS_CPU@ be the target architecture, e.g. arm, powerpc, sparc, etc. Let @RTEMS_BSP_FAMILIY@ be a BSP family base directory, e.g. erc32, imx, qoriq, etc. The new cpukit include directories are: * cpukit/include * cpukit/score/cpu/@RTEMS_CPU@/include * cpukit/libnetworking The new BSP include directories are: * bsps/include * bsps/@RTEMS_CPU@/include * bsps/@RTEMS_CPU@/@RTEMS_BSP_FAMILIY@/include There are build tree include directories for generated files. The include directory order favours the most general header file, e.g. it is not possible to override general header files via the include path order. The "bootstrap -p" option was removed. The new "bootstrap -H" option should be used to regenerate the "headers.am" files. Update #3254.
Diffstat (limited to 'cpukit/include/rtems/rfs')
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-bitmaps.h326
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-block-pos.h242
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-block.h344
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-buffer.h283
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-data.h89
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-dir-hash.h36
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-dir.h209
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-file-system-fwd.h29
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-file-system.h410
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-file.h416
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-group.h181
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-inode.h728
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-link.h124
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-mutex.h116
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-trace.h135
15 files changed, 3668 insertions, 0 deletions
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-bitmaps.h b/cpukit/include/rtems/rfs/rtems-rfs-bitmaps.h
new file mode 100644
index 0000000000..5574339421
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-bitmaps.h
@@ -0,0 +1,326 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File Systems Bitmap Routines
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File Systems Bitmap Routines.
+ *
+ * These functions manage bit maps. A bit map consists of the map of bit
+ * allocated in a block and a search map where a bit represents 32 actual
+ * bits. The search map allows for a faster search for an available bit as 32
+ * search bits can checked in a test.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+
+#if !defined (_RTEMS_RFS_BITMAPS_H_)
+#define _RTEMS_RFS_BITMAPS_H_
+
+#include <rtems/rfs/rtems-rfs-buffer.h>
+#include <rtems/rfs/rtems-rfs-file-system-fwd.h>
+#include <rtems/rfs/rtems-rfs-trace.h>
+
+/**
+ * Define the way the bits are configured. We can have them configured as clear
+ * being 0 or clear being 1. This does not effect how masks are defined. A mask
+ * always has a 1 for set and 0 for clear.
+ */
+#define RTEMS_RFS_BITMAP_CLEAR_ZERO 0
+
+#if RTEMS_RFS_BITMAP_CLEAR_ZERO
+/*
+ * Bit set is a 1 and clear is 0.
+ */
+#define RTEMS_RFS_BITMAP_BIT_CLEAR 0
+#define RTEMS_RFS_BITMAP_BIT_SET 1
+#define RTEMS_RFS_BITMAP_ELEMENT_SET (RTEMS_RFS_BITMAP_ELEMENT_FULL_MASK)
+#define RTEMS_RFS_BITMAP_ELEMENT_CLEAR (0)
+#define RTEMS_RFS_BITMAP_SET_BITS(_t, _b) ((_t) | (_b))
+#define RTEMS_RFS_BITMAP_CLEAR_BITS(_t, _b) ((_t) & ~(_b))
+#define RTEMS_RFS_BITMAP_TEST_BIT(_t, _b) (((_t) & (1 << (_b))) != 0 ? true : false)
+#else
+/*
+ * Bit set is a 0 and clear is 1.
+ */
+#define RTEMS_RFS_BITMAP_BIT_CLEAR 1
+#define RTEMS_RFS_BITMAP_BIT_SET 0
+#define RTEMS_RFS_BITMAP_ELEMENT_SET (0)
+#define RTEMS_RFS_BITMAP_ELEMENT_CLEAR (RTEMS_RFS_BITMAP_ELEMENT_FULL_MASK)
+#define RTEMS_RFS_BITMAP_SET_BITS(_t, _b) ((_t) & ~(_b))
+#define RTEMS_RFS_BITMAP_CLEAR_BITS(_t, _b) ((_t) | (_b))
+#define RTEMS_RFS_BITMAP_TEST_BIT(_t, _b) (((_t) & (1 << (_b))) == 0 ? true : false)
+#endif
+
+/**
+ * Invert a mask. Masks are always 1 for set and 0 for clear.
+ */
+#define RTEMS_RFS_BITMAP_INVERT_MASK(_mask) (~(_mask))
+
+/**
+ * This is the full mask of the length of the element. A mask is always a 1 for
+ * set and 0 for clear. It is not effected by the state of
+ * RTEMS_RFS_BITMAP_CLEAR_ZERO.
+ */
+#define RTEMS_RFS_BITMAP_ELEMENT_FULL_MASK (0xffffffffUL)
+
+/**
+ * The bitmap search window. Searches occur around a seed in either direction
+ * for half the window.
+ */
+#define RTEMS_RFS_BITMAP_SEARCH_WINDOW (rtems_rfs_bitmap_element_bits () * 64)
+
+/**
+ * A bit in a map.
+ */
+typedef int32_t rtems_rfs_bitmap_bit;
+
+/**
+ * The basic element of a bitmap. A bitmap is manipulated by elements.
+ */
+typedef uint32_t rtems_rfs_bitmap_element;
+
+/**
+ * The power of 2 number of bits in the element.
+ */
+#define RTEMS_RFS_ELEMENT_BITS_POWER_2 (5)
+
+/**
+ * A bitmap or map is an array of bitmap elements.
+ */
+typedef rtems_rfs_bitmap_element* rtems_rfs_bitmap_map;
+
+/**
+ * The bitmap control is a simple way to manage the various parts of a bitmap.
+ */
+typedef struct rtems_rfs_bitmap_control_s
+{
+ rtems_rfs_buffer_handle* buffer; //< Handle the to buffer with the bit
+ //map.
+ rtems_rfs_file_system* fs; //< The map's file system.
+ rtems_rfs_buffer_block block; //< The map's block number on disk.
+ size_t size; //< Number of bits in the map. Passed
+ //to create.
+ size_t free; //< Number of bits in the map that are
+ //free (clear).
+ rtems_rfs_bitmap_map search_bits; //< The search bit map memory.
+} rtems_rfs_bitmap_control;
+
+/**
+ * Return the number of bits for the number of bytes provided.
+ */
+#define rtems_rfs_bitmap_numof_bits(_bytes) (8 * (_bytes))
+
+/**
+ * Return the number of bits for the number of bytes provided. The search
+ * element and the element must have the same number of bits.
+ */
+#define rtems_rfs_bitmap_element_bits() \
+ rtems_rfs_bitmap_numof_bits (sizeof (rtems_rfs_bitmap_element))
+
+/**
+ * Return the number of bits a search element covers.
+ */
+#define rtems_rfs_bitmap_search_element_bits() \
+ (rtems_rfs_bitmap_element_bits() * rtems_rfs_bitmap_element_bits())
+
+/**
+ * Return the number of elements for a given number of bits.
+ */
+#define rtems_rfs_bitmap_elements(_bits) \
+ ((((_bits) - 1) / rtems_rfs_bitmap_element_bits()) + 1)
+
+/**
+ * Release the bitmap buffer back to the buffer pool or cache.
+ */
+#define rtems_rfs_bitmap_release_buffer(_fs, _bm) \
+ rtems_rfs_buffer_handle_release (_fs, (_bm)->buffer)
+
+/**
+ * Return the element index for a given bit. We use a macro to hide any
+ * implementation assuptions. Typically this would be calculated by dividing
+ * the bit index by the number of bits in an element. Given we have a power of
+ * 2 as the number of bits we can avoid the division by using a shift. A good
+ * compiler should figure this out but I would rather enforce this than rely on
+ * the specific backend of a compiler to do the right thing.
+ */
+#define rtems_rfs_bitmap_map_index(_b) \
+ ((_b) >> RTEMS_RFS_ELEMENT_BITS_POWER_2)
+
+/**
+ * Return the bit offset for a given bit in an element in a map. See @ref
+ * rtems_rfs_bitmap_map_index for a detailed reason why.
+ */
+#define rtems_rfs_bitmap_map_offset(_b) \
+ ((_b) & ((1 << RTEMS_RFS_ELEMENT_BITS_POWER_2) - 1))
+
+/**
+ * Return the size of the bitmap.
+ */
+#define rtems_rfs_bitmap_map_size(_c) ((_c)->size)
+
+/**
+ * Return the number of free bits in the bitmap.
+ */
+#define rtems_rfs_bitmap_map_free(_c) ((_c)->free)
+
+/**
+ * Return the buffer handle.
+ */
+#define rtems_rfs_bitmap_map_handle(_c) ((_c)->buffer)
+
+/**
+ * Return the bitmap map block.
+ */
+#define rtems_rfs_bitmap_map_block(_c) ((_c)->block)
+
+/**
+ * Create a bit mask with the specified number of bits up to an element's
+ * size. The mask is aligned to bit 0 of the element.
+ *
+ * @param[in] size is the number of bits in the mask.
+ *
+ * @return The mask of the argument size number of bits.
+ */
+rtems_rfs_bitmap_element rtems_rfs_bitmap_mask (unsigned int size);
+
+/**
+ * Create a bit mask section. A mask section is a mask that is not aligned to
+ * an end of the element.
+ *
+ * @param[in] start is the first bit of the mask numbered from 0.
+ * @param[in] end is the end bit of the mask numbered from 0.
+ *
+ * @return Mask section as defined by the start and end arguments.
+ */
+rtems_rfs_bitmap_element rtems_rfs_bitmap_mask_section (unsigned int start,
+ unsigned int end);
+
+/**
+ * Set a bit in a map and if all the bits are set, set the search map bit as
+ * well.
+ *
+ * @param[in] control is the control for the map.
+ * @param[in] bit is the bit in the map to set.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_bitmap_map_set (rtems_rfs_bitmap_control* control,
+ rtems_rfs_bitmap_bit bit);
+
+/**
+ * Clear a bit in a map and make sure the search map bit is clear so a search
+ * will find this bit available.
+ *
+ * @param[in] control is the control for the map.
+ * @param[in] bit is the bit in the map to clear.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_bitmap_map_clear (rtems_rfs_bitmap_control* control,
+ rtems_rfs_bitmap_bit bit);
+
+/**
+ * Test a bit in the map.
+ *
+ * @param[in] control is the bitmap control.
+ * @param[in] bit is the bit to test.
+ * @param[in] state is the state of the bit if no error is returned.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int
+rtems_rfs_bitmap_map_test (rtems_rfs_bitmap_control* control,
+ rtems_rfs_bitmap_bit bit,
+ bool* state);
+
+/**
+ * Set all bits in the bitmap and set the dirty bit.
+ *
+ * @param[in] control is the bitmap control.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_bitmap_map_set_all (rtems_rfs_bitmap_control* control);
+
+/**
+ * Clear all bits in the bitmap and set the dirty bit.
+ *
+ * @param[in] control is the bitmap control.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_bitmap_map_clear_all (rtems_rfs_bitmap_control* control);
+
+/**
+ * Find a free bit searching from the seed up and down until found. The search
+ * is performing by moving up from the seed for the window distance then to
+ * search down from the seed for the window distance. This is repeated out
+ * from the seed for each window until a free bit is found. The search is
+ * performed by checking the search map to see if the map has a free bit.
+ *
+ * @param[in] control is the map control.
+ * @param[in] seed is the bit to search out from.
+ * @param[out] allocate A bit was allocated.
+ * @param[out] bit will contain the bit found free if true is returned.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_bitmap_map_alloc (rtems_rfs_bitmap_control* control,
+ rtems_rfs_bitmap_bit seed,
+ bool* allocate,
+ rtems_rfs_bitmap_bit* bit);
+
+/**
+ * Create a search bit map from the actual bit map.
+ *
+ * @param[in] control is the map control.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_bitmap_create_search (rtems_rfs_bitmap_control* control);
+
+/**
+ * Open a bitmap control with a map and search map.
+ *
+ * @param[in] control is the map control.
+ * @param[in] fs is the file system data.
+ * @param[in] buffer is a pointer to the buffer handle the map is
+ * stored in.
+ * @param[in] size is the number of bits in the map.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_bitmap_open (rtems_rfs_bitmap_control* control,
+ rtems_rfs_file_system* fs,
+ rtems_rfs_buffer_handle* buffer,
+ size_t size,
+ rtems_rfs_buffer_block block);
+
+/**
+ * Close a bitmap.
+ *
+ * @param[in] control is the bit map control.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_bitmap_close (rtems_rfs_bitmap_control* control);
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-block-pos.h b/cpukit/include/rtems/rfs/rtems-rfs-block-pos.h
new file mode 100644
index 0000000000..7d0f0693be
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-block-pos.h
@@ -0,0 +1,242 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File Systems Block Position and Size Management
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File Systems Block Position and Size Management.
+ *
+ * These functions manage the position in a block map as well as a size of data
+ * held in a block map. The position is the block count plus the offset into
+ * the last block where a block position of 0 and an offset of 0 is the start
+ * of a map. The size has a block count plus an offset, but the offset into the
+ * last block gives the actual size of the data in the map. This means a size
+ * will always have a block count greater than 0 when the file is not empty. A
+ * size offset of 0 and a non-zero block count means the length if aligned to
+ * the end of the block. For this reason there are 2 similar types so we know
+ * which set of rules are in use and the reason for this file.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if !defined (_RTEMS_RFS_BLOCK_POS_H_)
+#define _RTEMS_RFS_BLOCK_POS_H_
+
+#include <rtems/rfs/rtems-rfs-file-system.h>
+#include <rtems/rfs/rtems-rfs-inode.h>
+
+/**
+ * The block number is the same type as the inode block number. This makes sure
+ * the sizes of the types match.
+ */
+typedef rtems_rfs_inode_block rtems_rfs_block_no;
+
+/**
+ * The offset into a block.
+ */
+typedef uint32_t rtems_rfs_block_off;
+
+/**
+ * A block position is a block number times the block size plus the offset. The
+ * block field can be used hold a block number for the position as a look up
+ * cache.
+ */
+typedef struct rtems_rfs_block_pos_s
+{
+ /**
+ * The block index in the map. Range is from 0 to the maps block count minus
+ * 1.
+ */
+ rtems_rfs_block_no bno;
+
+ /**
+ * The offset into the block. Must be less than the block size.
+ */
+ rtems_rfs_block_off boff;
+
+ /**
+ * The block number that the bpos + boff map to. The 0 value is invalid and
+ * means no block number has been set.
+ */
+ rtems_rfs_block_no block;
+
+} rtems_rfs_block_pos;
+
+/**
+ * Copy a block position.
+ *
+ * @param[in] _lhs is the left hand side.
+ * @param[in] _rhs is the right hand side.
+ */
+#define rtems_rfs_block_copy_bpos(_lhs, _rhs) \
+ do { (_lhs)->bno = (_rhs)->bno; \
+ (_lhs)->boff = (_rhs)->boff; \
+ (_lhs)->block = (_rhs)->block; } while (0)
+
+/**
+ * Zero a block position.
+ *
+ * @param[in] bpos is a pointer to the block position.
+ */
+static inline void
+rtems_rfs_block_set_bpos_zero (rtems_rfs_block_pos* bpos)
+{
+ bpos->bno = 0;
+ bpos->boff = 0;
+ bpos->block = 0;
+}
+
+/**
+ * Given a position compute the block number and block offset.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] pos is the position as an absolute offset from the start.
+ * @param[out] bpos is a pointer to the block position to fill in.
+ */
+void rtems_rfs_block_get_bpos (rtems_rfs_file_system* fs,
+ rtems_rfs_pos pos,
+ rtems_rfs_block_pos* bpos);
+
+/**
+ * Given a block position compute the absolute offset.
+ *
+ * @param[in] fs is the file system data.
+ * @param[out] bpos is a pointer to the block position to fill in.
+ *
+ * @retval offset The absolute offset.
+ */
+rtems_rfs_pos rtems_rfs_block_get_pos (rtems_rfs_file_system* fs,
+ rtems_rfs_block_pos* bpos);
+
+/**
+ * Add the relative position to the block position. The relative position is
+ * signed.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] offset is the relative offset add to the block position.
+ * @param[out] bpos is a pointer to the block position to fill in.
+ */
+static inline void
+rtems_rfs_block_add_pos (rtems_rfs_file_system* fs,
+ rtems_rfs_pos_rel offset,
+ rtems_rfs_block_pos* bpos)
+{
+ rtems_rfs_block_get_bpos (fs,
+ rtems_rfs_block_get_pos (fs, bpos) + offset,
+ bpos);
+ bpos->block = 0;
+}
+
+/**
+ * A block size is the number of blocks less one plus the offset where the
+ * offset must be less than the block size.
+ */
+typedef struct rtems_rfs_block_size_s
+{
+ /**
+ * The count of blocks in a map. A 0 means no blocks and a zero length and
+ * the offset should also be 0.
+ */
+ rtems_rfs_block_no count;
+
+ /**
+ * The offset into the block. An offset of 0 means block size, ie the first
+ * byte of the next block which is not allocated.
+ */
+ rtems_rfs_block_off offset;
+
+} rtems_rfs_block_size;
+
+/**
+ * Copy a block size.
+ *
+ * @param[in] _lhs is the left hand side.
+ * @param[in] _rhs is the right hand side.
+ */
+#define rtems_rfs_block_copy_size(_lhs, _rhs) \
+ do { (_lhs)->count = (_rhs)->count; \
+ (_lhs)->offset = (_rhs)->offset; } while (0)
+
+/**
+ * Last block ?
+ */
+#define rtems_rfs_block_pos_last_block(_p, _s) \
+ ((((_p)->bno == 0) && ((_s)->count == 0)) || ((_p)->bno == ((_s)->count - 1)))
+
+/**
+ * Last block ?
+ */
+#define rtems_rfs_block_pos_past_end(_p, _s) \
+ (((_p)->bno && ((_s)->count == 0)) || \
+ ((_p)->bno >= (_s)->count) || \
+ (((_p)->bno == ((_s)->count - 1)) && ((_p)->boff > (_s)->offset)))
+
+/**
+ * Is the block position past the end.
+ */
+#define rtems_rfs_block_pos_block_past_end(_p, _s) \
+ (((_p)->bno && ((_s)->count == 0)) || ((_p)->bno >= (_s)->count))
+
+/**
+ * Copy the size to the block position. Note the block position and the size
+ * have different block counts.
+ */
+#define rtems_rfs_block_size_get_bpos(_s, _b) \
+ do { (_b)->bno = (_s)->count; \
+ (_b)->boff = (_s)->offset; \
+ (_b)->block = 0; \
+ if ((_b)->boff) --(_b)->bno; } while (0)
+
+/**
+ * Do the sizes match ?
+ */
+#define rtems_rfs_block_size_equal(_lhs, _rhs) \
+ (((_lhs)->count == (_rhs)->count) && ((_lhs)->offset == (_rhs)->offset))
+
+/**
+ * Zero a block size.
+ *
+ * @param[in] size is a pointer to the block size.
+ */
+static inline void
+rtems_rfs_block_set_size_zero (rtems_rfs_block_size* size)
+{
+ size->count = 0;
+ size->offset = 0;
+}
+
+/**
+ * Set the size given a position.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] pos is the position as an absolute offset from the start.
+ * @param[out] size is a pointer to the block size to fill in.
+ */
+void rtems_rfs_block_get_block_size (rtems_rfs_file_system* fs,
+ rtems_rfs_pos pos,
+ rtems_rfs_block_size* size);
+
+/**
+ * Calculate the position given the number of blocks and the offset. If the
+ * block count is 0 the size is 0. If the block is greater than 0 and the
+ * offset is 0 the size is number of blocks multipled by the block size and if
+ * the offset is not 0 it is the offset into the last block. For example if
+ * blocks is 1 and offset is 0 the size is the block size. If the block count
+ * is 1 and size is 100 the size is 100.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] size The size in blocks and offset.
+ *
+ * @retval size The size in bytes.
+ */
+rtems_rfs_pos rtems_rfs_block_get_size (rtems_rfs_file_system* fs,
+ rtems_rfs_block_size* size);
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-block.h b/cpukit/include/rtems/rfs/rtems-rfs-block.h
new file mode 100644
index 0000000000..394853b7ad
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-block.h
@@ -0,0 +1,344 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File Systems Block Management
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File Systems Block Management.
+ *
+ * These functions manage the blocks used in the file system.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+
+#if !defined (_RTEMS_RFS_BLOCK_H_)
+#define _RTEMS_RFS_BLOCK_H_
+
+#include <rtems/rfs/rtems-rfs-block-pos.h>
+#include <rtems/rfs/rtems-rfs-buffer.h>
+#include <rtems/rfs/rtems-rfs-data.h>
+#include <rtems/rfs/rtems-rfs-file-system.h>
+
+/**
+ * Get a block number in the media format and return it in the host format.
+ *
+ * @param[in] _h is the buffer handle of the block.
+ * @param[in] _b is the block number index.
+ *
+ * @retval block The block number.
+ */
+#define rtems_rfs_block_get_number(_h, _b) \
+ ((rtems_rfs_block_no) \
+ (rtems_rfs_read_u32 (rtems_rfs_buffer_data (_h) + \
+ ((_b) * sizeof (rtems_rfs_block_no)))))
+
+/**
+ * Set a block number in the media format given a number in the host format.
+ *
+ * @param[in] _h is the buffer handle of the block.
+ * @param[in] _b is the block number index, ie the number of block number not the
+ * buffer offset.
+ * @param[in] _n is the block number.
+ */
+#define rtems_rfs_block_set_number(_h, _b, _n) \
+ do { \
+ rtems_rfs_write_u32 (rtems_rfs_buffer_data (_h) + \
+ ((_b) * sizeof (rtems_rfs_block_no)), (_n)); \
+ rtems_rfs_buffer_mark_dirty (_h); \
+ } while (0)
+
+/**
+ * A block map manges the block lists that originate from an inode. The inode
+ * contains a number of block numbers. A block map takes those block numbers
+ * and manages them.
+ *
+ * The blocks cannot have all ones as a block number nor block 0. The block map
+ * is series of block numbers in a blocks. The size of the map determines the
+ * way the block numbers are stored. The map uses the following:
+ *
+ * @li @e Direct Access,
+ * @li @e Single Indirect Access, and
+ * @li @e Double Indirect Access.
+ *
+ * Direct access has the blocks numbers in the inode slots. The Single Indirect
+ * Access has block numbers in the inode slots that pointer to a table of block
+ * numbers that point to data blocks. The Double Indirect Access has block
+ * numbers in the inode that point to Single Indirect block tables.
+ *
+ * The inode can hold a number of Direct, Single Indirect, and Double Indirect
+ * block tables. The move from Direct to Single occurs then the block count in
+ * the map is above the number of slots in the inode. The move from Single to
+ * Double occurs when the map block count is greated than the block numbers per
+ * block multipled by the slots in the inode. The move from Single to Double
+ * occurs when the map block count is over the block numbers per block squared
+ * multipled by the number of slots in the inode.
+ *
+ * The block map can managed files of the follow size verses block size with 5
+ * inode slots:
+ *
+ * @li 41,943,040 bytes for a 512 byte block size,
+ * @li 335,544,320 bytes for a 1024 byte block size,
+ * @li 2,684,354,560 bytes for a 2048 byte block size, and
+ * @li 21,474,836,480 bytes for a 4096 byte block size.
+ */
+typedef struct rtems_rfs_block_map_s
+{
+ /**
+ * Is the map dirty ?
+ */
+ bool dirty;
+
+ /**
+ * The inode this map is attached to.
+ */
+ rtems_rfs_inode_handle* inode;
+
+ /**
+ * The size of the map.
+ */
+ rtems_rfs_block_size size;
+
+ /**
+ * The block map position. Used to navigate the map when seeking. The find
+ * call is to a position in the file/directory and is a block number plus
+ * offset. The block find only needs to locate a block and not worry about
+ * the offset while a seek can be less than a block size yet move across a
+ * block boundary. Therefore the position a block map has to maintain must
+ * include the offset so seeks work.
+ */
+ rtems_rfs_block_pos bpos;
+
+ /**
+ * The last map block allocated. This is used as the goal when allocating a
+ * new map block.
+ */
+ rtems_rfs_block_no last_map_block;
+
+ /**
+ * The last data block allocated. This is used as the goal when allocating a
+ * new data block.
+ */
+ rtems_rfs_block_no last_data_block;
+
+ /**
+ * The block map.
+ */
+ uint32_t blocks[RTEMS_RFS_INODE_BLOCKS];
+
+ /**
+ * Singly Buffer handle.
+ */
+ rtems_rfs_buffer_handle singly_buffer;
+
+ /**
+ * Doubly Buffer handle.
+ */
+ rtems_rfs_buffer_handle doubly_buffer;
+
+} rtems_rfs_block_map;
+
+/**
+ * Is the map dirty ?
+ */
+#define rtems_rfs_block_map_is_dirty(_m) ((_m)->dirty)
+
+/**
+ * Return the block count in the map.
+ */
+#define rtems_rfs_block_map_count(_m) ((_m)->size.count)
+
+/**
+ * Return the map's size element.
+ */
+#define rtems_rfs_block_map_size(_m) (&((_m)->size))
+
+/**
+ * Return the size offset for the map.
+ */
+#define rtems_rfs_block_map_size_offset(_m) ((_m)->size.offset)
+
+/**
+ * Are we at the last block in the map ?
+ */
+#define rtems_rfs_block_map_last(_m) \
+ rtems_rfs_block_pos_last_block (&(_m)->bpos, &(_m)->size)
+
+/**
+ * Is the position past the end of the block ?
+ */
+#define rtems_rfs_block_map_past_end(_m, _p) \
+ rtems_rfs_block_pos_past_end (_p, &(_m)->size)
+
+/**
+ * Return the current position in the map.
+ */
+#define rtems_rfs_block_map_pos(_f, _m) \
+ rtems_rfs_block_get_pos (_f, &(_m)->bpos)
+
+/**
+ * Return the map's current block number.
+ */
+#define rtems_rfs_block_map_block(_m) ((_m)->bpos.bno)
+
+/**
+ * Return the map's current block offset.
+ */
+#define rtems_rfs_block_map_block_offset(_m) ((_m)->bpos.boff)
+
+/**
+ * Set the size offset for the map. The map is tagged as dirty.
+ *
+ * @param[in] map is a pointer to the open map to set the offset in.
+ * @param[in] offset is the offset to set in the map's size.
+ */
+static inline void
+rtems_rfs_block_map_set_size_offset (rtems_rfs_block_map* map,
+ rtems_rfs_block_off offset)
+{
+ map->size.offset = offset;
+ map->dirty = true;
+}
+
+/**
+ * Set the map's size. The map is tagged as dirty.
+ *
+ * @param[in] map is a pointer to the open map to set the offset in.
+ * @param[in] size is the size to set in the map's size.
+ */
+static inline void
+rtems_rfs_block_map_set_size (rtems_rfs_block_map* map,
+ rtems_rfs_block_size* size)
+{
+ rtems_rfs_block_copy_size (&map->size, size);
+ map->dirty = true;
+}
+/**
+ * Open a block map. The block map data in the inode is copied into the
+ * map. The buffer handles are opened. The block position is set to the start
+ * so a seek of offset 0 will return the first block.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] inode is a pointer to the inode the map belongs to.
+ * @param[in] map is a pointer to the map that is opened.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_block_map_open (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* inode,
+ rtems_rfs_block_map* map);
+
+/**
+ * Close the map. The buffer handles are closed and any help buffers are
+ * released.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] map is a pointer to the map that is opened.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_block_map_close (rtems_rfs_file_system* fs,
+ rtems_rfs_block_map* map);
+
+/**
+ * Find a block number in the map from the position provided.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] map is a pointer to the map to search.
+ * @param[in] bpos is a pointer to the block position to find.
+ * @param[out] block will contain the block in when found.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_block_map_find (rtems_rfs_file_system* fs,
+ rtems_rfs_block_map* map,
+ rtems_rfs_block_pos* bpos,
+ rtems_rfs_buffer_block* block);
+
+/**
+ * Seek around the map.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] map is a pointer to the map to search.
+ * @param[in] offset is the distance to seek. It is signed.
+ * @param[out] block will contain the block in when found.
+ *
+ * @retval 0 Successful operation.
+ * @retval ENXIO Failed to seek because it is outside the block map.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_block_map_seek (rtems_rfs_file_system* fs,
+ rtems_rfs_block_map* map,
+ rtems_rfs_pos_rel offset,
+ rtems_rfs_buffer_block* block);
+
+/**
+ * Seek to the next block.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] map is a pointer to the map to search.
+ * @param[out] block will contain the block in when found.
+ *
+ * @retval 0 Successful operation.
+ * @retval ENXIO Failed to seek because it is outside the block map.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_block_map_next_block (rtems_rfs_file_system* fs,
+ rtems_rfs_block_map* map,
+ rtems_rfs_buffer_block* block);
+
+/**
+ * Grow the block map by the specified number of blocks.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] map is a pointer to the open map to grow.
+ * @param[in] blocks is the number of blocks to grow the map by.
+ * @param[out] new_block will contain first of the blocks allocated
+ * to the map.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_block_map_grow (rtems_rfs_file_system* fs,
+ rtems_rfs_block_map* map,
+ size_t blocks,
+ rtems_rfs_block_no* new_block);
+
+/**
+ * Grow the block map by the specified number of blocks.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] map is a pointer to the open map to shrink.
+ * @param[in] blocks is the number of blocks to shrink the map by. If more
+ * than the number of blocks the map is emptied.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_block_map_shrink (rtems_rfs_file_system* fs,
+ rtems_rfs_block_map* map,
+ size_t blocks);
+
+/**
+ * Free all blocks in the map.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] map is a pointer to the open map to free all blocks from.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_block_map_free_all (rtems_rfs_file_system* fs,
+ rtems_rfs_block_map* map);
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-buffer.h b/cpukit/include/rtems/rfs/rtems-rfs-buffer.h
new file mode 100644
index 0000000000..1c603e1827
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-buffer.h
@@ -0,0 +1,283 @@
+/**
+ * @file
+ *
+ * @ingroup rtems_rfs
+ *
+ * @brief Maps Blocks to the Media Interface Layers
+ *
+ * These functions map blocks to the media interface layers.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+
+#if !defined (_RTEMS_RFS_BUFFER_H_)
+#define _RTEMS_RFS_BUFFER_H_
+
+#include <errno.h>
+
+#include <rtems/rfs/rtems-rfs-file-system-fwd.h>
+#include <rtems/rfs/rtems-rfs-trace.h>
+
+/**
+ * Define the method used to interface to the buffers. It can be libblock or
+ * device I/O. The libblock interface is to the RTEMS cache and block devices
+ * and device I/O accesses the media via a device file handle.
+ */
+#if defined (__rtems__)
+#define RTEMS_RFS_USE_LIBBLOCK 1
+#endif
+
+/**
+ * The RTEMS RFS I/O Layering.
+ */
+#if RTEMS_RFS_USE_LIBBLOCK
+#include <rtems/bdbuf.h>
+#include <rtems/error.h>
+
+typedef rtems_blkdev_bnum rtems_rfs_buffer_block;
+typedef rtems_bdbuf_buffer rtems_rfs_buffer;
+#define rtems_rfs_buffer_io_request rtems_rfs_buffer_bdbuf_request
+#define rtems_rfs_buffer_io_release rtems_rfs_buffer_bdbuf_release
+
+/**
+ * Request a buffer from the RTEMS libblock BD buffer cache.
+ */
+int rtems_rfs_buffer_bdbuf_request (rtems_rfs_file_system* fs,
+ rtems_rfs_buffer_block block,
+ bool read,
+ rtems_rfs_buffer** buffer);
+/**
+ * Release a buffer to the RTEMS libblock BD buffer cache.
+ */
+int rtems_rfs_buffer_bdbuf_release (rtems_rfs_buffer* handle,
+ bool modified);
+#else /* Device I/O */
+typedef uint32_t rtems_rfs_buffer_block;
+typedef struct _rtems_rfs_buffer
+{
+ rtems_chain_node link;
+ rtems_rfs_buffer_block user;
+ void* buffer;
+ size_t size;
+ uint32_t references;
+} rtems_rfs_buffer;
+#define rtems_rfs_buffer_io_request rtems_rfs_buffer_deviceio_request
+#define rtems_rfs_buffer_io_release rtems_rfs_buffer_deviceio_release
+
+/**
+ * Request a buffer from the device I/O.
+ */
+int rtems_rfs_buffer_deviceio_request (rtems_rfs_file_system* fs,
+ rtems_rfs_buffer_block block,
+ bool read,
+ rtems_rfs_buffer* buffer);
+/**
+ * Release a buffer to the RTEMS libblock BD buffer cache.
+ */
+int rtems_rfs_buffer_deviceio_release (rtems_rfs_buffer* handle,
+ bool modified);
+#endif
+
+/**
+ * RFS Buffer handle.
+ */
+typedef struct rtems_rfs_buffer_handle_t
+{
+ /**
+ * Has the buffer been modifed?
+ */
+ bool dirty;
+
+ /**
+ * Block number. The lower layer block number may be absolute and we maybe
+ * relative to an offset in the disk so hold locally.
+ */
+ rtems_rfs_buffer_block bnum;
+
+ /**
+ * Reference the buffer descriptor.
+ */
+ rtems_rfs_buffer* buffer;
+
+} rtems_rfs_buffer_handle;
+
+/**
+ * The buffer linkage.
+ */
+#define rtems_rfs_buffer_link(_h) (&(_h)->buffer->link)
+
+/**
+ * Return the start of the data area of the buffer given a handle.
+ */
+#define rtems_rfs_buffer_data(_h) ((void*)((_h)->buffer->buffer))
+
+/**
+ * Return the size of the buffer given a handle.
+ */
+#define rtems_rfs_buffer_size(_h) ((_h)->buffer->size)
+
+/**
+ * Return the block number.
+ */
+#define rtems_rfs_buffer_bnum(_h) ((_h)->bnum)
+
+/**
+ * Return the buffer dirty status.
+ */
+#define rtems_rfs_buffer_dirty(_h) ((_h)->dirty)
+
+/**
+ * Does the handle have a valid block attached ?
+ */
+#define rtems_rfs_buffer_handle_has_block(_h) ((_h)->buffer ? true : false)
+
+/**
+ * Mark the buffer as dirty.
+ */
+#define rtems_rfs_buffer_mark_dirty(_h) ((_h)->dirty = true)
+
+/**
+ * Return the reference count.
+ */
+#define rtems_rfs_buffer_refs(_h) ((_h)->buffer->references)
+
+/**
+ * Increment the reference count.
+ */
+#define rtems_rfs_buffer_refs_up(_h) ((_h)->buffer->references += 1)
+
+/**
+ * Decrement the reference count.
+ */
+#define rtems_rfs_buffer_refs_down(_h) ((_h)->buffer->references -= 1)
+
+/**
+ * Request a buffer. The buffer can be filled with data from the media
+ * (read == true) or you can request a buffer to fill with data.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] handle is the handle the requested buffer is attached to.
+ * @param[in] block is the block number.
+ * @param[in] read Read the data from the disk.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_buffer_handle_request (rtems_rfs_file_system* fs,
+ rtems_rfs_buffer_handle* handle,
+ rtems_rfs_buffer_block block,
+ bool read);
+
+/**
+ * Release a buffer. If the buffer is dirty the buffer is written to disk. The
+ * result does not indicate if the data was successfully written to the disk as
+ * this operation may be performed in asynchronously to this release.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] handle is the handle the requested buffer is attached to.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_buffer_handle_release (rtems_rfs_file_system* fs,
+ rtems_rfs_buffer_handle* handle);
+
+/**
+ * Open a handle.
+ *
+ * @param[in] fs i the file system data.
+ * @param[in] handle i the buffer handle to open.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+static inline int
+rtems_rfs_buffer_handle_open (rtems_rfs_file_system* fs,
+ rtems_rfs_buffer_handle* handle)
+{
+ handle->dirty = false;
+ handle->bnum = 0;
+ handle->buffer = NULL;
+ return 0;
+}
+
+/**
+ * Close a handle.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] handle is the buffer handle to close.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+static inline int
+rtems_rfs_buffer_handle_close (rtems_rfs_file_system* fs,
+ rtems_rfs_buffer_handle* handle)
+{
+ rtems_rfs_buffer_handle_release (fs, handle);
+ handle->dirty = false;
+ handle->bnum = 0;
+ handle->buffer = NULL;
+ return 0;
+}
+
+/**
+ * Open the buffer interface.
+ *
+ * @param[in] name is a pointer to the device name to the media.
+ * @param[in] fs is the file system data.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_buffer_open (const char* name, rtems_rfs_file_system* fs);
+
+/**
+ * Close the buffer interface.
+ *
+ * @param[in] fs is the file system data.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_buffer_close (rtems_rfs_file_system* fs);
+
+/**
+ * Sync all buffers to the media.
+ *
+ * @param[in] fs is the file system data.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_buffer_sync (rtems_rfs_file_system* fs);
+
+/**
+ * Set the block size of the device.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] size is the new block size.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_buffer_setblksize (rtems_rfs_file_system* fs, uint32_t size);
+
+/**
+ * Release any chained buffers.
+ *
+ * @param[in] fs is the file system data.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_buffers_release (rtems_rfs_file_system* fs);
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-data.h b/cpukit/include/rtems/rfs/rtems-rfs-data.h
new file mode 100644
index 0000000000..6217e74587
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-data.h
@@ -0,0 +1,89 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File System Data
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File System Data.
+ *
+ * Access data in the correct byte order for the specific target we are running
+ * on.
+ *
+ * @todo Make direct access on matching byte ordered targets.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+
+#if !defined (_RTEMS_RFS_DATA_H_)
+#define _RTEMS_RFS_DATA_H_
+
+#include <stdint.h>
+
+/**
+ * Helper function to make sure we have a byte pointer.
+ */
+#define rtems_rfs_data_ptr(_d) ((uint8_t*)(_d))
+
+/**
+ * Helper function to get the data shifted in the correctly sized type.
+ */
+#define rtems_rfs_data_get(_d, _t, _o, _s) \
+ (((_t)(rtems_rfs_data_ptr (_d)[_o])) << (_s))
+
+/**
+ * RFS Read Unsigned 8bit Integer
+ */
+#define rtems_rfs_read_u8(_d) \
+ (*rtems_rfs_data_ptr (_d))
+
+/**
+ * RFS Read Unsigned 16bit Integer
+ */
+#define rtems_rfs_read_u16(_d) \
+ (rtems_rfs_data_get (_d, uint16_t, 0, 8) | \
+ rtems_rfs_data_get (_d, uint16_t, 1, 0))
+
+/**
+ * RFS Read Unsigned 32bit Integer
+ */
+#define rtems_rfs_read_u32(_d) \
+ (rtems_rfs_data_get (_d, uint32_t, 0, 24) | \
+ rtems_rfs_data_get (_d, uint32_t, 1, 16) | \
+ rtems_rfs_data_get (_d, uint32_t, 2, 8) | \
+ rtems_rfs_data_get (_d, uint32_t, 3, 0))
+
+/**
+ * RFS Write Unsigned 8bit Integer
+ */
+#define rtems_rfs_write_u8(_d, _v) \
+ (*rtems_rfs_data_ptr (_d) = (uint8_t)(_v))
+
+/**
+ * RFS Write Unsigned 16bit Integer
+ */
+#define rtems_rfs_write_u16(_d, _v) \
+ do { \
+ rtems_rfs_data_ptr (_d)[0] = (uint8_t)(((uint16_t)(_v)) >> 8); \
+ rtems_rfs_data_ptr (_d)[1] = (uint8_t)((_v)); \
+ } while (0)
+
+/**
+ * RFS Write Unsigned 32bit Integer
+ */
+#define rtems_rfs_write_u32(_d, _v) \
+ do { \
+ rtems_rfs_data_ptr (_d)[0] = (uint8_t)(((uint32_t)(_v)) >> 24); \
+ rtems_rfs_data_ptr (_d)[1] = (uint8_t)(((uint32_t)(_v)) >> 16); \
+ rtems_rfs_data_ptr (_d)[2] = (uint8_t)(((uint32_t)(_v)) >> 8); \
+ rtems_rfs_data_ptr (_d)[3] = (uint8_t)((uint32_t)(_v)); \
+ } while (0)
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-dir-hash.h b/cpukit/include/rtems/rfs/rtems-rfs-dir-hash.h
new file mode 100644
index 0000000000..d9a8a2004f
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-dir-hash.h
@@ -0,0 +1,36 @@
+/**
+ * @file
+ *
+ * @brief Provides a 32bit Hash of a String used to Search a Directory
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File Systems Directory Hash provides a 32bit hash of a string. This is
+ * used to search a directory.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if !defined (_RTEMS_RFS_DIR_HASH_H_)
+#define _RTEMS_RFS_DIR_HAS_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+/**
+ * Compute a hash of the key over the length of string.
+ *
+ * @param[in] key is a pointer to the key to calculate the hash of.
+ * @param[in] length is the length of the key in bytes.
+ *
+ * @retval hash The computed uint32_t hash.
+ */
+uint32_t rtems_rfs_dir_hash (const void *key, size_t length);
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-dir.h b/cpukit/include/rtems/rfs/rtems-rfs-dir.h
new file mode 100644
index 0000000000..ae3647d03c
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-dir.h
@@ -0,0 +1,209 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File System Directory Support
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File System Directory Support
+ *
+ * This file provides the directory support functions.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if !defined (_RTEMS_RFS_DIR_H_)
+#define _RTEMS_RFS_DIR_H_
+
+#include <dirent.h>
+
+#include <rtems/libio_.h>
+
+#include <rtems/rfs/rtems-rfs-data.h>
+#include <rtems/rfs/rtems-rfs-file-system.h>
+#include <rtems/rfs/rtems-rfs-inode.h>
+
+/**
+ * Define the offsets of the fields of a directory entry.
+ */
+#define RTEMS_RFS_DIR_ENTRY_INO (0) /**< The ino offset in a directory
+ * entry. */
+#define RTEMS_RFS_DIR_ENTRY_HASH (4) /**< The hash offset in a directory
+ * entry. The hash is 32bits. We need at
+ * least 16bits and given the length and
+ * ino field are 4 the extra 2 bytes is
+ * not a big overhead.*/
+#define RTEMS_RFS_DIR_ENTRY_LEN (8) /**< The length offset in a directory
+ * entry. */
+
+/**
+ * The length of the directory entry header.
+ */
+#define RTEMS_RFS_DIR_ENTRY_SIZE (4 + 4 + 2)
+
+/**
+ * The length when the remainder of the directory block is empty.
+ */
+#define RTEMS_RFS_DIR_ENTRY_EMPTY (0xffff)
+
+/**
+ * Return the hash of the entry.
+ *
+ * @param[in] _e is a pointer to the directory entry.
+ *
+ * @retval hash The uint32_t hash of the entry.
+ */
+#define rtems_rfs_dir_entry_hash(_e) \
+ rtems_rfs_read_u32 (_e + RTEMS_RFS_DIR_ENTRY_HASH)
+
+/**
+ * Set the hash of the entry.
+ *
+ * @param[in] _e is a pointer to the directory entry.
+ *
+ * @param[in] _h is the hash of the entry.
+ */
+#define rtems_rfs_dir_set_entry_hash(_e, _h) \
+ rtems_rfs_write_u32 (_e + RTEMS_RFS_DIR_ENTRY_HASH, _h)
+
+/**
+ * Return the ino of the entry.
+ *
+ * @param[in] _e is a pointer to the directory entry.
+ *
+ * @retval ino The ino of the entry.
+ */
+#define rtems_rfs_dir_entry_ino(_e) \
+ rtems_rfs_read_u32 (_e + RTEMS_RFS_DIR_ENTRY_INO)
+
+/**
+ * Set the ino of the entry.
+ *
+ * @param[in] _e is a pointer to the directory entry.
+ *
+ * @param[in] _i is the ino of the entry.
+ */
+#define rtems_rfs_dir_set_entry_ino(_e, _i) \
+ rtems_rfs_write_u32 (_e + RTEMS_RFS_DIR_ENTRY_INO, _i)
+
+/**
+ * Return the length of the entry.
+ *
+ * @param[in] _e Pointer to the directory entry.
+ *
+ * @retval length The length of the entry.
+ */
+#define rtems_rfs_dir_entry_length(_e) \
+ rtems_rfs_read_u16 (_e + RTEMS_RFS_DIR_ENTRY_LEN)
+
+/**
+ * Set the length of the entry.
+ *
+ * @param[in] _e is a pointer to the directory entry.
+ * @param[in] _l is the length.
+ */
+#define rtems_rfs_dir_set_entry_length(_e, _l) \
+ rtems_rfs_write_u16 (_e + RTEMS_RFS_DIR_ENTRY_LEN, _l)
+
+/**
+ * Look up a directory entry in the directory pointed to by the inode. The look
+ * up is local to this directory. No need to decend.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] inode is a pointer to the inode of the directory to search.
+ * @param[in] name is a pointer to the name to look up. The name may not be
+ * nul terminated.
+ * @param[in] length is the length of the name.
+ * @param[out] ino will be filled in with the inode number
+ * if there is no error.
+ * @param[in] offset is the offset in the directory for the entry.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_dir_lookup_ino (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* inode,
+ const char* name,
+ int length,
+ rtems_rfs_ino* ino,
+ uint32_t* offset);
+
+/**
+ * Add an entry to the directory returing the inode number allocated to the
+ * entry.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] dir is a pointer to the directory inode the
+ * entry is to be added too.
+ * @param[in] name is a pointer to the name of the entry to be added.
+ * @param[in] length is the length of the name excluding a terminating 0.
+ * @param[in] ino is the ino of the entry.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_dir_add_entry (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* dir,
+ const char* name,
+ size_t length,
+ rtems_rfs_ino ino);
+
+/**
+ * Del an entry from the directory using an inode number as a key.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] dir is a pointer to the directory inode the
+ * entry is to be deleted from.
+ * @param[in] ino is the ino of the entry.
+ * @param[in] offset is the offset in the directory of the entry
+ * to delete. If 0 search from the start for the ino.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_dir_del_entry (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* dir,
+ rtems_rfs_ino ino,
+ uint32_t offset);
+
+/**
+ * Read the directory entry from offset into the directory entry buffer and
+ * return the length of space this entry uses in the directory table.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] dir is a pointer to the direct inode handler.
+ * @param[in] offset is the offset in the directory to read from.
+ * @param[in] dirent is a ointer to the dirent structure the entry
+ * is written into.
+ * @param[out] length will contain the length this entry
+ * takes in the directory.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_dir_read (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* dir,
+ rtems_rfs_pos_rel offset,
+ struct dirent* dirent,
+ size_t* length);
+
+/**
+ * Check if the directory is empty. The current and parent directory entries
+ * are ignored.
+ *
+ * @param[in] fs is the file system data
+ * @param[in] dir is a pointer to the directory inode to check.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_dir_empty (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* dir);
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-file-system-fwd.h b/cpukit/include/rtems/rfs/rtems-rfs-file-system-fwd.h
new file mode 100644
index 0000000000..e239c25d6f
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-file-system-fwd.h
@@ -0,0 +1,29 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File Systems Data Forward Declaration
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File Systems Data forward decl.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+
+#if !defined (_RTEMS_RFS_FILE_SYSTEM_FWD_H_)
+#define _RTEMS_RFS_FILE_SYSTEM_FWD_H_
+
+/**
+ * Forward reference to the file system data.
+ */
+struct _rtems_rfs_file_system;
+typedef struct _rtems_rfs_file_system rtems_rfs_file_system;
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-file-system.h b/cpukit/include/rtems/rfs/rtems-rfs-file-system.h
new file mode 100644
index 0000000000..e00b142532
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-file-system.h
@@ -0,0 +1,410 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File System Data
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File System Data
+ *
+ * This file defines the file system data.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if !defined (_RTEMS_RFS_FILE_SYSTEM_H_)
+#define _RTEMS_RFS_FILE_SYSTEM_H_
+
+#include <rtems/rfs/rtems-rfs-group.h>
+
+/**
+ * Superblock offsets and values.
+ */
+#define RTEMS_RFS_SB_OFFSET_MAGIC (0)
+#define RTEMS_RFS_SB_MAGIC (0x28092001)
+#define RTEMS_RFS_SB_OFFSET_VERSION (RTEMS_RFS_SB_OFFSET_MAGIC + 4)
+#define RTEMS_RFS_SB_OFFSET_BLOCK_SIZE (RTEMS_RFS_SB_OFFSET_VERSION + 4)
+#define RTEMS_RFS_SB_OFFSET_BLOCKS (RTEMS_RFS_SB_OFFSET_BLOCK_SIZE + 4)
+#define RTEMS_RFS_SB_OFFSET_BAD_BLOCKS (RTEMS_RFS_SB_OFFSET_BLOCKS + 4)
+#define RTEMS_RFS_SB_OFFSET_MAX_NAME_LENGTH (RTEMS_RFS_SB_OFFSET_BAD_BLOCKS + 4)
+#define RTEMS_RFS_SB_OFFSET_GROUPS (RTEMS_RFS_SB_OFFSET_MAX_NAME_LENGTH + 4)
+#define RTEMS_RFS_SB_OFFSET_GROUP_BLOCKS (RTEMS_RFS_SB_OFFSET_GROUPS + 4)
+#define RTEMS_RFS_SB_OFFSET_GROUP_INODES (RTEMS_RFS_SB_OFFSET_GROUP_BLOCKS + 4)
+#define RTEMS_RFS_SB_OFFSET_INODE_SIZE (RTEMS_RFS_SB_OFFSET_GROUP_INODES + 4)
+
+/**
+ * RFS Version Number.
+ */
+#define RTEMS_RFS_VERSION (0x00000000)
+
+/**
+ * RFS Version Number Mask. The mask determines which bits of the version
+ * number indicate compatility issues.
+ */
+#define RTEMS_RFS_VERSION_MASK INT32_C(0x00000000)
+
+/**
+ * The root inode number. Do not use 0 as this has special meaning in some
+ * Unix operating systems.
+ */
+#define RTEMS_RFS_ROOT_INO (1)
+
+/**
+ * Empty inode number.
+ */
+#define RTEMS_RFS_EMPTY_INO (0)
+
+/**
+ * The number of blocks in the inode. This number effects the size of the
+ * inode and that effects the overhead of the inode tables in a group.
+ */
+#define RTEMS_RFS_INODE_BLOCKS (5)
+
+/**
+ * The inode overhead is the percentage of space reserved for inodes. It is
+ * calculated as the percentage number of blocks in a group. The number of
+ * blocks in a group is the number of bits a block can hold.
+ */
+#define RTEMS_RFS_INODE_OVERHEAD_PERCENTAGE (1)
+
+/**
+ * Number of blocks in the superblock. Yes I know it is a superblock and not
+ * superblocks but if for any reason this needs to change it is handled.
+ */
+#define RTEMS_RFS_SUPERBLOCK_SIZE (1)
+
+/**
+ * The maximum number of buffers held by the file system at any one time.
+ */
+#define RTEMS_RFS_FS_MAX_HELD_BUFFERS (5)
+
+/**
+ * Absolute position. Make a 64bit value.
+ */
+typedef uint64_t rtems_rfs_pos;
+
+/**
+ * Relative position. Make a 64bit value.
+ */
+typedef int64_t rtems_rfs_pos_rel;
+
+/**
+ * Flags to control the file system.
+ */
+#define RTEMS_RFS_FS_BITMAPS_HOLD (1 << 0) /**< Do not release bitmaps
+ * when finished. Default is
+ * off so they are released. */
+#define RTEMS_RFS_FS_NO_LOCAL_CACHE (1 << 1) /**< Do not cache the buffers
+ * and release directly to the
+ * buffer support layer. The
+ * default is to hold buffers. */
+#define RTEMS_RFS_FS_FORCE_OPEN (1 << 2) /**< Force open and ignore any
+ * errors. */
+#define RTEMS_RFS_FS_READ_ONLY (1 << 3) /**< Make the mount
+ * read-only. Currently not
+ * supported. */
+/**
+ * RFS File System data.
+ */
+struct _rtems_rfs_file_system
+{
+ /**
+ * Flags to control the file system. Some can be controlled via the ioctl.
+ */
+ uint32_t flags;
+
+ /**
+ * The number of blocks in the disk. The size of the disk is the number of
+ * blocks by the block size. This should be within a block size of the size
+ * returned by the media driver.
+ */
+ size_t blocks;
+
+ /**
+ * The size of a block. This must be a multiple of the disk's media block
+ * size.
+ */
+ size_t block_size;
+
+ /**
+ * The file descriptor for device I/O.
+ */
+ int device;
+
+#if RTEMS_RFS_USE_LIBBLOCK
+ /**
+ * The disk device. This is the data about the block device this file system
+ * is mounted on. We access the data held in this structure rather than
+ * making an extra copy in this structure.
+ */
+ rtems_disk_device* disk;
+#else
+ /**
+ * The number of blocks in the file system.
+ */
+ size_t size;
+#endif
+
+ /**
+ * Inode count.
+ */
+ uint32_t inodes;
+
+ /**
+ * Bad block blocks. This is a table of blocks that have been found to be
+ * bad.
+ */
+ uint32_t bad_blocks;
+
+ /**
+ * Maximum length of names supported by this file system.
+ */
+ uint32_t max_name_length;
+
+ /**
+ * A disk is broken down into a series of groups.
+ */
+ rtems_rfs_group* groups;
+
+ /**
+ * Number of groups.
+ */
+ int group_count;
+
+ /**
+ * Number of blocks in a group.
+ */
+ size_t group_blocks;
+
+ /**
+ * Number of inodes in a group.
+ */
+ size_t group_inodes;
+
+ /**
+ * Number of inodes in each block.
+ */
+ size_t inodes_per_block;
+
+ /**
+ * Number of block numbers in a block.
+ */
+ size_t blocks_per_block;
+
+ /**
+ * Block map single indirect count. This is the block number per block
+ * multiplied but the slots in the inode.
+ */
+ size_t block_map_singly_blocks;
+
+ /**
+ * Block map double indirect count. This is the block number per block
+ * squared and multiplied by the slots in the inode. It is the maximum
+ * number of blocks a map (file/directory) can have.
+ */
+ size_t block_map_doubly_blocks;
+
+ /**
+ * Number of buffers held before releasing back to the cache.
+ */
+ uint32_t max_held_buffers;
+
+ /**
+ * List of buffers attached to buffer handles. Allows sharing.
+ */
+ rtems_chain_control buffers;
+
+ /**
+ * Number of buffers held on the buffers list.
+ */
+ uint32_t buffers_count;
+
+ /**
+ * List of buffers that need to be released when the processing of a file
+ * system request has completed.
+ */
+ rtems_chain_control release;
+
+ /**
+ * Number of buffers held on the release list.
+ */
+ uint32_t release_count;
+
+ /**
+ * List of buffers that need to be released modified when the processing of a
+ * file system request has completed.
+ */
+ rtems_chain_control release_modified;
+
+ /**
+ * Number of buffers held on the release modified list.
+ */
+ uint32_t release_modified_count;
+
+ /**
+ * List of open shared file node data. The shared node data such as the inode
+ * and block map allows a single file to be open more than once.
+ */
+ rtems_chain_control file_shares;
+
+ /**
+ * Pointer to user data supplied when opening.
+ */
+ void* user;
+};
+
+/**
+ * Return the flags.
+ *
+ * @param[in] _fs is a pointer to the file system.
+ */
+#define rtems_rfs_fs_flags(_f) ((_f)->flags)
+/**
+ * Should bitmap buffers be released when finished ?
+ *
+ * @param[in] _fs is a pointer to the file system.
+ */
+#define rtems_rfs_fs_release_bitmaps(_f) (!((_f)->flags & RTEMS_RFS_FS_BITMAPS_HOLD))
+
+/**
+ * Are the buffers locally cache or released back to the buffering layer ?
+ *
+ * @param[in] _fs is a pointer to the file system.
+ */
+#define rtems_rfs_fs_no_local_cache(_f) ((_f)->flags & RTEMS_RFS_FS_NO_LOCAL_CACHE)
+
+/**
+ * The disk device number.
+ *
+ * @param[in] _fs is a pointer to the file system.
+ */
+#if RTEMS_RFS_USE_LIBBLOCK
+#define rtems_rfs_fs_device(_fs) ((_fs)->disk)
+#else
+#define rtems_rfs_fs_device(_fs) ((_fs)->device)
+#endif
+
+/**
+ * The size of the disk in blocks.
+ *
+ * @param[in] _fs is a pointer to the file system.
+ */
+#define rtems_rfs_fs_blocks(_fs) ((_fs)->blocks)
+
+/**
+ * The block size.
+ *
+ * @param[in] _fs is a pointer to the file system.
+ */
+#define rtems_rfs_fs_block_size(_fs) ((_fs)->block_size)
+
+/**
+ * The number of inodes.
+ *
+ * @param[in] _fs is a pointer to the file system.
+ */
+#define rtems_rfs_fs_inodes(_fs) ((_fs)->inodes)
+
+/**
+ * Calculate a block in the file system given the group and the block within
+ * the group.
+ *
+ * @param[in] _fs is a pointer to the file system.
+ * @param[in] _grp is the group.
+ * @param[in] _blk is the block within the group.
+ * @return The absolute block number.
+ */
+#define rtems_rfs_fs_block(_fs, _grp, _blk) \
+ ((((_fs)->group_blocks) * (_grp)) + (_blk) + 1)
+
+/**
+ * The media size of the disk in media size blocks.
+ *
+ * @param[in] _fs is a pointer to the file system.
+ */
+#if RTEMS_RFS_USE_LIBBLOCK
+#define rtems_rfs_fs_media_blocks(_fs) ((_fs)->disk->size)
+#else
+#define rtems_rfs_fs_media_blocks(_fs) ((_fs)->media_size)
+#endif
+
+/**
+ * The media block size. This is the size of a block on disk. For a device I/O
+ * this value is 1.
+ *
+ * @param[in] _fs is a pointer to the file system.
+ */
+#if RTEMS_RFS_USE_LIBBLOCK
+#define rtems_rfs_fs_media_block_size(_fs) ((_fs)->disk->media_block_size)
+#else
+#define rtems_rfs_fs_media_block_size(_fs) (1)
+#endif
+
+/**
+ * The maximum length of a name supported by the file system.
+ */
+#define rtems_rfs_fs_max_name(_fs) ((_fs)->max_name_length)
+
+/**
+ * Return the maximum number of blocks in a block map.
+ *
+ * @return uint32_t The maximum number of blocks possible.
+ */
+#define rtems_rfs_fs_max_block_map_blocks(_fs) ((_fs)->block_map_doubly_blocks)
+
+/**
+ * Return the user pointer.
+ */
+#define rtems_rfs_fs_user(_fs) ((_fs)->user)
+
+/**
+ * Return the size of the disk in bytes.
+ *
+ * @param[in] fs is a pointer to the file system.
+ * @return uint64_t The size of the disk in bytes.
+ */
+uint64_t rtems_rfs_fs_size(rtems_rfs_file_system* fs);
+
+/**
+ * The size of the disk in bytes calculated from the media parameters..
+ *
+ * @param[in] fs is a pointer to the file system.
+ * @return uint64_t The size of the disk in bytes.
+ */
+uint64_t rtems_rfs_fs_media_size (rtems_rfs_file_system* fs);
+
+/**
+ * Open the file system given a file path.
+ *
+ * @param[in] name is a pointer to the device to open.
+ * @param[in] fs is the file system data filled in by this call.
+ * @param[in] user is a pointer to the user data.
+ * @param[in] flags is a initial set of user flags for the file system.
+ * @param[in] max_held_buffers is the maximum number of buffers the RFS holds.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 Error. See errno
+ */
+int rtems_rfs_fs_open (const char* name,
+ void* user,
+ uint32_t flags,
+ uint32_t max_held_buffers,
+ rtems_rfs_file_system** fs);
+
+/**
+ * Close the file system.
+ *
+ * @param[in] fs is the file system data.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 Error. See errno
+ */
+int rtems_rfs_fs_close (rtems_rfs_file_system* fs);
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-file.h b/cpukit/include/rtems/rfs/rtems-rfs-file.h
new file mode 100644
index 0000000000..772e846143
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-file.h
@@ -0,0 +1,416 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File System File Support
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File System File Support
+ *
+ * This file provides the support functions.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if !defined (_RTEMS_RFS_FILE_H_)
+#define _RTEMS_RFS_FILE_H_
+
+#include <rtems/libio_.h>
+
+#include <rtems/rfs/rtems-rfs-block.h>
+#include <rtems/rfs/rtems-rfs-data.h>
+#include <rtems/rfs/rtems-rfs-file-system.h>
+#include <rtems/rfs/rtems-rfs-inode.h>
+
+/**
+ * File data that is shared by various file handles accessing the same file. We
+ * hold various inode values common to the file that can change frequently so
+ * the inode is not thrashed yet we meet the requirements of the POSIX
+ * standard. The stat call needs to check the shared file data.
+ */
+typedef struct _rtems_rfs_file_shared
+{
+ /**
+ * The shared parts are maintained as a list.
+ */
+ rtems_chain_node link;
+
+ /**
+ * Reference count the users of this data.
+ */
+ int references;
+
+ /**
+ * The inode for the file.
+ */
+ rtems_rfs_inode_handle inode;
+
+ /**
+ * The block map for the file. The handle holds the file's position not the
+ * map.
+ */
+ rtems_rfs_block_map map;
+
+ /**
+ * The size of the file as taken from the inode. The map's size and
+ * this size should be the same.
+ */
+ rtems_rfs_block_size size;
+
+ /**
+ * The access time. The last time the file was read.
+ */
+ rtems_rfs_time atime;
+
+ /**
+ * The modified time. The last time the file was written too.
+ */
+ rtems_rfs_time mtime;
+
+ /**
+ * The change time. The last time the inode was written too.
+ */
+ rtems_rfs_time ctime;
+
+ /**
+ * Hold a pointer to the file system data so users can take the handle and
+ * use it without the needing to hold the file system data pointer.
+ */
+ rtems_rfs_file_system* fs;
+
+} rtems_rfs_file_shared;
+
+/**
+ * Get the atime.
+ *
+ * @param[in] shared is a pointer to the shared file data.
+ *
+ * @retval atime The atime.
+ */
+static inline rtems_rfs_time
+rtems_rfs_file_shared_get_atime (rtems_rfs_file_shared* shared)
+{
+ return shared->atime;
+}
+
+/**
+ * Get the mtime.
+ *
+ * @param[in] shared is a pointer to the shared file data.
+ *
+ * @retval mtime The mtime.
+ */
+static inline rtems_rfs_time
+rtems_rfs_file_shared_get_mtime (rtems_rfs_file_shared* shared)
+{
+ return shared->mtime;
+}
+
+/**
+ * Get the ctime.
+ *
+ * @param[in] shared is a pointer to the shared file data.
+ *
+ * @retval ctime The ctime.
+ */
+static inline rtems_rfs_time
+rtems_rfs_file_shared_get_ctime (rtems_rfs_file_shared* shared)
+{
+ return shared->ctime;
+}
+
+/**
+ * Get the block count.
+ *
+ * @param[in] shared is a pointer to the shared file data.
+ *
+ * @retval count The block count.
+ */
+static inline uint32_t
+rtems_rfs_file_shared_get_block_count (rtems_rfs_file_shared* shared)
+{
+ return shared->size.count;
+}
+
+/**
+ * Get the block offset.
+ *
+ * @param shared is a pointer to the shared file data.
+ *
+ * @retval offset The block offset.
+ */
+static inline uint16_t
+rtems_rfs_file_shared_get_block_offset (rtems_rfs_file_shared* shared)
+{
+ return shared->size.offset;
+}
+
+/**
+ * Calculate the size of data.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] shared is a pointer to the shared file data.
+ *
+ * @retval data The data size in bytes.
+ */
+static inline rtems_rfs_pos
+rtems_rfs_file_shared_get_size (rtems_rfs_file_system* fs,
+ rtems_rfs_file_shared* shared)
+{
+ return rtems_rfs_block_get_size (fs, &shared->size);
+}
+
+/**
+ * File flags.
+ */
+#define RTEMS_RFS_FILE_NO_ATIME_UPDATE (1 << 0) /**< Do not update the atime
+ * field in the inode if
+ * set. */
+#define RTEMS_RFS_FILE_NO_MTIME_UPDATE (1 << 1) /**< Do not update the mtime
+ * field in the inode if
+ * set. */
+#define RTEMS_RFS_FILE_NO_LENGTH_UPDATE (1 << 2) /**< Do not update the position
+ * field in the inode if
+ * set. */
+
+/**
+ * File data used to managed an open file.
+ */
+typedef struct _rtems_rfs_file_handle
+{
+ /**
+ * Special flags that can be controlled by the fctrl call.
+ */
+ int flags;
+
+ /**
+ * The buffer of data at the file's position.
+ */
+ rtems_rfs_buffer_handle buffer;
+
+ /**
+ * The block position of this file handle.
+ */
+ rtems_rfs_block_pos bpos;
+
+ /**
+ * Pointer to the shared file data.
+ */
+ rtems_rfs_file_shared* shared;
+
+} rtems_rfs_file_handle;
+
+/**
+ * Access the data in the buffer.
+ */
+#define rtems_rfs_file_data(_f) \
+ (rtems_rfs_buffer_data (&(_f)->buffer) + (_f)->bpos.boff)
+
+/**
+ * Return the file system data pointer given a file handle.
+ */
+#define rtems_rfs_file_fs(_f) ((_f)->shared->fs)
+
+/**
+ * Return the file's inode handle pointer given a file handle.
+ */
+#define rtems_rfs_file_inode(_f) (&(_f)->shared->inode)
+
+/**
+ * Return the file's block map pointer given a file handle.
+ */
+#define rtems_rfs_file_map(_f) (&(_f)->shared->map)
+
+/**
+ * Return the file's block position pointer given a file handle.
+ */
+#define rtems_rfs_file_bpos(_f) (&(_f)->bpos)
+
+/**
+ * Return the file's block number given a file handle.
+ */
+#define rtems_rfs_file_block(_f) ((_f)->bpos.bno)
+
+/**
+ * Return the file's block offset given a file handle.
+ */
+#define rtems_rfs_file_block_offset(_f) ((_f)->bpos.boff)
+
+/**
+ * Set the file's block position given a file position (absolute).
+ */
+#define rtems_rfs_file_set_bpos(_f, _p) \
+ rtems_rfs_block_get_bpos (rtems_rfs_file_fs (_f), _p, (&(_f)->bpos))
+
+/**
+ * Return the file's buffer handle pointer given a file handle.
+ */
+#define rtems_rfs_file_buffer(_f) (&(_f)->buffer)
+
+/**
+ * Update the access time field of the inode when reading if flagged to do so.
+ */
+#define rtems_rfs_file_update_atime(_f) \
+ (((_f)->flags & RTEMS_RFS_FILE_NO_ATIME_UPDATE) == 0)
+
+/**
+ * Update the modified time field of the inode when writing if flagged to do so.
+ */
+#define rtems_rfs_file_update_mtime(_f) \
+ (((_f)->flags & RTEMS_RFS_FILE_NO_MTIME_UPDATE) == 0)
+
+/**
+ * Update the length field of the inode.
+ */
+#define rtems_rfs_file_update_length(_f) \
+ (((_f)->flags & RTEMS_RFS_FILE_NO_LENGTH_UPDATE) == 0)
+
+/**
+ * Return the shared size varable.
+ */
+#define rtems_rfs_file_get_size(_f) \
+ (&(_f)->shared->size)
+
+/**
+ * Return the size of file.
+ */
+#define rtems_rfs_file_size(_f) \
+ rtems_rfs_file_shared_get_size (rtems_rfs_file_fs (_f), (_f)->shared)
+
+/**
+ * Return the file block count.
+ */
+#define rtems_rfs_file_size_count(_f) \
+ rtems_rfs_file_shared_get_block_count ((_f)->shared)
+
+/**
+ * Return the file block offset.
+ */
+#define rtems_rfs_file_size_offset(_f) \
+ rtems_rfs_file_shared_get_block_offset ((_f)->shared)
+
+/**
+ * Open a file handle.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] ino is the inode number of the file to be opened.
+ * @param[out] handle will be filled in with the handle pointer.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_file_open (rtems_rfs_file_system* fs,
+ rtems_rfs_ino ino,
+ int oflag,
+ rtems_rfs_file_handle** handle);
+
+/**
+ * Close an open file handle.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] handle is the open file handle.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_file_close (rtems_rfs_file_system* fs,
+ rtems_rfs_file_handle* handle);
+
+/**
+ * Start I/O on a block of a file. This call only requests the block from the
+ * media if reading and makes the buffer available to you the via the
+ * rtems_rfs_file_data interface after the call. The available amount data is
+ * taken from the current file position until the end of the block. The file
+ * position is not adujsted until the I/O ends. An I/O request cannot perform
+ * I/O past the end of a block so the call returns the amount of data
+ * available.
+ *
+ * @param[in] handle is the file handle.
+ * @param[in] available is the amount of data available for I/O.
+ * @param[in] read is the I/O operation is a read so the block is read from the media.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_file_io_start (rtems_rfs_file_handle* handle,
+ size_t* available,
+ bool read);
+
+/**
+ * End the I/O. Any buffers held in the file handle and returned to the
+ * cache. If inode updating is not disable and the I/O is a read the atime
+ * field is updated and if a write I/O the mtime is updated.
+ *
+ * If the file's position is updated by the size amount.
+ *
+ * @param[in] handle is the file handle.
+ * @param[in] size is the amount of data read or written.
+ * @param[in] read is the I/O was a read if true else it was a write.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_file_io_end (rtems_rfs_file_handle* handle,
+ size_t size,
+ bool read);
+
+/**
+ * Release the I/O resources without any changes. If data has changed in the
+ * buffer and the buffer was not already released as modified the data will be
+ * lost.
+ *
+ * @param[in] handle is the file handle.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_file_io_release (rtems_rfs_file_handle* handle);
+
+/**
+ * The file to the position returning the old position. The position is
+ * abolute.
+ *
+ * @param[in] handle The file handle.
+ * @param[in] pos is the position to seek to.
+ * @param[out] new_pos will contain the actual position.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_file_seek (rtems_rfs_file_handle* handle,
+ rtems_rfs_pos pos,
+ rtems_rfs_pos* new_pos);
+
+/**
+ * Set the size of the file to the new size. This can extend the file to a new
+ * size.
+ *
+ * @param[in] handle is the file handle.
+ * @param[in] size is the new size of the file.
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_file_set_size (rtems_rfs_file_handle* handle,
+ rtems_rfs_pos size);
+
+/**
+ * Return the shared file data for an ino.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] ino is the inode number to locate the data for.
+ * @return rtems_rfs_file_shared* The shared data or NULL is not located.
+ *
+ * @retval shared The shared data.
+ * @retval NULL No shared file data is located.
+ */
+rtems_rfs_file_shared* rtems_rfs_file_get_shared (rtems_rfs_file_system* fs,
+ rtems_rfs_ino ino);
+
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-group.h b/cpukit/include/rtems/rfs/rtems-rfs-group.h
new file mode 100644
index 0000000000..23e6434b2c
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-group.h
@@ -0,0 +1,181 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File Systems Group Management
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File Systems Group Management.
+ *
+ * These functions manage the groups used in the file system.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+
+#if !defined (_RTEMS_RFS_GROUP_H_)
+#define _RTEMS_RFS_GROUP_H_
+
+/**
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File System Group Management
+ */
+/**@{*/
+
+#include <rtems/rfs/rtems-rfs-trace.h>
+#include <rtems/rfs/rtems-rfs-bitmaps.h>
+#include <rtems/rfs/rtems-rfs-buffer.h>
+
+/**
+ * Block allocations for a group on disk.
+ */
+#define RTEMS_RFS_GROUP_BLOCK_BITMAP_BLOCK (0)
+#define RTEMS_RFS_GROUP_INODE_BITMAP_BLOCK (1)
+#define RTEMS_RFS_GROUP_INODE_BLOCK (2)
+
+/**
+ * @brief Creates bit allocator for blocks in the group simpler.
+ *
+ * A group is a selection of blocks on the disk. Typically the number of blocks
+ * in a group is determined by the number of bits a block holds. This makes the
+ * bit allocator for blocks in the group simpler plus is allows a simple way to
+ * localise access to files and directories.
+ */
+typedef struct _rtems_rfs_group
+{
+ /**
+ * Base block number.
+ */
+ rtems_rfs_buffer_block base;
+
+ /**
+ * The number of blocks in the group. Groups may be different sizes.
+ */
+ size_t size;
+
+ /**
+ * The block bitmap control.
+ */
+ rtems_rfs_bitmap_control block_bitmap;
+
+ /**
+ * The handle to the block bitmap buffer.
+ */
+ rtems_rfs_buffer_handle block_bitmap_buffer;
+
+ /**
+ * The inode bitmap control.
+ */
+ rtems_rfs_bitmap_control inode_bitmap;
+
+ /**
+ * The handle to the inode bitmap buffer.
+ */
+ rtems_rfs_buffer_handle inode_bitmap_buffer;
+
+} rtems_rfs_group;
+
+/**
+ * Return the disk's block for a block in a group.
+ */
+#define rtems_rfs_group_block(_g, _b) (((_g)->base) + (_b))
+
+/**
+ * Return the file system inode for a inode in a group.
+ */
+#define rtems_rfs_group_inode(_f, _g, _i) \
+ (((_f)->group_inodes * (_g)) + (_i) + RTEMS_RFS_ROOT_INO)
+
+/**
+ * @brief Open a group.
+ *
+ * Allocate all the resources including the bitmaps.
+ *
+ * @param fs The file system.
+ * @param base The base block number.
+ * @param size The number of blocks in the group.
+ * @param group Reference to the group to open.
+ * @retval int The error number (errno). No error if 0.
+ */
+int rtems_rfs_group_open (rtems_rfs_file_system* fs,
+ rtems_rfs_buffer_block base,
+ size_t size,
+ size_t inodes,
+ rtems_rfs_group* group);
+
+/**
+ * @brief Close a group.
+ *
+ * Release all resources the group holds.
+ *
+ * @param fs The file system.
+ * @param group The group to close.
+ * @retval int The error number (errno). No error if 0.
+ */
+int rtems_rfs_group_close (rtems_rfs_file_system* fs,
+ rtems_rfs_group* group);
+
+/**
+ * @brief Allocate an inode or block.
+ *
+ * The groups are searched to find the next
+ * available inode or block.
+ *
+ * @param fs The file system data.
+ * @param goal The goal to seed the bitmap search.
+ * @param inode If true allocate an inode else allocate a block.
+ * @param result The allocated bit in the bitmap.
+ * @retval int The error number (errno). No error if 0.
+ */
+int rtems_rfs_group_bitmap_alloc (rtems_rfs_file_system* fs,
+ rtems_rfs_bitmap_bit goal,
+ bool inode,
+ rtems_rfs_bitmap_bit* result);
+
+/**
+ * @brief Free the group allocated bit.
+ *
+ * @param fs The file system data.
+ * @param inode If true the number to free is an inode else it is a block.
+ * @param block The inode or block number to free.
+ * @retval int The error number (errno). No error if 0.
+ */
+int rtems_rfs_group_bitmap_free (rtems_rfs_file_system* fs,
+ bool inode,
+ rtems_rfs_bitmap_bit no);
+
+/**
+ * @brief Test the group allocated bit.
+ *
+ * @param fs The file system data.
+ * @param inode If true the number to free is an inode else it is a block.
+ * @param block The inode or block number to free.
+ * @param state Return the state of the bit.
+ * @retval int The error number (errno). No error if 0.
+ */
+int rtems_rfs_group_bitmap_test (rtems_rfs_file_system* fs,
+ bool inode,
+ rtems_rfs_bitmap_bit no,
+ bool* state);
+
+/**
+ * @brief Determine the number of blocks and inodes used.
+ *
+ * @param fs The file system data.
+ * @param blocks The number of blocks used.
+ * @param inodes The number of inodes used.
+ * @retval int The error number (errno). No error if 0.
+ */
+int rtems_rfs_group_usage (rtems_rfs_file_system* fs,
+ size_t* blocks,
+ size_t* inodes);
+
+/** @} */
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-inode.h b/cpukit/include/rtems/rfs/rtems-rfs-inode.h
new file mode 100644
index 0000000000..95861ea8a7
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-inode.h
@@ -0,0 +1,728 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File System Information Node
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File System Information Node.
+ *
+ * The information nodes hold the data about all nodes in the file system.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+
+#if !defined (_RTEMS_RFS_INODE_H_)
+#define _RTEMS_RFS_INODE_H_
+
+#include <sys/stat.h>
+
+#include <rtems/rfs/rtems-rfs-data.h>
+#include <rtems/rfs/rtems-rfs-file-system.h>
+
+/**
+ * The RFS mode definitions. Currently map to the C library ones.
+ */
+#define RTEMS_RFS_S_ISUID S_ISUID /**< Set user id on execution */
+#define RTEMS_RFS_S_ISGID S_ISGID /**< Set group id on execution */
+#define RTEMS_RFS_S_ISVTX S_ISVTX /**< Save swapped text even after use */
+#define RTEMS_RFS_S_IREAD S_IREAD /**< Read permission, owner */
+#define RTEMS_RFS_S_IWRITE S_IWRITE /**< Write permission, owner */
+#define RTEMS_RFS_S_IEXEC S_IEXEC /**< Execute/search permission, owner */
+#define RTEMS_RFS_S_ENFMT S_ENFMT /**< Enforcement-mode locking */
+#define RTEMS_RFS_S_IFMT S_IFMT /**< Type of file */
+#define RTEMS_RFS_S_IFDIR S_IFDIR /**< Directory */
+#define RTEMS_RFS_S_IFCHR S_IFCHR /**< Character special */
+#define RTEMS_RFS_S_IFBLK S_IFBLK /**< Block special */
+#define RTEMS_RFS_S_IFREG S_IFREG /**< Regular */
+#define RTEMS_RFS_S_IFLNK S_IFLNK /**< Symbolic link */
+#define RTEMS_RFS_S_IFSOCK S_IFSOCK /**< Socket */
+#define RTEMS_RFS_S_IFIFO S_IFIFO /**< Fifo */
+#define RTEMS_RFS_S_IRWXU S_IRWXU
+#define RTEMS_RFS_S_IRUSR S_IRUSR /**< Read permission, owner */
+#define RTEMS_RFS_S_IWUSR S_IWUSR /**< Write permission, owner */
+#define RTEMS_RFS_S_IXUSR S_IXUSR /**< Execute/search permission, owner */
+#define RTEMS_RFS_S_IRWXG S_IRWXG
+#define RTEMS_RFS_S_IRGRP S_IRGRP /**< Read permission, group */
+#define RTEMS_RFS_S_IWGRP S_IWGRP /**< Write permission, grougroup */
+#define RTEMS_RFS_S_IXGRP S_IXGRP /**< Execute/search permission, group */
+#define RTEMS_RFS_S_IRWXO S_IRWXO
+#define RTEMS_RFS_S_IROTH S_IROTH /**< Read permission, other */
+#define RTEMS_RFS_S_IWOTH S_IWOTH /**< Write permission, other */
+#define RTEMS_RFS_S_IXOTH S_IXOTH /**< Execute/search permission, other */
+
+#define RTEMS_RFS_S_ISBLK(m) S_ISBLK(m)
+#define RTEMS_RFS_S_ISCHR(m) S_ISCHR(m)
+#define RTEMS_RFS_S_ISDIR(m) S_ISDIR(m)
+#define RTEMS_RFS_S_ISFIFO(m) S_ISFIFO(m)
+#define RTEMS_RFS_S_ISREG(m) S_ISREG(m)
+#define RTEMS_RFS_S_ISLNK(m) S_ISLNK(m)
+#define RTEMS_RFS_S_ISSOCK(m) S_ISSOCK(m)
+
+/**
+ * Permissions of a symlink.
+ */
+#define RTEMS_RFS_S_SYMLINK \
+ RTEMS_RFS_S_IFLNK | RTEMS_RFS_S_IRWXU | RTEMS_RFS_S_IRWXG | RTEMS_RFS_S_IRWXO
+
+/**
+ * The inode number or ino.
+ */
+typedef uint32_t rtems_rfs_ino;
+
+/**
+ * The time in the file system.
+ */
+typedef uint32_t rtems_rfs_time;
+
+/**
+ * The size of a block value on disk. This include the inodes and indirect
+ * tables.
+ */
+typedef uint32_t rtems_rfs_inode_block;
+
+/**
+ * The size of the data name field in the inode.
+ */
+#define RTEMS_RFS_INODE_DATA_NAME_SIZE \
+ (RTEMS_RFS_INODE_BLOCKS * sizeof (rtems_rfs_inode_block))
+
+/**
+ * The inode.
+ */
+typedef struct _rtems_rfs_inode
+{
+ /**
+ * The number of links to the inode.
+ */
+ uint16_t links;
+
+ /**
+ * The mode of the node.
+ */
+ uint16_t mode;
+
+ /**
+ * The owner of the node.
+ */
+ uint32_t owner;
+
+ /**
+ * Reserved.
+ */
+ uint16_t flags;
+
+ /**
+ * Amount of data held in the last block data.
+ */
+ uint16_t block_offset;
+
+ /**
+ * Number of blocks held by this file.
+ */
+ uint32_t block_count;
+
+ /**
+ * The access time. The last time the file was read.
+ */
+ rtems_rfs_time atime;
+
+ /**
+ * The modified time. The last time the file was written too.
+ */
+ rtems_rfs_time mtime;
+
+ /**
+ * The change time. The last time the inode was written too.
+ */
+ rtems_rfs_time ctime;
+
+ /**
+ * Blocks. These are the block numbers used by the node or table of
+ * nodes. The flags indicate the mode the blocks are being held in. In the
+ * direct table mode the blocks are entries in this table. In the indirect
+ * mode the blocks point to blocks that hold the block numbers. The data can
+ * also be a name if it fits. For example a symbolic link.
+ */
+ union
+ {
+ rtems_rfs_inode_block blocks[RTEMS_RFS_INODE_BLOCKS];
+ uint8_t name[RTEMS_RFS_INODE_DATA_NAME_SIZE];
+ } data;
+
+ /**
+ * The last block map block. Used as the goal when allocating a new block for
+ * use in the map.
+ */
+ rtems_rfs_inode_block last_map_block;
+
+ /**
+ * The last data block. Used as the goal when allocating a new block.
+ */
+ rtems_rfs_inode_block last_data_block;
+
+} rtems_rfs_inode;
+
+/**
+ * The size of an inode.
+ */
+#define RTEMS_RFS_INODE_SIZE (sizeof (rtems_rfs_inode))
+
+/**
+ * RFS Inode Handle.
+ */
+typedef struct _rtems_rfs_inode_handle
+{
+ /**
+ * Handles can be linked as a list for easy processing.
+ */
+ rtems_chain_node link;
+
+ /**
+ * The ino for this handle.
+ */
+ rtems_rfs_ino ino;
+
+ /**
+ * The pointer to the inode.
+ */
+ rtems_rfs_inode* node;
+
+ /**
+ * The buffer that contains this inode.
+ */
+ rtems_rfs_buffer_handle buffer;
+
+ /**
+ * The block number that holds the inode.
+ */
+ rtems_rfs_buffer_block block;
+
+ /**
+ * The offset into the block for the inode.
+ */
+ int offset;
+
+ /**
+ * Number of load requests.
+ */
+ int loads;
+
+} rtems_rfs_inode_handle;
+
+/**
+ * Is the inode loaded ?
+ */
+#define rtems_rfs_inode_is_loaded(_h) ((_h)->node)
+
+/**
+ * Get the inode ino for a handle.
+ */
+#define rtems_rfs_inode_ino(_h) ((_h)->ino)
+
+/**
+ * Get the link count.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval links The link count.
+ */
+static inline uint16_t
+rtems_rfs_inode_get_links (rtems_rfs_inode_handle* handle)
+{
+ uint16_t links;
+ links = rtems_rfs_read_u16 (&handle->node->links);
+ if (links == 0xffff)
+ links = 0;
+ return links;
+}
+
+/**
+ * Set the link count.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] links are the links.
+ */
+static inline void
+rtems_rfs_inode_set_links (rtems_rfs_inode_handle* handle, uint16_t links)
+{
+ rtems_rfs_write_u16 (&handle->node->links, links);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the flags.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval flags The flags.
+ */
+static inline uint16_t
+rtems_rfs_inode_get_flags (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u16 (&handle->node->flags);
+}
+
+/**
+ * Set the flags.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] flags are the flags.
+ */
+static inline void
+rtems_rfs_inode_set_flags (rtems_rfs_inode_handle* handle, uint16_t flags)
+{
+ rtems_rfs_write_u16 (&handle->node->flags, flags);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the mode.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval mode The mode.
+ */
+static inline uint16_t
+rtems_rfs_inode_get_mode (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u16 (&handle->node->mode);
+}
+
+/**
+ * Set the mode.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] mode is the mode.
+ */
+static inline void
+rtems_rfs_inode_set_mode (rtems_rfs_inode_handle* handle, uint16_t mode)
+{
+ rtems_rfs_write_u16 (&handle->node->mode, mode);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the user id.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval uid The used id.
+ */
+static inline uint16_t
+rtems_rfs_inode_get_uid (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u32 (&handle->node->owner) & 0xffff;
+}
+
+/**
+ * Get the group id.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval gid The grpup id.
+ */
+static inline uint16_t
+rtems_rfs_inode_get_gid (rtems_rfs_inode_handle* handle)
+{
+ return (rtems_rfs_read_u32 (&handle->node->owner) >> 16) & 0xffff;
+}
+
+/**
+ * Set the user id and group id.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] uid is the user id (uid).
+ * @param[in] gid is the group id (gid).
+ */
+static inline void
+rtems_rfs_inode_set_uid_gid (rtems_rfs_inode_handle* handle,
+ uint16_t uid, uint16_t gid)
+{
+ rtems_rfs_write_u32 (&handle->node->owner, (((uint32_t) gid) << 16) | uid);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the block offset.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval offset The block offset.
+ */
+static inline uint16_t
+rtems_rfs_inode_get_block_offset (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u16 (&handle->node->block_offset);
+}
+
+/**
+ * Set the block offset.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] block_count is the block offset.
+ */
+static inline void
+rtems_rfs_inode_set_block_offset (rtems_rfs_inode_handle* handle,
+ uint16_t block_offset)
+{
+ rtems_rfs_write_u16 (&handle->node->block_offset, block_offset);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the block count.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval count The block count.
+ */
+static inline uint32_t
+rtems_rfs_inode_get_block_count (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u32 (&handle->node->block_count);
+}
+
+/**
+ * Set the block count.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] block_count is the block count.
+ */
+static inline void
+rtems_rfs_inode_set_block_count (rtems_rfs_inode_handle* handle, uint32_t block_count)
+{
+ rtems_rfs_write_u32 (&handle->node->block_count, block_count);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the atime.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval atime The atime.
+ */
+static inline rtems_rfs_time
+rtems_rfs_inode_get_atime (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u32 (&handle->node->atime);
+}
+
+/**
+ * Set the atime.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] atime The atime.
+ */
+static inline void
+rtems_rfs_inode_set_atime (rtems_rfs_inode_handle* handle,
+ rtems_rfs_time atime)
+{
+ rtems_rfs_write_u32 (&handle->node->atime, atime);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the mtime.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval mtime The mtime.
+ */
+static inline rtems_rfs_time
+rtems_rfs_inode_get_mtime (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u32 (&handle->node->mtime);
+}
+
+/**
+ * Set the mtime.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] mtime The mtime.
+ */
+static inline void
+rtems_rfs_inode_set_mtime (rtems_rfs_inode_handle* handle,
+ rtems_rfs_time mtime)
+{
+ rtems_rfs_write_u32 (&handle->node->mtime, mtime);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the ctime.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval ctime The ctime.
+ */
+static inline rtems_rfs_time
+rtems_rfs_inode_get_ctime (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u32 (&handle->node->ctime);
+}
+
+/**
+ * Set the ctime.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] ctime The ctime.
+ */
+static inline void
+rtems_rfs_inode_set_ctime (rtems_rfs_inode_handle* handle,
+ rtems_rfs_time ctime)
+{
+ rtems_rfs_write_u32 (&handle->node->ctime, ctime);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the block number.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] block is the block number to return.
+ *
+ * @retval block The block number.
+ */
+static inline uint32_t
+rtems_rfs_inode_get_block (rtems_rfs_inode_handle* handle, int block)
+{
+ return rtems_rfs_read_u32 (&handle->node->data.blocks[block]);
+}
+
+/**
+ * Set the block number for a given block index.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] block is the block index.
+ * @param[in] bno is the block number.
+ */
+static inline void
+rtems_rfs_inode_set_block (rtems_rfs_inode_handle* handle, int block, uint32_t bno)
+{
+ rtems_rfs_write_u32 (&handle->node->data.blocks[block], bno);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the last map block from the inode.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval block The last map block number.
+ */
+static inline uint32_t
+rtems_rfs_inode_get_last_map_block (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u32 (&handle->node->last_map_block);
+}
+
+/**
+ * Set the last map block.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] block_count is last map block number.
+ */
+static inline void
+rtems_rfs_inode_set_last_map_block (rtems_rfs_inode_handle* handle, uint32_t last_map_block)
+{
+ rtems_rfs_write_u32 (&handle->node->last_map_block, last_map_block);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the last data block from the inode.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval block The last data block number.
+ *
+ */
+static inline uint32_t
+rtems_rfs_inode_get_last_data_block (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u32 (&handle->node->last_data_block);
+}
+
+/**
+ * Set the last data block.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] block_count is the last data block number.
+ */
+static inline void
+rtems_rfs_inode_set_last_data_block (rtems_rfs_inode_handle* handle, uint32_t last_data_block)
+{
+ rtems_rfs_write_u32 (&handle->node->last_data_block, last_data_block);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Allocate an inode number and return it.
+ *
+ * @param[in] fs is the file system data.
+ * @param[out] ino will contain the ino.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_inode_alloc (rtems_rfs_file_system* fs,
+ rtems_rfs_bitmap_bit goal,
+ rtems_rfs_ino* ino);
+
+/**
+ * Free an inode.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] ino is the ino too free.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_inode_free (rtems_rfs_file_system* fs,
+ rtems_rfs_ino ino);
+
+/**
+ * Open the inode handle. This reads the inode into the buffer and sets the
+ * data pointer. All data is in media byte order and needs to be accessed via
+ * the supporting calls.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] ino is the inode number.
+ * @param[in] handle is the handle to the inode we are opening.
+ * @param[in] load If true load the inode into memory from the media.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_inode_open (rtems_rfs_file_system* fs,
+ rtems_rfs_ino ino,
+ rtems_rfs_inode_handle* handle,
+ bool load);
+
+/**
+ * The close inode handle. All opened inodes need to be closed.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] handle is the handle to close.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_inode_close (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* handle);
+
+/**
+ * Load the inode into memory.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] handle is the inode handle to load.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_inode_load (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* handle);
+
+/**
+ * Unload the inode from memory.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] handle is the inode handle to unload.
+ * @param[in] update_ctime Update the ctime field of the inode.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_inode_unload (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* handle,
+ bool update_ctime);
+
+/**
+ * Create an inode allocating, initialising and adding an entry to the parent
+ * directory.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] parent is the parent inode number to add the directory entry to.
+ * @param[in] name is a pointer to the name of the directory entryinode
+ * to create.
+ *
+ */
+int rtems_rfs_inode_create (rtems_rfs_file_system* fs,
+ rtems_rfs_ino parent,
+ const char* name,
+ size_t length,
+ uint16_t mode,
+ uint16_t links,
+ uid_t uid,
+ gid_t gid,
+ rtems_rfs_ino* ino);
+
+/**
+ * Delete the inode eraseing it and release the buffer to commit the write. You
+ * need to load the inode again if you wish to use it again.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] handle is the inode handle to erase.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_inode_delete (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* handle);
+
+/**
+ * Initialise a new inode.
+ *
+ * @param[in] handle is the inode handle to initialise.
+ * @param[in] links are the number of links to the inode.
+ * @param[in] mode is the inode mode.
+ * @param[in] uid is the user id.
+ * @param[in] gid is the group id.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_inode_initialise (rtems_rfs_inode_handle* handle,
+ uint16_t links,
+ uint16_t mode,
+ uid_t uid,
+ gid_t gid);
+
+/**
+ * Time stamp the inode with the current time. The ctime field is hanlded
+ * automatically.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] atime Update the atime field.
+ * @param[in] mtime UPdate the mtime field.
+ *
+ * @retval 0 Successful operation.
+ * @retval ENXIO No inode is loaded.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_inode_time_stamp_now (rtems_rfs_inode_handle* handle,
+ bool atime,
+ bool mtime);
+
+/**
+ * Calculate the size of data attached to the inode.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] handle is the inode handle.
+ *
+ * @retval size The data size in bytes in the block map attched to the inode.
+ */
+rtems_rfs_pos rtems_rfs_inode_get_size (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* handle);
+
+#endif
+
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-link.h b/cpukit/include/rtems/rfs/rtems-rfs-link.h
new file mode 100644
index 0000000000..d30814aaff
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-link.h
@@ -0,0 +1,124 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File System Link Support
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File System Link Support
+ *
+ * This file provides the link support functions.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+
+#if !defined (_RTEMS_RFS_LINK_H_)
+#define _RTEMS_RFS_LINK_H_
+
+#include <dirent.h>
+
+#include <rtems/rfs/rtems-rfs-file-system.h>
+#include <rtems/rfs/rtems-rfs-inode.h>
+
+/**
+ * Directory unlink modes.
+ */
+typedef enum rtems_rfs_unlink_dir_e
+{
+ rtems_rfs_unlink_dir_denied, /**< Not allowed to unlink a directory. */
+ rtems_rfs_unlink_dir_if_empty, /**< Unlink if the directory is empty. */
+ rtems_rfs_unlink_dir_allowed /**< Unlinking of directories is allowed. */
+} rtems_rfs_unlink_dir;
+
+/**
+ * Create a link. Do not link directories unless renaming or you will create
+ * loops in the file system.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] name is a pointer to the name of the link.
+ * @param[in] length is the length of the name.
+ * @param[in] parent is the inode number of the parent directory.
+ * @param[in] target is the inode of the target.
+ * @param[in] link_dir If true directories can be linked. Useful when
+ * renaming.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_link (rtems_rfs_file_system* fs,
+ const char* name,
+ int length,
+ rtems_rfs_ino parent,
+ rtems_rfs_ino target,
+ bool link_dir);
+
+/**
+ * Unlink the node from the parent directory. A directory offset for the
+ * target entry is required because links cause a number of inode numbers to
+ * appear in a single directory so scanning does not work.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] parent is the inode number of the parent directory.
+ * @param[in] target is the inode of the target.
+ * @param[in] doff is the parent directory entry offset for the target entry.
+ * @param[in] dir_mode is the directory unlink mode.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_unlink (rtems_rfs_file_system* fs,
+ rtems_rfs_ino parent,
+ rtems_rfs_ino target,
+ uint32_t doff,
+ rtems_rfs_unlink_dir dir_mode);
+
+/**
+ * Symbolic link is an inode that has a path attached.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] name is a pointer to the name of the node.
+ * @param[in] length is the length of the name of the node.
+ * @param[in] link is a pointer to the link path attached to the
+ * symlink inode.
+ * @param[in] link_length is the length of the link path.
+ * @param[in] parent is the parent inode number.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_symlink (rtems_rfs_file_system* fs,
+ const char* name,
+ int length,
+ const char* link,
+ int link_length,
+ uid_t uid,
+ gid_t gid,
+ rtems_rfs_ino parent);
+
+/**
+ * Read a symbolic link into the provided buffer returning the link of link
+ * name.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] link is the link inode number to read.
+ * @param[in] path is a pointer to the buffer to write the link path into.
+ * @param[in] size is the size of the buffer.
+ * @param[out] length will contain the length of the link path.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_symlink_read (rtems_rfs_file_system* fs,
+ rtems_rfs_ino link,
+ char* path,
+ size_t size,
+ size_t* length);
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-mutex.h b/cpukit/include/rtems/rfs/rtems-rfs-mutex.h
new file mode 100644
index 0000000000..606fd53233
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-mutex.h
@@ -0,0 +1,116 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File System Mutex
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File System Mutex.
+ *
+ * It may be suprising we abstract this for the RTEMS file system but this code
+ * is designed to be run on host operating systems.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if !defined (_RTEMS_RFS_MUTEX_H_)
+#define _RTEMS_RFS_MUTEX_H_
+
+#include <errno.h>
+
+#include <rtems/rfs/rtems-rfs-trace.h>
+
+#if __rtems__
+#include <rtems.h>
+#include <rtems/error.h>
+#endif
+
+/**
+ * RFS Mutex type.
+ */
+#if __rtems__
+typedef rtems_id rtems_rfs_mutex;
+#else
+typedef uint32_t rtems_rfs_mutex; /* place holder */
+#endif
+
+/**
+ * @brief Create the mutex.
+ *
+ * @param [in] mutex is pointer to the mutex handle returned to the caller.
+ *
+ * @retval 0 Successful operation.
+ * @retval EIO An error occurred.
+ *
+ */
+int rtems_rfs_mutex_create (rtems_rfs_mutex* mutex);
+
+/**
+ * @brief Destroy the mutex.
+ *
+ * @param[in] mutex Reference to the mutex handle returned to the caller.
+ *
+ * @retval 0 Successful operation.
+ * @retval EIO An error occurred.
+ */
+int rtems_rfs_mutex_destroy (rtems_rfs_mutex* mutex);
+
+/**
+ * @brief Lock the mutex.
+ *
+ * @param[in] mutex is a pointer to the mutex to lock.
+ *
+ * @retval 0 Successful operation.
+ * @retval EIO An error occurred.
+ */
+static inline int
+rtems_rfs_mutex_lock (rtems_rfs_mutex* mutex)
+{
+#if __rtems__
+ rtems_status_code sc = rtems_semaphore_obtain (*mutex, RTEMS_WAIT, 0);
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+#if RTEMS_RFS_TRACE
+ if (rtems_rfs_trace (RTEMS_RFS_TRACE_MUTEX))
+ printf ("rtems-rfs: mutex: obtain failed: %s\n",
+ rtems_status_text (sc));
+#endif
+ return EIO;
+ }
+#endif
+ return 0;
+}
+
+/**
+ * @brief Unlock the mutex.
+ *
+ * @param[in] mutex is a pointer to the mutex to unlock.
+ *
+ * @retval 0 Successful operation.
+ * @retval EIO An error occurred.
+ */
+static inline int
+rtems_rfs_mutex_unlock (rtems_rfs_mutex* mutex)
+{
+#if __rtems__
+ rtems_status_code sc = rtems_semaphore_release (*mutex);
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+#if RTEMS_RFS_TRACE
+ if (rtems_rfs_trace (RTEMS_RFS_TRACE_MUTEX))
+ printf ("rtems-rfs: mutex: release failed: %s\n",
+ rtems_status_text (sc));
+#endif
+ return EIO;
+ }
+#endif
+ return 0;
+}
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-trace.h b/cpukit/include/rtems/rfs/rtems-rfs-trace.h
new file mode 100644
index 0000000000..4d6d0c9ddb
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-trace.h
@@ -0,0 +1,135 @@
+/**
+ * @file
+ *
+ * @brief Manages the Trace and Debugging Features of the
+ * RTEMS RFS File System
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File Systems Trace manages the trace and debugging features of the
+ * RTEMS RFS file system. The design allows all tracing code and strings to be
+ * removed from the target code for small footprint systems.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+
+#if !defined (_RTEMS_RFS_TRACE_H_)
+#define _RTEMS_RFS_TRACE_H_
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+
+/**
+ * Is tracing enabled ?
+ */
+#if !defined (RTEMS_RFS_TRACE)
+#define RTEMS_RFS_TRACE 1
+#endif
+
+/**
+ * The type of the mask.
+ */
+typedef uint64_t rtems_rfs_trace_mask;
+
+/**
+ * List of tracing bits for the various parts of the file system.
+ */
+#define RTEMS_RFS_TRACE_ALL (0xffffffffffffffffULL)
+#define RTEMS_RFS_TRACE_OPEN (1ULL << 0)
+#define RTEMS_RFS_TRACE_CLOSE (1ULL << 1)
+#define RTEMS_RFS_TRACE_MUTEX (1ULL << 2)
+#define RTEMS_RFS_TRACE_BUFFER_OPEN (1ULL << 3)
+#define RTEMS_RFS_TRACE_BUFFER_CLOSE (1ULL << 4)
+#define RTEMS_RFS_TRACE_BUFFER_SYNC (1ULL << 5)
+#define RTEMS_RFS_TRACE_BUFFER_RELEASE (1ULL << 6)
+#define RTEMS_RFS_TRACE_BUFFER_CHAINS (1ULL << 7)
+#define RTEMS_RFS_TRACE_BUFFER_HANDLE_REQUEST (1ULL << 8)
+#define RTEMS_RFS_TRACE_BUFFER_HANDLE_RELEASE (1ULL << 9)
+#define RTEMS_RFS_TRACE_BUFFER_SETBLKSIZE (1ULL << 10)
+#define RTEMS_RFS_TRACE_BUFFERS_RELEASE (1ULL << 11)
+#define RTEMS_RFS_TRACE_BLOCK_FIND (1ULL << 12)
+#define RTEMS_RFS_TRACE_BLOCK_MAP_GROW (1ULL << 13)
+#define RTEMS_RFS_TRACE_BLOCK_MAP_SHRINK (1ULL << 14)
+#define RTEMS_RFS_TRACE_GROUP_OPEN (1ULL << 15)
+#define RTEMS_RFS_TRACE_GROUP_CLOSE (1ULL << 16)
+#define RTEMS_RFS_TRACE_GROUP_BITMAPS (1ULL << 17)
+#define RTEMS_RFS_TRACE_INODE_OPEN (1ULL << 18)
+#define RTEMS_RFS_TRACE_INODE_CLOSE (1ULL << 19)
+#define RTEMS_RFS_TRACE_INODE_LOAD (1ULL << 20)
+#define RTEMS_RFS_TRACE_INODE_UNLOAD (1ULL << 21)
+#define RTEMS_RFS_TRACE_INODE_CREATE (1ULL << 22)
+#define RTEMS_RFS_TRACE_INODE_DELETE (1ULL << 23)
+#define RTEMS_RFS_TRACE_LINK (1ULL << 24)
+#define RTEMS_RFS_TRACE_UNLINK (1ULL << 25)
+#define RTEMS_RFS_TRACE_DIR_LOOKUP_INO (1ULL << 26)
+#define RTEMS_RFS_TRACE_DIR_LOOKUP_INO_CHECK (1ULL << 27)
+#define RTEMS_RFS_TRACE_DIR_LOOKUP_INO_FOUND (1ULL << 28)
+#define RTEMS_RFS_TRACE_DIR_ADD_ENTRY (1ULL << 29)
+#define RTEMS_RFS_TRACE_DIR_DEL_ENTRY (1ULL << 30)
+#define RTEMS_RFS_TRACE_DIR_READ (1ULL << 31)
+#define RTEMS_RFS_TRACE_DIR_EMPTY (1ULL << 32)
+#define RTEMS_RFS_TRACE_SYMLINK (1ULL << 33)
+#define RTEMS_RFS_TRACE_SYMLINK_READ (1ULL << 34)
+#define RTEMS_RFS_TRACE_FILE_OPEN (1ULL << 35)
+#define RTEMS_RFS_TRACE_FILE_CLOSE (1ULL << 36)
+#define RTEMS_RFS_TRACE_FILE_IO (1ULL << 37)
+#define RTEMS_RFS_TRACE_FILE_SET (1ULL << 38)
+
+/**
+ * Call to check if this part is bring traced. If RTEMS_RFS_TRACE is defined to
+ * 0 the code is dead code elminiated when built with -Os, -O2, or higher.
+ *
+ * @param[in] mask is the part of the API to trace.
+ *
+ * @retval true Tracing is active for the mask.
+ * @retval false Do not trace.
+ */
+#if RTEMS_RFS_TRACE
+bool rtems_rfs_trace (rtems_rfs_trace_mask mask);
+#else
+#define rtems_rfs_trace(_m) (0)
+#endif
+
+/**
+ * Set the mask.
+ *
+ * @param[in] mask are the mask bits to set.
+ *
+ * @retval mask The previous mask.
+ */
+#if RTEMS_RFS_TRACE
+rtems_rfs_trace_mask rtems_rfs_trace_set_mask (rtems_rfs_trace_mask mask);
+#else
+#define rtems_rfs_trace_set_mask(_m)
+#endif
+
+/**
+ * Clear the mask.
+ *
+ * @param[in] mask are the mask bits to clear.
+ *
+ * @retval mask The previous mask.
+ */
+#if RTEMS_RFS_TRACE
+rtems_rfs_trace_mask rtems_rfs_trace_clear_mask (rtems_rfs_trace_mask mask);
+#else
+#define rtems_rfs_trace_clear_mask(_m)
+#endif
+
+/**
+ * Add shell trace shell command.
+ */
+#if RTEMS_RFS_TRACE
+int rtems_rfs_trace_shell_command (int argc, char *argv[]);
+#endif
+
+#endif