Changeset add5835 in mainline for uspace/srv/fs/fat/fat_ops.c
- 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
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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.