source: rtems/cpukit/libfs/src/imfs/imfs.h @ 95308caf

4.115
Last change on this file since 95308caf was 95308caf, checked in by Sebastian Huber <sebastian.huber@…>, on 01/31/15 at 20:25:57

IMFS: Use rtems_filesystem_make_dev_t_from_pointer

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