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

4.104.115
Last change on this file since 1d539c0 was 355b0544, checked in by Chris Johns <chrisj@…>, on 03/27/10 at 04:04:40

2010-03-27 Chris Johns <chrisj@…>

libfs/src/nfsclient/src/cexphelp.c,
libfs/src/nfsclient/src/dirutils.c,
libfs/src/nfsclient/src/nfs.modini.c,
libfs/src/nfsclient/src/nfsTest.c,
libfs/src/nfsclient/src/rpcio.c,
libfs/src/nfsclient/src/rpcio.modini.c,
libfs/src/nfsclient/src/sock_mbuf.c,
libfs/src/nfsclient/src/xdr_mbuf.c,
libfs/src/rfs/rtems-rfs-bitmaps-ut.c,
libfs/src/rfs/rtems-rfs-bitmaps.c,
libfs/src/rfs/rtems-rfs-block.c,
libfs/src/rfs/rtems-rfs-buffer-bdbuf.c,
libfs/src/rfs/rtems-rfs-buffer-devio.c,
libfs/src/rfs/rtems-rfs-buffer.c,
libfs/src/rfs/rtems-rfs-dir-hash.c, libfs/src/rfs/rtems-rfs-dir.c,
libfs/src/rfs/rtems-rfs-file-system.c,
libfs/src/rfs/rtems-rfs-file.c, libfs/src/rfs/rtems-rfs-format.c,
libfs/src/rfs/rtems-rfs-group.c, libfs/src/rfs/rtems-rfs-inode.c,
libfs/src/rfs/rtems-rfs-link.c, libfs/src/rfs/rtems-rfs-mutex.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-utils.c,
libfs/src/rfs/rtems-rfs-rtems.c, libfs/src/rfs/rtems-rfs-shell.c,
libfs/src/rfs/rtems-rfs-trace.c: Add HAVE_CONFIG_H support to let
files receive configure defines.

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