Changeset add5835 in mainline
- Timestamp:
- 2008-05-17T20:10:54Z (17 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e811bde
- Parents:
- 78a1b7b
- Location:
- uspace/srv/fs/fat
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat.h
r78a1b7b radd5835 181 181 link_t uih_link; 182 182 183 futex_t lock; 183 184 dev_handle_t dev_handle; 184 185 fs_index_t index; … … 198 199 /** FAT in-core node. */ 199 200 typedef struct fat_node { 201 futex_t lock; 200 202 fat_node_type_t type; 201 203 fat_idx_t *idx; -
uspace/srv/fs/fat/fat_idx.c
r78a1b7b radd5835 75 75 static LIST_INITIALIZE(unused_head); 76 76 77 /** Futex protecting the up_hash and ui_hash. 78 * 79 * The locking strategy assumes that there will be at most one fibril for each 80 * dev_handle. Therefore it will be sufficient to hold the futex for shorter 81 * times (i.e. only during hash table operations as opposed to holding it the 82 * whole time between an unsuccessful find and the following insert). Should the 83 * assumption break, the locking strategy for this futex will have to be 84 * reconsidered. 85 */ 77 /** Futex protecting the up_hash and ui_hash. */ 86 78 static futex_t used_futex = FUTEX_INITIALIZER; 87 79 … … 353 345 futex_down(&used_futex); 354 346 l = hash_table_find(&up_hash, pkey); 355 futex_up(&used_futex);356 347 if (l) { 357 348 fidx = hash_table_get_instance(l, fat_idx_t, uph_link); … … 359 350 fidx = (fat_idx_t *) malloc(sizeof(fat_idx_t)); 360 351 if (!fidx) { 352 futex_up(&used_futex); 361 353 return NULL; 362 354 } 363 355 if (!fat_idx_alloc(dev_handle, &fidx->index)) { 364 356 free(fidx); 357 futex_up(&used_futex); 365 358 return NULL; 366 359 } … … 373 366 link_initialize(&fidx->uph_link); 374 367 link_initialize(&fidx->uih_link); 368 futex_initialize(&fidx->lock, 1); 375 369 fidx->dev_handle = dev_handle; 376 370 fidx->pfc = pfc; … … 378 372 fidx->nodep = NULL; 379 373 380 futex_down(&used_futex);381 374 hash_table_insert(&up_hash, pkey, &fidx->uph_link); 382 375 hash_table_insert(&ui_hash, ikey, &fidx->uih_link); 383 futex_up(&used_futex); 384 } 376 } 377 futex_down(&fidx->lock); 378 futex_up(&used_futex); 385 379 386 380 return fidx; … … 399 393 futex_down(&used_futex); 400 394 l = hash_table_find(&ui_hash, ikey); 401 futex_up(&used_futex);402 395 if (l) { 403 396 fidx = hash_table_get_instance(l, fat_idx_t, uih_link); 404 } 397 futex_down(&fidx->lock); 398 } 399 futex_up(&used_futex); 405 400 406 401 return fidx; -
uspace/srv/fs/fat/fat_ops.c
r78a1b7b radd5835 51 51 #define BS_BLOCK 0 52 52 53 /** List of free FAT nodes that still contain valid data. */ 54 LIST_INITIALIZE(ffn_head); 53 /** Futex protecting the list of cached free FAT nodes. */ 54 static futex_t ffn_futex = FUTEX_INITIALIZER; 55 56 /** List of cached free FAT nodes. */ 57 static LIST_INITIALIZE(ffn_head); 55 58 56 59 #define FAT_NAME_LEN 8 … … 180 183 static void fat_node_initialize(fat_node_t *node) 181 184 { 185 futex_initialize(&node->lock, 1); 182 186 node->idx = NULL; 183 187 node->type = 0; … … 237 241 } 238 242 239 /** Instantiate a FAT in-core node. */ 240 static void *fat_node_get(dev_handle_t dev_handle, fs_index_t index) 241 { 242 fat_idx_t *idx; 243 /** Internal version of fat_node_get(). 244 * 245 * @param idxp Locked index structure. 246 */ 247 static void *fat_node_get_core(fat_idx_t *idxp) 248 { 243 249 block_t *b; 244 250 fat_dentry_t *d; … … 247 253 unsigned dps; 248 254 249 idx = fat_idx_get_by_index(dev_handle, index); 250 if (!idx) 251 return NULL; 252 253 if (idx->nodep) { 255 if (idxp->nodep) { 254 256 /* 255 257 * We are lucky. 256 258 * The node is already instantiated in memory. 257 259 */ 258 if (!idx->nodep->refcnt++) 260 futex_down(&idxp->nodep->lock); 261 if (!idxp->nodep->refcnt++) 259 262 list_remove(&nodep->ffn_link); 260 return idx->nodep; 263 futex_up(&idxp->nodep->lock); 264 return idxp->nodep; 261 265 } 262 266 … … 265 269 */ 266 270 267 assert(idx->pfc); 268 271 assert(idxp->pfc); 272 273 futex_down(&ffn_futex); 269 274 if (!list_empty(&ffn_head)) { 270 /* Try to use a cached unused node structure. */ 275 /* Try to use a cached free node structure. */ 276 fat_idx_t *idxp_tmp; 271 277 nodep = list_get_instance(ffn_head.next, fat_node_t, ffn_link); 278 if (futex_trydown(&nodep->lock) == ESYNCH_WOULD_BLOCK) 279 goto skip_cache; 280 idxp_tmp = nodep->idx; 281 if (futex_trydown(&idxp_tmp->lock) == ESYNCH_WOULD_BLOCK) { 282 futex_up(&nodep->lock); 283 goto skip_cache; 284 } 285 list_remove(&nodep->ffn_link); 286 futex_up(&ffn_futex); 272 287 if (nodep->dirty) 273 288 fat_node_sync(nodep); 274 list_remove(&nodep->ffn_link); 275 nodep->idx->nodep = NULL; 289 idxp_tmp->nodep = NULL; 290 futex_up(&nodep->lock); 291 futex_up(&idxp_tmp->lock); 276 292 } else { 293 skip_cache: 277 294 /* Try to allocate a new node structure. */ 295 futex_up(&ffn_futex); 278 296 nodep = (fat_node_t *)malloc(sizeof(fat_node_t)); 279 297 if (!nodep) … … 282 300 fat_node_initialize(nodep); 283 301 284 bps = fat_bps_get( dev_handle);302 bps = fat_bps_get(idxp->dev_handle); 285 303 dps = bps / sizeof(fat_dentry_t); 286 304 287 305 /* Read the block that contains the dentry of interest. */ 288 b = _fat_block_get( dev_handle, idx->pfc,289 (idx ->pdi * sizeof(fat_dentry_t)) / bps);306 b = _fat_block_get(idxp->dev_handle, idxp->pfc, 307 (idxp->pdi * sizeof(fat_dentry_t)) / bps); 290 308 assert(b); 291 309 292 d = ((fat_dentry_t *)b->data) + (idx ->pdi % dps);310 d = ((fat_dentry_t *)b->data) + (idxp->pdi % dps); 293 311 if (d->attr & FAT_ATTR_SUBDIR) { 294 312 /* … … 309 327 310 328 /* Link the idx structure with the node structure. */ 311 nodep->idx = idx ;312 idx ->nodep = nodep;329 nodep->idx = idxp; 330 idxp->nodep = nodep; 313 331 314 332 return nodep; 315 333 } 316 334 335 /** Instantiate a FAT in-core node. */ 336 static void *fat_node_get(dev_handle_t dev_handle, fs_index_t index) 337 { 338 void *node; 339 fat_idx_t *idxp; 340 341 idxp = fat_idx_get_by_index(dev_handle, index); 342 if (!idxp) 343 return NULL; 344 /* idxp->lock held */ 345 node = fat_node_get_core(idxp); 346 futex_up(&idxp->lock); 347 return node; 348 } 349 317 350 static void fat_node_put(void *node) 318 351 { 319 352 fat_node_t *nodep = (fat_node_t *)node; 320 353 354 futex_down(&nodep->lock); 321 355 if (!--nodep->refcnt) { 356 futex_down(&ffn_futex); 322 357 list_append(&nodep->ffn_link, &ffn_head); 323 } 358 futex_up(&ffn_futex); 359 } 360 futex_up(&nodep->lock); 324 361 } 325 362 … … 380 417 if (strcmp(name, component) == 0) { 381 418 /* hit */ 419 void *node; 382 420 fat_idx_t *idx = fat_idx_get_by_pos( 383 421 parentp->idx->dev_handle, parentp->firstc, … … 391 429 return NULL; 392 430 } 393 void *node = fat_node_get(idx->dev_handle,394 idx->index);431 node = fat_node_get_core(idx); 432 futex_up(&idx->lock); 395 433 block_put(b); 396 434 return node; … … 433 471 return false; 434 472 473 futex_down(&nodep->idx->lock); 435 474 bps = fat_bps_get(nodep->idx->dev_handle); 436 475 dps = bps / sizeof(fat_dentry_t); … … 453 492 case FAT_DENTRY_LAST: 454 493 block_put(b); 494 futex_up(&nodep->idx->lock); 455 495 return false; 456 496 default: 457 497 case FAT_DENTRY_VALID: 458 498 block_put(b); 499 futex_up(&nodep->idx->lock); 459 500 return true; 460 501 } 461 502 block_put(b); 503 futex_up(&nodep->idx->lock); 462 504 return true; 463 505 } … … 465 507 } 466 508 509 futex_up(&nodep->idx->lock); 467 510 return false; 468 511 }
Note:
See TracChangeset
for help on using the changeset viewer.