Changeset 3711e7e in mainline
- Timestamp:
- 2011-10-05T09:35:12Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3712434
- Parents:
- cfa1a8a
- Location:
- uspace
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/libext4_block_group.c
rcfa1a8a r3711e7e 36 36 */ 37 37 38 #include "libext4_block_group.h" 38 #include <byteorder.h> 39 #include "libext4.h" 39 40 41 uint64_t ext4_block_group_get_inode_table_first_block(ext4_block_group_t *bg) 42 { 43 return ((uint64_t)uint32_t_le2host(bg->inode_table_first_hi) << 32) | 44 uint32_t_le2host(bg->inode_table_first_lo); 45 } 40 46 41 47 /** -
uspace/lib/ext4/libext4_block_group.h
rcfa1a8a r3711e7e 34 34 #define LIBEXT4_LIBEXT4_BLOCK_GROUP_H_ 35 35 36 #include <libblock.h> 36 37 #include <sys/types.h> 37 38 #include "libext4_block_group.h" 38 39 /* 39 40 * Structure of a blocks group descriptor … … 42 43 uint32_t block_bitmap_lo; // Blocks bitmap block 43 44 uint32_t inode_bitmap_lo; // Inodes bitmap block 44 uint32_t inode_table_ lo; // Inodes table block45 uint32_t inode_table_first_lo; // Inodes table block 45 46 uint16_t free_blocks_count_lo; // Free blocks count 46 47 uint16_t free_inodes_count_lo; // Free inodes count … … 52 53 uint32_t block_bitmap_hi; // Blocks bitmap block MSB 53 54 uint32_t inode_bitmap_hi; // Inodes bitmap block MSB 54 uint32_t inode_table_ hi; // Inodes table block MSB55 uint32_t inode_table_first_hi; // Inodes table block MSB 55 56 uint16_t free_blocks_count_hi; // Free blocks count MSB 56 57 uint16_t free_inodes_count_hi; // Free inodes count MSB … … 58 59 uint16_t itable_unused_hi; // Unused inodes count MSB 59 60 uint32_t reserved2[3]; // Padding 60 } ext4_group_desc_t; 61 } ext4_block_group_t; 62 63 typedef struct ext4_block_group_ref { 64 block_t *block; // Reference to a block containing this block group descr 65 ext4_block_group_t *block_group; 66 } ext4_block_group_ref_t; 67 68 // TODO check value 69 #define EXT4_BLOCK_GROUP_DESCRIPTOR_SIZE 32 70 71 extern uint64_t ext4_block_group_get_inode_table_first_block(ext4_block_group_t *); 61 72 62 73 #endif -
uspace/lib/ext4/libext4_directory.c
rcfa1a8a r3711e7e 36 36 */ 37 37 38 #include "libext4 _directory.h"38 #include "libext4.h" 39 39 40 40 -
uspace/lib/ext4/libext4_filesystem.c
rcfa1a8a r3711e7e 38 38 #include <errno.h> 39 39 #include <malloc.h> 40 #include "libext4 _filesystem.h"40 #include "libext4.h" 41 41 42 42 /** … … 83 83 84 84 return EOK; 85 } 86 87 /** 88 * TODO doxy 89 */ 90 void ext4_filesystem_fini(ext4_filesystem_t *fs) 91 { 92 free(fs->superblock); 93 block_fini(fs->device); 85 94 } 86 95 … … 132 141 * TODO doxy 133 142 */ 134 void ext4_filesystem_fini(ext4_filesystem_t *fs) 135 { 136 free(fs->superblock); 137 block_fini(fs->device); 138 } 139 143 int ext4_filesystem_get_block_group_ref(ext4_filesystem_t *fs, uint32_t bgid, 144 ext4_block_group_ref_t **ref) 145 { 146 int rc; 147 aoff64_t block_id; 148 uint32_t descriptors_per_block; 149 size_t offset; 150 ext4_block_group_ref_t *newref; 151 152 newref = malloc(sizeof(ext4_block_group_ref_t)); 153 if (newref == NULL) { 154 return ENOMEM; 155 } 156 157 descriptors_per_block = ext4_superblock_get_block_size(fs->superblock) 158 / EXT4_BLOCK_GROUP_DESCRIPTOR_SIZE; 159 160 /* Block group descriptor table starts at the next block after superblock */ 161 block_id = ext4_superblock_get_first_block(fs->superblock) + 1; 162 163 /* Find the block containing the descriptor we are looking for */ 164 block_id += bgid / descriptors_per_block; 165 offset = (bgid % descriptors_per_block) * EXT4_BLOCK_GROUP_DESCRIPTOR_SIZE; 166 167 rc = block_get(&newref->block, fs->device, block_id, 0); 168 if (rc != EOK) { 169 free(newref); 170 return rc; 171 } 172 173 newref->block_group = newref->block->data + offset; 174 175 *ref = newref; 176 177 return EOK; 178 } 179 180 /** 181 * TODO doxy 182 */ 183 int ext4_filesystem_get_inode_ref(ext4_filesystem_t *fs, uint32_t index, 184 ext4_inode_ref_t **ref) 185 { 186 int rc; 187 aoff64_t block_id; 188 uint32_t block_group; 189 uint32_t offset_in_group; 190 uint32_t byte_offset_in_group; 191 size_t offset_in_block; 192 uint32_t inodes_per_group; 193 uint32_t inode_table_start; 194 uint16_t inode_size; 195 uint32_t block_size; 196 ext4_block_group_ref_t *bg_ref; 197 ext4_inode_ref_t *newref; 198 199 newref = malloc(sizeof(ext4_inode_ref_t)); 200 if (newref == NULL) { 201 return ENOMEM; 202 } 203 204 inodes_per_group = ext4_superblock_get_inodes_per_group(fs->superblock); 205 206 /* inode numbers are 1-based, but it is simpler to work with 0-based 207 * when computing indices 208 */ 209 index -= 1; 210 block_group = index / inodes_per_group; 211 offset_in_group = index % inodes_per_group; 212 213 rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref); 214 if (rc != EOK) { 215 free(newref); 216 return rc; 217 } 218 219 inode_table_start = ext4_block_group_get_inode_table_first_block( 220 bg_ref->block_group); 221 222 inode_size = ext4_superblock_get_inode_size(fs->superblock); 223 block_size = ext4_superblock_get_block_size(fs->superblock); 224 225 byte_offset_in_group = offset_in_group * inode_size; 226 227 block_id = inode_table_start + (byte_offset_in_group / block_size); 228 offset_in_block = byte_offset_in_group % block_size; 229 230 rc = block_get(&newref->block, fs->device, block_id, 0); 231 if (rc != EOK) { 232 free(newref); 233 return rc; 234 } 235 236 newref->inode = newref->block->data + offset_in_block; 237 /* we decremented index above, but need to store the original value 238 * in the reference 239 */ 240 newref->index = index+1; 241 242 *ref = newref; 243 244 return EOK; 245 } 140 246 141 247 /** -
uspace/lib/ext4/libext4_filesystem.h
rcfa1a8a r3711e7e 35 35 36 36 #include <libblock.h> 37 #include "libext4_block_group.h" 38 #include "libext4_inode.h" 37 39 #include "libext4_superblock.h" 38 40 … … 42 44 } ext4_filesystem_t; 43 45 44 #define EXT4_MAX_BLOCK_SIZE 65536 //64 KiB45 46 #define EXT4_MAX_BLOCK_SIZE 65536 //64 KiB 47 #define EXT4_REV0_INODE_SIZE 128 46 48 47 49 /* Compatible features */ … … 99 101 100 102 extern int ext4_filesystem_init(ext4_filesystem_t *, service_id_t); 103 extern void ext4_filesystem_fini(ext4_filesystem_t *fs); 101 104 extern int ext4_filesystem_check_sanity(ext4_filesystem_t *fs); 102 105 extern int ext4_filesystem_check_features(ext4_filesystem_t *, bool *); 103 extern void ext4_filesystem_fini(ext4_filesystem_t *fs); 106 extern int ext4_filesystem_get_block_group_ref(ext4_filesystem_t *, uint32_t, 107 ext4_block_group_ref_t **); 108 extern int ext4_filesystem_get_inode_ref(ext4_filesystem_t *, uint32_t, 109 ext4_inode_ref_t **); 110 104 111 105 112 #endif -
uspace/lib/ext4/libext4_inode.c
rcfa1a8a r3711e7e 37 37 38 38 #include <byteorder.h> 39 #include "libext4 _inode.h"39 #include "libext4.h" 40 40 41 41 // TODO check return type -
uspace/lib/ext4/libext4_superblock.c
rcfa1a8a r3711e7e 40 40 #include <libblock.h> 41 41 #include <malloc.h> 42 #include "libext4 _superblock.h"42 #include "libext4.h" 43 43 44 44 /** … … 80 80 { 81 81 return uint32_t_le2host(sb->rev_level); 82 } 83 84 /** 85 * TODO doxy 86 */ 87 uint16_t ext4_superblock_get_inode_size(ext4_superblock_t *sb) 88 { 89 if (ext4_superblock_get_rev_level(sb) == 0) { 90 return EXT4_REV0_INODE_SIZE; 91 } 92 return uint16_t_le2host(sb->inode_size); 93 } 94 95 /** 96 * TODO doxy 97 */ 98 uint32_t ext4_superblock_get_inodes_per_group(ext4_superblock_t *sb) 99 { 100 return uint32_t_le2host(sb->inodes_per_group); 82 101 } 83 102 -
uspace/lib/ext4/libext4_superblock.h
rcfa1a8a r3711e7e 51 51 uint32_t s_blocks_per_group; // Number of blocks per group 52 52 uint32_t s_obso_frags_per_group; // Obsoleted fragments per group 53 uint32_t s_inodes_per_group; // Number of inodes per group53 uint32_t inodes_per_group; // Number of inodes per group 54 54 uint32_t s_mtime; // Mount time 55 55 uint32_t s_wtime; // Write time … … 69 69 // Fields for EXT4_DYNAMIC_REV superblocks only. 70 70 uint32_t s_first_ino; // First non-reserved inode 71 uint16_t s_inode_size; // Size of inode structure71 uint16_t inode_size; // Size of inode structure 72 72 uint16_t s_block_group_nr; // Block group number of this superblock 73 73 uint32_t features_compatible; // Compatible feature set … … 147 147 extern uint32_t ext4_superblock_get_block_size(ext4_superblock_t *); 148 148 extern uint32_t ext4_superblock_get_rev_level(ext4_superblock_t *); 149 extern uint16_t ext4_superblock_get_inode_size(ext4_superblock_t *); 150 extern uint32_t ext4_superblock_get_inodes_per_group(ext4_superblock_t *); 149 151 extern uint32_t ext4_superblock_get_features_compatible(ext4_superblock_t *); 150 152 extern uint32_t ext4_superblock_get_features_incompatible(ext4_superblock_t *); -
uspace/srv/fs/ext4fs/ext4fs_ops.c
rcfa1a8a r3711e7e 42 42 #include <malloc.h> 43 43 #include <stdio.h> 44 #include <adt/hash_table.h> 44 45 #include <ipc/loc.h> 45 46 #include "ext4fs.h" … … 48 49 #define EXT4FS_NODE(node) ((node) ? (ext4fs_node_t *) (node)->data : NULL) 49 50 #define EXT4FS_DBG(format, ...) {if (true) printf("ext4fs: %s: " format "\n", __FUNCTION__, ##__VA_ARGS__);} 51 52 #define OPEN_NODES_KEYS 2 53 #define OPEN_NODES_DEV_HANDLE_KEY 0 54 #define OPEN_NODES_INODE_KEY 1 55 #define OPEN_NODES_BUCKETS 256 50 56 51 57 typedef struct ext4fs_instance { … … 96 102 static LIST_INITIALIZE(instance_list); 97 103 static FIBRIL_MUTEX_INITIALIZE(instance_list_mutex); 104 static hash_table_t open_nodes; 98 105 static FIBRIL_MUTEX_INITIALIZE(open_nodes_lock); 99 106 100 101 /** 102 * TODO doxy 103 */ 107 /* Hash table interface for open nodes hash table */ 108 static hash_index_t open_nodes_hash(unsigned long key[]) 109 { 110 /* TODO: This is very simple and probably can be improved */ 111 return key[OPEN_NODES_INODE_KEY] % OPEN_NODES_BUCKETS; 112 } 113 114 static int open_nodes_compare(unsigned long key[], hash_count_t keys, 115 link_t *item) 116 { 117 ext4fs_node_t *enode = hash_table_get_instance(item, ext4fs_node_t, link); 118 assert(keys > 0); 119 if (enode->instance->service_id != 120 ((service_id_t) key[OPEN_NODES_DEV_HANDLE_KEY])) { 121 return false; 122 } 123 if (keys == 1) { 124 return true; 125 } 126 assert(keys == 2); 127 return (enode->inode_ref->index == key[OPEN_NODES_INODE_KEY]); 128 } 129 130 static void open_nodes_remove_cb(link_t *link) 131 { 132 /* We don't use remove callback for this hash table */ 133 } 134 135 static hash_table_operations_t open_nodes_ops = { 136 .hash = open_nodes_hash, 137 .compare = open_nodes_compare, 138 .remove_callback = open_nodes_remove_cb, 139 }; 140 141 104 142 int ext4fs_global_init(void) 105 143 { 106 // TODO 107 return EOK; 108 } 109 110 /** 111 * TODO doxy 112 */ 144 if (!hash_table_create(&open_nodes, OPEN_NODES_BUCKETS, 145 OPEN_NODES_KEYS, &open_nodes_ops)) { 146 return ENOMEM; 147 } 148 return EOK; 149 } 150 151 113 152 int ext4fs_global_fini(void) 114 153 { 115 // TODO154 hash_table_destroy(&open_nodes); 116 155 return EOK; 117 156 } … … 122 161 */ 123 162 124 /**125 * TODO doxy126 */127 163 int ext4fs_instance_get(service_id_t service_id, ext4fs_instance_t **inst) 128 164 { 165 EXT4FS_DBG(""); 166 129 167 ext4fs_instance_t *tmp; 130 168 131 169 fibril_mutex_lock(&instance_list_mutex); 170 171 EXT4FS_DBG("Checking lists"); 132 172 133 173 if (list_empty(&instance_list)) { … … 135 175 return EINVAL; 136 176 } 177 178 EXT4FS_DBG("checked"); 137 179 138 180 list_foreach(instance_list, link) { … … 146 188 } 147 189 190 EXT4FS_DBG("Not found"); 191 148 192 fibril_mutex_unlock(&instance_list_mutex); 149 193 return EINVAL; 150 194 } 151 195 152 /** 153 * TODO doxy 154 */ 196 155 197 int ext4fs_root_get(fs_node_t **rfn, service_id_t service_id) 156 198 { … … 158 200 } 159 201 160 /** 161 * TODO doxy 162 */ 202 163 203 int ext4fs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component) 164 204 { … … 167 207 } 168 208 169 /** 170 * TODO doxy 171 */ 209 172 210 int ext4fs_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index) 173 211 { … … 183 221 } 184 222 185 /** 186 * TODO doxy 187 */ 223 188 224 int ext4fs_node_get_core(fs_node_t **rfn, ext4fs_instance_t *inst, 189 225 fs_index_t index) 190 226 { 191 // TODO 192 return EOK; 193 } 194 195 /** 196 * TODO doxy 197 */ 227 228 int rc; 229 fs_node_t *node = NULL; 230 ext4fs_node_t *enode = NULL; 231 232 ext4_inode_ref_t *inode_ref = NULL; 233 234 fibril_mutex_lock(&open_nodes_lock); 235 236 /* Check if the node is not already open */ 237 unsigned long key[] = { 238 [OPEN_NODES_DEV_HANDLE_KEY] = inst->service_id, 239 [OPEN_NODES_INODE_KEY] = index, 240 }; 241 link_t *already_open = hash_table_find(&open_nodes, key); 242 243 if (already_open) { 244 enode = hash_table_get_instance(already_open, ext4fs_node_t, link); 245 *rfn = enode->fs_node; 246 enode->references++; 247 248 fibril_mutex_unlock(&open_nodes_lock); 249 return EOK; 250 } 251 252 enode = malloc(sizeof(ext4fs_node_t)); 253 if (enode == NULL) { 254 fibril_mutex_unlock(&open_nodes_lock); 255 return ENOMEM; 256 } 257 258 node = malloc(sizeof(fs_node_t)); 259 if (node == NULL) { 260 free(enode); 261 fibril_mutex_unlock(&open_nodes_lock); 262 return ENOMEM; 263 } 264 fs_node_initialize(node); 265 266 rc = ext4_filesystem_get_inode_ref(inst->filesystem, index, &inode_ref); 267 if (rc != EOK) { 268 free(enode); 269 free(node); 270 fibril_mutex_unlock(&open_nodes_lock); 271 return rc; 272 } 273 274 enode->inode_ref = inode_ref; 275 enode->instance = inst; 276 enode->references = 1; 277 enode->fs_node = node; 278 link_initialize(&enode->link); 279 280 node->data = enode; 281 *rfn = node; 282 283 hash_table_insert(&open_nodes, key, &enode->link); 284 inst->open_nodes_count++; 285 286 fibril_mutex_unlock(&open_nodes_lock); 287 288 return EOK; 289 } 290 291 198 292 int ext4fs_node_put_core(ext4fs_node_t *enode) { 199 293 // TODO … … 201 295 } 202 296 203 /** 204 * TODO doxy 205 */ 297 206 298 int ext4fs_node_open(fs_node_t *fn) 207 299 { … … 233 325 } 234 326 327 235 328 int ext4fs_create_node(fs_node_t **rfn, service_id_t service_id, int flags) 236 329 { … … 239 332 } 240 333 334 241 335 int ext4fs_destroy_node(fs_node_t *fn) 242 336 { … … 245 339 } 246 340 341 247 342 int ext4fs_link(fs_node_t *pfn, fs_node_t *cfn, const char *name) 248 343 { … … 251 346 } 252 347 348 253 349 int ext4fs_unlink(fs_node_t *pfn, fs_node_t *cfn, const char *nm) 254 350 { … … 257 353 } 258 354 355 259 356 int ext4fs_has_children(bool *has_children, fs_node_t *fn) 260 357 { … … 270 367 } 271 368 369 272 370 aoff64_t ext4fs_size_get(fs_node_t *fn) 273 371 { … … 276 374 } 277 375 376 278 377 unsigned ext4fs_lnkcnt_get(fs_node_t *fn) 279 378 { … … 282 381 } 283 382 383 284 384 bool ext4fs_is_directory(fs_node_t *fn) 285 385 { … … 288 388 } 289 389 390 290 391 bool ext4fs_is_file(fs_node_t *fn) 291 392 { … … 293 394 return false; 294 395 } 396 295 397 296 398 service_id_t ext4fs_service_get(fs_node_t *fn) … … 327 429 */ 328 430 329 /**330 * TODO doxy331 */332 431 static int ext4fs_mounted(service_id_t service_id, const char *opts, 333 432 fs_index_t *index, aoff64_t *size, unsigned *lnkcnt) 334 433 { 335 336 EXT4FS_DBG("Mounting...");337 434 338 435 int rc; … … 353 450 return ENOMEM; 354 451 } 355 356 EXT4FS_DBG("Basic structures allocated");357 452 358 453 /* Initialize the filesystem */ … … 363 458 return rc; 364 459 } 365 366 EXT4FS_DBG("initialized");367 460 368 461 /* Do some sanity checking */ … … 375 468 } 376 469 377 EXT4FS_DBG("Checked and clean");378 379 470 /* Check flags */ 380 471 rc = ext4_filesystem_check_features(fs, &read_only); … … 386 477 } 387 478 388 EXT4FS_DBG("Features checked");389 390 479 /* Initialize instance */ 391 480 link_initialize(&inst->link); … … 394 483 inst->open_nodes_count = 0; 395 484 396 EXT4FS_DBG("Instance initialized");397 398 485 /* Read root node */ 399 486 fs_node_t *root_node; 400 rc = ext4fs_ root_get(&root_node, inst->service_id);487 rc = ext4fs_node_get_core(&root_node, inst, EXT4_INODE_ROOT_INDEX); 401 488 if (rc != EOK) { 402 489 ext4_filesystem_fini(fs); … … 407 494 ext4fs_node_t *enode = EXT4FS_NODE(root_node); 408 495 409 EXT4FS_DBG("Root node found");410 411 496 /* Add instance to the list */ 412 497 fibril_mutex_lock(&instance_list_mutex); … … 414 499 fibril_mutex_unlock(&instance_list_mutex); 415 500 416 EXT4FS_DBG("Instance added");417 418 501 *index = EXT4_INODE_ROOT_INDEX; 419 502 *size = 0; 420 503 *lnkcnt = ext4_inode_get_usage_count(enode->inode_ref->inode); 421 504 422 EXT4FS_DBG("Return values set");423 424 505 ext4fs_node_put(root_node); 425 506 426 EXT4FS_DBG("Mounting finished"); 427 428 return EOK; 429 } 430 431 /** 432 * TODO doxy 433 */ 507 return EOK; 508 } 509 510 434 511 static int ext4fs_unmounted(service_id_t service_id) 435 512 { … … 463 540 } 464 541 465 /** 466 * TODO doxy 467 */ 542 468 543 static int 469 544 ext4fs_read(service_id_t service_id, fs_index_t index, aoff64_t pos, … … 474 549 } 475 550 476 /** 477 * TODO doxy 478 */ 551 479 552 static int 480 553 ext4fs_write(service_id_t service_id, fs_index_t index, aoff64_t pos, … … 485 558 } 486 559 487 /** 488 * TODO doxy 489 */ 560 490 561 static int 491 562 ext4fs_truncate(service_id_t service_id, fs_index_t index, aoff64_t size) … … 495 566 } 496 567 497 /** 498 * TODO doxy 499 */ 568 500 569 static int ext4fs_close(service_id_t service_id, fs_index_t index) 501 570 { … … 504 573 } 505 574 506 /** 507 * TODO doxy 508 */ 575 509 576 static int ext4fs_destroy(service_id_t service_id, fs_index_t index) 510 577 { … … 513 580 } 514 581 515 /** 516 * TODO doxy 517 */ 582 518 583 static int ext4fs_sync(service_id_t service_id, fs_index_t index) 519 584 {
Note:
See TracChangeset
for help on using the changeset viewer.