source: rtems/cpukit/libfs/src/rfs/rtems-rfs-inode.c @ a9fa9b7

4.104.11
Last change on this file since a9fa9b7 was a9fa9b7, checked in by Chris Johns <chrisj@…>, on Feb 18, 2010 at 12:24:25 AM

2010-02-18 Chris Johns <chrisj@…>

  • libfs/src/rfs/rtems-rfs-bitmaps.c, libfs/src/rfs/rtems-rfs-bitmaps.h, libfs/src/rfs/rtems-rfs-bitmaps-ut.c, libfs/src/rfs/rtems-rfs-block.c, libfs/src/rfs/rtems-rfs-block.h, libfs/src/rfs/rtems-rfs-block-pos.h, libfs/src/rfs/rtems-rfs-buffer-bdbuf.c, libfs/src/rfs/rtems-rfs-buffer.c, libfs/src/rfs/rtems-rfs-buffer-devio.c, libfs/src/rfs/rtems-rfs-buffer.h, libfs/src/rfs/rtems-rfs-data.h, libfs/src/rfs/rtems-rfs-dir.c, libfs/src/rfs/rtems-rfs-dir.h, libfs/src/rfs/rtems-rfs-dir-hash.c, libfs/src/rfs/rtems-rfs-dir-hash.h, libfs/src/rfs/rtems-rfs-file.c, libfs/src/rfs/rtems-rfs-file.h, libfs/src/rfs/rtems-rfs-file-system.c, libfs/src/rfs/rtems-rfs-file-system-fwd.h, libfs/src/rfs/rtems-rfs-file-system.h, libfs/src/rfs/rtems-rfs-format.c, libfs/src/rfs/rtems-rfs-format.h, libfs/src/rfs/rtems-rfs-group.c, libfs/src/rfs/rtems-rfs-group.h, libfs/src/rfs/rtems-rfs.h, libfs/src/rfs/rtems-rfs-inode.c, libfs/src/rfs/rtems-rfs-inode.h, libfs/src/rfs/rtems-rfs-link.c, libfs/src/rfs/rtems-rfs-link.h, libfs/src/rfs/rtems-rfs-mutex.c, libfs/src/rfs/rtems-rfs-mutex.h, libfs/src/rfs/rtems-rfs-rtems.c, libfs/src/rfs/rtems-rfs-rtems-dev.c, libfs/src/rfs/rtems-rfs-rtems-dir.c, libfs/src/rfs/rtems-rfs-rtems-file.c, libfs/src/rfs/rtems-rfs-rtems.h, libfs/src/rfs/rtems-rfs-rtems-utils.c, libfs/src/rfs/rtems-rfs-shell.c, libfs/src/rfs/rtems-rfs-shell.h, libfs/src/rfs/rtems-rfs-trace.c, libfs/src/rfs/rtems-rfs-trace.h: New.
  • Makefile.am, preinstall.am, libfs/Makefile.am, wrapup/Makefile.am: Updated with the RFS support.
  • libfs/README: Updated after 10 years.
  • libblock/src/flashdisk.c, libblock/src/nvdisk.c, libblock/src/ramdisk-driver.c: Updated to the new error reporting in libblock.
  • libmisc/shell/main_ls.c, libmisc/shell/print-ls.c: Fix printing the size in long mode.
  • libnetworking/nfs/bootp_subr.c, libnetworking/rtems/rtems_bootp.c, libnetworking/rtems/rtems_bsdnet_internal.h: Return the BOOTP/DHCP to the forever behaviour of 4.9 with the ability to call BOOTP and control the process if required.
  • Property mode set to 100644
