source: rtems/cpukit/libfs/src/imfs/imfs.h @ cf36b70

4.115
Last change on this file since cf36b70 was cf36b70, checked in by Sebastian Huber <sebastian.huber@…>, on 12/31/14 at 09:56:05

IMFS: Replace node union with individual struct

This reduces the average node size.

Add and use IMFS_GENERIC_INITIALIZER().

  • Property mode set to 100644
File size: 25.1 KB
Line 
1/**
2 * @file
3 *
4 * @brief Header File for the In-Memory File System
5 */
6
7/*
8 *  COPYRIGHT (c) 1989-2011.
9 *  On-Line Applications Research Corporation (OAR).
10 *
11 *  The license and distribution terms for this file may be
12 *  found in the file LICENSE in this distribution or at
13 *  http://www.rtems.org/license/LICENSE.
14 */
15
16#ifndef _RTEMS_IMFS_H
17#define _RTEMS_IMFS_H
18
19#include <limits.h>
20
21#include <rtems/libio_.h>
22#include <rtems/pipe.h>
23
24/**
25 * @brief In-Memory File System Support.
26 *
27 * @defgroup IMFS In-Memory File System Support
28 *
29 * @ingroup FileSystemTypesAndMount
30 */
31/**@{*/
32
33#ifdef __cplusplus
34extern "C" {
35#endif
36
37/*
38 *  Data types
39 */
40
41struct IMFS_jnode_tt;
42typedef struct IMFS_jnode_tt IMFS_jnode_t;
43
44/**
45 *  IMFS "memfile" information
46 *
47 *  The data structure for the in-memory "memfiles" is based on classic UNIX.
48 *
49 *  block_ptr is a pointer to a block of IMFS_MEMFILE_BYTES_PER_BLOCK in
50 *  length which could be data or a table of pointers to blocks.
51 *
52 *  Setting IMFS_MEMFILE_BYTES_PER_BLOCK to different values has a significant
53 *  impact on the maximum file size supported as well as the amount of
54 *  memory wasted due to internal file fragmentation.  The following
55 *  is a list of maximum file sizes based on various settings
56 *
57 *  @code
58 *    max_filesize with blocks of   16 is         1,328
59 *    max_filesize with blocks of   32 is        18,656
60 *    max_filesize with blocks of   64 is       279,488
61 *    max_filesize with blocks of  128 is     4,329,344
62 *    max_filesize with blocks of  256 is    68,173,568
63 *    max_filesize with blocks of  512 is 1,082,195,456
64 *  @endcode
65 */
66#define IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK     128
67  extern int imfs_rq_memfile_bytes_per_block;
68  extern int imfs_memfile_bytes_per_block;
69
70#define IMFS_MEMFILE_BYTES_PER_BLOCK imfs_memfile_bytes_per_block
71#define IMFS_MEMFILE_BLOCK_SLOTS \
72  (IMFS_MEMFILE_BYTES_PER_BLOCK / sizeof(void *))
73
74typedef uint8_t *block_p;
75typedef block_p *block_ptr;
76
77/*
78 *  Important block numbers for "memfiles"
79 */
80#define FIRST_INDIRECT           (0)
81#define LAST_INDIRECT            (IMFS_MEMFILE_BLOCK_SLOTS - 1)
82
83#define FIRST_DOUBLY_INDIRECT    (LAST_INDIRECT + 1)
84#define LAST_DOUBLY_INDIRECT     \
85   (LAST_INDIRECT + \
86     (IMFS_MEMFILE_BLOCK_SLOTS * IMFS_MEMFILE_BLOCK_SLOTS))
87
88#define FIRST_TRIPLY_INDIRECT    (LAST_DOUBLY_INDIRECT + 1)
89#define LAST_TRIPLY_INDIRECT \
90   (LAST_DOUBLY_INDIRECT +\
91     (IMFS_MEMFILE_BLOCK_SLOTS * \
92        IMFS_MEMFILE_BLOCK_SLOTS * IMFS_MEMFILE_BLOCK_SLOTS))
93
94#define IMFS_MEMFILE_MAXIMUM_SIZE \
95  (LAST_TRIPLY_INDIRECT * IMFS_MEMFILE_BYTES_PER_BLOCK)
96
97/*
98 *  What types of IMFS file systems entities there can be.
99 */
100typedef enum {
101  IMFS_DIRECTORY,
102  IMFS_DEVICE,
103  IMFS_HARD_LINK,
104  IMFS_SYM_LINK,
105  IMFS_MEMORY_FILE,
106  IMFS_LINEAR_FILE,
107  IMFS_FIFO
108} IMFS_jnode_types_t;
109
110#define IMFS_TYPE_COUNT (IMFS_FIFO + 1)
111
112/** @} */
113
114/**
115 * @addtogroup IMFSGenericNodes
116 */
117/**@{*/
118
119/**
120 * @brief Initializes an IMFS node.
121 *
122 * @param[in] node The IMFS node.
123 * @param[in] arg The user provided argument pointer.  It may contain node
124 *   specific initialization information.
125 *
126 * @retval node Successful operation.
127 * @retval NULL An error occurred.  The @c errno indicates the error.  This
128 * will abort the make operation.
129 *
130 * @see IMFS_node_control, IMFS_node_initialize_default(), and
131 * IMFS_node_initialize_generic().
132 */
133typedef IMFS_jnode_t *(*IMFS_node_control_initialize)(
134  IMFS_jnode_t *node,
135  void *arg
136);
137
138/**
139 * @brief Returns the node and does nothing else.
140 *
141 * @param[in] node The IMFS node.
142 * @param[in] arg The user provided argument pointer.  It is not used.
143 *
144 * @retval node Returns always the node passed as parameter.
145 *
146 * @see IMFS_node_control.
147 */
148IMFS_jnode_t *IMFS_node_initialize_default(
149  IMFS_jnode_t *node,
150  void *arg
151);
152
153/**
154 * @brief Returns the node and sets the generic node context.
155 *
156 * @param[in] node The IMFS node.
157 * @param[in] arg The user provided argument pointer.  It must contain the
158 *   generic context.
159 *
160 * @retval node Returns always the node passed as parameter.
161 *
162 * @see IMFS_node_control.
163 */
164IMFS_jnode_t *IMFS_node_initialize_generic(
165  IMFS_jnode_t *node,
166  void *arg
167);
168
169/**
170 * @brief Prepares the removal of an IMFS node from its parent directory.
171 *
172 * @param[in] node The IMFS node.
173 *
174 * @retval node Successful operation.
175 * @retval NULL An error occurred.  The @c errno indicates the error.  This
176 * will abort the removal operation.
177 *
178 * @see IMFS_node_control and IMFS_node_remove_default().
179 */
180typedef IMFS_jnode_t *(*IMFS_node_control_remove)(
181  IMFS_jnode_t *node
182);
183
184/**
185 * @brief Returns the node and does nothing else.
186 *
187 * @param[in] node The IMFS node.
188 *
189 * @retval node Returns always the node passed as parameter.
190 *
191 * @see IMFS_node_control.
192 */
193IMFS_jnode_t *IMFS_node_remove_default(
194  IMFS_jnode_t *node
195);
196
197/**
198 * @brief Destroys an IMFS node.
199 *
200 * @param[in] node The IMFS node.
201 *
202 * @see IMFS_node_control and IMFS_node_destroy_default().
203 */
204typedef void (*IMFS_node_control_destroy)( IMFS_jnode_t *node );
205
206/**
207 * @brief Frees the node.
208 *
209 * @param[in] node The IMFS node.
210 *
211 * @see IMFS_node_control.
212 */
213void IMFS_node_destroy_default( IMFS_jnode_t *node );
214
215/**
216 * @brief IMFS node control.
217 */
218typedef struct {
219  const rtems_filesystem_file_handlers_r *handlers;
220  size_t node_size;
221  IMFS_node_control_initialize node_initialize;
222  IMFS_node_control_remove node_remove;
223  IMFS_node_control_destroy node_destroy;
224} IMFS_node_control;
225
226/** @} */
227
228/**
229 * @addtogroup IMFS
230 */
231/**@{*/
232
233/*
234 * Major device number for the IMFS. This is not a real device number because
235 * the IMFS is just a file system and does not have a driver.
236 */
237#define IMFS_DEVICE_MAJOR_NUMBER (0xfffe)
238
239/**
240 * @ingroup IMFSGenericNodes
241 *
242 * @brief Generic IMFS device major number.
243 */
244#define IMFS_GENERIC_DEVICE_MAJOR_NUMBER (0xfffd)
245
246/*
247 *  Maximum length of a "basename" of an IMFS file/node.
248 */
249
250#define IMFS_NAME_MAX  32
251
252/*
253 *  The control structure for an IMFS jnode.
254 */
255
256struct IMFS_jnode_tt {
257  rtems_chain_node    Node;                  /* for chaining them together */
258  IMFS_jnode_t       *Parent;                /* Parent node */
259  char                name[IMFS_NAME_MAX+1]; /* "basename" */
260  mode_t              st_mode;               /* File mode */
261  unsigned short      reference_count;
262  nlink_t             st_nlink;              /* Link count */
263  ino_t               st_ino;                /* inode */
264
265  uid_t               st_uid;                /* User ID of owner */
266  gid_t               st_gid;                /* Group ID of owner */
267
268  time_t              stat_atime;            /* Time of last access */
269  time_t              stat_mtime;            /* Time of last modification */
270  time_t              stat_ctime;            /* Time of last status change */
271  const IMFS_node_control *control;
272};
273
274typedef struct {
275  IMFS_jnode_t                          Node;
276  rtems_chain_control                   Entries;
277  rtems_filesystem_mount_table_entry_t *mt_fs;
278} IMFS_directory_t;
279
280typedef struct {
281  IMFS_jnode_t              Node;
282  rtems_device_major_number major;
283  rtems_device_minor_number minor;
284} IMFS_device_t;
285
286typedef struct {
287  IMFS_jnode_t  Node;
288  IMFS_jnode_t *link_node;
289} IMFS_link_t;
290
291typedef struct {
292  IMFS_jnode_t  Node;
293  char         *name;
294} IMFS_sym_link_t;
295
296typedef struct {
297  IMFS_jnode_t Node;
298  size_t       size;             /* size of file in bytes */
299} IMFS_filebase_t;
300
301typedef struct {
302  IMFS_filebase_t File;
303  block_ptr       indirect;         /* array of 128 data blocks pointers */
304  block_ptr       doubly_indirect;  /* 128 indirect blocks */
305  block_ptr       triply_indirect;  /* 128 doubly indirect blocks */
306} IMFS_memfile_t;
307
308typedef struct {
309  IMFS_filebase_t File;
310  block_p         direct;           /* pointer to file image */
311} IMFS_linearfile_t;
312
313/* Support copy on write for linear files */
314typedef union {
315  IMFS_jnode_t      Node;
316  IMFS_filebase_t   File;
317  IMFS_memfile_t    Memfile;
318  IMFS_linearfile_t Linearfile;
319} IMFS_file_t;
320
321typedef struct {
322  IMFS_jnode_t    Node;
323  pipe_control_t *pipe;
324} IMFS_fifo_t;
325
326typedef struct {
327  IMFS_jnode_t  Node;
328  void         *context;
329} IMFS_generic_t;
330
331static inline IMFS_directory_t *IMFS_iop_to_directory(
332  const rtems_libio_t *iop
333)
334{
335  return (IMFS_directory_t *) iop->pathinfo.node_access;
336}
337
338static inline IMFS_device_t *IMFS_iop_to_device( const rtems_libio_t *iop )
339{
340  return (IMFS_device_t *) iop->pathinfo.node_access;
341}
342
343static inline IMFS_file_t *IMFS_iop_to_file( const rtems_libio_t *iop )
344{
345  return (IMFS_file_t *) iop->pathinfo.node_access;
346}
347
348static inline IMFS_memfile_t *IMFS_iop_to_memfile( const rtems_libio_t *iop )
349{
350  return (IMFS_memfile_t *) iop->pathinfo.node_access;
351}
352
353static inline void IMFS_update_atime( IMFS_jnode_t *jnode )
354{
355  struct timeval now;
356
357  gettimeofday( &now, 0 );
358
359  jnode->stat_atime = now.tv_sec;
360}
361
362static inline void IMFS_update_mtime( IMFS_jnode_t *jnode )
363{
364  struct timeval now;
365
366  gettimeofday( &now, 0 );
367
368  jnode->stat_mtime = now.tv_sec;
369}
370
371static inline void IMFS_update_ctime( IMFS_jnode_t *jnode )
372{
373  struct timeval now;
374
375  gettimeofday( &now, 0 );
376
377  jnode->stat_ctime = now.tv_sec;
378}
379
380static inline void IMFS_mtime_ctime_update( IMFS_jnode_t *jnode )
381{
382  struct timeval now;
383
384  gettimeofday( &now, 0 );
385
386  jnode->stat_mtime = now.tv_sec;
387  jnode->stat_ctime = now.tv_sec;
388}
389
390typedef struct {
391  int instance;
392  ino_t ino_count;
393  const IMFS_node_control *node_controls [IMFS_TYPE_COUNT];
394} IMFS_fs_info_t;
395
396/*
397 *  Shared Data
398 */
399
400extern const IMFS_node_control IMFS_node_control_directory;
401extern const IMFS_node_control IMFS_node_control_device;
402extern const IMFS_node_control IMFS_node_control_hard_link;
403extern const IMFS_node_control IMFS_node_control_sym_link;
404extern const IMFS_node_control IMFS_node_control_memfile;
405extern const IMFS_node_control IMFS_node_control_linfile;
406extern const IMFS_node_control IMFS_node_control_fifo;
407extern const IMFS_node_control IMFS_node_control_enosys;
408
409extern const rtems_filesystem_operations_table miniIMFS_ops;
410extern const rtems_filesystem_operations_table IMFS_ops;
411extern const rtems_filesystem_operations_table fifoIMFS_ops;
412
413extern const rtems_filesystem_limits_and_options_t  IMFS_LIMITS_AND_OPTIONS;
414
415/*
416 *  Routines
417 */
418
419extern int IMFS_initialize(
420   rtems_filesystem_mount_table_entry_t *mt_entry,
421   const void                           *data
422);
423
424extern int fifoIMFS_initialize(
425  rtems_filesystem_mount_table_entry_t  *mt_entry,
426  const void                            *data
427);
428
429extern int miniIMFS_initialize(
430   rtems_filesystem_mount_table_entry_t *mt_entry,
431   const void                           *data
432);
433
434/**
435 * @brief IMFS initialization support.
436 */
437extern int IMFS_initialize_support(
438  rtems_filesystem_mount_table_entry_t *mt_entry,
439  const rtems_filesystem_operations_table *op_table,
440  const IMFS_node_control *const node_controls [IMFS_TYPE_COUNT]
441);
442/**
443 * @brief Unmount this instance of IMFS.
444 */
445extern void IMFS_fsunmount(
446   rtems_filesystem_mount_table_entry_t *mt_entry
447);
448
449/**
450 * @brief RTEMS load tarfs.
451 *
452 * This file implements the "mount" procedure for tar-based IMFS
453 * extensions.  The TAR is not actually mounted under the IMFS.
454 * Directories from the TAR file are created as usual in the IMFS.
455 * File entries are created as IMFS_LINEAR_FILE nodes with their nods
456 * pointing to addresses in the TAR image.
457 *
458 * Here we create the mountpoint directory and load the tarfs at
459 * that node.  Once the IMFS has been mounted, we work through the
460 * tar image and perform as follows:
461 *  - For directories, simply call mkdir().  The IMFS creates nodes as
462 *    needed.
463 *  - For files, we make our own calls to IMFS eval_for_make and
464 *    create_node.
465 *
466 * TAR file format:
467 *
468 * @code
469 *   Offset   Length                 Contents
470 *     0    100  bytes  File name ('\0' terminated, 99 maxmum length)
471 *   100      8  bytes  File mode (in octal ascii)
472 *   108      8  bytes  User ID (in octal ascii)
473 *   116      8  bytes  Group ID (in octal ascii)
474 *   124     12  bytes  File size (s) (in octal ascii)
475 *   136     12  bytes  Modify time (in octal ascii)
476 *   148      8  bytes  Header checksum (in octal ascii)
477 *   156      1  bytes  Link flag
478 *   157    100  bytes  Linkname ('\0' terminated, 99 maxmum length)
479 *   257      8  bytes  Magic PAX ("ustar\0" + 2 bytes padding)
480 *   257      8  bytes  Magic GNU tar ("ustar  \0")
481 *   265     32  bytes  User name ('\0' terminated, 31 maxmum length)
482 *   297     32  bytes  Group name ('\0' terminated, 31 maxmum length)
483 *   329      8  bytes  Major device ID (in octal ascii)
484 *   337      8  bytes  Minor device ID (in octal ascii)
485 *   345    167  bytes  Padding
486 *   512   (s+p) bytes  File contents (s+p) := (((s) + 511) & ~511),
487 *                      round up to 512 bytes
488 * @endcode
489 *
490 *  Checksum:
491 *  @code
492 *    int   i, sum;
493 *    char *header = tar_header_pointer;
494 *
495 *    sum = 0;
496 *    for (i = 0; i < 512; i++)
497 *        sum += 0xFF & header[i];
498 * @endcode
499 */
500extern int rtems_tarfs_load(
501   const char *mountpoint,
502   uint8_t *tar_image,
503   size_t tar_size
504);
505
506/**
507 * @brief Destroy an IMFS node.
508 */
509extern void IMFS_node_destroy( IMFS_jnode_t *node );
510
511/**
512 * @brief Clone an IMFS node.
513 */
514extern int IMFS_node_clone( rtems_filesystem_location_info_t *loc );
515
516/**
517 * @brief Free an IMFS node.
518 */
519extern void IMFS_node_free( const rtems_filesystem_location_info_t *loc );
520
521/**
522 * @brief Perform a status processing for the IMFS.
523 *
524 * This routine provides a stat for the IMFS file system.
525 */
526extern int IMFS_stat(
527  const rtems_filesystem_location_info_t *loc,
528  struct stat *buf
529);
530
531/**
532 * @brief IMFS evaluation node support.
533 */
534extern void IMFS_eval_path(
535  rtems_filesystem_eval_path_context_t *ctx
536);
537
538/**
539 * @brief Create a new IMFS link node.
540 *
541 * The following rouine creates a new link node under parent with the
542 * name given in name.  The link node is set to point to the node at
543 * to_loc.
544 */
545extern int IMFS_link(
546  const rtems_filesystem_location_info_t *parentloc,
547  const rtems_filesystem_location_info_t *targetloc,
548  const char *name,
549  size_t namelen
550);
551
552/**
553 * @brief Change the owner of IMFS.
554 *
555 * This routine is the implementation of the chown() system
556 * call for the IMFS.
557 */
558extern int IMFS_chown(
559  const rtems_filesystem_location_info_t *loc,
560  uid_t owner,
561  gid_t group
562);
563
564/**
565 * @brief Create an IMFS node.
566 *
567 * Routine to create a node in the IMFS file system.
568 */
569extern int IMFS_mknod(
570  const rtems_filesystem_location_info_t *parentloc,
571  const char *name,
572  size_t namelen,
573  mode_t mode,
574  dev_t dev
575);
576
577/**
578 * @brief Create a new IMFS node.
579 *
580 * Routine to create a new in memory file system node.
581 */
582extern IMFS_jnode_t *IMFS_allocate_node(
583  IMFS_fs_info_t *fs_info,
584  const IMFS_node_control *node_control,
585  const char *name,
586  size_t namelen,
587  mode_t mode,
588  void *arg
589);
590
591/**
592 * @brief Create an IMFS node.
593 *
594 * Create an IMFS filesystem node of an arbitrary type that is NOT
595 * the root directory node.
596 */
597extern IMFS_jnode_t *IMFS_create_node_with_control(
598  const rtems_filesystem_location_info_t *parentloc,
599  const IMFS_node_control *node_control,
600  const char *name,
601  size_t namelen,
602  mode_t mode,
603  void *arg
604);
605
606extern bool IMFS_is_imfs_instance(
607  const rtems_filesystem_location_info_t *loc
608);
609
610/** @} */
611
612/**
613 * @defgroup IMFSGenericNodes IMFS Generic Nodes
614 *
615 * @ingroup LibIO
616 *
617 * @brief Generic nodes are an alternative to standard drivers in RTEMS.
618 *
619 * The handlers of a generic node are called with less overhead compared to the
620 * standard driver operations.  The usage of file system node handlers enable
621 * more features like support for fsync() and fdatasync().  The generic nodes
622 * use the reference counting of the IMFS.  This provides automatic node
623 * destruction when the last reference vanishes.
624 *
625 * @{
626 */
627
628/**
629 * @brief Initializer for a generic node control.
630 *
631 * @param[in] handlers The file system node handlers.
632 * @param[in] init The node initialization method.
633 * @param[in] destroy The node destruction method.
634 */
635#define IMFS_GENERIC_INITIALIZER( handlers, init, destroy ) \
636  { \
637    ( handlers ), \
638    sizeof( IMFS_generic_t ), \
639    ( init ), \
640    IMFS_node_remove_default, \
641    ( destroy ) \
642  }
643
644/**
645 * @brief Makes a generic IMFS node.
646 *
647 * @param[in] path The path to the new generic IMFS node.
648 * @param[in] mode The node mode.
649 * @param[in] node_control The node control.
650 * @param[in] context The node control handler context.
651 *
652 * @retval 0 Successful operation.
653 * @retval -1 An error occurred.  The @c errno indicates the error.
654 *
655 * @code
656 * #include <sys/stat.h>
657 * #include <assert.h>
658 * #include <fcntl.h>
659 *
660 * #include <rtems/imfs.h>
661 *
662 * static const rtems_filesystem_file_handlers_r some_node_handlers = {
663 *   ...
664 * };
665 *
666 * static IMFS_jnode_t *some_node_init(IMFS_jnode_t *node, void *arg)
667 * {
668 *   void *context;
669 *
670 *   node = IMFS_node_initialize_generic(node, arg);
671 *   context = IMFS_generic_get_context_by_node(node);
672 *
673 *   return node;
674 * }
675 *
676 * static void some_node_destroy(IMFS_jnode_t *node)
677 * {
678 *   void *context = IMFS_generic_get_context_by_node(node);
679 *
680 *   IMFS_node_destroy_default(node);
681 * }
682 *
683 * static const IMFS_node_control some_node_control = IMFS_GENERIC_INITIALIZER(
684 *   &some_node_handlers,
685 *   some_node_init,
686 *   some_node_destroy
687 * );
688 *
689 * void example(void *some_node_context)
690 * {
691 *   int rv;
692 *
693 *   rv = IMFS_make_generic_node(
694 *     "/path/to/some/generic/node",
695 *     S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
696 *     &some_node_control,
697 *     some_node_context
698 *   );
699 *   assert(rv == 0);
700 * }
701 * @endcode
702 */
703extern int IMFS_make_generic_node(
704  const char *path,
705  mode_t mode,
706  const IMFS_node_control *node_control,
707  void *context
708);
709
710/** @} */
711
712/**
713 * @addtogroup IMFS
714 */
715/**@{*/
716
717/**
718 * @brief Mount an IMFS.
719 */
720extern int IMFS_mount(
721  rtems_filesystem_mount_table_entry_t *mt_entry  /* IN */
722);
723
724/**
725 * @brief Unmount an IMFS.
726 */
727extern int IMFS_unmount(
728  rtems_filesystem_mount_table_entry_t *mt_entry  /* IN */
729);
730
731extern void IMFS_memfile_remove(
732 IMFS_jnode_t  *the_jnode         /* IN/OUT */
733);
734
735/**
736 * @brief Truncate a memory file.
737 *
738 * This routine processes the ftruncate() system call.
739 */
740extern int memfile_ftruncate(
741  rtems_libio_t *iop,               /* IN  */
742  off_t          length             /* IN  */
743);
744
745/**
746 * @brief Read the next directory of the IMFS.
747 *
748 * This routine will read the next directory entry based on the directory
749 * offset. The offset should be equal to -n- time the size of an individual
750 * dirent structure. If n is not an integer multiple of the sizeof a
751 * dirent structure, an integer division will be performed to determine
752 * directory entry that will be returned in the buffer. Count should reflect
753 * -m- times the sizeof dirent bytes to be placed in the buffer.
754 * If there are not -m- dirent elements from the current directory position
755 * to the end of the exisiting file, the remaining entries will be placed in
756 * the buffer and the returned value will be equal to -m actual- times the
757 * size of a directory entry.
758 */
759extern ssize_t imfs_dir_read(
760  rtems_libio_t *iop,              /* IN  */
761  void          *buffer,           /* IN  */
762  size_t         count             /* IN  */
763);
764
765/**
766 * @name IMFS Memory File Handlers
767 *
768 * This section contains the set of handlers used to process operations on
769 * IMFS memory file nodes.  The memory files are created in memory using
770 * malloc'ed memory.  Thus any data stored in one of these files is lost
771 * at system shutdown unless special arrangements to copy the data to
772 * some type of non-volailte storage are made by the application.
773 */
774/**@{*/
775
776/**
777 * @brief Open a linear file.
778 *
779 * Transforms the file into a memfile if opened for writing.
780 */
781extern int IMFS_linfile_open(
782  rtems_libio_t *iop,             /* IN  */
783  const char    *pathname,        /* IN  */
784  int            oflag,           /* IN  */
785  mode_t         mode             /* IN  */
786);
787
788extern ssize_t IMFS_linfile_read(
789  rtems_libio_t *iop,
790  void          *buffer,
791  size_t         count
792);
793
794/**
795 * @brief Read a memory file.
796 *
797 * This routine processes the read() system call.
798 */
799extern ssize_t memfile_read(
800  rtems_libio_t *iop,             /* IN  */
801  void          *buffer,          /* IN  */
802  size_t         count            /* IN  */
803);
804
805/**
806 * @brief Write a memory file.
807 *
808 * This routine processes the write() system call.
809 */
810extern ssize_t memfile_write(
811  rtems_libio_t *iop,             /* IN  */
812  const void    *buffer,          /* IN  */
813  size_t         count            /* IN  */
814);
815
816/** @} */
817
818/**
819 * @name IMFS Device Node Handlers
820 *
821 * This section contains the set of handlers used to map operations on
822 * IMFS device nodes onto calls to the RTEMS Classic API IO Manager.
823 */
824/**@{*/
825
826extern int device_open(
827  rtems_libio_t *iop,            /* IN  */
828  const char    *pathname,       /* IN  */
829  int            oflag,          /* IN  */
830  mode_t         mode            /* IN  */
831);
832
833extern int device_close(
834  rtems_libio_t *iop             /* IN  */
835);
836
837extern ssize_t device_read(
838  rtems_libio_t *iop,            /* IN  */
839  void          *buffer,         /* IN  */
840  size_t         count           /* IN  */
841);
842
843extern ssize_t device_write(
844  rtems_libio_t *iop,               /* IN  */
845  const void    *buffer,            /* IN  */
846  size_t         count              /* IN  */
847);
848
849extern int device_ioctl(
850  rtems_libio_t   *iop,
851  ioctl_command_t  command,
852  void            *buffer
853);
854
855extern int device_ftruncate(
856  rtems_libio_t *iop,               /* IN  */
857  off_t          length             /* IN  */
858);
859
860/** @} */
861
862/**
863 * @brief Set IMFS file access and modification times.
864 *
865 *
866 * This routine is the implementation of the utime() system
867 * call for the IMFS.
868 */
869extern int IMFS_utime(
870  const rtems_filesystem_location_info_t *loc,
871  time_t actime,
872  time_t modtime
873);
874
875/**
876 * @brief Change the IMFS file mode.
877 */
878extern int IMFS_fchmod(
879  const rtems_filesystem_location_info_t *loc,
880  mode_t mode
881);
882
883/**
884 * @brief Create a new IMFS symbolic link node.
885 *
886 * The following rouine creates a new symbolic link node under parent
887 * with the name given in name.  The node is set to point to the node at
888 * to_loc.
889 */
890extern int IMFS_symlink(
891  const rtems_filesystem_location_info_t *parentloc,
892  const char *name,
893  size_t namelen,
894  const char *target
895);
896
897/**
898 * @brief Put IMFS symbolic link into buffer.
899 *
900 * The following rouine puts the symbolic links destination name into
901 * buff.
902 *
903 */
904extern ssize_t IMFS_readlink(
905  const rtems_filesystem_location_info_t *loc,
906  char *buf,
907  size_t bufsize
908);
909
910/**
911 * @brief Rename the IMFS.
912 *
913 * The following rouine creates a new link node under parent with the
914 * name given in name and removes the old.
915 */
916extern int IMFS_rename(
917  const rtems_filesystem_location_info_t *oldparentloc,
918  const rtems_filesystem_location_info_t *oldloc,
919  const rtems_filesystem_location_info_t *newparentloc,
920  const char *name,
921  size_t namelen
922);
923/**
924 * @brief IMFS node removal handler.
925 *
926 * This file contains the handler used to remove a node when a file type
927 * does not require special actions.
928 */
929extern int IMFS_rmnod(
930  const rtems_filesystem_location_info_t *parentloc,
931  const rtems_filesystem_location_info_t *loc
932);
933
934/*
935 *  Turn on IMFS assertions when RTEMS_DEBUG is defined.
936 */
937#ifdef RTEMS_DEBUG
938  #include <assert.h>
939
940  #define IMFS_assert(_x) assert(_x)
941#else
942  #define IMFS_assert(_x)
943#endif
944
945static inline void IMFS_Set_handlers( rtems_filesystem_location_info_t *loc )
946{
947  IMFS_jnode_t *node = (IMFS_jnode_t *) loc->node_access;
948
949  loc->handlers = node->control->handlers;
950}
951
952static inline void IMFS_add_to_directory(
953  IMFS_jnode_t *dir_node,
954  IMFS_jnode_t *entry_node
955)
956{
957  IMFS_directory_t *dir = (IMFS_directory_t *) dir_node;
958
959  entry_node->Parent = dir_node;
960  rtems_chain_append_unprotected( &dir->Entries, &entry_node->Node );
961}
962
963static inline void IMFS_remove_from_directory( IMFS_jnode_t *node )
964{
965  IMFS_assert( node->Parent != NULL );
966  node->Parent = NULL;
967  rtems_chain_extract_unprotected( &node->Node );
968}
969
970static inline bool IMFS_is_directory( const IMFS_jnode_t *node )
971{
972  return S_ISDIR( node->st_mode );
973}
974
975#define IMFS_STAT_FMT_HARD_LINK 0
976
977static inline bool IMFS_is_hard_link( mode_t mode )
978{
979  return ( mode & S_IFMT ) == IMFS_STAT_FMT_HARD_LINK;
980}
981
982static inline IMFS_jnode_t *IMFS_create_node(
983  const rtems_filesystem_location_info_t *parentloc,
984  IMFS_jnode_types_t type,
985  const char *name,
986  size_t namelen,
987  mode_t mode,
988  void *arg
989)
990{
991  const IMFS_fs_info_t *fs_info =
992    (const IMFS_fs_info_t *) parentloc->mt_entry->fs_info;
993
994  return IMFS_create_node_with_control(
995    parentloc,
996    fs_info->node_controls [type],
997    name,
998    namelen,
999    mode,
1000    arg
1001  );
1002}
1003
1004/** @} */
1005
1006/**
1007 * @addtogroup IMFSGenericNodes
1008 */
1009/**@{*/
1010
1011static inline void *IMFS_generic_get_context_by_node(
1012  const IMFS_jnode_t *node
1013)
1014{
1015  const IMFS_generic_t *generic = (const IMFS_generic_t *) node;
1016
1017  return generic->context;
1018}
1019
1020static inline void *IMFS_generic_get_context_by_location(
1021  const rtems_filesystem_location_info_t *loc
1022)
1023{
1024  return loc->node_access_2;
1025}
1026
1027static inline void *IMFS_generic_get_context_by_iop(
1028  const rtems_libio_t *iop
1029)
1030{
1031  return IMFS_generic_get_context_by_location( &iop->pathinfo );
1032}
1033
1034static inline dev_t IMFS_generic_get_device_identifier_by_node(
1035  const IMFS_jnode_t *node
1036)
1037{
1038  return rtems_filesystem_make_dev_t(
1039    IMFS_GENERIC_DEVICE_MAJOR_NUMBER,
1040    node->st_ino
1041  );
1042}
1043
1044#ifdef __cplusplus
1045}
1046#endif
1047/** @} */
1048#endif
1049/* end of include file */
Note: See TracBrowser for help on using the repository browser.