Changeset 869e546 in mainline
- Timestamp:
- 2008-04-20T22:37:13Z (17 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 297f1197
- Parents:
- 34f62f8
- Location:
- uspace/srv/fs/fat
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat.h
r34f62f8 r869e546 140 140 } __attribute__ ((packed)) fat_dentry_t; 141 141 142 typedef uint16_t fat_cluster_t; 143 142 144 typedef enum { 143 145 FAT_INVALID, … … 146 148 } fat_node_type_t; 147 149 150 struct fat_node; 151 152 /** FAT index structure. 153 * 154 * This structure exists to help us to overcome certain limitations of the FAT 155 * file system design. The problem with FAT is that it is hard to find 156 * an entity which could represent a VFS index. There are two candidates: 157 * 158 * a) number of the node's first cluster 159 * b) the pair of the parent directory's first cluster and the dentry index 160 * within the parent directory 161 * 162 * We need VFS indices to be: 163 * A) unique 164 * B) stable in time, at least until the next mount 165 * 166 * Unfortunately a) does not meet the A) criterion because zero-length files 167 * will have the first cluster field cleared. And b) does not meet the B) 168 * criterion because unlink() and rename() will both free up the original 169 * dentry, which contains all the essential info about the file. 170 * 171 * Therefore, a completely opaque indices are used and the FAT server maintains 172 * a mapping between them and otherwise nice b) variant. On rename(), the VFS 173 * index stays unaltered, while the internal FAT "physical tree address" 174 * changes. The unlink case is also handled this way thanks to an in-core node 175 * pointer embedded in the index structure. 176 */ 177 typedef struct { 178 dev_handle_t dev_handle; 179 fs_index_t index; 180 /** 181 * Parent first cluster. 182 * Zero is used if this node is not linked, in which case nodep must 183 * contain a pointer to the in-core node structure. 184 * One is used when the parent is the root directory. 185 */ 186 fat_cluster_t pfc; 187 /** Parent directory entry index. */ 188 unsigned pdi; 189 /** Pointer to in-core node instance. */ 190 struct fat_node *nodep; 191 } fat_idx_t; 192 148 193 /** FAT in-core node. */ 149 typedef struct { 150 /** Protects an instance of this type. */ 151 futex_t lock; 194 typedef struct fat_node { 152 195 fat_node_type_t type; 153 /** VFS index is the node's first allocated cluster. */ 154 fs_index_t index; 155 /** VFS index of the parent node. */ 156 fs_index_t pindex; 157 dev_handle_t dev_handle; 196 fat_idx_t *idx; 197 /** 198 * Node's first cluster. 199 * Zero is used for zero-length nodes. 200 * One is used to mark root directory. 201 */ 202 fat_cluster_t firstc; 158 203 /** FAT in-core node hash table link. */ 159 204 link_t fin_link; -
uspace/srv/fs/fat/fat_ops.c
r34f62f8 r869e546 54 54 #define FIN_KEY_INDEX 1 55 55 56 /** Futex protecting both fin_hash and ffn_head. */57 futex_t fin_futex = FUTEX_INITIALIZER;58 59 56 /** Hash table of FAT in-core nodes. */ 60 57 hash_table_t fin_hash; … … 116 113 } 117 114 115 static fat_idx_t *fat_idx_map(fat_cluster_t pfc, unsigned pdi) 116 { 117 return NULL; /* TODO */ 118 } 118 119 119 120 #define FAT_BS(b) ((fat_bs_t *)((b)->data)) 120 121 122 #define FAT_CLST_RES0 0x0000 123 #define FAT_CLST_RES1 0x0001 /* internally used to mark root directory */ 121 124 #define FAT_CLST_FIRST 0x0002 122 125 #define FAT_CLST_BAD 0xfff7 … … 124 127 #define FAT_CLST_LAST8 0xffff 125 128 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) 129 static block_t *fat_block_get(fat_node_t *nodep, off_t offset) 134 130 { 135 131 block_t *bb; … … 144 140 unsigned ssa; /* size of the system area */ 145 141 unsigned clusters; 146 unsigned clst = index;142 fat_cluster_t clst = nodep->firstc; 147 143 unsigned i; 148 144 149 bb = block_get( dev_handle, BS_BLOCK);145 bb = block_get(nodep->idx->dev_handle, BS_BLOCK); 150 146 bps = uint16_t_le2host(FAT_BS(bb)->bps); 151 147 spc = FAT_BS(bb)->spc; … … 160 156 ssa = rscnt + fatcnt * sf + rds; 161 157 162 if ( !index) {158 if (nodep->idx->index == FAT_CLST_RES1) { 163 159 /* root directory special case */ 164 160 assert(offset < rds); 165 b = block_get(dev_handle, rscnt + fatcnt * sf + offset); 161 b = block_get(nodep->idx->dev_handle, 162 rscnt + fatcnt * sf + offset); 166 163 return b; 167 164 } … … 173 170 174 171 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));172 fsec = (clst * sizeof(fat_cluster_t)) / bps; 173 fidx = clst % (bps / sizeof(fat_cluster_t)); 177 174 /* read FAT1 */ 178 b = block_get( dev_handle, rscnt + fsec);179 clst = uint16_t_le2host((( uint16_t *)b->data)[fidx]);175 b = block_get(nodep->idx->dev_handle, rscnt + fsec); 176 clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]); 180 177 assert(clst != FAT_CLST_BAD); 181 178 assert(clst < FAT_CLST_LAST1); … … 183 180 } 184 181 185 b = block_get( dev_handle, ssa + (clst - FAT_CLST_FIRST) * spc+186 offset % spc);182 b = block_get(nodep->idx->dev_handle, ssa + 183 (clst - FAT_CLST_FIRST) * spc + offset % spc); 187 184 188 185 return b; … … 191 188 static void fat_node_initialize(fat_node_t *node) 192 189 { 193 futex_initialize(&node->lock, 1);190 node->idx = NULL; 194 191 node->type = 0; 195 node->index = 0;196 node->pindex = 0;197 node->dev_handle = 0;198 192 link_initialize(&node->fin_link); 199 193 link_initialize(&node->ffn_link); … … 295 289 block_t *b; 296 290 297 bps = fat_bps_get(parentp-> dev_handle);291 bps = fat_bps_get(parentp->idx->dev_handle); 298 292 dps = bps / sizeof(fat_dentry_t); 299 293 blocks = parentp->size / bps + (parentp->size % bps != 0); … … 301 295 unsigned dentries; 302 296 303 b = fat_block_get(parentp ->dev_handle, parentp->index, i);297 b = fat_block_get(parentp, i); 304 298 dentries = (i == blocks - 1) ? 305 299 parentp->size % sizeof(fat_dentry_t) : … … 320 314 if (strcmp(name, component) == 0) { 321 315 /* hit */ 322 void *node = fat_node_get(parentp->dev_handle, 323 (fs_index_t)uint16_t_le2host(d->firstc)); 316 fat_idx_t *idx = fat_idx_map(parentp->firstc, 317 i * dps + j); 318 void *node = fat_node_get(idx->dev_handle, 319 idx->index); 324 320 block_put(b); 325 321 return node; … … 337 333 if (!fnodep) 338 334 return 0; 339 return fnodep->i ndex;335 return fnodep->idx->index; 340 336 } 341 337 … … 362 358 return false; 363 359 364 bps = fat_bps_get(nodep-> dev_handle);360 bps = fat_bps_get(nodep->idx->dev_handle); 365 361 dps = bps / sizeof(fat_dentry_t); 366 362 … … 371 367 fat_dentry_t *d; 372 368 373 b = fat_block_get(nodep ->dev_handle, nodep->index, i);369 b = fat_block_get(nodep, i); 374 370 dentries = (i == blocks - 1) ? 375 371 nodep->size % sizeof(fat_dentry_t) : … … 399 395 static void *fat_root_get(dev_handle_t dev_handle) 400 396 { 401 return fat_node_get(dev_handle, 0);397 return fat_node_get(dev_handle, FAT_CLST_RES1); 402 398 } 403 399
Note:
See TracChangeset
for help on using the changeset viewer.