source: rtems/cpukit/libfs/src/rfs/rtems-rfs-rtems.c @ 9b4422a2

4.11
Last change on this file since 9b4422a2 was 9b4422a2, checked in by Joel Sherrill <joel.sherrill@…>, on May 3, 2012 at 3:09:24 PM

Remove All CVS Id Strings Possible Using a Script

Script does what is expected and tries to do it as
smartly as possible.

+ remove occurrences of two blank comment lines

next to each other after Id string line removed.

+ remove entire comment blocks which only exited to

contain CVS Ids

+ If the processing left a blank line at the top of

a file, it was removed.

  • Property mode set to 100644
File size: 26.7 KB
Line 
1/*
2 *  COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
3 *
4 *  Modifications to support reference counting in the file system are
5 *  Copyright (c) 2012 embedded brains GmbH.
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.com/license/LICENSE.
10 */
11/**
12 * @file
13 *
14 * @ingroup rtems-rfs
15 *
16 * RTEMS File System Interface for RTEMS.
17 */
18
19#if HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include <inttypes.h>
24#include <stdlib.h>
25
26#if SIZEOF_MODE_T == 8
27#define PRIomode_t PRIo64
28#elif SIZEOF_MODE_T == 4
29#define PRIomode_t PRIo32
30#else
31#error "unsupport size of mode_t"
32#endif
33
34#include <rtems/rfs/rtems-rfs-file.h>
35#include <rtems/rfs/rtems-rfs-dir.h>
36#include <rtems/rfs/rtems-rfs-link.h>
37#include "rtems-rfs-rtems.h"
38
39static bool
40rtems_rfs_rtems_eval_perms (rtems_filesystem_eval_path_context_t *ctx,
41                            int eval_flags,
42                            rtems_rfs_inode_handle* inode)
43{
44  return rtems_filesystem_eval_path_check_access(
45    ctx,
46    eval_flags,
47    rtems_rfs_inode_get_mode (inode),
48    rtems_rfs_inode_get_uid (inode),
49    rtems_rfs_inode_get_gid (inode)
50  );
51}
52
53static rtems_filesystem_node_types_t
54rtems_rfs_rtems_node_type_by_inode (rtems_rfs_inode_handle* inode)
55{
56  /*
57   * Do not return RTEMS_FILESYSTEM_HARD_LINK because this would result in an
58   * eval link which does not make sense in the case of the RFS file
59   * system. All directory entries are links to an inode. A link such as a HARD
60   * link is actually the normal path to a regular file, directory, device
61   * etc's inode. Links to inodes can be considered "the real" one, yet they
62   * are all links.
63   */
64  uint16_t mode = rtems_rfs_inode_get_mode (inode);
65  if (RTEMS_RFS_S_ISDIR (mode))
66    return RTEMS_FILESYSTEM_DIRECTORY;
67  else if (RTEMS_RFS_S_ISLNK (mode))
68    return RTEMS_FILESYSTEM_SYM_LINK;
69  else if (RTEMS_RFS_S_ISBLK (mode) || RTEMS_RFS_S_ISCHR (mode))
70    return RTEMS_FILESYSTEM_DEVICE;
71  else
72    return RTEMS_FILESYSTEM_MEMORY_FILE;
73}
74
75static void
76rtems_rfs_rtems_lock_by_mt_entry (rtems_filesystem_mount_table_entry_t *mt_entry)
77{
78  rtems_rfs_file_system* fs = mt_entry->fs_info;
79
80  rtems_rfs_rtems_lock (fs);
81}
82
83static void
84rtems_rfs_rtems_unlock_by_mt_entry (rtems_filesystem_mount_table_entry_t *mt_entry)
85{
86  rtems_rfs_file_system* fs = mt_entry->fs_info;
87
88  rtems_rfs_rtems_unlock (fs);
89}
90
91static bool
92rtems_rfs_rtems_is_directory(
93  rtems_filesystem_eval_path_context_t *ctx,
94  void *arg
95)
96{
97  rtems_rfs_inode_handle* inode = arg;
98
99  return rtems_rfs_rtems_node_type_by_inode (inode)
100    == RTEMS_FILESYSTEM_DIRECTORY;
101}
102
103static void rtems_rfs_rtems_follow_link(
104  rtems_filesystem_eval_path_context_t* ctx,
105  rtems_rfs_file_system* fs,
106  rtems_rfs_ino ino
107)
108{
109  size_t len = MAXPATHLEN;
110  char *link = malloc(len + 1);
111
112  if (link != NULL) {
113    int rc = rtems_rfs_symlink_read (fs, ino, link, len, &len);
114
115    if (rc == 0) {
116      rtems_filesystem_eval_path_recursive (ctx, link, len);
117    } else {
118      rtems_filesystem_eval_path_error (ctx, 0);
119    }
120
121    free(link);
122  } else {
123    rtems_filesystem_eval_path_error (ctx, ENOMEM);
124  }
125}
126
127static rtems_filesystem_eval_path_generic_status
128rtems_rfs_rtems_eval_token(
129  rtems_filesystem_eval_path_context_t *ctx,
130  void *arg,
131  const char *token,
132  size_t tokenlen
133)
134{
135  rtems_filesystem_eval_path_generic_status status =
136    RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
137  rtems_rfs_inode_handle* inode = arg;
138  bool access_ok = rtems_rfs_rtems_eval_perms (ctx, RTEMS_FS_PERMS_EXEC, inode);
139
140  if (access_ok) {
141    if (rtems_filesystem_is_current_directory (token, tokenlen)) {
142      rtems_filesystem_eval_path_clear_token (ctx);
143    } else {
144      rtems_filesystem_location_info_t *currentloc =
145        rtems_filesystem_eval_path_get_currentloc( ctx );
146      rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (currentloc);
147      rtems_rfs_ino entry_ino;
148      uint32_t entry_doff;
149      int rc = rtems_rfs_dir_lookup_ino (
150        fs,
151        inode,
152        token,
153        tokenlen,
154        &entry_ino,
155        &entry_doff
156      );
157
158      if (rc == 0) {
159        rc = rtems_rfs_inode_close (fs, inode);
160        if (rc == 0) {
161          rc = rtems_rfs_inode_open (fs, entry_ino, inode, true);
162        }
163
164        if (rc != 0) {
165          /*
166           * This prevents the rtems_rfs_inode_close() from doing something in
167           * rtems_rfs_rtems_eval_path().
168           */
169          memset (inode, 0, sizeof(*inode));
170        }
171      } else {
172        status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY;
173        rc = -1;
174      }
175
176      if (rc == 0) {
177        bool is_sym_link = rtems_rfs_rtems_node_type_by_inode (inode)
178          == RTEMS_FILESYSTEM_SYM_LINK;
179        int eval_flags = rtems_filesystem_eval_path_get_flags (ctx);
180        bool follow_sym_link = (eval_flags & RTEMS_FS_FOLLOW_SYM_LINK) != 0;
181        bool terminal = !rtems_filesystem_eval_path_has_path (ctx);
182
183        rtems_filesystem_eval_path_clear_token (ctx);
184
185        if (is_sym_link && (follow_sym_link || !terminal)) {
186          rtems_rfs_rtems_follow_link (ctx, fs, entry_ino);
187        } else {
188          rc = rtems_rfs_rtems_set_handlers (currentloc, inode) ? 0 : EIO;
189          if (rc == 0) {
190            rtems_rfs_rtems_set_pathloc_ino (currentloc, entry_ino);
191            rtems_rfs_rtems_set_pathloc_doff (currentloc, entry_doff);
192
193            if (!terminal) {
194              status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE;
195            }
196          } else {
197            rtems_filesystem_eval_path_error (
198              ctx,
199              rtems_rfs_rtems_error ("eval_path: set handlers", rc)
200            );
201          }
202        }
203      }
204    }
205  }
206
207  return status;
208}
209
210static const rtems_filesystem_eval_path_generic_config
211rtems_rfs_rtems_eval_config = {
212  .is_directory = rtems_rfs_rtems_is_directory,
213  .eval_token = rtems_rfs_rtems_eval_token
214};
215
216static void
217rtems_rfs_rtems_eval_path (rtems_filesystem_eval_path_context_t *ctx)
218{
219  rtems_filesystem_location_info_t *currentloc =
220    rtems_filesystem_eval_path_get_currentloc (ctx);
221  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (currentloc);
222  rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (currentloc);
223  rtems_rfs_inode_handle inode;
224  int rc;
225
226  rc = rtems_rfs_inode_open (fs, ino, &inode, true);
227  if (rc == 0) {
228    rtems_filesystem_eval_path_generic (
229      ctx,
230      &inode,
231      &rtems_rfs_rtems_eval_config
232    );
233    rc = rtems_rfs_inode_close (fs, &inode);
234    if (rc != 0) {
235      rtems_filesystem_eval_path_error (
236        ctx,
237        rtems_rfs_rtems_error ("eval_path: closing inode", rc)
238      );
239    }
240  } else {
241    rtems_filesystem_eval_path_error (
242      ctx,
243      rtems_rfs_rtems_error ("eval_path: opening inode", rc)
244    );
245  }
246}
247
248/**
249 * The following rouine creates a new link node under parent with the name
250 * given in name. The link node is set to point to the node at targetloc.
251 */
252static int
253rtems_rfs_rtems_link (const rtems_filesystem_location_info_t *parentloc,
254                      const rtems_filesystem_location_info_t *targetloc,
255                      const char *name,
256                      size_t namelen)
257{
258  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (targetloc);
259  rtems_rfs_ino          target = rtems_rfs_rtems_get_pathloc_ino (targetloc);
260  rtems_rfs_ino          parent = rtems_rfs_rtems_get_pathloc_ino (parentloc);
261  int                    rc;
262
263  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_LINK))
264    printf ("rtems-rfs-rtems: link: in: parent:%" PRId32 " target:%" PRId32 "\n",
265            parent, target);
266
267  rc = rtems_rfs_link (fs, name, namelen, parent, target, false);
268  if (rc)
269  {
270    return rtems_rfs_rtems_error ("link: linking", rc);
271        }
272
273
274        return 0;
275}
276
277/**
278 * The following verifies that and returns the type of node that the loc refers
279 * to.
280 *
281 * @param pathloc
282 * @return rtems_filesystem_node_types_t
283 */
284
285static rtems_filesystem_node_types_t
286rtems_rfs_rtems_node_type (const rtems_filesystem_location_info_t* pathloc)
287{
288  rtems_rfs_file_system*        fs = rtems_rfs_rtems_pathloc_dev (pathloc);
289  rtems_rfs_ino                 ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
290  rtems_filesystem_node_types_t type;
291  rtems_rfs_inode_handle        inode;
292  int                           rc;
293
294  rc = rtems_rfs_inode_open (fs, ino, &inode, true);
295  if (rc > 0)
296  {
297    return rtems_rfs_rtems_error ("node_type: opening inode", rc);
298  }
299
300  type = rtems_rfs_rtems_node_type_by_inode (&inode);
301
302  rc = rtems_rfs_inode_close (fs, &inode);
303  if (rc > 0)
304  {
305    return rtems_rfs_rtems_error ("node_type: closing inode", rc);
306  }
307
308  return type;
309}
310
311/**
312 * This routine is the implementation of the chown() system call for the
313 * RFS.
314 *
315 * @param pathloc
316 * @param owner
317 * @param group
318 * return int
319 */
320
321static int
322rtems_rfs_rtems_chown (const rtems_filesystem_location_info_t *pathloc,
323                       uid_t                                   owner,
324                       gid_t                                   group)
325{
326  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
327  rtems_rfs_ino          ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
328  rtems_rfs_inode_handle inode;
329#if defined (RTEMS_POSIX_API)
330  uid_t                  uid;
331#endif
332  int                    rc;
333
334  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_CHOWN))
335    printf ("rtems-rfs-rtems: chown: in: ino:%" PRId32 " uid:%d gid:%d\n",
336            ino, owner, group);
337
338  rc = rtems_rfs_inode_open (fs, ino, &inode, true);
339  if (rc > 0)
340  {
341    return rtems_rfs_rtems_error ("chown: opening inode", rc);
342  }
343
344  /*
345   *  Verify I am the owner of the node or the super user.
346   */
347
348#if defined (RTEMS_POSIX_API)
349  uid = geteuid();
350
351  if ((uid != rtems_rfs_inode_get_uid (&inode)) && (uid != 0))
352  {
353    rtems_rfs_inode_close (fs, &inode);
354    return rtems_rfs_rtems_error ("chown: not able", EPERM);
355  }
356#endif
357
358  rtems_rfs_inode_set_uid_gid (&inode, owner, group);
359
360  rc = rtems_rfs_inode_close (fs, &inode);
361  if (rc)
362  {
363    return rtems_rfs_rtems_error ("chown: closing inode", rc);
364  }
365
366  return 0;
367}
368
369/**
370 * This routine is the implementation of the utime() system call for the
371 * RFS.
372 *
373 * @param pathloc
374 * @param atime
375 * @param mtime
376 * return int
377 */
378
379static int
380rtems_rfs_rtems_utime(const rtems_filesystem_location_info_t* pathloc,
381                      time_t                                  atime,
382                      time_t                                  mtime)
383{
384  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
385  rtems_rfs_ino          ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
386  rtems_rfs_inode_handle inode;
387  int                    rc;
388
389  rc = rtems_rfs_inode_open (fs, ino, &inode, true);
390  if (rc)
391  {
392    return rtems_rfs_rtems_error ("utime: read inode", rc);
393  }
394
395  rtems_rfs_inode_set_atime (&inode, atime);
396  rtems_rfs_inode_set_mtime (&inode, mtime);
397
398  rc = rtems_rfs_inode_close (fs, &inode);
399  if (rc)
400  {
401    return rtems_rfs_rtems_error ("utime: closing inode", rc);
402  }
403
404  return 0;
405}
406
407/**
408 * The following routine creates a new symbolic link node under parent with the
409 * name given in node_name.
410 */
411
412static int
413rtems_rfs_rtems_symlink (const rtems_filesystem_location_info_t* parent_loc,
414                         const char*                             node_name,
415                         size_t                                  node_name_len,
416                         const char*                             target)
417{
418  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (parent_loc);
419  rtems_rfs_ino          parent = rtems_rfs_rtems_get_pathloc_ino (parent_loc);
420  int                    rc;
421
422  rc = rtems_rfs_symlink (fs, node_name, node_name_len,
423                          target, strlen (target),
424                          geteuid(), getegid(), parent);
425  if (rc)
426  {
427    return rtems_rfs_rtems_error ("symlink: linking", rc);
428  }
429
430  return 0;
431}
432
433/**
434 * The following rouine puts the symblic links destination name into buf.
435 */
436
437static ssize_t
438rtems_rfs_rtems_readlink (const rtems_filesystem_location_info_t* pathloc,
439                          char*                                   buf,
440                          size_t                                  bufsize)
441{
442  rtems_rfs_file_system*  fs = rtems_rfs_rtems_pathloc_dev (pathloc);
443  rtems_rfs_ino           ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
444  size_t                  length;
445  int                     rc;
446
447  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_READLINK))
448    printf ("rtems-rfs-rtems: readlink: in: ino:%" PRId32 "\n", ino);
449
450  rc = rtems_rfs_symlink_read (fs, ino, buf, bufsize, &length);
451  if (rc)
452  {
453    return rtems_rfs_rtems_error ("readlink: reading link", rc);
454  }
455
456  return (ssize_t) length;
457}
458
459static int
460rtems_rfs_rtems_fchmod (const rtems_filesystem_location_info_t* pathloc,
461                        mode_t                                  mode)
462{
463  rtems_rfs_file_system*  fs = rtems_rfs_rtems_pathloc_dev (pathloc);
464  rtems_rfs_ino           ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
465  rtems_rfs_inode_handle  inode;
466  uint16_t                imode;
467#if defined (RTEMS_POSIX_API)
468  uid_t                   uid;
469#endif
470  int                     rc;
471
472  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FCHMOD))
473    printf ("rtems-rfs-rtems: fchmod: in: ino:%" PRId32 " mode:%06" PRIomode_t "\n",
474            ino, mode);
475
476  rc = rtems_rfs_inode_open (fs, ino, &inode, true);
477  if (rc)
478  {
479    return rtems_rfs_rtems_error ("fchmod: opening inode", rc);
480  }
481
482  imode = rtems_rfs_inode_get_mode (&inode);
483
484  /*
485   *  Verify I am the owner of the node or the super user.
486   */
487#if defined (RTEMS_POSIX_API)
488  uid = geteuid();
489
490  if ((uid != rtems_rfs_inode_get_uid (&inode)) && (uid != 0))
491  {
492    rtems_rfs_inode_close (fs, &inode);
493    return rtems_rfs_rtems_error ("fchmod: checking uid", EPERM);
494  }
495#endif
496
497  imode &= ~(S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX);
498  imode |= mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX);
499
500  rtems_rfs_inode_set_mode (&inode, imode);
501
502  rc = rtems_rfs_inode_close (fs, &inode);
503  if (rc > 0)
504  {
505    return rtems_rfs_rtems_error ("fchmod: closing inode", rc);
506  }
507
508  return 0;
509}
510
511int
512rtems_rfs_rtems_fstat (const rtems_filesystem_location_info_t* pathloc,
513                       struct stat*                            buf)
514{
515  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
516  rtems_rfs_ino          ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
517  rtems_rfs_inode_handle inode;
518  rtems_rfs_file_shared* shared;
519  uint16_t               mode;
520  int                    rc;
521
522  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_STAT))
523    printf ("rtems-rfs-rtems: stat: in: ino:%" PRId32 "\n", ino);
524
525  rc = rtems_rfs_inode_open (fs, ino, &inode, true);
526  if (rc)
527  {
528    return rtems_rfs_rtems_error ("stat: opening inode", rc);
529  }
530
531  mode = rtems_rfs_inode_get_mode (&inode);
532
533  if (RTEMS_RFS_S_ISCHR (mode) || RTEMS_RFS_S_ISBLK (mode))
534  {
535    buf->st_rdev =
536      rtems_filesystem_make_dev_t (rtems_rfs_inode_get_block (&inode, 0),
537                                   rtems_rfs_inode_get_block (&inode, 1));
538  }
539
540  buf->st_dev     = rtems_rfs_fs_device (fs);
541  buf->st_ino     = rtems_rfs_inode_ino (&inode);
542  buf->st_mode    = rtems_rfs_rtems_mode (mode);
543  buf->st_nlink   = rtems_rfs_inode_get_links (&inode);
544  buf->st_uid     = rtems_rfs_inode_get_uid (&inode);
545  buf->st_gid     = rtems_rfs_inode_get_gid (&inode);
546
547  /*
548   * Need to check is the ino is an open file. If so we take the values from
549   * the open file rather than the inode.
550   */
551  shared = rtems_rfs_file_get_shared (fs, rtems_rfs_inode_ino (&inode));
552
553  if (shared)
554  {
555    buf->st_atime   = rtems_rfs_file_shared_get_atime (shared);
556    buf->st_mtime   = rtems_rfs_file_shared_get_mtime (shared);
557    buf->st_ctime   = rtems_rfs_file_shared_get_ctime (shared);
558    buf->st_blocks  = rtems_rfs_file_shared_get_block_count (shared);
559
560    if (S_ISLNK (buf->st_mode))
561      buf->st_size = rtems_rfs_file_shared_get_block_offset (shared);
562    else
563      buf->st_size = rtems_rfs_file_shared_get_size (fs, shared);
564  }
565  else
566  {
567    buf->st_atime   = rtems_rfs_inode_get_atime (&inode);
568    buf->st_mtime   = rtems_rfs_inode_get_mtime (&inode);
569    buf->st_ctime   = rtems_rfs_inode_get_ctime (&inode);
570    buf->st_blocks  = rtems_rfs_inode_get_block_count (&inode);
571
572    if (S_ISLNK (buf->st_mode))
573      buf->st_size = rtems_rfs_inode_get_block_offset (&inode);
574    else
575      buf->st_size = rtems_rfs_inode_get_size (fs, &inode);
576  }
577
578  buf->st_blksize = rtems_rfs_fs_block_size (fs);
579
580  rc = rtems_rfs_inode_close (fs, &inode);
581  if (rc > 0)
582  {
583    return rtems_rfs_rtems_error ("stat: closing inode", rc);
584  }
585
586  return 0;
587}
588
589/**
590 * Routine to create a node in the RFS file system.
591 */
592
593static int
594rtems_rfs_rtems_mknod (const rtems_filesystem_location_info_t *parentloc,
595                       const char                             *name,
596                       size_t                                  namelen,
597                       mode_t                                  mode,
598                       dev_t                                   dev)
599{
600  rtems_rfs_file_system*  fs = rtems_rfs_rtems_pathloc_dev (parentloc);
601  rtems_rfs_ino           parent = rtems_rfs_rtems_get_pathloc_ino (parentloc);
602  rtems_rfs_ino           ino;
603  rtems_rfs_inode_handle  inode;
604  uid_t                   uid;
605  gid_t                   gid;
606  int                     rc;
607
608#if defined(RTEMS_POSIX_API)
609  uid = geteuid ();
610  gid = getegid ();
611#else
612  uid = 0;
613  gid = 0;
614#endif
615
616  rc = rtems_rfs_inode_create (fs, parent, name, namelen,
617                               rtems_rfs_rtems_imode (mode),
618                               1, uid, gid, &ino);
619  if (rc > 0)
620  {
621    return rtems_rfs_rtems_error ("mknod: inode create", rc);
622  }
623
624  rc = rtems_rfs_inode_open (fs, ino, &inode, true);
625  if (rc > 0)
626  {
627    return rtems_rfs_rtems_error ("mknod: inode open", rc);
628  }
629
630  if (S_ISDIR(mode) || S_ISREG(mode))
631  {
632  }
633  else if (S_ISCHR (mode) || S_ISBLK (mode))
634  {
635    int major;
636    int minor;
637    rtems_filesystem_split_dev_t (dev, major, minor);
638    rtems_rfs_inode_set_block (&inode, 0, major);
639    rtems_rfs_inode_set_block (&inode, 1, minor);
640  }
641  else
642  {
643    rtems_rfs_inode_close (fs, &inode);
644    return rtems_rfs_rtems_error ("mknod: bad mode", EINVAL);
645  }
646
647  rc = rtems_rfs_inode_close (fs, &inode);
648  if (rc > 0)
649  {
650    return rtems_rfs_rtems_error ("mknod: closing inode", rc);
651  }
652
653  return 0;
654}
655
656/**
657 * Routine to remove a node from the RFS file system.
658 *
659 * @param parent_pathloc
660 * @param pathloc
661 * @return int
662 */
663int
664rtems_rfs_rtems_rmnod (const rtems_filesystem_location_info_t* parent_pathloc,
665                       const rtems_filesystem_location_info_t* pathloc)
666{
667  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
668  rtems_rfs_ino          parent = rtems_rfs_rtems_get_pathloc_ino (parent_pathloc);
669  rtems_rfs_ino          ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
670  uint32_t               doff = rtems_rfs_rtems_get_pathloc_doff (pathloc);
671  int                    rc;
672
673  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_RMNOD))
674    printf ("rtems-rfs: rmnod: parent:%" PRId32 " doff:%" PRIu32 ", ino:%" PRId32 "\n",
675            parent, doff, ino);
676
677  if (ino == RTEMS_RFS_ROOT_INO)
678    return rtems_rfs_rtems_error ("rmnod: root inode", EBUSY);
679
680  rc = rtems_rfs_unlink (fs, parent, ino, doff, rtems_rfs_unlink_dir_if_empty);
681  if (rc)
682  {
683    return rtems_rfs_rtems_error ("rmnod: unlinking", rc);
684  }
685
686  return 0;
687}
688
689/**
690 * The following routine does a sync on an inode node. Currently it flushes
691 * everything related to this device.
692 *
693 * @param iop
694 * @return int
695 */
696int
697rtems_rfs_rtems_fdatasync (rtems_libio_t* iop)
698{
699  int rc;
700
701  rc = rtems_rfs_buffer_sync (rtems_rfs_rtems_pathloc_dev (&iop->pathinfo));
702  if (rc)
703    return rtems_rfs_rtems_error ("fdatasync: sync", rc);
704
705  return 0;
706}
707
708/**
709 * Rename the node.
710 */
711static int
712rtems_rfs_rtems_rename(const rtems_filesystem_location_info_t* old_parent_loc,
713                       const rtems_filesystem_location_info_t* old_loc,
714                       const rtems_filesystem_location_info_t* new_parent_loc,
715                       const char*                             new_name,
716                       size_t                                  new_name_len)
717{
718  rtems_rfs_file_system*  fs = rtems_rfs_rtems_pathloc_dev (old_loc);
719  rtems_rfs_ino           old_parent;
720  rtems_rfs_ino           new_parent;
721  rtems_rfs_ino           ino;
722  uint32_t                doff;
723  int                     rc;
724
725  old_parent = rtems_rfs_rtems_get_pathloc_ino (old_parent_loc);
726  new_parent = rtems_rfs_rtems_get_pathloc_ino (new_parent_loc);
727
728  ino  = rtems_rfs_rtems_get_pathloc_ino (old_loc);
729  doff = rtems_rfs_rtems_get_pathloc_doff (old_loc);
730
731  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_RENAME))
732    printf ("rtems-rfs: rename: ino:%" PRId32 " doff:%" PRIu32 ", new parent:%" PRId32 "\n",
733            ino, doff, new_parent);
734
735  /*
736   * Link to the inode before unlinking so the inode is not erased when
737   * unlinked.
738   */
739  rc = rtems_rfs_link (fs, new_name, new_name_len, new_parent, ino, true);
740  if (rc)
741  {
742    return rtems_rfs_rtems_error ("rename: linking", rc);
743  }
744
745  /*
746   * Unlink all inodes even directories with the dir option as false because a
747   * directory may not be empty.
748   */
749  rc = rtems_rfs_unlink (fs, old_parent, ino, doff,
750                         rtems_rfs_unlink_dir_allowed);
751  if (rc)
752  {
753    return rtems_rfs_rtems_error ("rename: unlinking", rc);
754  }
755
756  return 0;
757}
758
759/**
760 * Return the file system stat data.
761 *
762 * @param pathloc
763 * @param sb
764 * @return int
765 */
766static int
767rtems_rfs_rtems_statvfs (const rtems_filesystem_location_info_t* pathloc,
768                         struct statvfs*                         sb)
769{
770  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
771  size_t                 blocks;
772  size_t                 inodes;
773
774  rtems_rfs_group_usage (fs, &blocks, &inodes);
775
776  sb->f_bsize   = rtems_rfs_fs_block_size (fs);
777  sb->f_frsize  = rtems_rfs_fs_media_block_size (fs);
778  sb->f_blocks  = rtems_rfs_fs_media_blocks (fs);
779  sb->f_bfree   = rtems_rfs_fs_blocks (fs) - blocks;
780  sb->f_bavail  = sb->f_bfree;
781  sb->f_files   = rtems_rfs_fs_inodes (fs);
782  sb->f_ffree   = rtems_rfs_fs_inodes (fs) - inodes;
783  sb->f_favail  = sb->f_ffree;
784  sb->f_fsid    = RTEMS_RFS_SB_MAGIC;
785  sb->f_flag    = rtems_rfs_fs_flags (fs);
786  sb->f_namemax = rtems_rfs_fs_max_name (fs);
787
788  return 0;
789}
790
791/**
792 *  Handler table for RFS link nodes
793 */
794const rtems_filesystem_file_handlers_r rtems_rfs_rtems_link_handlers =
795{
796  .open_h      = rtems_filesystem_default_open,
797  .close_h     = rtems_filesystem_default_close,
798  .read_h      = rtems_filesystem_default_read,
799  .write_h     = rtems_filesystem_default_write,
800  .ioctl_h     = rtems_filesystem_default_ioctl,
801  .lseek_h     = rtems_filesystem_default_lseek,
802  .fstat_h     = rtems_rfs_rtems_fstat,
803  .ftruncate_h = rtems_filesystem_default_ftruncate,
804  .fsync_h     = rtems_filesystem_default_fsync_or_fdatasync,
805  .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
806  .fcntl_h     = rtems_filesystem_default_fcntl
807};
808
809/**
810 * Forward decl for the ops table.
811 */
812
813int rtems_rfs_rtems_initialise (rtems_filesystem_mount_table_entry_t *mt_entry,
814                                const void                           *data);
815void rtems_rfs_rtems_shutdown (rtems_filesystem_mount_table_entry_t *mt_entry);
816
817/**
818 * RFS file system operations table.
819 */
820const rtems_filesystem_operations_table rtems_rfs_ops =
821{
822  .lock_h         = rtems_rfs_rtems_lock_by_mt_entry,
823  .unlock_h       = rtems_rfs_rtems_unlock_by_mt_entry,
824  .are_nodes_equal_h = rtems_filesystem_default_are_nodes_equal,
825  .eval_path_h    = rtems_rfs_rtems_eval_path,
826  .link_h         = rtems_rfs_rtems_link,
827  .node_type_h    = rtems_rfs_rtems_node_type,
828  .fchmod_h       = rtems_rfs_rtems_fchmod,
829  .mknod_h        = rtems_rfs_rtems_mknod,
830  .rmnod_h        = rtems_rfs_rtems_rmnod,
831  .chown_h        = rtems_rfs_rtems_chown,
832  .clonenod_h     = rtems_filesystem_default_clonenode,
833  .freenod_h      = rtems_filesystem_default_freenode,
834  .mount_h        = rtems_filesystem_default_mount,
835  .fsmount_me_h   = rtems_rfs_rtems_initialise,
836  .unmount_h      = rtems_filesystem_default_unmount,
837  .fsunmount_me_h = rtems_rfs_rtems_shutdown,
838  .utime_h        = rtems_rfs_rtems_utime,
839  .symlink_h      = rtems_rfs_rtems_symlink,
840  .readlink_h     = rtems_rfs_rtems_readlink,
841  .rename_h       = rtems_rfs_rtems_rename,
842  .statvfs_h      = rtems_rfs_rtems_statvfs
843};
844
845/**
846 * Open the file system.
847 */
848
849int
850rtems_rfs_rtems_initialise (rtems_filesystem_mount_table_entry_t* mt_entry,
851                            const void*                           data)
852{
853  rtems_rfs_rtems_private* rtems;
854  rtems_rfs_file_system*   fs;
855  uint32_t                 flags = 0;
856  uint32_t                 max_held_buffers = RTEMS_RFS_FS_MAX_HELD_BUFFERS;
857  const char*              options = data;
858  int                      rc;
859
860  /*
861   * Parse the options the user specifiies.
862   */
863  while (options)
864  {
865    printf ("options=%s\n", options);
866    if (strncmp (options, "hold-bitmaps",
867                 sizeof ("hold-bitmaps") - 1) == 0)
868      flags |= RTEMS_RFS_FS_BITMAPS_HOLD;
869    else if (strncmp (options, "no-local-cache",
870                      sizeof ("no-local-cache") - 1) == 0)
871      flags |= RTEMS_RFS_FS_NO_LOCAL_CACHE;
872    else if (strncmp (options, "max-held-bufs",
873                      sizeof ("max-held-bufs") - 1) == 0)
874    {
875      max_held_buffers = strtoul (options + sizeof ("max-held-bufs"), 0, 0);
876    }
877    else
878      return rtems_rfs_rtems_error ("initialise: invalid option", EINVAL);
879
880    options = strchr (options, ',');
881    if (options)
882    {
883      ++options;
884      if (*options == '\0')
885        options = NULL;
886    }
887  }
888
889  rtems = malloc (sizeof (rtems_rfs_rtems_private));
890  if (!rtems)
891    return rtems_rfs_rtems_error ("initialise: local data", ENOMEM);
892
893  memset (rtems, 0, sizeof (rtems_rfs_rtems_private));
894
895  rc = rtems_rfs_mutex_create (&rtems->access);
896  if (rc > 0)
897  {
898    free (rtems);
899    return rtems_rfs_rtems_error ("initialise: cannot create mutex", rc);
900  }
901
902  rc = rtems_rfs_mutex_lock (&rtems->access);
903  if (rc > 0)
904  {
905    rtems_rfs_mutex_destroy (&rtems->access);
906    free (rtems);
907    return rtems_rfs_rtems_error ("initialise: cannot lock access  mutex", rc);
908  }
909
910  rc = rtems_rfs_fs_open (mt_entry->dev, rtems, flags, max_held_buffers, &fs);
911  if (rc)
912  {
913    free (rtems);
914    return rtems_rfs_rtems_error ("initialise: open", rc);
915  }
916
917  mt_entry->fs_info = fs;
918
919  mt_entry->mt_fs_root->location.node_access = (void*) RTEMS_RFS_ROOT_INO;
920  mt_entry->mt_fs_root->location.handlers    = &rtems_rfs_rtems_dir_handlers;
921  mt_entry->mt_fs_root->location.ops         = &rtems_rfs_ops;
922
923  rtems_rfs_rtems_unlock (fs);
924
925  return 0;
926}
927
928/**
929 * Shutdown the file system.
930 */
931void
932rtems_rfs_rtems_shutdown (rtems_filesystem_mount_table_entry_t* mt_entry)
933{
934  rtems_rfs_file_system*   fs = mt_entry->fs_info;
935  rtems_rfs_rtems_private* rtems;
936
937  rtems = rtems_rfs_fs_user (fs);
938
939  /* FIXME: Return value? */
940  rtems_rfs_fs_close(fs);
941
942  rtems_rfs_mutex_destroy (&rtems->access);
943  free (rtems);
944}
Note: See TracBrowser for help on using the repository browser.