Rev 3314 | Rev 3335 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3314 | Rev 3325 | ||
---|---|---|---|
Line 221... | Line 221... | ||
221 | offset % spc, bps); |
221 | offset % spc, bps); |
222 | 222 | ||
223 | return b; |
223 | return b; |
224 | } |
224 | } |
225 | 225 | ||
- | 226 | /** Return number of blocks allocated to a file. |
|
- | 227 | * |
|
- | 228 | * @param dev_handle Device handle of the device with the file. |
|
- | 229 | * @param firstc First cluster of the file. |
|
- | 230 | * |
|
- | 231 | * @return Number of blocks allocated to the file. |
|
- | 232 | */ |
|
- | 233 | static uint16_t |
|
- | 234 | _fat_blcks_get(dev_handle_t dev_handle, fat_cluster_t firstc) |
|
- | 235 | { |
|
- | 236 | block_t *bb; |
|
- | 237 | block_t *b; |
|
- | 238 | unsigned bps; |
|
- | 239 | unsigned spc; |
|
- | 240 | unsigned rscnt; /* block address of the first FAT */ |
|
- | 241 | unsigned clusters = 0; |
|
- | 242 | fat_cluster_t clst = firstc; |
|
- | 243 | ||
- | 244 | bb = block_get(dev_handle, BS_BLOCK, BS_SIZE); |
|
- | 245 | bps = uint16_t_le2host(FAT_BS(bb)->bps); |
|
- | 246 | spc = FAT_BS(bb)->spc; |
|
- | 247 | rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt); |
|
- | 248 | block_put(bb); |
|
- | 249 | ||
- | 250 | if (firstc == FAT_CLST_RES0) { |
|
- | 251 | /* No space allocated to the file. */ |
|
- | 252 | return 0; |
|
- | 253 | } |
|
- | 254 | ||
- | 255 | while (clst < FAT_CLST_LAST1) { |
|
- | 256 | unsigned fsec; /* sector offset relative to FAT1 */ |
|
- | 257 | unsigned fidx; /* FAT1 entry index */ |
|
- | 258 | ||
- | 259 | assert(clst >= FAT_CLST_FIRST); |
|
- | 260 | fsec = (clst * sizeof(fat_cluster_t)) / bps; |
|
- | 261 | fidx = clst % (bps / sizeof(fat_cluster_t)); |
|
- | 262 | /* read FAT1 */ |
|
- | 263 | b = block_get(dev_handle, rscnt + fsec, bps); |
|
- | 264 | clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]); |
|
- | 265 | assert(clst != FAT_CLST_BAD); |
|
- | 266 | block_put(b); |
|
- | 267 | clusters++; |
|
- | 268 | } |
|
- | 269 | ||
- | 270 | return clusters * spc; |
|
- | 271 | } |
|
- | 272 | ||
226 | static void fat_node_initialize(fat_node_t *node) |
273 | static void fat_node_initialize(fat_node_t *node) |
227 | { |
274 | { |
228 | futex_initialize(&node->lock, 1); |
275 | futex_initialize(&node->lock, 1); |
229 | node->idx = NULL; |
276 | node->idx = NULL; |
230 | node->type = 0; |
277 | node->type = 0; |
Line 357... | Line 404... | ||
357 | * root directory itself. The root directory node is handled |
404 | * root directory itself. The root directory node is handled |
358 | * and initialized elsewhere. |
405 | * and initialized elsewhere. |
359 | */ |
406 | */ |
360 | nodep->type = FAT_DIRECTORY; |
407 | nodep->type = FAT_DIRECTORY; |
361 | /* |
408 | /* |
362 | * TODO: determine the size by walking FAT. Surprisingly, the |
409 | * Unfortunately, the 'size' field of the FAT dentry is not |
363 | * 'size' filed of the FAT dentry is not defined for the |
410 | * defined for the directory entry type. We must determine the |
364 | * directory entry type. |
411 | * size of the directory by walking the FAT. |
365 | */ |
412 | */ |
366 | nodep->size = 64 * sizeof(fat_dentry_t); |
413 | nodep->size = bps * _fat_blcks_get(idxp->dev_handle, |
- | 414 | uint16_t_le2host(d->firstc)); |
|
367 | } else { |
415 | } else { |
368 | nodep->type = FAT_FILE; |
416 | nodep->type = FAT_FILE; |
369 | nodep->size = uint32_t_le2host(d->size); |
417 | nodep->size = uint32_t_le2host(d->size); |
370 | } |
418 | } |
371 | nodep->firstc = uint16_t_le2host(d->firstc); |
419 | nodep->firstc = uint16_t_le2host(d->firstc); |