Rev 2858 | Rev 2863 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2858 | Rev 2859 | ||
---|---|---|---|
Line 108... | Line 108... | ||
108 | static block_t *block_get(dev_handle_t dev_handle, off_t offset) |
108 | static block_t *block_get(dev_handle_t dev_handle, off_t offset) |
109 | { |
109 | { |
110 | return NULL; /* TODO */ |
110 | return NULL; /* TODO */ |
111 | } |
111 | } |
112 | 112 | ||
113 | static block_t *fat_block_get(dev_handle_t dev_handle, fs_index_t index, |
- | |
114 | off_t offset) { |
- | |
115 | return NULL; /* TODO */ |
- | |
116 | } |
- | |
117 | - | ||
118 | static void block_put(block_t *block) |
113 | static void block_put(block_t *block) |
119 | { |
114 | { |
120 | /* TODO */ |
115 | /* TODO */ |
121 | } |
116 | } |
122 | 117 | ||
- | 118 | ||
- | 119 | #define FAT_BS(b) ((fat_bs_t *)((b)->data)) |
|
- | 120 | ||
- | 121 | #define FAT_CLST_FIRST 0x0002 |
|
- | 122 | #define FAT_CLST_BAD 0xfff7 |
|
- | 123 | #define FAT_CLST_LAST1 0xfff8 |
|
- | 124 | #define FAT_CLST_LAST8 0xffff |
|
- | 125 | ||
- | 126 | /** Convert cluster number to an index within a FAT. |
|
- | 127 | * |
|
- | 128 | * Format Identifier and cluster numbering is considered. |
|
- | 129 | */ |
|
- | 130 | #define C2FAT_IDX(c) (1 + (c) - FAT_CLST_FIRST) |
|
- | 131 | ||
- | 132 | static block_t *fat_block_get(dev_handle_t dev_handle, fs_index_t index, |
|
- | 133 | off_t offset) |
|
- | 134 | { |
|
- | 135 | block_t *bb; |
|
- | 136 | block_t *b; |
|
- | 137 | unsigned bps; |
|
- | 138 | unsigned spc; |
|
- | 139 | unsigned rscnt; /* block address of the first FAT */ |
|
- | 140 | unsigned fatcnt; |
|
- | 141 | unsigned rde; |
|
- | 142 | unsigned rds; /* root directory size */ |
|
- | 143 | unsigned sf; |
|
- | 144 | unsigned ssa; /* size of the system area */ |
|
- | 145 | unsigned clusters; |
|
- | 146 | unsigned clst = index; |
|
- | 147 | unsigned i; |
|
- | 148 | ||
- | 149 | bb = block_get(dev_handle, BS_BLOCK); |
|
- | 150 | bps = uint16_t_le2host(FAT_BS(bb)->bps); |
|
- | 151 | spc = FAT_BS(bb)->spc; |
|
- | 152 | rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt); |
|
- | 153 | fatcnt = FAT_BS(bb)->fatcnt; |
|
- | 154 | rde = uint16_t_le2host(FAT_BS(bb)->root_ent_max); |
|
- | 155 | sf = uint16_t_le2host(FAT_BS(bb)->sec_per_fat); |
|
- | 156 | block_put(bb); |
|
- | 157 | ||
- | 158 | rds = (sizeof(fat_dentry_t) * rde) / bps; |
|
- | 159 | rds += ((sizeof(fat_dentry_t) * rde) % bps != 0); |
|
- | 160 | ssa = rscnt + fatcnt * sf + rds; |
|
- | 161 | ||
- | 162 | if (!index) { |
|
- | 163 | /* root directory special case */ |
|
- | 164 | assert(offset < rds); |
|
- | 165 | b = block_get(dev_handle, rscnt + fatcnt * sf + offset); |
|
- | 166 | return b; |
|
- | 167 | } |
|
- | 168 | ||
- | 169 | clusters = offset / spc; |
|
- | 170 | for (i = 0; i < clusters; i++) { |
|
- | 171 | unsigned fsec; /* sector offset relative to FAT1 */ |
|
- | 172 | unsigned fidx; /* FAT1 entry index */ |
|
- | 173 | ||
- | 174 | assert(clst >= FAT_CLST_FIRST && clst < FAT_CLST_BAD); |
|
- | 175 | fsec = (C2FAT_IDX(clst) * sizeof(uint16_t)) / bps; |
|
- | 176 | fidx = C2FAT_IDX(clst) % (bps / sizeof(uint16_t)); |
|
- | 177 | /* read FAT1 */ |
|
- | 178 | b = block_get(dev_handle, rscnt + fsec); |
|
- | 179 | clst = uint16_t_le2host(((uint16_t *)b->data)[fidx]); |
|
- | 180 | assert(clst != FAT_CLST_BAD); |
|
- | 181 | assert(clst < FAT_CLST_LAST1); |
|
- | 182 | block_put(b); |
|
- | 183 | } |
|
- | 184 | ||
- | 185 | b = block_get(dev_handle, ssa + (clst - FAT_CLST_FIRST) * spc + |
|
- | 186 | offset % spc); |
|
- | 187 | ||
- | 188 | return b; |
|
- | 189 | } |
|
- | 190 | ||
123 | static void fat_node_initialize(fat_node_t *node) |
191 | static void fat_node_initialize(fat_node_t *node) |
124 | { |
192 | { |
125 | futex_initialize(&node->lock, 1); |
193 | futex_initialize(&node->lock, 1); |
126 | node->type = 0; |
194 | node->type = 0; |
127 | node->index = 0; |
195 | node->index = 0; |
Line 140... | Line 208... | ||
140 | block_t *bb; |
208 | block_t *bb; |
141 | uint16_t bps; |
209 | uint16_t bps; |
142 | 210 | ||
143 | bb = block_get(dev_handle, BS_BLOCK); |
211 | bb = block_get(dev_handle, BS_BLOCK); |
144 | assert(bb != NULL); |
212 | assert(bb != NULL); |
145 | bps = uint16_t_le2host(((fat_bs_t *)bb->data)->bps); |
213 | bps = uint16_t_le2host(FAT_BS(bb)->bps); |
146 | block_put(bb); |
214 | block_put(bb); |
147 | 215 | ||
148 | return bps; |
216 | return bps; |
149 | } |
217 | } |
150 | 218 |