Changeset 2e07f62c in mainline
- Timestamp:
- 2010-01-31T18:11:24Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1735f3e, 7d6f7d2b
- Parents:
- ab4bace (diff), 430de97 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libblock/libblock.c
rab4bace r2e07f62c 198 198 assert(devcon); 199 199 200 if (devcon->cache) 201 (void) block_cache_fini(dev_handle); 202 200 203 devcon_remove(devcon); 201 204 202 205 if (devcon->bb_buf) 203 206 free(devcon->bb_buf); 204 205 if (devcon->cache) {206 hash_table_destroy(&devcon->cache->block_hash);207 free(devcon->cache);208 }209 207 210 208 munmap(devcon->comm_area, devcon->comm_size); … … 302 300 303 301 devcon->cache = cache; 302 return EOK; 303 } 304 305 int block_cache_fini(dev_handle_t dev_handle) 306 { 307 devcon_t *devcon = devcon_search(dev_handle); 308 cache_t *cache; 309 int rc; 310 311 if (!devcon) 312 return ENOENT; 313 if (!devcon->cache) 314 return EOK; 315 cache = devcon->cache; 316 317 /* 318 * We are expecting to find all blocks for this device handle on the 319 * free list, i.e. the block reference count should be zero. Do not 320 * bother with the cache and block locks because we are single-threaded. 321 */ 322 while (!list_empty(&cache->free_head)) { 323 block_t *b = list_get_instance(cache->free_head.next, 324 block_t, free_link); 325 326 list_remove(&b->free_link); 327 if (b->dirty) { 328 memcpy(devcon->comm_area, b->data, b->size); 329 rc = write_blocks(devcon, b->boff, 1); 330 if (rc != EOK) 331 return rc; 332 } 333 334 long key = b->boff; 335 hash_table_remove(&cache->block_hash, &key, 1); 336 337 free(b->data); 338 free(b); 339 } 340 341 hash_table_destroy(&cache->block_hash); 342 devcon->cache = NULL; 343 free(cache); 344 304 345 return EOK; 305 346 } -
uspace/lib/libblock/libblock.h
rab4bace r2e07f62c 100 100 101 101 extern int block_cache_init(dev_handle_t, size_t, unsigned, enum cache_mode); 102 extern int block_cache_fini(dev_handle_t); 102 103 103 104 extern int block_get(block_t **, dev_handle_t, bn_t, int); -
uspace/srv/fs/fat/fat_idx.c
rab4bace r2e07f62c 149 149 { 150 150 dev_handle_t dev_handle = (dev_handle_t)key[UPH_DH_KEY]; 151 fat_cluster_t pfc = (fat_cluster_t)key[UPH_PFC_KEY];152 unsigned pdi = (unsigned)key[UPH_PDI_KEY];151 fat_cluster_t pfc; 152 unsigned pdi; 153 153 fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uph_link); 154 154 155 return (dev_handle == fidx->dev_handle) && (pfc == fidx->pfc) && 156 (pdi == fidx->pdi); 155 switch (keys) { 156 case 1: 157 return (dev_handle == fidx->dev_handle); 158 case 3: 159 pfc = (fat_cluster_t) key[UPH_PFC_KEY]; 160 pdi = (unsigned) key[UPH_PDI_KEY]; 161 return (dev_handle == fidx->dev_handle) && (pfc == fidx->pfc) && 162 (pdi == fidx->pdi); 163 default: 164 assert((keys == 1) || (keys == 3)); 165 } 157 166 } 158 167 … … 197 206 { 198 207 dev_handle_t dev_handle = (dev_handle_t)key[UIH_DH_KEY]; 199 fs_index_t index = (fs_index_t)key[UIH_INDEX_KEY];208 fs_index_t index; 200 209 fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uih_link); 201 210 202 return (dev_handle == fidx->dev_handle) && (index == fidx->index); 211 switch (keys) { 212 case 1: 213 return (dev_handle == fidx->dev_handle); 214 case 2: 215 index = (fs_index_t) key[UIH_INDEX_KEY]; 216 return (dev_handle == fidx->dev_handle) && 217 (index == fidx->index); 218 default: 219 assert((keys == 1) || (keys == 2)); 220 } 203 221 } 204 222 205 223 static void idx_remove_callback(link_t *item) 206 224 { 207 /* nothing to do */ 225 fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uih_link); 226 227 free(fidx); 208 228 } 209 229 … … 486 506 [UIH_INDEX_KEY] = idx->index, 487 507 }; 508 dev_handle_t dev_handle = idx->dev_handle; 509 fs_index_t index = idx->index; 488 510 489 511 assert(idx->pfc == FAT_CLST_RES0); … … 498 520 fibril_mutex_unlock(&used_lock); 499 521 /* Release the VFS index. */ 500 fat_index_free(idx->dev_handle, idx->index); 501 /* Deallocate the structure. */ 502 free(idx); 522 fat_index_free(dev_handle, index); 523 /* The index structure itself is freed in idx_remove_callback(). */ 503 524 } 504 525 … … 543 564 void fat_idx_fini_by_dev_handle(dev_handle_t dev_handle) 544 565 { 545 unused_t *u; 546 547 u = unused_find(dev_handle, true); 566 unsigned long ikey[] = { 567 [UIH_DH_KEY] = dev_handle 568 }; 569 unsigned long pkey[] = { 570 [UPH_DH_KEY] = dev_handle 571 }; 572 573 /* 574 * Remove this instance's index structure from up_hash and ui_hash. 575 * Process up_hash first and ui_hash second because the index structure 576 * is actually removed in idx_remove_callback(). 577 */ 578 fibril_mutex_lock(&used_lock); 579 hash_table_remove(&up_hash, pkey, 1); 580 hash_table_remove(&ui_hash, ikey, 1); 581 fibril_mutex_unlock(&used_lock); 582 583 /* 584 * Free the unused and freed structures for this instance. 585 */ 586 unused_t *u = unused_find(dev_handle, true); 548 587 assert(u); 549 588 list_remove(&u->link); -
uspace/srv/fs/fat/fat_ops.c
rab4bace r2e07f62c 137 137 rc = block_put(b); 138 138 return rc; 139 } 140 141 static int fat_node_fini_by_dev_handle(dev_handle_t dev_handle) 142 { 143 link_t *lnk; 144 fat_node_t *nodep; 145 int rc; 146 147 /* 148 * We are called from fat_unmounted() and assume that there are already 149 * no nodes belonging to this instance with non-zero refcount. Therefore 150 * it is sufficient to clean up only the FAT free node list. 151 */ 152 153 restart: 154 fibril_mutex_lock(&ffn_mutex); 155 for (lnk = ffn_head.next; lnk != &ffn_head; lnk = lnk->next) { 156 nodep = list_get_instance(lnk, fat_node_t, ffn_link); 157 if (!fibril_mutex_trylock(&nodep->lock)) { 158 fibril_mutex_unlock(&ffn_mutex); 159 goto restart; 160 } 161 if (!fibril_mutex_trylock(&nodep->idx->lock)) { 162 fibril_mutex_unlock(&nodep->lock); 163 fibril_mutex_unlock(&ffn_mutex); 164 goto restart; 165 } 166 if (nodep->idx->dev_handle != dev_handle) { 167 fibril_mutex_unlock(&nodep->idx->lock); 168 fibril_mutex_unlock(&nodep->lock); 169 continue; 170 } 171 172 list_remove(&nodep->ffn_link); 173 fibril_mutex_unlock(&ffn_mutex); 174 175 /* 176 * We can unlock the node and its index structure because we are 177 * the last player on this playground and VFS is preventing new 178 * players from entering. 179 */ 180 fibril_mutex_unlock(&nodep->idx->lock); 181 fibril_mutex_unlock(&nodep->lock); 182 183 if (nodep->dirty) { 184 rc = fat_node_sync(nodep); 185 if (rc != EOK) 186 return rc; 187 } 188 nodep->idx->nodep = NULL; 189 free(nodep->bp); 190 free(nodep); 191 192 /* Need to restart because we changed the ffn_head list. */ 193 goto restart; 194 } 195 fibril_mutex_unlock(&ffn_mutex); 196 197 return EOK; 139 198 } 140 199 … … 986 1045 rc = fat_sanity_check(bs, dev_handle); 987 1046 if (rc != EOK) { 1047 (void) block_cache_fini(dev_handle); 988 1048 block_fini(dev_handle); 989 1049 ipc_answer_0(rid, rc); … … 993 1053 rc = fat_idx_init_by_dev_handle(dev_handle); 994 1054 if (rc != EOK) { 1055 (void) block_cache_fini(dev_handle); 995 1056 block_fini(dev_handle); 996 1057 ipc_answer_0(rid, rc); … … 1001 1062 fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t)); 1002 1063 if (!rfn) { 1064 (void) block_cache_fini(dev_handle); 1003 1065 block_fini(dev_handle); 1004 1066 fat_idx_fini_by_dev_handle(dev_handle); … … 1010 1072 if (!rootp) { 1011 1073 free(rfn); 1074 (void) block_cache_fini(dev_handle); 1012 1075 block_fini(dev_handle); 1013 1076 fat_idx_fini_by_dev_handle(dev_handle); … … 1021 1084 free(rfn); 1022 1085 free(rootp); 1086 (void) block_cache_fini(dev_handle); 1023 1087 block_fini(dev_handle); 1024 1088 fat_idx_fini_by_dev_handle(dev_handle); … … 1051 1115 void fat_unmounted(ipc_callid_t rid, ipc_call_t *request) 1052 1116 { 1053 ipc_answer_0(rid, ENOTSUP); 1117 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 1118 fs_node_t *fn; 1119 fat_node_t *nodep; 1120 int rc; 1121 1122 rc = fat_root_get(&fn, dev_handle); 1123 if (rc != EOK) { 1124 ipc_answer_0(rid, rc); 1125 return; 1126 } 1127 nodep = FAT_NODE(fn); 1128 1129 /* 1130 * We expect exactly two references on the root node. One for the 1131 * fat_root_get() above and one created in fat_mounted(). 1132 */ 1133 if (nodep->refcnt != 2) { 1134 (void) fat_node_put(fn); 1135 ipc_answer_0(rid, EBUSY); 1136 return; 1137 } 1138 1139 /* 1140 * Put the root node and force it to the FAT free node list. 1141 */ 1142 (void) fat_node_put(fn); 1143 (void) fat_node_put(fn); 1144 1145 /* 1146 * Perform cleanup of the node structures, index structures and 1147 * associated data. Write back this file system's dirty blocks and 1148 * stop using libblock for this instance. 1149 */ 1150 (void) fat_node_fini_by_dev_handle(dev_handle); 1151 fat_idx_fini_by_dev_handle(dev_handle); 1152 (void) block_cache_fini(dev_handle); 1153 block_fini(dev_handle); 1154 1155 ipc_answer_0(rid, EOK); 1054 1156 } 1055 1157
Note:
See TracChangeset
for help on using the changeset viewer.