FreeCalypso > hg > freecalypso-sw
annotate gsm-fw/services/ffs/core.c @ 286:146e7bf3fa4e
fc-fsio: fd debug commands implemented
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Fri, 28 Feb 2014 06:45:10 +0000 |
parents | 842c9fd828fd |
children |
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, ¬_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, ¬_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) |