Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2858 → Rev 2859

/trunk/uspace/srv/fs/fat/fat_ops.c
110,16 → 110,84
return NULL; /* TODO */
}
 
static block_t *fat_block_get(dev_handle_t dev_handle, fs_index_t index,
off_t offset) {
return NULL; /* TODO */
}
 
static void block_put(block_t *block)
{
/* TODO */
}
 
 
#define FAT_BS(b) ((fat_bs_t *)((b)->data))
 
#define FAT_CLST_FIRST 0x0002
#define FAT_CLST_BAD 0xfff7
#define FAT_CLST_LAST1 0xfff8
#define FAT_CLST_LAST8 0xffff
 
/** Convert cluster number to an index within a FAT.
*
* Format Identifier and cluster numbering is considered.
*/
#define C2FAT_IDX(c) (1 + (c) - FAT_CLST_FIRST)
 
static block_t *fat_block_get(dev_handle_t dev_handle, fs_index_t index,
off_t offset)
{
block_t *bb;
block_t *b;
unsigned bps;
unsigned spc;
unsigned rscnt; /* block address of the first FAT */
unsigned fatcnt;
unsigned rde;
unsigned rds; /* root directory size */
unsigned sf;
unsigned ssa; /* size of the system area */
unsigned clusters;
unsigned clst = index;
unsigned i;
 
bb = block_get(dev_handle, BS_BLOCK);
bps = uint16_t_le2host(FAT_BS(bb)->bps);
spc = FAT_BS(bb)->spc;
rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt);
fatcnt = FAT_BS(bb)->fatcnt;
rde = uint16_t_le2host(FAT_BS(bb)->root_ent_max);
sf = uint16_t_le2host(FAT_BS(bb)->sec_per_fat);
block_put(bb);
 
rds = (sizeof(fat_dentry_t) * rde) / bps;
rds += ((sizeof(fat_dentry_t) * rde) % bps != 0);
ssa = rscnt + fatcnt * sf + rds;
 
if (!index) {
/* root directory special case */
assert(offset < rds);
b = block_get(dev_handle, rscnt + fatcnt * sf + offset);
return b;
}
 
clusters = offset / spc;
for (i = 0; i < clusters; i++) {
unsigned fsec; /* sector offset relative to FAT1 */
unsigned fidx; /* FAT1 entry index */
 
assert(clst >= FAT_CLST_FIRST && clst < FAT_CLST_BAD);
fsec = (C2FAT_IDX(clst) * sizeof(uint16_t)) / bps;
fidx = C2FAT_IDX(clst) % (bps / sizeof(uint16_t));
/* read FAT1 */
b = block_get(dev_handle, rscnt + fsec);
clst = uint16_t_le2host(((uint16_t *)b->data)[fidx]);
assert(clst != FAT_CLST_BAD);
assert(clst < FAT_CLST_LAST1);
block_put(b);
}
 
b = block_get(dev_handle, ssa + (clst - FAT_CLST_FIRST) * spc +
offset % spc);
 
return b;
}
 
static void fat_node_initialize(fat_node_t *node)
{
futex_initialize(&node->lock, 1);
142,7 → 210,7
bb = block_get(dev_handle, BS_BLOCK);
assert(bb != NULL);
bps = uint16_t_le2host(((fat_bs_t *)bb->data)->bps);
bps = uint16_t_le2host(FAT_BS(bb)->bps);
block_put(bb);
 
return bps;