annotate gsm-fw/services/ffs/core.c @ 281:082d12a1651e

fc-fsio: single command invokation works
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Mon, 24 Feb 2014 07:44:33 +0000
parents 842c9fd828fd
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
211
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1 /******************************************************************************
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2 * Flash File System (ffs)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
3 * Idea, design and coding by Mads Meisner-Jensen, mmj@ti.com
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
4 *
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
5 * FFS core functions (not public)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
6 *
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
7 * $Id: core.c 1.156.1.13.1.1.1.50 Thu, 08 Jan 2004 15:05:23 +0100 tsj $
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
8 *
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
9 ******************************************************************************/
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
10
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
11 #include "ffs.h"
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
12 #include "core.h"
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
13 #include "drv.h"
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
14 #include "ffstrace.h"
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
15 #include "tmffs.h"
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
16 #include <string.h>
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
17 #include <limits.h>
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
18
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
19 /******************************************************************************
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
20 * Globals
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
21 ******************************************************************************/
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
22
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
23 struct fs_s fs;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
24 struct block_stat_s bstat[FFS_BLOCKS_MAX];
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
25
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
26 struct ffs_stats_s stats;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
27
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
28 // The following line is automatically expanded by the revision control
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
29 // system to make a unique ffs revision. The revision can be retrieved by
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
30 // ffs_query().
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
31
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
32 //$Format: "static const uint16 ffs_revision = ($ProjectMajorVersion$<<12)|(0x$ProjectMinorVersion$);"$
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
33 static const uint16 ffs_revision = (5<<12)|(0x56);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
34
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
35
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
36 /******************************************************************************
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
37 * Main Functions
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
38 ******************************************************************************/
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
39
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
40 // Create a new ffs object (object type is undefined)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
41 iref_t object_create(const char *name, const char *buf, int size, iref_t dir)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
42 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
43 iref_t i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
44 struct inode_s *ip;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
45 int realsize, namelength;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
46 offset_t offset;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
47 char *dataaddr;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
48 char is_journal;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
49 char name_copy[FFS_FILENAME_MAX + 1]; // NOTEME: make dynamic?
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
50
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
51 ttw(ttr(TTrObj, "ocr(%s){" NL, name));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
52 tw(tr(TR_BEGIN, TrObject, "object_create('%s', ?, %d, %d) {\n",
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
53 name, size, dir));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
54
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
55 // NOTEME: special case just for format()!?
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
56 if (dir == 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
57 namelength = ffs_strlen(name);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
58 else
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
59 namelength = is_filename(name);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
60
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
61 if (namelength < 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
62 tw(tr(TR_END, TrObject, "} %d\n", namelength));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
63 ttw(ttr(TTrObj, "} %d" NL, namelength));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
64 return namelength;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
65 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
66
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
67 is_journal = (name[0] == '.' && ffs_strcmp(name, FFS_JOURNAL_NAME) == 0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
68 if (is_journal)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
69 tw(tr(TR_FUNC, TrObject, "Journal file creation!\n"));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
70 else
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
71 if (buf == NULL && size > 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
72 tw(tr(TR_END, TrObject, "} %d\n", EFFS_INVALID));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
73 ttw(ttr(TTrObj, "} %d" NL, EFFS_INVALID));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
74 return EFFS_INVALID;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
75 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
76
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
77 // We don't write the data null_terminator if no data exists
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
78 realsize = namelength + 1 + size + (size > 0 ? 1 : 0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
79 fs.journal.size = realsize = atomalign(realsize);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
80
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
81 // We save the diri in the ram journal because this will be updated if
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
82 // chunk_alloc trigger a data_reclaim
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
83 fs.journal.diri = dir;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
84
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
85 // We have to make a local copy of name because name can be destroyed if
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
86 // it points into an object that is relocated by an ffs_data_reclaim.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
87 memcpy(name_copy, name, ffs_strlen(name) + 1);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
88
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
89 if ((i = chunk_alloc(realsize, is_journal, &offset)) < 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
90 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
91
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
92 ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
93
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
94 // Write filename including null-terminator
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
95 ffsdrv.write(addr2name(offset2addr(offset)), name_copy, namelength + 1);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
96
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
97 // Write data and null terminator. We null-terminate the data block,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
98 // such that blocks_fsck() can determine the amount of used data block
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
99 // space correctly. Note that we don't write null-terminator for objects
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
100 // with no data, e.g. empty files and directories.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
101 if (size > 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
102 dataaddr = addr2name(offset2addr(offset)) + namelength + 1;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
103 // Do NOT write data if we are creating the journal file --- it must
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
104 // be created as empty!
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
105 if (!is_journal)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
106 ffsdrv.write(dataaddr, buf, size);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
107 ffsdrv_write_byte(dataaddr + size, 0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
108 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
109
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
110 // Insert object in parent directory if this is not the root dir
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
111 if (dir != 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
112 fs.journal.diri = dir_traverse(fs.journal.diri, 0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
113 else
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
114 fs.journal.diri = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
115
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
116 tw(tr(TR_END, TrObject, "} %d\n", i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
117 ttw(ttr(TTrObj, "} %d" NL,i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
118
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
119 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
120 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
121
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
122 int file_read(const char *name, void *addr, int size)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
123 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
124 int size_read, object_size, total_read = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
125 iref_t i, dir;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
126 char *not_used;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
127 fd_t fdi;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
128
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
129 if (size < 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
130 return EFFS_INVALID;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
131
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
132 if ((i = object_lookup(name, &not_used, &dir)) < 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
133 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
134
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
135 if ((fdi = get_fdi(i)) >= 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
136 if (is_open_option(fs.fd[fdi].options, FFS_O_WRONLY))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
137 return EFFS_LOCKED;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
138
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
139 object_size = object_datasize(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
140
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
141 do {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
142 size_read = segment_read(i, (char*)addr + total_read,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
143 size - total_read, 0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
144 total_read += size_read;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
145 } while ((i = segment_next(i)) != 0 && size > total_read);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
146
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
147 // Did we read the comlete object?
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
148 if (object_size > size)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
149 return EFFS_FILETOOBIG;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
150
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
151 return total_read; // number of bytes read
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
152 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
153
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
154
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
155 int stream_read(fd_t fdi, void *src, int size)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
156 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
157 int offset, size_read = 0, copied = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
158 iref_t i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
159
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
160 if (!is_fd_valid(fdi))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
161 return EFFS_BADFD;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
162
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
163 if (!is_open_option(fs.fd[fdi].options, FFS_O_RDONLY))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
164 return EFFS_INVALID;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
165
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
166 if (src == NULL || size < 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
167 return EFFS_INVALID;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
168
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
169 // NOTEME: do this in another way?
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
170 // No data to read because fp is ad eof.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
171 if (fs.fd[fdi].fp >= fs.fd[fdi].size) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
172 tw(tr(TR_FUNC, TrObject, "eof(no data read)\n"));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
173 return 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
174 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
175
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
176 segfile_seek(fs.fd[fdi].seghead, fs.fd[fdi].fp, &i, &offset);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
177
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
178 // Read data from chunks or buffer until all data is read or eof is reach.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
179 do {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
180 if (is_offset_in_buf(fs.fd[fdi].fp, fdi)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
181 offset = fs.fd[fdi].fp - fs.fd[fdi].wfp;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
182 size_read = size - copied; // requested data that is left
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
183 // Saturate size to max left in buf or max left to eof
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
184 if (size_read > (fs.chunk_size_max - offset))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
185 size_read = fs.chunk_size_max - offset;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
186 if (size_read > (fs.fd[fdi].size - fs.fd[fdi].fp))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
187 size_read = fs.fd[fdi].size - fs.fd[fdi].fp;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
188
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
189 memcpy((char*)src + copied, fs.fd[fdi].buf + offset, size_read);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
190 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
191 else {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
192 // Data is only in the chunk
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
193 size_read = segment_read(i, (char*) src + copied,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
194 size - copied, offset);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
195 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
196
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
197 offset = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
198 fs.fd[fdi].fp += size_read;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
199 copied += size_read;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
200
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
201 if ((i = segment_next(i)) < 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
202 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
203
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
204 } while (copied != size && fs.fd[fdi].fp < fs.fd[fdi].size);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
205
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
206 if (copied == size) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
207 tw(tr(TR_FUNC, TrObject, "All requested data has been read\n"));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
208 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
209 if (fs.fd[fdi].fp >= fs.fd[fdi].size) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
210 tw(tr(TR_FUNC, TrObject, "eof\n"));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
211 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
212
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
213 return copied; // number of bytes read
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
214 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
215
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
216
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
217 int object_read(const char *name, char *buf, int size, int linkflag)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
218 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
219 iref_t i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
220 struct inode_s *ip;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
221 struct xstat_s stat;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
222 char *p;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
223
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
224 tw(tr(TR_BEGIN, TrObject, "object_read('%s', 0x%x, %d, %d) {\n",
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
225 name, buf, size, linkflag));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
226
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
227 if (buf == NULL || size < 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
228 tw(tr(TR_END, TrObject, "} %d\n", EFFS_INVALID));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
229 return EFFS_INVALID;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
230 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
231
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
232 i = object_stat(name, &stat, linkflag, 0, 0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
233 if (i < 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
234 tw(tr(TR_END, TrObject, "} %d\n", EFFS_NOTFOUND));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
235 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
236 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
237
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
238 ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
239
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
240 if (stat.size > size) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
241 tw(tr(TR_END, TrObject, "} %d\n", EFFS_FILETOOBIG));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
242 return EFFS_FILETOOBIG;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
243 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
244
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
245 // return error if called as readlink() and object is not a link
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
246 if (!is_object(ip, OT_LINK) && linkflag) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
247 tw(tr(TR_END, TrObject, "} %d\n", EFFS_INVALID));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
248 return EFFS_INVALID;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
249 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
250
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
251 // Even though the ffs architecture allows to have data in directory
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
252 // objects, we don't want to complicate matters, so we return an error
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
253 if (is_object(ip, OT_DIR) && !(fs.flags & FS_DIR_DATA)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
254 tw(tr(TR_END, TrObject, "} %d\n", EFFS_NOTAFILE));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
255 return EFFS_NOTAFILE;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
256 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
257
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
258 p = offset2addr(location2offset(ip->location));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
259 size = stat.size;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
260
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
261 p = addr2data(p, ip);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
262
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
263 // Copy data. NOTEME: Should be optimized!
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
264 while (size--)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
265 *buf++ = *p++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
266
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
267 tw(tr(TR_END, TrObject, "} %d\n", stat.size));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
268 return stat.size;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
269 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
270
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
271
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
272 // Convert an object data addres to pure data address
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
273 char *addr2data(const char *addr, const struct inode_s *ip)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
274 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
275 // OT_SEGMENT is pure data so it do not have any name to skip
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
276 if (!is_object(ip, OT_SEGMENT)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
277 while (*addr++)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
278 ;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
279 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
280
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
281 return (char *) addr;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
282 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
283
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
284 // Calculate exact size of file data; without filename and null terminator
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
285 // and without data null terminator and succeeding alignment padding.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
286 // NOTEME: Does this also work for empty files and directories?
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
287 int object_datasize(iref_t i)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
288 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
289 iref_t not_used;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
290 return segfile_seek(i, INT_MAX, &not_used, 0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
291 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
292
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
293 iref_t object_stat(const char *name, struct xstat_s *stat,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
294 int linkflag, int fdi, int extended)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
295 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
296 iref_t i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
297 fd_t other_fdi;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
298 struct inode_s *ip;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
299
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
300 tw(tr(TR_BEGIN, TrObject, "object_stat('%s', ?, %x, %d, %d) {\n",
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
301 name, linkflag, fdi, extended));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
302
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
303 if (stat == NULL) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
304 tw(tr(TR_END, TrObject, "} %d\n", EFFS_INVALID));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
305 return EFFS_INVALID;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
306 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
307
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
308 if (linkflag)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
309 i = object_lookup_once(name, 0, 0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
310 else if (name == 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
311 fdi -= FFS_FD_OFFSET;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
312 if (!is_fd_valid(fdi)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
313 tw(tr(TR_END, TrObject, "} %d\n", EFFS_BADFD));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
314 return EFFS_BADFD;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
315 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
316 i = fs.fd[fdi].seghead;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
317 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
318 else
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
319 i = object_lookup(name, 0, 0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
320
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
321 if (i > 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
322 ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
323 stat->type = ip->flags & OT_MASK;;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
324 stat->flags = ~ip->flags & OF_MASK;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
325 stat->inode = i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
326
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
327 // If the file is open so get the size from the file descriptor
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
328 if ((other_fdi = get_fdi(i)) >= 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
329 if (i == fs.fd[other_fdi].seghead) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
330 stat->size = fs.fd[other_fdi].size;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
331 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
332 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
333
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
334 else
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
335 stat->size = object_datasize(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
336
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
337 if (extended) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
338 stat->location = ip->location;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
339 stat->block = offset2block(location2offset(stat->location));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
340 stat->space = ip->size;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
341 while ((i = segment_next(i)) > 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
342 ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
343 stat->space += ip->size;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
344 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
345 stat->reserved = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
346 stat->sequence = ip->sequence;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
347 stat->updates = ip->updates;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
348 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
349 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
350
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
351 tw(tr(TR_END, TrObject, "} %d\n", i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
352
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
353 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
354 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
355
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
356
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
357 /******************************************************************************
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
358 * Remove and Rename
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
359 ******************************************************************************/
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
360
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
361 // Delete a ffs object
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
362 effs_t object_remove(iref_t i)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
363 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
364 struct inode_s *ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
365 iref_t entries;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
366
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
367 tw(tr(TR_BEGIN, TrObject, "object_remove(%d) {\n", i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
368
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
369 // if object is a dir, ensure it is empty
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
370 if (is_object(ip, OT_DIR)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
371 dir_traverse(-i, &entries);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
372 if (entries) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
373 tw(tr(TR_END, TrObject, "} %d\n", EFFS_DIRNOTEMPTY));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
374 return EFFS_DIRNOTEMPTY;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
375 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
376 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
377
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
378 // We don't actually journal deletions, this is why we call
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
379 // journal_commit() instead of journal_end(). We have to set
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
380 // journal.location to something else, otherwise journal_commit() will
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
381 // not discount the number of bytes lost by this delete.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
382 if (is_object(ip, OT_DIR)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
383 journal_begin(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
384 fs.journal.location = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
385 journal_commit(0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
386 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
387 else {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
388 // NOTE: This is not nice if we get a break down however the
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
389 // remaning chunks will be removed later by a block reclaim.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
390 do {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
391 journal_begin(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
392 fs.journal.location = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
393 journal_commit(0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
394 } while ((i = segment_next(i)) != 0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
395 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
396
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
397 tw(tr(TR_END, TrObject, "} %d\n", EFFS_OK));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
398
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
399 return EFFS_OK;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
400 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
401
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
402 // Rename an object. <newname> is the new name.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
403 iref_t object_rename(iref_t oldi, const char *newname, iref_t newdir)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
404 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
405 iref_t newi;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
406 struct inode_s *oldip;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
407 char *olddata;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
408 int oldsize, namelength, realsize, offset;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
409
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
410 tw(tr(TR_BEGIN, TrObject, "object_rename(%d, '%s', %d) {\n",
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
411 oldi, newname, newdir));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
412
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
413 oldip = inode_addr(oldi);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
414 oldsize = segment_datasize(oldip);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
415
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
416 // Make sure that there is enough space to make the rename without
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
417 // object_create() trigger a data_reclaim() (awoid relocate oldi/data
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
418 // source)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
419 namelength = is_filename(newname);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
420 realsize = namelength + 1 + oldsize + (oldsize > 0 ? 1 : 0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
421 realsize = atomalign(realsize);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
422
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
423 // Save newdir in fs.xx because it will be updated if it is relocated.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
424 fs.i_backup = newdir;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
425
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
426 if ((offset = data_prealloc(realsize)) <= 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
427 return EFFS_NOSPACE;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
428
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
429 // Use fs.journal.oldi because i would have been updated if
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
430 // data_reclaim() relocate oldi
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
431 oldip = inode_addr(fs.journal.oldi);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
432 olddata = offset2addr(location2offset(oldip->location));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
433 olddata = addr2data(olddata, oldip);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
434
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
435 newi = object_create(newname, olddata, oldsize, fs.i_backup);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
436
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
437 tw(tr(TR_END, TrObject, "} %d\n", newi));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
438 return newi;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
439 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
440
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
441
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
442 /******************************************************************************
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
443 * Object Lookup
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
444 ******************************************************************************/
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
445
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
446 // We can *not* use global variables, only local --- we must be re-entrant!
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
447
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
448 #if 0
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
449
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
450 // NEW CODE!
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
451
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
452 iref_t ffs_object_lookup_do(const char **path, iref_t *dir, int readlink);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
453
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
454 iref_t ffs_object_lookup_once(const char *path, char **leaf, iref_t *dir)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
455 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
456 iref_t i, mydir;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
457 const char *mypath;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
458
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
459 tw(tr(TR_BEGIN, TrLookup, "object_lookup_once('%s', ?, ?) {\n", path));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
460 ttw(ttr(TTrInode, "olu(%s){" NL, path));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
461
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
462 mypath = path;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
463 mydir = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
464 i = object_lookup_do(&mypath, &mydir, 0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
465 if (leaf) *leaf = (char *) mypath;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
466 if (dir) *dir = mydir;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
467
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
468 tw(tr(TR_END, TrLookup, "} (%d, '%s') %d\n",
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
469 (dir ? *dir : 0), (leaf ? *leaf : ""), i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
470 ttw(ttr(TTrInode, "} %d" NL, i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
471
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
472 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
473 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
474
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
475 // Lookup an object. Symlinks are followed.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
476 iref_t ffs_object_lookup(const char *path, char **leaf, iref_t *dir)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
477 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
478 iref_t i, mydir;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
479 const char *mypath;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
480
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
481 tw(tr(TR_BEGIN, TrLookup, "object_lookup('%s', ?, ?) {\n", path));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
482 ttw(ttr(TTrInode, "olu(%s){" NL, path));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
483
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
484 mypath = path;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
485 mydir = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
486 i = object_lookup_do(&mypath, &mydir, 1);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
487
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
488 if (is_object(ip, OT_LINK)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
489 // If it is a link, we unconditionally follow it
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
490 mypath = offset2addr(location2offset(ip->location));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
491 mypath += ffs_strlen(mypath) + 1; // point to data
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
492 if (*mypath == '/') {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
493 mypath++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
494 depth = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
495 d = fs.root;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
496 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
497 i = d;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
498 ip = inode_addr(d);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
499 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
500
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
501 if (leaf) *leaf = (char *) mypath;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
502 if (dir) *dir = mydir;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
503
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
504 tw(tr(TR_END, TrLookup, "} (%d, '%s') %d\n",
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
505 (dir ? *dir : 0), (leaf ? *leaf : ""), i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
506 ttw(ttr(TTrInode, "} %d" NL, i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
507
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
508 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
509 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
510
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
511 // NEW CODE!
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
512
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
513 // Ignore all occurrences of two successive slashes. Accept trailing slash
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
514 // in directory name.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
515 iref_t ffs_object_lookup_do(const char **path, iref_t *dir, int followlink)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
516 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
517 // int lookup_followed; // number of symlinks followed
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
518 iref_t i, j, d;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
519 struct inode_s *ip;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
520 const char *p, *q, *mypath = *path;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
521 uint8 depth = 1;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
522
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
523 tw(tr(TR_FUNC, TrLookup, "object_lookup_do('%s', ?, %d) {\n",
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
524 *path, followlink));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
525
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
526 d = fs.root;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
527 if (*mypath == '/') {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
528 mypath++; // silently ignore and skip prefix slash
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
529 // root directory is a special case
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
530 if (*mypath == 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
531 j = d;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
532 if (path) *path = mypath;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
533 if (dir) *dir = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
534 tw(tr(TR_NULL, TrLookup, "} ('%s', %d) %d\n", mypath, 0, j));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
535 return j;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
536 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
537 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
538
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
539 // set default return value if root dir is empty (child link empty)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
540 j = EFFS_NOTFOUND;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
541
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
542 ip = inode_addr(d);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
543
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
544 tw(tr(TR_FUNC, TrLookup, ""));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
545
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
546 while ((i = ip->child) != (iref_t) IREF_NULL)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
547 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
548 j = 0; // default to not found
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
549 do {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
550 tw(tr(TR_NULL, TrLookup, " %d", (int) i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
551
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
552 p = mypath;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
553 ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
554 if (is_object_valid(ip) && !is_object(ip, OT_SEGMENT)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
555 q = addr2name(offset2addr(location2offset(ip->location)));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
556 tw(tr(TR_NULL, TrLookup, ":%s", q));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
557 while (*p == *q && *p != 0 && *q != 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
558 p++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
559 q++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
560 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
561 if (*q == 0 && (*p == 0 || *p == '/')) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
562 j = i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
563 break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
564 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
565 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
566 } while ((i = ip->sibling) != (iref_t) IREF_NULL);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
567
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
568 if (j == 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
569 // we did not find this component of the mypath. Let's see if this
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
570 // was the leafname component or not...
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
571 while (*p != 0 && *p != '/')
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
572 p++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
573
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
574 if (*p == 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
575 // The mypath component was indeed the leafname
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
576 j = EFFS_NOTFOUND;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
577 else
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
578 // The path component was not the last, so it obviously
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
579 // contained an object that was not a directory.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
580 j = EFFS_NOTADIR;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
581 break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
582 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
583
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
584 if (*p == '/') {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
585 // if there are more path components, the object found must be a
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
586 // directory or a symlink...
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
587 if (is_object(ip, OT_LINK)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
588 // If it is a link, we unconditionally follow it
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
589 mypath = offset2addr(location2offset(ip->location));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
590 mypath += ffs_strlen(mypath) + 1; // point to data
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
591 if (*mypath == '/') {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
592 mypath++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
593 depth = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
594 d = fs.root;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
595 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
596 i = d;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
597 ip = inode_addr(d);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
598 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
599 else if (is_object(ip, OT_DIR)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
600 mypath = p + 1;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
601 d = i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
602 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
603 else {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
604 j = EFFS_NOTADIR;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
605 break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
606 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
607 if (++depth > fs.path_depth_max) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
608 j = EFFS_PATHTOODEEP;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
609 break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
610 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
611
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
612 // if this dir inode has no children, we will leave the while
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
613 // loop, so we preset the return error code. NOTEME: Not
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
614 // strictly correct because if we still have a lot of the
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
615 // pathname left, it should return the error EFFS_NOTADIR
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
616 j = EFFS_NOTFOUND;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
617
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
618 tw(tr(TR_NULL, TrLookup, " /"));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
619
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
620 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
621 else {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
622 // It is a fact that *p == 0. So we found the object
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
623 if (is_object(ip, OT_LINK) && followlink) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
624 // If object is a link, we conditionally follow it...
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
625 mypath = offset2addr(location2offset(ip->location));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
626 mypath += ffs_strlen(mypath) + 1; // point to data
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
627 if (*mypath == '/') {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
628 mypath++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
629 depth = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
630 d = fs.root;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
631 i = fs.root;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
632 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
633 else
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
634 i = d;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
635 ip = inode_addr(d);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
636 tw(tr(TR_NULL, TrLookup, " -%d->", d));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
637 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
638 else {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
639 break; // Success, we found the object!
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
640 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
641 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
642 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
643
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
644 if (path) *path = (char *) mypath;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
645 if (dir) *dir = d;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
646
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
647 tw(tr(TR_NULL, TrLookup, "} (%d, '%s') %d\n", d, mypath, j));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
648
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
649 return j;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
650 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
651
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
652 #else
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
653
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
654 // Lookup an object. Symlinks are followed.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
655 iref_t object_lookup(const char *path, char **leaf, iref_t *dir)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
656 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
657 iref_t i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
658 struct inode_s *ip;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
659
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
660 tw(tr(TR_BEGIN, TrLookup, "object_lookup('%s', ?, ?) {\n", path));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
661 ttw(ttr(TTrInode, "olu(%s){" NL, path));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
662
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
663 i = object_lookup_once(path, leaf, dir);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
664 ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
665
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
666 if (i > 0 && is_object(ip, OT_LINK)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
667 path = offset2addr(location2offset(ip->location));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
668 path += ffs_strlen(path) + 1; // point to data portion
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
669 i = object_lookup_once(path, leaf, dir);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
670
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
671 // Links may only point to regular files...
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
672 ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
673 if (+i > 0 && !is_object(ip, OT_FILE))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
674 i = EFFS_NOTAFILE;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
675 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
676 else {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
677 leaf = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
678 dir = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
679 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
680 tw(tr(TR_END, TrLookup, "} (%d, '%s') %d\n",
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
681 (dir ? *dir : 0), (leaf ? *leaf : ""), i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
682
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
683 ttw(ttr(TTrInode, "} %d" NL, i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
684 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
685 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
686
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
687 // Lookup an object. If object is found: Return iref of object and
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
688 // directory of object in <dir>. If object is not found: Return
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
689 // EFFS_NOTFOUND and last directory component of path in <dir> and leafname
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
690 // of pathname in <leaf>
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
691 iref_t object_lookup_once(const char *path, char **leaf, iref_t *dir)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
692 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
693 iref_t i, j, d;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
694 struct inode_s *ip;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
695 const char *p, *q;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
696 uint8 depth = 1;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
697
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
698 tw(tr(TR_FUNC, TrLookup, "object_lookup_once('%s', ?, ?) { ", path));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
699
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
700 if (path == NULL)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
701 return EFFS_BADNAME;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
702
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
703 d = fs.root;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
704 if (*path == '/') {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
705 path++; // silently ignore and skip prefix slash
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
706 // root directory is a special case
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
707 if (*path == 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
708 j = d;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
709 if (leaf) *leaf = (char *) path;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
710 if (dir) *dir = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
711 tw(tr(TR_NULL, TrLookup, "} ('%s', %d) %d\n", path, 0, j));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
712 return j;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
713 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
714 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
715 else
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
716 return EFFS_BADNAME;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
717
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
718 // set default return value if root dir is completely empty
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
719 // (child link empty)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
720 j = EFFS_NOTFOUND;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
721
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
722 ip = inode_addr(d);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
723
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
724 while ((i = ip->child) != (iref_t) IREF_NULL)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
725 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
726 j = 0; // default to not found
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
727 do {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
728 tw(tr(TR_NULL, TrLookup, "i%d ", (int) i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
729
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
730 p = path;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
731 ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
732 if (is_object_valid(ip) && !is_object(ip, OT_SEGMENT)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
733 q = addr2name(offset2addr(location2offset(ip->location)));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
734 tw(tr(TR_NULL, TrLookup, "%s ", q));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
735 while (*p == *q && *p != 0 && *q != 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
736 p++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
737 q++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
738 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
739 if (*q == 0 && (*p == 0 || *p == '/')) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
740 j = i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
741 break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
742 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
743 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
744 } while ((i = ip->sibling) != (iref_t) IREF_NULL);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
745
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
746
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
747 if (j == 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
748 // we did not find this component of the path. Let's
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
749 // see if this was the leafname component or not...
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
750 while (*p != 0 && *p != '/')
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
751 p++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
752
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
753 if (*p == 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
754 // The path component was indeed the leafname
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
755 j = EFFS_NOTFOUND;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
756 else
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
757 // The path component was not the last, so it
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
758 // obviously contained an object that was not a
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
759 // directory.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
760 j = EFFS_NOTADIR;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
761 break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
762 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
763
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
764 if (*p == '/') {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
765 // if there are more path components, the object found
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
766 // must be a directory...
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
767 if (!is_object(ip, OT_DIR)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
768 j = EFFS_NOTADIR;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
769 break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
770 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
771 if (++depth > fs.path_depth_max) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
772 j = EFFS_PATHTOODEEP;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
773 break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
774 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
775 path = p + 1;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
776 d = i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
777
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
778 // if this dir inode has no children, we will leave the
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
779 // while loop, so we preset the return error code. NOTEME:
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
780 // Not strictly correct because if we still have a lot of
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
781 // the pathname left, it should return the error
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
782 // EFFS_NOTADIR
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
783 j = EFFS_NOTFOUND;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
784
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
785 tw(tr(TR_NULL, TrLookup, "/ "));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
786
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
787 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
788 else {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
789 // It is a fact that *p == 0. So we found the object!
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
790 break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
791 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
792 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
793
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
794 if (leaf) *leaf = (char *) path;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
795 if (dir) *dir = d;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
796
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
797 tw(tr(TR_NULL, TrLookup, "} (%d, '%s') %d\n", d, path, j));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
798
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
799 return j;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
800 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
801
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
802 #endif
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
803
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
804
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
805 /******************************************************************************
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
806 * Directory Operations
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
807 ******************************************************************************/
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
808
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
809 // Open a directory, returning the iref of the directory's inode.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
810 iref_t dir_open(const char *name)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
811 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
812 iref_t i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
813 struct inode_s *ip;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
814
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
815 tw(tr(TR_BEGIN, TrDirHigh, "dir_open('%s') {\n", name));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
816
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
817 if ((i = object_lookup(name, 0, 0)) < 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
818 tw(tr(TR_END, TrDirHigh, "} %d\n", i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
819 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
820 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
821
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
822 ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
823 if (!is_object(ip, OT_DIR))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
824 i = EFFS_NOTADIR;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
825
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
826 tw(tr(TR_END, TrDirHigh, "} %d\n", i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
827
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
828 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
829 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
830
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
831 // Return name and iref of next entry in directory <dir>. <i> is the last
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
832 // entry we returned from this function. In case this is the first call
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
833 // after the initial call to dir_open(), <i> equals <dir>.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
834 iref_t dir_next(iref_t dir, iref_t i, char *name, int8 size)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
835 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
836 struct inode_s *ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
837 char *p;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
838
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
839 tw(tr(TR_BEGIN, TrDirHigh, "dir_next(%d, %d, ?, %d) {\n", dir, i, size));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
840
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
841 i = (i == dir ? ip->child : ip->sibling);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
842
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
843 while (i != (iref_t) IREF_NULL) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
844 ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
845 if (is_object_valid(ip)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
846 p = offset2addr(location2offset(ip->location));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
847 while (size-- && (*name++ = *p++))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
848 ;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
849 break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
850 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
851 i = ip->sibling;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
852 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
853 if (i == (iref_t) IREF_NULL)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
854 i = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
855
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
856 tw(tr(TR_END, TrDirHigh, "} %d\n", i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
857
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
858 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
859 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
860
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
861 // Traverse a directory given by inode reference <i>. If <i> is negative, it
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
862 // refers to the actual directory so we start by traversing the child link.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
863 // Otherwise if <i> is positive, it refers to an entry within the directory
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
864 // and we only traverse sibling links. Returns iref of last object in
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
865 // directory (or negative iref of directory if the child link is empty).
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
866 // <entries> is number of non-deleted objects in the dir (only valid if
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
867 // traversed from the start, eg. with negative <i>).
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
868 iref_t dir_traverse(iref_t i, iref_t *entries)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
869 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
870 iref_t j = 0, valid = 0, erased = 0, invalid = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
871 struct inode_s *ip;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
872
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
873 tw(tr(TR_FUNC, TrDirLow, "dir_traverse(%d, ?) { ", i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
874
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
875 if (i < 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
876 // If directory's child is empty, this is a virgin directory and we
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
877 // return negative iref of the directory itself.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
878 j = i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
879 i = -i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
880 ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
881 i = ip->child;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
882 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
883 if (i != (iref_t) IREF_NULL) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
884 do {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
885 if (j == i) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
886 tw(tr(TR_NULL, TrDirLow, "LOOP! "));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
887 return EFFS_SIBLINGLOOP;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
888 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
889
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
890 j = i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
891 ip = inode_addr(j);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
892
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
893 tw(tr(TR_NULL, TrDirLow, "%d/%x ", j, ip->flags));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
894
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
895 if (is_object_valid(ip))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
896 valid++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
897 else if (is_object(ip, OT_ERASED))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
898 erased++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
899 else
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
900 invalid++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
901
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
902 } while ((i = ip->sibling) != (iref_t) IREF_NULL);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
903 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
904
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
905 if (entries != 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
906 *entries = valid;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
907
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
908 tw(tr(TR_NULL, TrDirLow, "} (valid = %d, erased = %d, invalid = %d) %d\n",
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
909 valid, erased, invalid, j));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
910
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
911 return j;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
912 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
913
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
914
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
915 /******************************************************************************
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
916 * Block, Inode and Data Allocation
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
917 ******************************************************************************/
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
918
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
919 // Find the youngest free block. Return block index on success. If the
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
920 // argument <priority> is zero, this is a normal alloc and it will leave at
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
921 // least fs.blocks_free_min spare blocks. Otherwise, if it is non-zero, it
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
922 // is a privileged alloc (initiated by a reclaim operation) and it will not
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
923 // necessarily leave any spare blocks.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
924 bref_t block_alloc(bref_t priority, uint16 flags)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
925 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
926 bref_t i, b, b_min, b_max, blocks_free;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
927 struct block_header_s *bhp;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
928 age_t age, age_min, age_max;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
929
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
930 tw(tr(TR_BEGIN, TrBlock, "block_alloc(%d, 0x%x) {\n", priority, flags));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
931 ttw(ttr(TTrData, "ba(%d,0x%x) {" NL, priority, flags));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
932
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
933 age_min = BLOCK_AGE_MAX;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
934 age_max = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
935 blocks_free = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
936 b_min = b_max = -1;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
937
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
938 tw(tr(TR_FUNC, TrBlock, "blocks(age): "));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
939 for (i = dev.numblocks - 1; i >= 0; i--)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
940 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
941 if (is_block(i, BF_IS_FREE))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
942 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
943 blocks_free++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
944 bhp = (struct block_header_s *) offset2addr(dev.binfo[i].offset);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
945 age = bhp->age;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
946
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
947 tw(tr(TR_NULL, TrBlock, "%d(%d) ", i, age));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
948
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
949 // Remember index of block found. We use '<=' and '>=' operators
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
950 // (instead of '<' and '>') to ensure we have both limits
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
951 // properly set on exit from this loop.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
952 if (age <= age_min) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
953 b_min = i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
954 age_min = age;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
955 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
956 if (age >= age_max) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
957 b_max = i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
958 age_max = age;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
959 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
960 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
961 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
962 tw(tr(TR_NULL, TrBlock, "\n"));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
963
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
964 // Handle age wrap around
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
965 b = b_min;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
966 if (b_min != -1) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
967 // Either age_max really is max age, so b_min is youngest block OR
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
968 // age_max really is min age, so b_max is youngest block
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
969 b = (age_max - age_min) < 0x8000 ? b_min : b_max;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
970 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
971
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
972 // Only privileged allocs will get the last free block
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
973 if (blocks_free <= fs.blocks_free_min - priority) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
974 b = -1;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
975 tw(tr(TR_FUNC, TrBlock, "Only %d block(s) left, required = %d\n",
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
976 blocks_free, fs.blocks_free_min - priority));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
977 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
978 else {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
979 // Prepare/format the block for holding data/inodes
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
980 if (flags == BF_DATA) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
981 bstat[b].used = BHEADER_SIZE;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
982 bstat[b].lost = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
983 bstat[b].objects = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
984 block_flags_write(b, BF_DATA);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
985 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
986 else if (flags == BF_COPYING) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
987 // This code is used on a fresh format and when allocating a new
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
988 // block for reclaiming inodes
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
989 block_flags_write(b, BF_COPYING);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
990 bstat[b].used = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
991 bstat[b].lost = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
992 bstat[b].objects = 1; // first inode to be allocated
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
993 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
994 else {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
995 tw(tr(TR_FUNC, TrBlock, "FATAL: Bad input (flags = 0x%X)\n", flags));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
996 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
997 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
998
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
999 tw(tr(TR_END, TrBlock, "} (%d) %d\n", blocks_free, b));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1000 ttw(ttr(TTrData, "} 0x%x" NL, b));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1001
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1002 return b;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1003 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1004
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1005 // Free and schedule a block for erase.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1006 void block_free(bref_t b)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1007 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1008 tw(tr(TR_BEGIN, TrBlock, "block_free(%d) {\n", b));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1009
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1010 // mark block as invalid and schedule erasure
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1011 block_flags_write(b, BF_LOST);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1012 block_reclaim(b);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1013
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1014 tw(tr(TR_END, TrBlock, "}\n"));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1015 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1016
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1017 void block_flags_write(uint8 block, uint8 flags)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1018 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1019 struct block_header_s *bhp =
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1020 (struct block_header_s *) offset2addr(dev.binfo[block].offset);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1021
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1022 tw(tr(TR_BEGIN, TrBlock, "block_flags_write(%d, 0x%x)\n", block, flags));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1023
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1024 bstat[block].flags = BIT_SET(bstat[block].flags, flags);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1025 ffsdrv.write_halfword((uint16 *) &bhp->flags, bstat[block].flags );
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1026
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1027 tw(tr(TR_END, TrBlock, ""));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1028 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1029
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1030 // Allocate an inode for a new object. We use bstat[fs.inodes].objects to
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1031 // start our scan for a free inode instead of starting from the first time
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1032 // each time.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1033 iref_t inode_alloc(void)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1034 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1035 iref_t i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1036
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1037 tw(tr(TR_BEGIN, TrInode, "inode_alloc() {\n"));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1038 ttw(ttr(TTrInode, "i_a() {" NL));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1039
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1040 if ((i = inode_alloc_try()) == 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1041 // FIXME NO we are not always of inodes, maybe dos there exist to
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1042 // many objects! It will not help to reclaim the inodes in that case!
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1043 tw(tr(TR_FUNC, TrInode, "NOTE: Out of free inodes...\n"));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1044 inodes_reclaim();
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1045 i = inode_alloc_try();
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1046 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1047
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1048 tw(tr(TR_END, TrInode, "} %d\n", i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1049 ttw(ttr(TTrInode, "} %d" NL, i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1050
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1051 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1052 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1053
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1054 iref_t inode_alloc_try(void)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1055 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1056 iref_t i = fs.inodes_max;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1057 struct inode_s *ip;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1058
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1059 // If we have not yet reached the maximum allowed number of objects,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1060 // search for next free inode...
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1061 if (bstat[fs.inodes].used - bstat[fs.inodes].lost < fs.objects_max)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1062 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1063 ip = inode_addr(bstat[fs.inodes].objects);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1064 for (i = bstat[fs.inodes].objects;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1065 i < fs.inodes_max - FFS_INODES_MARGIN; i++, ip++) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1066 if (ip->location == FLASH_NULL32) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1067 bstat[fs.inodes].objects = i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1068 bstat[fs.inodes].used++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1069 break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1070 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1071 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1072 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1073 if (i >= fs.inodes_max - FFS_INODES_MARGIN)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1074 i = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1075
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1076 tw(tr(TR_FUNC, TrInode, "inode_alloc_try() %d\n", i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1077 ttw(ttr(TTrInode, "i_a_t() %d" NL, i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1078
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1079 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1080 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1081
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1082 // NOTEME: Should file data be word aligned to enable faster reads and
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1083 // writes in word quantities AND to be more compatible with the inherent
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1084 // 16-bit access width of flash memories?
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1085 offset_t data_alloc(int size)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1086 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1087 offset_t offset = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1088 bref_t b;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1089
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1090 tw(tr(TR_BEGIN, TrData, "data_alloc(%d) {\n", size));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1091 ttw(ttr(TTrData, "da(%d) {" NL, size));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1092
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1093 offset = data_prealloc(size);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1094
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1095 // If we did allocate the space, we update bstat[]
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1096 if (offset > 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1097 b = offset2block(offset);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1098 bstat[b].used += size;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1099 stats.data_allocated += size; // STATS
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1100 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1101
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1102 tw(tr(TR_END, TrData, "} 0x%04x\n", offset));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1103 ttw(ttr(TTrData, "} %x" NL, offset));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1104
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1105 return offset;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1106 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1107
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1108 offset_t data_prealloc(int realsize)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1109 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1110 int result, i, bytes_free;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1111 offset_t offset;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1112
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1113 // Is it possible to get this amount of free space and still have enough
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1114 // reserved space?
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1115 ffs_query(Q_BYTES_FREE_RAW, &bytes_free);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1116 if (realsize > (bytes_free + FFS_FILENAME_MAX + dev.atomsize))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1117 return 0; // Not enough unused space
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1118
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1119 for (i = 0; i < dev.numblocks; i++) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1120 if ((offset = data_alloc_try(realsize)) > 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1121 return offset; // Space found
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1122
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1123 if ((result = data_reclaim(realsize)) < 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1124 return 0; // Data reclaim failed!
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1125 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1126
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1127 return 0; // No space found
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1128 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1129
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1130 // Find free data space of size <size>. Return zero if no space available.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1131 // Note that we ensure that we always have space immediately available for a
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1132 // privileged data_alloc(), e.g. a data_alloc() that allocates data space
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1133 // without performing a data_reclaim(). This is important when
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1134 // re-creating/re-locating the journal file.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1135 offset_t data_alloc_try(int size)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1136 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1137 bref_t b;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1138 int free;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1139 offset_t offset_big = 0, offset_small = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1140 int size_big_ok = 0, size_small_ok = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1141 int size_big, size_small;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1142 int reserved;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1143
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1144 tw(tr(TR_FUNC, TrData, "data_alloc_try(%d) { ", size));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1145 ttw(ttr(TTrData, "dat(%d) {" NL, size));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1146
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1147 // NOTE when we alloc do we only need to have reserved space for X
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1148 // number of journal files, where X is the max number of used journals
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1149 // per data reclaim. The only exception is when an object_relocate has
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1150 // failed thus we set reserved_space to zero.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1151 reserved = RESERVED_LOW;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1152
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1153 if (fs.reserved_space < reserved)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1154 reserved = fs.reserved_space;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1155
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1156 // Set size_big to the grater of the sizes and size_small to the lesser.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1157 size_big = (size > reserved ? size : reserved);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1158 size_small = (size > reserved ? reserved : size);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1159 tw(tr(TR_NULL, TrData, "(size_big, small = %d, %d) ", size_big, size_small));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1160
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1161 // First search for free space in data blocks
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1162 tw(tr(TR_NULL, TrData, "block:free,objects: "));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1163
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1164 for (b = 0; b < dev.numblocks; b++) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1165 if (is_block(b, BF_IS_DATA)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1166 free = dev.blocksize - bstat[b].used;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1167 tw(tr(TR_NULL, TrData, "%d:%d,%d ", b, free, bstat[b].objects));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1168 if (bstat[b].objects < fs.block_files_max - fs.block_files_reserved) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1169 if (!size_big_ok && !size_small_ok &&
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1170 (free >= size_big + size_small)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1171 size_big_ok = size_small_ok = 1;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1172 offset_big = offset_small =
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1173 dev.binfo[b].offset + bstat[b].used;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1174 tw(tr(TR_NULL, TrData, "big/small_ok "));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1175 break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1176 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1177 else if (!size_big_ok && free >= size_big) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1178 size_big_ok = 1;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1179 offset_big = dev.binfo[b].offset + bstat[b].used;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1180 tw(tr(TR_NULL, TrData, "big_ok "));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1181 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1182 else if (!size_small_ok && free >= size_small) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1183 size_small_ok = 1;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1184 offset_small = dev.binfo[b].offset + bstat[b].used;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1185 tw(tr(TR_NULL, TrData, "small_ok "));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1186 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1187 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1188 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1189 if (size_small_ok && size_big_ok)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1190 break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1191 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1192
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1193 if (size_big_ok && size_small_ok)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1194 offset_big = (size > reserved ? offset_big : offset_small);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1195 else
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1196 offset_big = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1197
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1198 tw(tr(TR_NULL, TrData, "} 0x%x\n", offset_big));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1199 ttw(ttr(TTrData, "} %x " NL, offset_big));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1200
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1201 return offset_big;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1202 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1203
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1204 offset_t data_reserved_alloc(int size)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1205 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1206 bref_t b;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1207 offset_t offset = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1208 int free;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1209
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1210 tw(tr(TR_BEGIN, TrData, "data_reserved_alloc(%d) {\n", size));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1211 ttw(ttr(TTrData, "dra(%d) {" NL, size));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1212
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1213 tw(tr(TR_NULL, TrData, "block:free,objects: "));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1214 for (b = 0; b < dev.numblocks; b++) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1215 if (is_block(b, BF_IS_DATA)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1216 free = dev.blocksize - bstat[b].used;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1217 tw(tr(TR_NULL, TrData, "%d:%d,%d ", b, free, bstat[b].objects));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1218 if (free >= size) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1219 offset = dev.binfo[b].offset + bstat[b].used;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1220 break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1221 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1222 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1223 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1224
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1225 // If we did allocate the space, we update bstat[]
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1226 if (offset != 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1227 b = offset2block(offset);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1228 bstat[b].used += size;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1229 stats.data_allocated += size; // STATS
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1230 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1231
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1232 tw(tr(TR_END, TrData, "} 0x%04x\n", offset));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1233 ttw(ttr(TTrData, "} %x" NL, offset));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1234
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1235 return offset;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1236 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1237
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1238
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1239 iref_t chunk_alloc(int realsize, int is_journal, offset_t *offset)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1240 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1241 iref_t i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1242
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1243 if (realsize < 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1244 return EFFS_INVALID;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1245
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1246 // Have we reached objects_max? We make a similar test in
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1247 // inode_alloc_try(), however we need to do it here or else we risk to start
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1248 // a data_reclaim we not can finish.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1249 if (bstat[fs.inodes].used - bstat[fs.inodes].lost >= fs.objects_max) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1250 tw(tr(TR_END, TrObject, "} %d\n", EFFS_FSFULL));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1251 ttw(ttr(TTrObj, "} %d" NL, EFFS_FSFULL));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1252 return EFFS_FSFULL;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1253 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1254
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1255 // Allocate space for the object name (and object data)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1256 if (is_journal)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1257 *offset = data_reserved_alloc(realsize);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1258 else
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1259 *offset = data_alloc(realsize);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1260
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1261 if (*offset == 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1262 tw(tr(TR_END, TrObject, "} %d\n", EFFS_NOSPACE));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1263 ttw(ttr(TTrObj, "} %d" NL, EFFS_NOSPACE));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1264 return EFFS_NOSPACE;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1265 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1266 fs.journal.location = offset2location(*offset);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1267
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1268 // Allocate an inode for the object
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1269 i = fs.journal.i = inode_alloc();
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1270 if (i == 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1271 tw(tr(TR_END, TrObject, "} %d\n", EFFS_FSFULL));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1272 ttw(ttr(TTrObj, "} %d" NL, EFFS_FSFULL));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1273 return EFFS_FSFULL;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1274 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1275
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1276 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1277 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1278
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1279 /******************************************************************************
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1280 * query and fcontrol
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1281 ******************************************************************************/
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1282
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1283 #if 0
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1284 extern uint16 ffs_flash_device;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1285 extern uint16 ffs_flash_manufact;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1286 #endif
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1287
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1288 effs_t object_control(iref_t i, int8 action, int value)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1289 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1290 effs_t error = EFFS_OK;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1291
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1292 tw(tr(TR_BEGIN, TrOther, "object_control(%d, %d, 0x%x) {\n",
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1293 i, action, value));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1294 ttw(ttr(TTrApi, "obj_control(%d,%d,0x%x)" NL, i, action, value));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1295
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1296 switch (action) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1297 case OC_FLAGS:
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1298 // Set/clear object flags. Attempting to modify the "/dev/ffs"
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1299 // object (i = 0) or any non-defined flags is an invalid operation.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1300 if (i <= 0 || value & ~OF_ALL) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1301 error = EFFS_INVALID;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1302 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1303 else {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1304 // there are two cases; either we only set bits in the flags.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1305 // This is simple, as we just have to update the flags byte. The
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1306 // other case is harder because we have to clear bits and for
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1307 // this we have to copy the old inode to a new inode, setting
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1308 // the flags appropriately. For now we always just allocate a
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1309 // new inode and set the flags according to the <value>
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1310 // argument.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1311 journal_begin(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1312 fs.journal.flags |= OF_MASK; // reset all flags
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1313 fs.journal.flags = BIT_SET(fs.journal.flags, value);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1314 if ((fs.journal.i = inode_alloc()) == 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1315 error = EFFS_FSFULL;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1316 else {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1317 fs.journal.diri = dir_traverse(fs.journal.diri, 0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1318 journal_end(0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1319 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1320 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1321 break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1322
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1323 case OC_FS_FLAGS: fs.flags = value; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1324 #if 0
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1325 case OC_DEV_MANUFACT: ffs_flash_manufact = value; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1326 case OC_DEV_DEVICE: ffs_flash_device = value; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1327 #endif
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1328 case OC_FS_TESTFLAGS: fs.testflags = value; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1329 case OC_DEBUG_0:
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1330 case OC_DEBUG_1:
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1331 case OC_DEBUG_2:
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1332 case OC_DEBUG_3: fs.debug[action - OC_DEBUG_FIRST] = value; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1333 case OC_TRACE_INIT:
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1334 #if (TARGET == 1)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1335 ttr_init(value);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1336 #endif
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1337 break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1338 default:
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1339 error = EFFS_INVALID;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1340 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1341
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1342 tw(tr(TR_END, TrOther, "} %d\n", error));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1343
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1344 return error;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1345 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1346
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1347 extern int tmffs_bufsize(void); // used by ffs_query()
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1348 extern unsigned char *tmffs_bufaddr(void); // used by ffs_query()
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1349
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1350 #if (TARGET == 1)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1351 // request_id_last is only used in TARGET not to any use on the PC side
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1352 extern req_id_t request_id_last; // from task.c
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1353 #else
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1354 req_id_t request_id_last;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1355 #endif
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1356
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1357 // If tmffs not is represented we define a dummy tm version
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1358 #ifndef FFS_TM_VERSION
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1359 #define FFS_TM_VERSION ((uint16) 0x0BAD)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1360 #endif
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1361
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1362 effs_t ffs_query(int8 query, void *p)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1363 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1364 tw(tr(TR_FUNC, TrOther, "query(%d) (?)\n", query));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1365
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1366 if (p == NULL)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1367 return EFFS_INVALID;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1368
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1369 switch (query)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1370 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1371 case Q_BYTES_FREE:
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1372 case Q_BYTES_USED:
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1373 case Q_BYTES_LOST:
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1374 case Q_BYTES_MAX:
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1375 case Q_OBJECTS_TOTAL:
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1376 case Q_BLOCKS_FREE:
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1377 case Q_BYTES_FREE_RAW:
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1378 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1379 bref_t b;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1380 bref_t blocks_free = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1381 iref_t objects = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1382 offset_t max, used = 0, lost = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1383 struct block_stat_s *bp;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1384
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1385 // Don't count free blocks, inode block, block header and reserved space.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1386 max = (dev.numblocks - fs.blocks_free_min - 1) *
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1387 (dev.blocksize - BHEADER_SIZE) - fs.reserved_space;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1388
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1389 // Furthermore don't count the ovewrhead from each chunk (alignment)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1390 // NOTE: If we call query while FFS not is formatted there is a risk
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1391 // of deviding with zero!
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1392 if (fs.chunk_size_max > 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1393 max -= ((max / fs.chunk_size_max + 1) * dev.atomsize);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1394
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1395 for (b = 0, bp = &bstat[0]; b < dev.numblocks; b++, bp++) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1396 if (is_block(b, BF_IS_FREE))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1397 blocks_free++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1398 if (is_block(b, BF_IS_DATA)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1399 objects += bp->objects;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1400 used += bp->used;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1401 lost += bp->lost;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1402 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1403 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1404
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1405 switch (query) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1406 case Q_BYTES_FREE: *(uint32*)p = max - (used - lost) - FFS_FILENAME_MAX;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1407 break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1408 case Q_BYTES_FREE_RAW:*(uint32*)p = max - (used - lost); break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1409 case Q_BYTES_USED: *(uint32*)p = used; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1410 case Q_BYTES_LOST: *(uint32*)p = lost; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1411 case Q_BYTES_MAX: *(uint32*)p = max; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1412 case Q_OBJECTS_TOTAL: *(uint16*)p = objects; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1413 case Q_BLOCKS_FREE: *(uint16*)p = blocks_free; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1414 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1415 break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1416 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1417
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1418 case Q_TM_BUFADDR: *(uint32*)p = (uint32) tmffs_bufaddr(); break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1419 case Q_TM_BUFSIZE: *(uint32*)p = tmffs_bufsize(); break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1420 case Q_DEV_BASE: *(uint32*)p = (uint32) dev.base; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1421
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1422 // FFS versions
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1423 case Q_FFS_API_VERSION: *(uint16*)p = FFS_API_VERSION; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1424 case Q_FFS_DRV_VERSION: *(uint16*)p = FFS_DRV_VERSION; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1425 case Q_FFS_REVISION: *(uint16*)p = ffs_revision; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1426 case Q_FFS_FORMAT_WRITE: *(uint16*)p = FFS_FORMAT_VERSION; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1427 case Q_FFS_FORMAT_READ: *(uint16*)p = fs.format; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1428 case Q_FFS_LASTERROR: *(int16*)p = fs.initerror; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1429 case Q_FFS_TM_VERSION: *(int16*)p = FFS_TM_VERSION; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1430
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1431 // File system queries
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1432 case Q_FILENAME_MAX: *(uint16*)p = fs.filename_max; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1433 case Q_PATH_DEPTH_MAX: *(uint16*)p = fs.path_depth_max; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1434
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1435 case Q_OBJECTS_FREE: *(uint16*)p = fs.objects_max -
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1436 (bstat[fs.inodes].used -
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1437 bstat[fs.inodes].lost); break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1438 case Q_INODES_USED: *(uint16*)p = bstat[fs.inodes].used; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1439 case Q_INODES_LOST: *(uint16*)p = bstat[fs.inodes].lost; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1440 case Q_OBJECTS_MAX: *(uint16*)p = fs.objects_max; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1441
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1442 case Q_INODES_MAX: *(uint16*)p = fs.inodes_max; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1443 case Q_CHUNK_SIZE_MAX: *(uint16*)p = fs.chunk_size_max; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1444
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1445 // File descriptor queris
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1446 case Q_FD_BUF_SIZE: *(uint32*)p = fs.fd_buf_size; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1447 case Q_FD_MAX: *(uint16*)p = fs.fd_max; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1448
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1449 // device queries
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1450 case Q_DEV_MANUFACTURER: *(uint16*)p = dev.manufact; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1451 case Q_DEV_DEVICE: *(uint16*)p = dev.device; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1452 case Q_DEV_BLOCKS: *(uint16*)p = dev.numblocks; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1453 case Q_DEV_ATOMSIZE: *(uint16*)p = dev.atomsize; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1454 case Q_DEV_DRIVER: *(uint16*)p = dev.driver; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1455
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1456 // Miscellaneous/Internal
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1457 case Q_BLOCKS_FREE_MIN: *(uint16*)p = fs.blocks_free_min; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1458 case Q_LOST_HIGH: *(uint16*)p = fs.lost_threshold; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1459
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1460 // Debug queries
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1461 case Q_FS_FLAGS: *(uint16*)p = fs.flags; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1462 case Q_FS_INODES: *(uint16*)p = fs.inodes; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1463 case Q_FS_ROOT: *(uint16*)p = fs.root; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1464
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1465 case Q_STATS_DRECLAIMS: *(uint32*)p = stats.drec.most_lost +
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1466 stats.drec.most_unused +
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1467 stats.drec.youngest; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1468 case Q_STATS_IRECLAIMS: *(uint32*)p = stats.irec.num; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1469 case Q_STATS_DATA_RECLAIMED: *(uint32*)p = stats.drec.valid[0] +
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1470 stats.drec.lost[0]; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1471 case Q_STATS_INODES_RECLAIMED: *(uint32*)p = stats.irec.valid + stats.irec.lost;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1472 break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1473 case Q_STATS_DATA_ALLOCATED: *(uint32*)p = stats.data_allocated; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1474 case Q_REQUEST_ID_LAST: *(uint32*)p = request_id_last; break;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1475
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1476 default:
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1477 if (query >= Q_BSTAT && (query - Q_BSTAT) < dev.numblocks)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1478 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1479 struct block_header_s *bhp;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1480 uint32 *myp = p;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1481
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1482 query -= Q_BSTAT;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1483 bhp = (struct block_header_s *) offset2addr(dev.binfo[query].offset);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1484
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1485 *myp++ = bstat[query].used;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1486 *myp++ = bstat[query].lost;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1487 // If we are in READ mode or this block is not lost, we can
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1488 // safely read the age. Otherwise it is maybe currently erasing
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1489 // and thus we cannot read the age.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1490 // NOTEME: Should this not have been handled by a driver function?
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1491 if (dev.state == DEV_READ || !is_block_flag(query, BF_LOST))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1492 *myp++ = (bhp->age << 16) | bstat[query].flags;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1493 else
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1494 *myp++ = ( 0xFFFE << 16) | bstat[query].flags;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1495 *myp++ = bstat[query].objects;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1496 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1497 else if (query >= Q_DEBUG_FIRST && query < Q_DEBUG_LAST) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1498 *(uint32*)p = fs.debug[query - Q_DEBUG_FIRST];
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1499 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1500 else
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1501 return EFFS_INVALID;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1502 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1503
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1504 return EFFS_OK;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1505 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1506
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1507
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1508 /******************************************************************************
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1509 * Miscellaneous Helper Functions
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1510 ******************************************************************************/
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1511
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1512 // Check if an object is read-only. Note that the root inode is always
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1513 // readonly, no matter what! Returns error or original <i>.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1514 iref_t is_readonly(iref_t i, const char *path)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1515 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1516 struct inode_s *ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1517
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1518 tw(tr(TR_FUNC, TrObject, "is_readonly(%d, '%s') ", i, path));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1519
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1520 if (i == fs.root || i == fs.ijournal ||
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1521 (IS_BIT_SET(ip->flags, OF_READONLY) && !ffs_is_modifiable(path)))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1522 i = EFFS_ACCESS;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1523
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1524 tw(tr(TR_NULL, TrObject, "(0x%X) %d\n", ip->flags, i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1525
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1526 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1527 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1528
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1529
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1530 // Check if filename is valid. Return EFFS_BADNAME if name contains
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1531 // invalid chars. Return RFFS_NAMETOOLONG if name is too
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1532 // long. Otherwise return filename length.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1533 effs_t is_filename(const char *s)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1534 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1535 char *p = (char *) s;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1536 int n = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1537
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1538 while ( (*s >= 'a' && *s <= 'z') ||
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1539 (*s >= 'A' && *s <= 'Z') ||
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1540 (*s >= '0' && *s <= '9') ||
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1541 *s == '.' ||
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1542 *s == ',' ||
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1543 *s == '_' ||
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1544 *s == '-' ||
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1545 *s == '+' ||
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1546 *s == '%' ||
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1547 *s == '$' ||
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1548 *s == '#' )
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1549 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1550 s++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1551 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1552
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1553 if (*s != 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1554 n = EFFS_BADNAME; // invalid file name character found
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1555 else {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1556 n = s - p;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1557 if (n > fs.filename_max)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1558 n = EFFS_NAMETOOLONG;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1559 if (n == 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1560 n = EFFS_BADNAME;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1561 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1562
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1563 tw(tr(TR_FUNC, TrUtil, "is_filename('%s') %d\n", p, n));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1564
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1565 return n;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1566 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1567
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1568 int ffs_strlen(const char *s)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1569 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1570 const char *p = s;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1571
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1572 while (*p++)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1573 ;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1574
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1575 tw(tr(TR_FUNC, TrUtil, "strlen('%s') %d\n", s, p-s-1));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1576
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1577 return p-s-1;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1578 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1579
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1580 // Return zero if strings are equal, otherwise return non-zero.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1581 int ffs_strcmp(const char *s, const char *p)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1582 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1583 int8 n = 1;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1584
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1585 tw(tr(TR_FUNC, TrUtil, "strcmp('%s', '%s') ", s, p));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1586
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1587 while (*s == *p && *p != 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1588 s++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1589 p++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1590 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1591 if (*s == *p)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1592 n = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1593
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1594 tw(tr(TR_NULL, TrUtil, "(%d)\n", n));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1595
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1596 return n;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1597 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1598
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1599 // Note: rename function? like get_fdi..
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1600 fd_t get_fdi(iref_t i)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1601 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1602 int j;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1603
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1604 tw(tr(TR_FUNC, TrUtil, "get_fdi(%d)\n", i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1605
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1606 if (i > 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1607 for (j = 0; j < fs.fd_max; j++) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1608 if (i == fs.fd[j].seghead) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1609 return j; // Return fdi without offset
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1610 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1611 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1612 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1613 return -1;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1614 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1615
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1616
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1617 effs_t is_fd_valid(fd_t fdi)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1618 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1619 if (fdi >= fs.fd_max || fdi < 0 || fs.fd[fdi].options == 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1620 return 0; // Not valid!
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1621 return 1;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1622 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1623
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1624 effs_t is_offset_in_buf(int offset, fd_t fdi)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1625 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1626 if (fs.fd[fdi].dirty == 1)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1627 if (offset >= fs.fd[fdi].wfp &&
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1628 offset < fs.fd[fdi].wfp + fs.chunk_size_max)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1629 return 1;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1630 return 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1631 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1632
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1633 /******************************************************************************
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1634 * Chunk Operations
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1635 ******************************************************************************/
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1636
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1637 iref_t segment_create(const char *buf, int size, iref_t dir)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1638 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1639 iref_t i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1640 struct inode_s *ip;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1641 int realsize;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1642 offset_t offset;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1643 char *dataaddr;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1644
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1645 ttw(ttr(TTrObj, "segc(%d, %d){" NL, size, dir));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1646 tw(tr(TR_BEGIN, TrObject, "segment_create( ?, %d, %d) {\n", size, dir));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1647
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1648 fs.journal.size = realsize = atomalign(size + 1);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1649
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1650 // Init journal.diri before chunk_alloc() because it might trigger a
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1651 // data_reclaim() which can relocate the dir inode
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1652 fs.journal.diri = dir;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1653
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1654 if ((i = chunk_alloc(realsize, 0, &offset)) < 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1655 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1656
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1657 ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1658 dataaddr = offset2addr(offset);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1659
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1660 // Write data and null terminator. We null-terminate the data block,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1661 // such that blocks_fsck() can determine the amount of used data block
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1662 // space correctly.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1663 ffsdrv.write(dataaddr, buf, size);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1664 dataaddr += size;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1665 ffsdrv_write_byte(dataaddr, 0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1666
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1667 // Segments is linked together by the child link(create) or by the
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1668 // sibling link(update or relocate). A negativ dir indicate that it is a
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1669 // update or relocate and the sign must be reversed so the journal
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1670 // system will use the sibling link to link the inode together.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1671 if (dir > 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1672 fs.journal.diri = chunk_traverse(fs.journal.diri);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1673
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1674 fs.journal.diri = -fs.journal.diri;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1675
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1676 tw(tr(TR_END, TrObject, "} %d\n", i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1677 ttw(ttr(TTrObj, "} %d" NL,i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1678
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1679 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1680 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1681
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1682
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1683 int segment_read(iref_t i, char *buf, int size, int offset)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1684 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1685 struct inode_s *ip;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1686 char *p;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1687 int chunk_size;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1688
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1689 tw(tr(TR_BEGIN, TrObject, "segment_read(%d, 0x%x, %d, %d) {\n",
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1690 i, buf, offset, size));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1691
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1692 if (buf == NULL) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1693 tw(tr(TR_END, TrObject, "} %d\n", EFFS_INVALID));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1694 return EFFS_INVALID;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1695 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1696
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1697 ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1698
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1699 chunk_size = segment_datasize(ip);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1700
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1701 // Saturate read buffer
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1702 if (size > chunk_size - offset)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1703 size = chunk_size - offset;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1704
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1705 p = offset2addr(location2offset(ip->location));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1706 p = addr2data(p, ip);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1707
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1708 memcpy(buf, &p[offset], size);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1709
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1710 tw(tr(TR_END, TrObject, "} %d\n", size));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1711 return size;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1712 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1713
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1714 // Find next valid chunk
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1715 iref_t segment_next(iref_t i)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1716 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1717 struct inode_s *ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1718
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1719 tw(tr(TR_BEGIN, TrDirHigh, "ffs_segment_next(%d) {\n", i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1720
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1721 // Dir is not allowed to contain data
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1722 if (is_object(ip, OT_DIR)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1723 tw(tr(TR_END, TrDirHigh, "} 0\n"));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1724 return 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1725 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1726
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1727 // Is this the last/only segment
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1728 if ((i = ip->child) == (iref_t) IREF_NULL) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1729 tw(tr(TR_END, TrDirHigh, "} 0\n"));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1730 return 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1731 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1732
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1733 // Get child (is valid?), search though segment by sibling link(is
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1734 // valid?), and again..
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1735 do {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1736 i = ip->child;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1737 ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1738 if (is_object_valid(ip)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1739 tw(tr(TR_END, TrDirHigh,"} %d\n", i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1740 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1741 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1742
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1743 while (ip->sibling != (iref_t) IREF_NULL) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1744 i = ip->sibling;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1745 ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1746 if (is_object_valid(ip)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1747 tw(tr(TR_END, TrDirHigh,"} %d\n", i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1748 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1749 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1750 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1751 } while (ip->child != (iref_t) IREF_NULL);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1752
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1753 // No segment found
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1754 tw(tr(TR_END, TrDirHigh,"} %d\n", i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1755 return 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1756 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1757
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1758 // The output "inode" will be the inode that contains the requested data or
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1759 // the last inode in the segmentfile. The segmenthead will be skiped if it
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1760 // don't contains any data. inode_offset is the offset in the found inode
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1761 // pointed to by target_offset. If target_offset point past the last segment
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1762 // will inode_offset be the size of the last inode. The return value will be
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1763 // the same as target_offset but maximum the total size of the object.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1764 int segfile_seek(iref_t seghead, int target_offset,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1765 iref_t *inode, int *inode_offset)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1766 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1767 int priv_count = 0, count_size = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1768 iref_t i = seghead;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1769 struct inode_s *ip;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1770
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1771 tw(tr(TR_BEGIN, TrObject, "segfile_seek(%d, %d, ?, ?) {\n",
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1772 seghead, target_offset));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1773
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1774 if (!is_object_valid(inode_addr(seghead))) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1775 tw(tr(TR_END, TrAll, "FATAL: Invalid seghead!\n"));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1776 return 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1777 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1778 *inode = seghead;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1779
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1780 while (1)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1781 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1782 ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1783 count_size += segment_datasize(ip);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1784
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1785 // Seghead will be skiped if it don't contain any data
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1786 if (count_size > target_offset && count_size != 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1787
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1788 if (inode_offset != 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1789 *inode_offset = target_offset - priv_count;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1790
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1791 tw(tr(TR_END, TrObject, "} %d\n", target_offset));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1792 return target_offset;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1793 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1794
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1795 if ((i = segment_next(i)) == 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1796 tw(tr(TR_END, TrObject, "} (eof!?) %d\n", count_size));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1797 if (inode_offset != 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1798 *inode_offset = count_size - priv_count;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1799 // *inode = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1800 return count_size; // No more segments
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1801 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1802 priv_count = count_size;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1803
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1804 *inode = i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1805 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1806 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1807
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1808 // Calculate exact size of file data; without filename and null terminator
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1809 // and without data null terminator and succeeding alignment padding.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1810 // NOTEME: Does this also work for empty files and directories?
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1811 int segment_datasize(const struct inode_s *ip)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1812 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1813 char *p, *q;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1814 int size;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1815
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1816 p = offset2addr(location2offset(ip->location));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1817 q = p + ip->size - 1;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1818
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1819 // Segments is not allowed to contain any name
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1820 if (!is_object(ip, OT_SEGMENT)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1821 // skip filename at start of data
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1822 while (*p)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1823 p++;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1824 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1825 else
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1826 // If it contained a name would p pointe to the null terminator of
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1827 // the name but because chunks don't have a name decrement we p to get
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1828 // the size correct
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1829 p--;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1830
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1831 // skip padding at end of data
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1832 while (*q)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1833 q--;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1834
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1835 // If there are data, there is also a null-terminator. Otherwise
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1836 // there is no null-terminator
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1837 size = q - p;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1838 if (size > 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1839 size--;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1840
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1841 tw(tr(TR_FUNC, TrObject, "segment_datasize(0x%x) %d\n", ip, size));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1842 return size;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1843 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1844
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1845
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1846 int object_truncate(const char *pathname, fd_t fdi, offset_t length)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1847 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1848 int segment_offset, flength, realsize, offset;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1849 iref_t i, dir, next_i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1850 char *name = 0, *olddata;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1851 struct inode_s *oldip;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1852 effs_t error;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1853
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1854 tw(tr(TR_FUNC, TrObject, "ffs_object_truncate('%s', %d, %d) \n",
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1855 pathname, fdi, length));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1856 if (length < 0) return EFFS_INVALID;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1857
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1858 if (pathname == 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1859 // File descriptor must be open and it have to be in write mode
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1860 if (!is_fd_valid(fdi))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1861 return EFFS_BADFD;;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1862
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1863 if (!is_open_option(fs.fd[fdi].options, FFS_O_WRONLY))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1864 return EFFS_INVALID;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1865
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1866 // It is not possible to truncate an open file to a size less than
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1867 // the current file pointer
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1868 if (length < fs.fd[fdi].fp)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1869 return EFFS_INVALID;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1870
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1871 i = fs.fd[fdi].seghead;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1872 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1873 else {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1874 // File must exists and not be open
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1875 if ((i = object_lookup(pathname, &name, &dir)) < 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1876 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1877
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1878 if (get_fdi(i) >= 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1879 return EFFS_LOCKED;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1880
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1881 oldip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1882 // Even though the ffs architecture allows to have data in directory
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1883 // objects, we don't want to complicate matters, so we return an error
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1884 if (is_object(oldip, OT_DIR) && !(fs.flags & FS_DIR_DATA))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1885 return EFFS_NOTAFILE;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1886
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1887 if ((i = is_readonly(i, pathname)) < 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1888 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1889 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1890 // Find the segment which length points in to
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1891 flength = segfile_seek(i, length, &i, &segment_offset);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1892
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1893 if (pathname == 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1894 if (is_offset_in_buf(length, fdi) == 1) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1895 fs.fd[fdi].size = (length > fs.fd[fdi].size ?
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1896 fs.fd[fdi].size : length); // Truncate the buffer
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1897
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1898 if (i == fs.fd[fdi].wch) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1899 next_i = segment_next(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1900 if (next_i > 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1901 if ((error = object_remove(next_i)) < 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1902 return error;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1903 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1904 return EFFS_OK;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1905 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1906 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1907
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1908 if (flength < length)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1909 return EFFS_OK;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1910
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1911 journal_begin(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1912
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1913 // Realsize do not always need to include a name but we simplify it.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1914 realsize = atomalign(segment_offset + 1 + fs.filename_max + 1);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1915
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1916 // Make sure that there is enough space to make the rename without
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1917 // object_create() trigger a data_reclaim() (awoid relocate oldi/data
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1918 // source)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1919 if ((offset = data_prealloc(realsize)) <= 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1920 return EFFS_NOSPACE;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1921
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1922 // Find the next segment if any.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1923 next_i = segment_next(fs.journal.oldi);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1924
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1925 // Find old data source
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1926 oldip = inode_addr(fs.journal.oldi);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1927 olddata = offset2addr(location2offset(oldip->location));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1928 name = addr2name(olddata); // reinit name (maybe relocated)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1929 olddata = addr2data(olddata, oldip);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1930
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1931 if (is_object(oldip, OT_SEGMENT)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1932 if (segment_offset == 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1933 next_i = fs.journal.oldi; // Remove the found object
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1934 else {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1935 if ((i = segment_create(olddata, segment_offset,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1936 -fs.journal.oldi)) < 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1937 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1938
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1939 fs.link_child = 0; //Do not link child
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1940 journal_end(0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1941 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1942 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1943 else {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1944 if ((i = object_create(name, olddata, length, fs.journal.oldi)) < 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1945 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1946 fs.link_child = 0; //Do not link child
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1947 journal_end(0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1948
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1949 if (is_fd_valid(fdi))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1950 fs.fd[fdi].seghead = i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1951 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1952
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1953 if (is_fd_valid(fdi))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1954 fs.fd[fdi].size = length;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1955
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1956 // If any remaning segment exists then remove them
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1957 if (next_i > 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1958 if ((error = object_remove(next_i)) < 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1959 return error;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1960
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1961 return EFFS_OK;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1962 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1963
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1964
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1965 // Find the last segment valid or not valid
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1966 iref_t chunk_traverse(iref_t i)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1967 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1968 struct inode_s *ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1969
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1970 tw(tr(TR_BEGIN, TrDirHigh, "ffs_chunk_traverse(%d) {\n", i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1971 // Is this the last/only segment?
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1972 if (ip->child == (iref_t) IREF_NULL) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1973 tw(tr(TR_END, TrDirHigh, "} %d\n", i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1974 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1975 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1976
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1977 // Get child, find the last segment by sibling link, and again..
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1978 do {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1979 i = ip->child;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1980 ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1981
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1982 while (ip->sibling != (iref_t) IREF_NULL) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1983 i = ip->sibling;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1984 ip = inode_addr(i);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1985 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1986 } while (ip->child != (iref_t) IREF_NULL);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1987
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1988 tw(tr(TR_END, TrDirHigh, "} %d\n", i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1989
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1990 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1991 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1992
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1993 // fdi include offset now but change this so core use pure fdi.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1994 effs_t datasync(fd_t fdi)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1995 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1996 int chunk_size;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1997 iref_t i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1998 struct inode_s *ip;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1999 char *name;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2000
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2001 tw(tr(TR_FUNC, TrObject, "datasync(%d) \n", fdi));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2002 ttw(ttr(TTrApi, "datasync(%d) {" NL, fdi));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2003
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2004 // NOTEME: is this necessary?
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2005 if (!is_fd_valid(fdi))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2006 return EFFS_BADFD;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2007
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2008 if (fs.fd[fdi].dirty == 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2009 return EFFS_OK;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2010
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2011 // If size - wfp is more than max is the complete buffer valid or else
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2012 // is it only a part of it that consist valid data
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2013 chunk_size = fs.fd[fdi].size - fs.fd[fdi].wfp;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2014 if (chunk_size > fs.chunk_size_max)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2015 chunk_size = fs.chunk_size_max;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2016
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2017 ip = inode_addr(fs.fd[fdi].wch);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2018
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2019 // Create new chunk or update a old one
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2020 if (fs.fd[fdi].wch > 0) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2021 // Update existing chunk
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2022 // Negativ dir input because it is a update (do not traverse)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2023 if (is_object(ip, OT_SEGMENT)) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2024 journal_begin(fs.fd[fdi].wch);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2025
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2026 if ((i = segment_create(fs.fd[fdi].buf, chunk_size,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2027 -fs.fd[fdi].wch)) < 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2028 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2029 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2030
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2031 else {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2032 // Seghead update (like a normal file)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2033 ip = inode_addr(fs.fd[fdi].seghead);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2034 name = addr2name(offset2addr(location2offset(ip->location)));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2035 journal_begin(fs.fd[fdi].seghead);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2036
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2037 if ((i = object_create(name, fs.fd[fdi].buf, chunk_size,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2038 fs.fd[fdi].seghead)) < 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2039 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2040
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2041 fs.fd[fdi].seghead = i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2042 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2043 journal_end(0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2044 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2045
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2046 else {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2047 // Create new chunk at the end of the existing ones.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2048 // BTW: A seghead will always have been made before this one.
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2049 journal_begin(0);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2050
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2051 if ((i = segment_create(fs.fd[fdi].buf, chunk_size,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2052 fs.fd[fdi].seghead)) < 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2053 return i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2054
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2055 journal_end(OT_SEGMENT);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2056 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2057 fs.fd[fdi].dirty = fs.fd[fdi].wch = 0;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2058
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2059 ttw(ttr(TTrApi, "} 0" NL));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2060 return EFFS_OK;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2061 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2062
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2063 /******************************************************************************
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2064 * Development and Tracing
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2065 ******************************************************************************/
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2066
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2067 #if (TARGET == 0)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2068
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2069 void tr_bstat(void)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2070 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2071 int i, n;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2072 struct block_header_s *bhp;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2073 struct block_stat_s *bsp;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2074
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2075 tw(tr(TR_BEGIN, TrBstat, "bstat = {\n"));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2076
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2077 bsp = &bstat[0];
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2078 tw(tr(TR_FUNC, TrBstat,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2079 " bf used lost free n age state\n"));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2080 for (i = 0, n = 0; i < dev.numblocks; i++, bsp++) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2081 bhp = (struct block_header_s *) offset2addr(dev.binfo[i].offset);
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2082 tw(tr(TR_FUNC, TrBstat, "%2d %02x %6d %6d %6d %3d %5d %s%s%s%s%s%s\n",
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2083 i, bsp->flags & 0xFF,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2084 bsp->used, bsp->lost,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2085 dev.blocksize - bsp->used,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2086 bsp->objects,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2087 bhp->age,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2088 (is_block(i, BF_IS_FREE) ? "FREE " : ""),
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2089 (is_block(i, BF_IS_DATA) ? "DATA " : ""),
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2090 (is_block(i, BF_IS_CLEANING) ? "CLEANING " : ""),
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2091 (is_block(i, BF_IS_COPYING) ? "COPYING " : ""),
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2092 (is_block(i, BF_IS_INODES) ? "INODES " : ""),
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2093 (is_block_flag(i, BF_LOST) ? "lost " : "")
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2094 ));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2095 if (is_block(i, BF_IS_DATA))
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2096 n += bsp->objects;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2097 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2098 i = bstat[fs.inodes].used - bstat[fs.inodes].lost;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2099 tw(tr(TR_FUNC, TrBstat,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2100 " %3d (used-lost = %d)\n",
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2101 n, i));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2102
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2103 if (n != i) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2104 tw(tr(TR_FUNC, TrAll, "WARNING: sum(bstat[x].objects) != bstat[fs.inodes].used - bstat[fs.inodes].lost\n"));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2105 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2106
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2107 tw(tr(TR_END, TrBstat, "}\n"));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2108 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2109
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2110 #else // (TARGET == 1)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2111
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2112 void tr_bstat(void)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2113 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2114 int i;
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2115 struct block_stat_s *bsp = &bstat[0];
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2116
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2117 for (i = 0; i < dev.numblocks; i++, bsp++) {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2118 ttw(ttr(TTrBstat, "%2d (%2x) u/l/f/n %6d %6d %6d %2d" NL,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2119 i, bsp->flags,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2120 bsp->used, bsp->lost,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2121 dev.blocksize - bsp->used,
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2122 bsp->objects
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2123 ));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2124 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2125 ttw(str(TTrBstat,"" NL));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2126 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2127
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2128
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2129 void tr_fd(fd_t fdi)
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2130 {
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2131 tw(tr(TR_BEGIN, TrHelper, "tr_fd(%d) {\n", fdi));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2132 tw(tr(TR_FUNC, TrHelper, "options: 0x%x \n", fd[fdi].options));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2133 tw(tr(TR_FUNC, TrHelper, "inode : %d \n", fd[fdi].inode_first));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2134 tw(tr(TR_FUNC, TrHelper, "fp : %d \n", fd[fdi].fp));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2135 tw(tr(TR_FUNC, TrHelper, "size : %d \n", fd[fdi].size));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2136 tw(tr(TR_FUNC, TrHelper, "dir : %d \n", fd[fdi].dir));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2137 tw(tr(TR_FUNC, TrHelper, "name : %s \n", fd[fdi].name));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2138 tw(tr(TR_END, TrHelper, "}\n", fdi));
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2139 }
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2140
847e2585a0f2 gsm-fw/services/ffs: core.c integrated
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2141 #endif // (TARGET == 0)