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

4.11
Last change on this file since c17d0b3 was c17d0b3, checked in by Sebastian Huber <sebastian.huber@…>, on Oct 2, 2012 at 1:44:59 PM

Filesystem: Reject removal of root nodes

Reject the removal of file system instance root nodes in rmdir() and
unlink() and return the EBUSY error status. File system instances can
be removed with unmount(). Remove root node special cases in IMFS,
DOSFS, and RFS.

  • Property mode set to 100644
File size: 15.3 KB
Line 
1/**
2 * @file rtems/imfs.h
3 *
4 * 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.com/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#ifdef __cplusplus
25extern "C" {
26#endif
27
28/*
29 *  Data types
30 */
31
32struct IMFS_jnode_tt;
33typedef struct IMFS_jnode_tt IMFS_jnode_t;
34
35typedef struct {
36  rtems_chain_control                    Entries;
37  rtems_filesystem_mount_table_entry_t  *mt_fs;
38}  IMFS_directory_t;
39
40typedef struct {
41  rtems_device_major_number  major;
42  rtems_device_minor_number  minor;
43}  IMFS_device_t;
44
45typedef struct {
46  IMFS_jnode_t  *link_node;
47} IMFS_link_t;
48
49typedef struct {
50  char *name;
51} IMFS_sym_link_t;
52
53typedef struct {
54  pipe_control_t  *pipe;
55} IMFS_fifo_t;
56
57typedef struct {
58  void *context;
59} IMFS_generic_t;
60
61/*
62 *  IMFS "memfile" information
63 *
64 *  The data structure for the in-memory "memfiles" is based on classic UNIX.
65 *
66 *  block_ptr is a pointer to a block of IMFS_MEMFILE_BYTES_PER_BLOCK in
67 *  length which could be data or a table of pointers to blocks.
68 *
69 *  Setting IMFS_MEMFILE_BYTES_PER_BLOCK to different values has a significant
70 *  impact on the maximum file size supported as well as the amount of
71 *  memory wasted due to internal file fragmentation.  The following
72 *  is a list of maximum file sizes based on various settings
73 *
74 *    max_filesize with blocks of   16 is         1,328
75 *    max_filesize with blocks of   32 is        18,656
76 *    max_filesize with blocks of   64 is       279,488
77 *    max_filesize with blocks of  128 is     4,329,344
78 *    max_filesize with blocks of  256 is    68,173,568
79 *    max_filesize with blocks of  512 is 1,082,195,456
80 */
81
82#define IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK     128
83  extern int imfs_rq_memfile_bytes_per_block;
84  extern int imfs_memfile_bytes_per_block;
85
86#define IMFS_MEMFILE_BYTES_PER_BLOCK imfs_memfile_bytes_per_block
87#define IMFS_MEMFILE_BLOCK_SLOTS \
88  (IMFS_MEMFILE_BYTES_PER_BLOCK / sizeof(void *))
89
90typedef uint8_t *block_p;
91typedef block_p *block_ptr;
92
93typedef struct {
94  off_t         size;             /* size of file in bytes */
95  block_ptr     indirect;         /* array of 128 data blocks pointers */
96  block_ptr     doubly_indirect;  /* 128 indirect blocks */
97  block_ptr     triply_indirect;  /* 128 doubly indirect blocks */
98} IMFS_memfile_t;
99
100typedef struct {
101  off_t         size;             /* size of file in bytes */
102  block_p       direct;           /* pointer to file image */
103} IMFS_linearfile_t;
104
105/*
106 *  Important block numbers for "memfiles"
107 */
108
109#define FIRST_INDIRECT           (0)
110#define LAST_INDIRECT            (IMFS_MEMFILE_BLOCK_SLOTS - 1)
111
112#define FIRST_DOUBLY_INDIRECT    (LAST_INDIRECT + 1)
113#define LAST_DOUBLY_INDIRECT     \
114   (LAST_INDIRECT + \
115     (IMFS_MEMFILE_BLOCK_SLOTS * IMFS_MEMFILE_BLOCK_SLOTS))
116
117#define FIRST_TRIPLY_INDIRECT    (LAST_DOUBLY_INDIRECT + 1)
118#define LAST_TRIPLY_INDIRECT \
119   (LAST_DOUBLY_INDIRECT +\
120     (IMFS_MEMFILE_BLOCK_SLOTS * \
121        IMFS_MEMFILE_BLOCK_SLOTS * IMFS_MEMFILE_BLOCK_SLOTS))
122
123#define IMFS_MEMFILE_MAXIMUM_SIZE \
124  (LAST_TRIPLY_INDIRECT * IMFS_MEMFILE_BYTES_PER_BLOCK)
125
126/*
127 *  What types of IMFS file systems entities there can be.
128 */
129
130typedef enum {
131  IMFS_DIRECTORY = RTEMS_FILESYSTEM_DIRECTORY,
132  IMFS_DEVICE = RTEMS_FILESYSTEM_DEVICE,
133  IMFS_HARD_LINK = RTEMS_FILESYSTEM_HARD_LINK,
134  IMFS_SYM_LINK =  RTEMS_FILESYSTEM_SYM_LINK,
135  IMFS_MEMORY_FILE = RTEMS_FILESYSTEM_MEMORY_FILE,
136  IMFS_LINEAR_FILE,
137  IMFS_FIFO,
138  IMFS_GENERIC,
139  IMFS_INVALID_NODE
140} IMFS_jnode_types_t;
141
142/* The IMFS_GENERIC does not count */
143#define IMFS_TYPE_COUNT (IMFS_FIFO + 1)
144
145typedef union {
146  IMFS_directory_t   directory;
147  IMFS_device_t      device;
148  IMFS_link_t        hard_link;
149  IMFS_sym_link_t    sym_link;
150  IMFS_memfile_t     file;
151  IMFS_linearfile_t  linearfile;
152  IMFS_fifo_t        fifo;
153  IMFS_generic_t     generic;
154} IMFS_types_union;
155
156typedef IMFS_jnode_t *(*IMFS_node_control_initialize)(
157  IMFS_jnode_t *node,
158  const IMFS_types_union *info
159);
160
161IMFS_jnode_t *IMFS_node_initialize_default(
162  IMFS_jnode_t *node,
163  const IMFS_types_union *info
164);
165
166IMFS_jnode_t *IMFS_node_initialize_generic(
167  IMFS_jnode_t *node,
168  const IMFS_types_union *info
169);
170
171typedef IMFS_jnode_t *(*IMFS_node_control_remove)(
172  IMFS_jnode_t *node
173);
174
175IMFS_jnode_t *IMFS_node_remove_default(
176  IMFS_jnode_t *node
177);
178
179typedef IMFS_jnode_t *(*IMFS_node_control_destroy)( IMFS_jnode_t *node );
180
181IMFS_jnode_t *IMFS_node_destroy_default( IMFS_jnode_t *node );
182
183typedef struct {
184  IMFS_jnode_types_t imfs_type;
185  const rtems_filesystem_file_handlers_r *handlers;
186  IMFS_node_control_initialize node_initialize;
187  IMFS_node_control_remove node_remove;
188  IMFS_node_control_destroy node_destroy;
189} IMFS_node_control;
190
191/*
192 * Major device number for the IMFS. This is not a real device number because
193 * the IMFS is just a file system and does not have a driver.
194 */
195#define IMFS_DEVICE_MAJOR_NUMBER (0xfffe)
196
197#define IMFS_GENERIC_DEVICE_MAJOR_NUMBER (0xfffd)
198
199/*
200 *  Maximum length of a "basename" of an IMFS file/node.
201 */
202
203#define IMFS_NAME_MAX  32
204
205/*
206 *  The control structure for an IMFS jnode.
207 */
208
209struct IMFS_jnode_tt {
210  rtems_chain_node    Node;                  /* for chaining them together */
211  IMFS_jnode_t       *Parent;                /* Parent node */
212  char                name[IMFS_NAME_MAX+1]; /* "basename" */
213  mode_t              st_mode;               /* File mode */
214  unsigned short      reference_count;
215  nlink_t             st_nlink;              /* Link count */
216  ino_t               st_ino;                /* inode */
217
218  uid_t               st_uid;                /* User ID of owner */
219  gid_t               st_gid;                /* Group ID of owner */
220
221  time_t              stat_atime;            /* Time of last access */
222  time_t              stat_mtime;            /* Time of last modification */
223  time_t              stat_ctime;            /* Time of last status change */
224  const IMFS_node_control *control;
225  IMFS_types_union    info;
226};
227
228#define IMFS_update_atime( _jnode )         \
229  do {                                      \
230    struct timeval tv;                      \
231    gettimeofday( &tv, 0 );                 \
232    _jnode->stat_atime  = (time_t) tv.tv_sec; \
233  } while (0)
234
235#define IMFS_update_mtime( _jnode )         \
236  do {                                      \
237    struct timeval tv;                      \
238    gettimeofday( &tv, 0 );                 \
239    _jnode->stat_mtime  = (time_t) tv.tv_sec; \
240  } while (0)
241
242#define IMFS_update_ctime( _jnode )         \
243  do {                                      \
244    struct timeval tv;                      \
245    gettimeofday( &tv, 0 );                 \
246    _jnode->stat_ctime  = (time_t) tv.tv_sec; \
247  } while (0)
248
249#define IMFS_mtime_ctime_update( _jnode )   \
250  do {                                      \
251    struct timeval tv;                      \
252    gettimeofday( &tv, 0 );                 \
253    _jnode->stat_mtime  = (time_t) tv.tv_sec; \
254    _jnode->stat_ctime  = (time_t) tv.tv_sec; \
255  } while (0)
256
257typedef struct {
258  int instance;
259  ino_t ino_count;
260  const IMFS_node_control *node_controls [IMFS_TYPE_COUNT];
261} IMFS_fs_info_t;
262
263/*
264 *  Shared Data
265 */
266
267extern const IMFS_node_control IMFS_node_control_directory;
268extern const IMFS_node_control IMFS_node_control_device;
269extern const IMFS_node_control IMFS_node_control_hard_link;
270extern const IMFS_node_control IMFS_node_control_sym_link;
271extern const IMFS_node_control IMFS_node_control_memfile;
272extern const IMFS_node_control IMFS_node_control_linfile;
273extern const IMFS_node_control IMFS_node_control_fifo;
274extern const IMFS_node_control IMFS_node_control_default;
275
276extern const rtems_filesystem_operations_table miniIMFS_ops;
277extern const rtems_filesystem_operations_table IMFS_ops;
278extern const rtems_filesystem_operations_table fifoIMFS_ops;
279
280extern const rtems_filesystem_limits_and_options_t  IMFS_LIMITS_AND_OPTIONS;
281
282/*
283 *  Routines
284 */
285
286extern int IMFS_initialize(
287   rtems_filesystem_mount_table_entry_t *mt_entry,
288   const void                           *data
289);
290
291extern int fifoIMFS_initialize(
292  rtems_filesystem_mount_table_entry_t  *mt_entry,
293  const void                            *data
294);
295
296extern int miniIMFS_initialize(
297   rtems_filesystem_mount_table_entry_t *mt_entry,
298   const void                           *data
299);
300
301extern int IMFS_initialize_support(
302  rtems_filesystem_mount_table_entry_t *mt_entry,
303  const rtems_filesystem_operations_table *op_table,
304  const IMFS_node_control *const node_controls [IMFS_TYPE_COUNT]
305);
306
307extern void IMFS_fsunmount(
308   rtems_filesystem_mount_table_entry_t *mt_entry
309);
310
311extern int rtems_tarfs_load(
312   const char *mountpoint,
313   uint8_t *tar_image,
314   size_t tar_size
315);
316
317extern void IMFS_dump( void );
318
319/*
320 * Return the size of the largest file which can be created
321 * using the IMFS memory file type.
322 */
323extern int IMFS_memfile_maximum_size( void );
324
325extern void IMFS_node_destroy( IMFS_jnode_t *node );
326
327extern int IMFS_node_clone( rtems_filesystem_location_info_t *loc );
328
329extern void IMFS_node_free( const rtems_filesystem_location_info_t *loc );
330
331extern rtems_filesystem_node_types_t IMFS_node_type(
332  const rtems_filesystem_location_info_t *loc
333);
334
335extern int IMFS_stat(
336  const rtems_filesystem_location_info_t *loc,
337  struct stat *buf
338);
339
340extern void IMFS_eval_path(
341  rtems_filesystem_eval_path_context_t *ctx
342);
343
344extern int IMFS_link(
345  const rtems_filesystem_location_info_t *parentloc,
346  const rtems_filesystem_location_info_t *targetloc,
347  const char *name,
348  size_t namelen
349);
350
351extern int IMFS_chown(
352  const rtems_filesystem_location_info_t *loc,
353  uid_t owner,
354  gid_t group
355);
356
357extern int IMFS_mknod(
358  const rtems_filesystem_location_info_t *parentloc,
359  const char *name,
360  size_t namelen,
361  mode_t mode,
362  dev_t dev
363);
364
365extern IMFS_jnode_t *IMFS_allocate_node(
366  IMFS_fs_info_t *fs_info,
367  const IMFS_node_control *node_control,
368  const char *name,
369  size_t namelen,
370  mode_t mode,
371  const IMFS_types_union *info
372);
373
374extern IMFS_jnode_t *IMFS_create_node_with_control(
375  const rtems_filesystem_location_info_t *parentloc,
376  const IMFS_node_control *node_control,
377  const char *name,
378  size_t namelen,
379  mode_t mode,
380  const IMFS_types_union *info
381);
382
383extern bool IMFS_is_imfs_instance(
384  const rtems_filesystem_location_info_t *loc
385);
386
387extern int IMFS_make_generic_node(
388  const char *path,
389  mode_t mode,
390  const IMFS_node_control *node_control,
391  void *context
392);
393
394extern int IMFS_mount(
395  rtems_filesystem_mount_table_entry_t *mt_entry  /* IN */
396);
397
398extern int IMFS_unmount(
399  rtems_filesystem_mount_table_entry_t *mt_entry  /* IN */
400);
401
402extern IMFS_jnode_t *IMFS_memfile_remove(
403 IMFS_jnode_t  *the_jnode         /* IN/OUT */
404);
405
406extern int memfile_ftruncate(
407  rtems_libio_t *iop,               /* IN  */
408  off_t          length             /* IN  */
409);
410
411extern ssize_t imfs_dir_read(
412  rtems_libio_t *iop,              /* IN  */
413  void          *buffer,           /* IN  */
414  size_t         count             /* IN  */
415);
416
417extern int memfile_open(
418  rtems_libio_t *iop,             /* IN  */
419  const char    *pathname,        /* IN  */
420  int            oflag,           /* IN  */
421  mode_t         mode             /* IN  */
422);
423
424extern ssize_t memfile_read(
425  rtems_libio_t *iop,             /* IN  */
426  void          *buffer,          /* IN  */
427  size_t         count            /* IN  */
428);
429
430extern ssize_t memfile_write(
431  rtems_libio_t *iop,             /* IN  */
432  const void    *buffer,          /* IN  */
433  size_t         count            /* IN  */
434);
435
436extern int device_open(
437  rtems_libio_t *iop,            /* IN  */
438  const char    *pathname,       /* IN  */
439  int            oflag,          /* IN  */
440  mode_t         mode            /* IN  */
441);
442
443extern int device_close(
444  rtems_libio_t *iop             /* IN  */
445);
446
447extern ssize_t device_read(
448  rtems_libio_t *iop,            /* IN  */
449  void          *buffer,         /* IN  */
450  size_t         count           /* IN  */
451);
452
453extern ssize_t device_write(
454  rtems_libio_t *iop,               /* IN  */
455  const void    *buffer,            /* IN  */
456  size_t         count              /* IN  */
457);
458
459extern int device_ioctl(
460  rtems_libio_t   *iop,
461  ioctl_command_t  command,
462  void            *buffer
463);
464
465extern int device_ftruncate(
466  rtems_libio_t *iop,               /* IN  */
467  off_t          length             /* IN  */
468);
469
470extern int IMFS_utime(
471  const rtems_filesystem_location_info_t *loc,
472  time_t actime,
473  time_t modtime
474);
475
476extern int IMFS_fchmod(
477  const rtems_filesystem_location_info_t *loc,
478  mode_t mode
479);
480
481extern int IMFS_symlink(
482  const rtems_filesystem_location_info_t *parentloc,
483  const char *name,
484  size_t namelen,
485  const char *target
486);
487
488extern ssize_t IMFS_readlink(
489  const rtems_filesystem_location_info_t *loc,
490  char *buf,
491  size_t bufsize
492);
493
494extern int IMFS_rename(
495  const rtems_filesystem_location_info_t *oldparentloc,
496  const rtems_filesystem_location_info_t *oldloc,
497  const rtems_filesystem_location_info_t *newparentloc,
498  const char *name,
499  size_t namelen
500);
501
502extern int IMFS_rmnod(
503  const rtems_filesystem_location_info_t *parentloc,
504  const rtems_filesystem_location_info_t *loc
505);
506
507/*
508 *  Turn on IMFS assertions when RTEMS_DEBUG is defined.
509 */
510#ifdef RTEMS_DEBUG
511  #include <assert.h>
512
513  #define IMFS_assert(_x) assert(_x)
514#else
515  #define IMFS_assert(_x)
516#endif
517
518static inline void IMFS_Set_handlers( rtems_filesystem_location_info_t *loc )
519{
520  IMFS_jnode_t *node = (IMFS_jnode_t *) loc->node_access;
521
522  loc->handlers = node->control->handlers;
523}
524
525static inline void IMFS_add_to_directory(
526  IMFS_jnode_t *dir,
527  IMFS_jnode_t *node
528)
529{
530  node->Parent = dir;
531  rtems_chain_append_unprotected( &dir->info.directory.Entries, &node->Node );
532}
533
534static inline void IMFS_remove_from_directory( IMFS_jnode_t *node )
535{
536  IMFS_assert( node->Parent != NULL );
537  node->Parent = NULL;
538  rtems_chain_extract_unprotected( &node->Node );
539}
540
541static inline IMFS_jnode_types_t IMFS_type( const IMFS_jnode_t *node )
542{
543  return node->control->imfs_type;
544}
545
546static inline bool IMFS_is_directory( const IMFS_jnode_t *node )
547{
548  return node->control->imfs_type == IMFS_DIRECTORY;
549}
550
551static inline IMFS_jnode_t *IMFS_create_node(
552  const rtems_filesystem_location_info_t *parentloc,
553  IMFS_jnode_types_t type,
554  const char *name,
555  size_t namelen,
556  mode_t mode,
557  const IMFS_types_union *info
558)
559{
560  const IMFS_fs_info_t *fs_info =
561    (const IMFS_fs_info_t *) parentloc->mt_entry->fs_info;
562
563  return IMFS_create_node_with_control(
564    parentloc,
565    fs_info->node_controls [type],
566    name,
567    namelen,
568    mode,
569    info
570  );
571}
572
573static inline void *IMFS_generic_get_context_by_node(
574  const IMFS_jnode_t *node
575)
576{
577  return node->info.generic.context;
578}
579
580static inline void *IMFS_generic_get_context_by_location(
581  const rtems_filesystem_location_info_t *loc
582)
583{
584  const IMFS_jnode_t *node = (const IMFS_jnode_t *) loc->node_access;
585
586  return IMFS_generic_get_context_by_node( node );
587}
588
589static inline void *IMFS_generic_get_context_by_iop(
590  const rtems_libio_t *iop
591)
592{
593  return IMFS_generic_get_context_by_location( &iop->pathinfo );
594}
595
596static inline dev_t IMFS_generic_get_device_identifier_by_node(
597  const IMFS_jnode_t *node
598)
599{
600  return rtems_filesystem_make_dev_t(
601    IMFS_GENERIC_DEVICE_MAJOR_NUMBER,
602    node->st_ino
603  );
604}
605
606#ifdef __cplusplus
607}
608#endif
609
610#endif
611/* end of include file */
Note: See TracBrowser for help on using the repository browser.