File size: 9.8 KB
Line 
1/*
2 *  COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
3 *
4 *  The license and distribution terms for this file may be
5 *  found in the file LICENSE in this distribution or at
6 *  http://www.rtems.com/license/LICENSE.
7 *
8 *  $Id$
9 */
10/**
11 * @file
12 *
13 * @ingroup rtems-rfs
14 *
15 * RTEMS File Systems Inode Routines.
16 *
17 * These functions manage inodes in the RFS file system. An inode is part of a
18 * block that reside after the bitmaps in the group.
19 */
20
21#include <rtems/rfs/rtems-rfs-block.h>
22#include <rtems/rfs/rtems-rfs-file-system.h>
23#include <rtems/rfs/rtems-rfs-inode.h>
24#include <rtems/rfs/rtems-rfs-dir.h>
25
26int
27rtems_rfs_inode_alloc (rtems_rfs_file_system* fs,
28                       rtems_rfs_bitmap_bit   goal,
29                       rtems_rfs_ino*         ino)
30{
31  rtems_rfs_bitmap_bit bit;
32  int                  rc;
33  rc = rtems_rfs_group_bitmap_alloc (fs, goal, true, &bit);
34  *ino = bit;
35  return rc;
36}
37
38int
39rtems_rfs_inode_free (rtems_rfs_file_system* fs,
40                      rtems_rfs_ino          ino)
41{
42  rtems_rfs_bitmap_bit bit;
43  bit = ino;
44  return rtems_rfs_group_bitmap_free (fs, true, bit);
45}
46
47int
48rtems_rfs_inode_open (rtems_rfs_file_system*  fs,
49                      rtems_rfs_ino           ino,
50                      rtems_rfs_inode_handle* handle,
51                      bool                    load)
52{
53  int group;
54  int gino;
55  int index;
56  int rc;
57 
58  if (rtems_rfs_trace (RTEMS_RFS_TRACE_INODE_OPEN))
59    printf ("rtems-rfs: inode-open: ino: %lu\n", ino);
60
61  if (ino == RTEMS_RFS_EMPTY_INO)
62    return EINVAL;
63 
64  if ((ino - RTEMS_RFS_ROOT_INO) > rtems_rfs_fs_inodes (fs))
65    return EINVAL;
66 
67  handle->ino = ino;
68  handle->node = NULL;
69  handle->loads = 0;
70 
71  gino  = ino - RTEMS_RFS_ROOT_INO;
72  group = gino / fs->group_inodes;
73  gino  = gino % fs->group_inodes;
74  index = (gino / fs->inodes_per_block) + RTEMS_RFS_GROUP_INODE_BLOCK;
75
76  handle->offset = gino % fs->inodes_per_block;
77  handle->block  = rtems_rfs_group_block (&fs->groups[group], index);
78
79  rc = rtems_rfs_buffer_handle_open (fs, &handle->buffer);
80  if ((rc == 0) && load)
81    rc = rtems_rfs_inode_load (fs, handle);
82  return rc;
83}
84
85int
86rtems_rfs_inode_close (rtems_rfs_file_system*  fs,
87                       rtems_rfs_inode_handle* handle)
88{
89  int rc;
90
91  if (rtems_rfs_trace (RTEMS_RFS_TRACE_INODE_CLOSE))
92    printf ("rtems-rfs: inode-close: ino: %lu\n", handle->ino);
93
94  rc = rtems_rfs_inode_unload (fs, handle, true);
95
96  if ((rc == 0) && (handle->loads > 0))
97  {
98    if (rtems_rfs_trace (RTEMS_RFS_TRACE_INODE_CLOSE))
99      printf ("rtems-rfs: inode-close: bad loads number: %d\n",
100              handle->loads);
101    rc = EIO;
102  }
103 
104  handle->ino = 0;
105  return rc;
106}
107
108int
109rtems_rfs_inode_load (rtems_rfs_file_system*  fs,
110                      rtems_rfs_inode_handle* handle)
111{
112  if (rtems_rfs_trace (RTEMS_RFS_TRACE_INODE_LOAD))
113    printf ("rtems-rfs: inode-load: ino=%lu loads=%i loaded=%s\n",
114            handle->ino, handle->loads,
115            rtems_rfs_inode_is_loaded (handle) ? "yes" : "no");
116
117  /*
118   * An inode does not move so once loaded no need to do again.
119   */
120
121  if (!rtems_rfs_inode_is_loaded (handle))
122  {
123    int rc;
124   
125    rc = rtems_rfs_buffer_handle_request (fs,&handle->buffer,
126                                          handle->block, true);
127    if (rc > 0)
128      return rc;
129
130    handle->node = rtems_rfs_buffer_data (&handle->buffer);
131    handle->node += handle->offset;
132  }
133
134  handle->loads++;
135 
136  return 0;
137}
138
139int
140rtems_rfs_inode_unload (rtems_rfs_file_system*  fs,
141                        rtems_rfs_inode_handle* handle,
142                        bool                    update_ctime)
143{
144  int rc = 0;
145 
146  if (rtems_rfs_trace (RTEMS_RFS_TRACE_INODE_UNLOAD))
147    printf ("rtems-rfs: inode-unload: ino=%lu loads=%i loaded=%s\n",
148            handle->ino, handle->loads,
149            rtems_rfs_inode_is_loaded (handle) ? "yes" : "no");
150 
151  if (rtems_rfs_inode_is_loaded (handle))
152  {
153    if (handle->loads == 0)
154      return EIO;
155
156    handle->loads--;
157   
158    if (handle->loads == 0)
159    {
160      /*
161       * If the buffer is dirty it will be release. Also set the ctime.
162       */
163      if (rtems_rfs_buffer_dirty (&handle->buffer) && update_ctime)
164        rtems_rfs_inode_set_ctime (handle, time (NULL));
165      rc = rtems_rfs_buffer_handle_release (fs, &handle->buffer);
166      handle->node = NULL;
167    }
168  }
169 
170  return rc;
171}
172
173int
174rtems_rfs_inode_create (rtems_rfs_file_system*  fs,
175                        rtems_rfs_ino           parent,
176                        const char*             name,
177                        size_t                  length,
178                        uint16_t                mode,
179                        uint16_t                links,
180                        uid_t                   uid,
181                        gid_t                   gid,
182                        rtems_rfs_ino*          ino)
183{
184  rtems_rfs_inode_handle parent_inode;
185  rtems_rfs_inode_handle inode;
186  int                    rc;
187 
188  if (rtems_rfs_trace (RTEMS_RFS_TRACE_INODE_CREATE))
189  {
190    const char* type = "unknown";
191    int         c;
192    if (RTEMS_RFS_S_ISDIR (mode))
193      type = "dir";
194    else if (RTEMS_RFS_S_ISCHR (mode))
195      type = "char";
196    else if (RTEMS_RFS_S_ISBLK (mode))
197      type = "block";
198    else if (RTEMS_RFS_S_ISREG (mode))
199      type = "file";
200    else if (RTEMS_RFS_S_ISLNK (mode))
201      type = "link";
202    printf("rtems-rfs: inode-create: parent:%lu name:", parent);
203    for (c = 0; c < length; c++)
204      printf ("%c", name[c]);
205    printf (" type:%s mode:%04x (%03o)\n", type, mode, mode & ((1 << 10) - 1));
206  }
207
208  rc = rtems_rfs_inode_alloc (fs, parent, ino);
209  if (rc > 0)
210    return rc;
211
212  rc = rtems_rfs_inode_open (fs, *ino, &inode, true);
213  if (rc > 0)
214    return rc;
215
216  rc = rtems_rfs_inode_initialise (&inode, links, mode, uid, gid);
217  if (rc > 0)
218  {
219    rtems_rfs_inode_close (fs, &inode);
220    rtems_rfs_inode_free (fs, *ino);
221    return rc;
222  }
223
224  /*
225   * Only handle the specifics of a directory. Let caller handle the others.
226   */
227  if (RTEMS_RFS_S_ISDIR (mode))
228  {
229    rc = rtems_rfs_dir_add_entry (fs, &inode, ".", 1, *ino);
230    if (rc == 0)
231      rc = rtems_rfs_dir_add_entry (fs, &inode, "..", 2, parent);
232    if (rc > 0)
233    {
234      rtems_rfs_inode_delete (fs, &inode);
235      rtems_rfs_inode_close (fs, &inode);
236      return rc;
237    }
238  }
239
240  rc = rtems_rfs_inode_open (fs, parent, &parent_inode, true);
241  if (rc > 0)
242  {
243    rtems_rfs_inode_delete (fs, &inode);
244    rtems_rfs_inode_close (fs, &inode);
245    return rc;
246  }
247
248  rc = rtems_rfs_dir_add_entry (fs, &parent_inode, name, length, *ino);
249  if (rc > 0)
250  {
251    rtems_rfs_inode_delete (fs, &inode);
252    rtems_rfs_inode_close (fs, &inode);
253    rtems_rfs_inode_close (fs, &parent_inode);
254    return rc;
255  }
256
257  /*
258   * If the node is a directory update the parent link count as the
259   * new directory has the '..' link that points to the parent.
260   */
261  if (RTEMS_RFS_S_ISDIR (mode))
262    rtems_rfs_inode_set_links (&parent_inode,
263                               rtems_rfs_inode_get_links (&parent_inode) + 1);
264 
265  rc = rtems_rfs_inode_close (fs, &parent_inode);
266  if (rc > 0)
267  {
268    rtems_rfs_inode_delete (fs, &inode);
269    rtems_rfs_inode_close (fs, &inode);
270    return rc;
271  }
272
273  rc = rtems_rfs_inode_close (fs, &inode);
274  if (rc > 0)
275  {
276    rtems_rfs_inode_free (fs, *ino);
277    return rc;
278  }
279 
280  return 0;
281}
282
283int
284rtems_rfs_inode_delete (rtems_rfs_file_system*  fs,
285                        rtems_rfs_inode_handle* handle)
286{
287  int rc = 0;
288  if (rtems_rfs_inode_is_loaded (handle))
289  {
290    rtems_rfs_block_map map;
291
292    /*
293     * Free the ino number.
294     */
295    rc = rtems_rfs_inode_free (fs, handle->ino);
296    if (rc > 0)
297      return rc;
298   
299    /*
300     * Free the blocks the inode may have attached.
301     */
302    rc = rtems_rfs_block_map_open (fs, handle, &map);
303    if (rc == 0)
304    {
305      int rrc;
306      rrc = rtems_rfs_block_map_free_all (fs, &map);
307      rc = rtems_rfs_block_map_close (fs, &map);
308      if (rc > 0)
309        rrc = rc;
310      memset (handle->node, 0xff, sizeof (rtems_rfs_inode));
311      rtems_rfs_buffer_mark_dirty (&handle->buffer);
312      /*
313       * Do the release here to avoid the ctime field being set on a
314       * close. Also if there loads is greater then one then other loads
315       * active. Forcing the loads count to 0.
316       */
317      rc = rtems_rfs_buffer_handle_release (fs, &handle->buffer);
318      handle->loads = 0;
319      handle->node = NULL;
320    }
321  }
322  return rc;
323}
324
325int
326rtems_rfs_inode_initialise (rtems_rfs_inode_handle* handle,
327                            uint16_t                links,
328                            uint16_t                mode,
329                            uid_t                   uid,
330                            gid_t                   gid)
331{
332  int b;
333  rtems_rfs_inode_set_links (handle, links);
334  rtems_rfs_inode_set_flags (handle, 0);
335  rtems_rfs_inode_set_mode (handle,  mode);
336  rtems_rfs_inode_set_uid_gid (handle, uid, gid);
337  rtems_rfs_inode_set_block_offset (handle, 0);
338  rtems_rfs_inode_set_block_count (handle, 0);
339  for (b = 0; b < RTEMS_RFS_INODE_BLOCKS; b++)
340    rtems_rfs_inode_set_block (handle, b, 0);
341  rtems_rfs_inode_set_last_map_block (handle, 0);
342  rtems_rfs_inode_set_last_data_block (handle, 0);
343  return rtems_rfs_inode_time_stamp_now (handle, true, true);
344}
345
346int
347rtems_rfs_inode_time_stamp_now (rtems_rfs_inode_handle* handle,
348                                bool                    atime, 
349                                bool                    mtime)
350{
351  time_t now;
352  if (!rtems_rfs_inode_is_loaded (handle))
353    return ENXIO;
354  now = time (NULL);
355  if (atime)
356    rtems_rfs_inode_set_atime (handle, now);
357  if (mtime)
358    rtems_rfs_inode_set_mtime (handle, now);
359  return 0;
360}
361
362rtems_rfs_pos
363rtems_rfs_inode_get_size (rtems_rfs_file_system*  fs,
364                          rtems_rfs_inode_handle* handle)
365{
366  rtems_rfs_block_size size;
367  size.count = rtems_rfs_inode_get_block_count (handle);
368  size.offset = rtems_rfs_inode_get_block_offset (handle);
369  return rtems_rfs_block_get_size (fs, &size);
370}
Note: See TracBrowser for help on using the repository browser.