Changeset 4cdac68 in mainline for uspace/lib/ext4/libext4_filesystem.c
- Timestamp:
- 2012-07-20T20:27:31Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade
- Children:
- b828907
- Parents:
- 865a4bf
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/libext4_filesystem.c
r865a4bf r4cdac68 78 78 79 79 /* Initialize block caching by libblock */ 80 rc = block_cache_init(service_id, block_size, 0, CACHE_MODE_W T);80 rc = block_cache_init(service_id, block_size, 0, CACHE_MODE_WB); 81 81 if (rc != EOK) { 82 82 block_fini(fs->device); … … 104 104 block_cache_fini(fs->device); 105 105 block_fini(fs->device); 106 EXT4FS_DBG(" invalid state error");106 EXT4FS_DBG("Unable to mount: Invalid state error"); 107 107 return ENOTSUP; 108 108 } … … 117 117 return rc; 118 118 } 119 120 uint16_t mnt_count = ext4_superblock_get_mount_count(fs->superblock); 121 ext4_superblock_set_mount_count(fs->superblock, mnt_count + 1); 119 122 120 123 return EOK; … … 189 192 incompatible_features &= ~EXT4_FEATURE_INCOMPAT_SUPP; 190 193 if (incompatible_features > 0) { 194 EXT4FS_DBG("Not supported incompatible features"); 191 195 return ENOTSUP; 192 196 } … … 199 203 compatible_read_only &= ~EXT4_FEATURE_RO_COMPAT_SUPP; 200 204 if (compatible_read_only > 0) { 205 EXT4FS_DBG("Not supported readonly features - mounting READ-ONLY"); 201 206 *read_only = true; 202 207 return EOK; 208 } 209 210 return EOK; 211 } 212 213 214 /** Convert block address to relative index in block group. 215 * 216 * @param sb superblock pointer 217 * @param block_addr block number to convert 218 * @return relative number of block 219 */ 220 uint32_t ext4_filesystem_blockaddr2_index_in_group(ext4_superblock_t *sb, 221 uint32_t block_addr) 222 { 223 uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb); 224 uint32_t first_block = ext4_superblock_get_first_data_block(sb); 225 226 /* First block == 0 or 1 */ 227 if (first_block == 0) { 228 return block_addr % blocks_per_group; 229 } else { 230 return (block_addr - 1) % blocks_per_group; 231 } 232 } 233 234 235 /** Convert relative block address in group to absolute address. 236 * 237 * @param sb superblock pointer 238 * @param block_addr block number to convert 239 * @return absolute block address 240 */ 241 uint32_t ext4_filesystem_index_in_group2blockaddr(ext4_superblock_t *sb, 242 uint32_t index, uint32_t bgid) 243 { 244 uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb); 245 246 if (ext4_superblock_get_first_data_block(sb) == 0) { 247 return bgid * blocks_per_group + index; 248 } else { 249 return bgid * blocks_per_group + index + 1; 250 } 251 252 } 253 254 /** Initialize block bitmap in block group. 255 * 256 * @param bg_ref reference to block group 257 * @return error code 258 */ 259 static int ext4_filesystem_init_block_bitmap(ext4_block_group_ref_t *bg_ref) 260 { 261 int rc; 262 263 /* Load bitmap */ 264 uint32_t bitmap_block_addr = ext4_block_group_get_block_bitmap( 265 bg_ref->block_group, bg_ref->fs->superblock); 266 block_t *bitmap_block; 267 268 rc = block_get(&bitmap_block, bg_ref->fs->device, 269 bitmap_block_addr, BLOCK_FLAGS_NOREAD); 270 if (rc != EOK) { 271 return rc; 272 } 273 274 uint8_t *bitmap = bitmap_block->data; 275 276 /* Initialize all bitmap bits to zero */ 277 uint32_t block_size = ext4_superblock_get_block_size(bg_ref->fs->superblock); 278 memset(bitmap, 0, block_size); 279 280 /* Determine first block and first data block in group */ 281 uint32_t first_idx = 0; 282 283 uint32_t first_data = ext4_balloc_get_first_data_block_in_group( 284 bg_ref->fs->superblock, bg_ref); 285 uint32_t first_data_idx = ext4_filesystem_blockaddr2_index_in_group( 286 bg_ref->fs->superblock, first_data); 287 288 /* Set bits from to first block to first data block - 1 to one (allocated) */ 289 for (uint32_t block = first_idx; block < first_data_idx; ++block) { 290 ext4_bitmap_set_bit(bitmap, block); 291 } 292 293 bitmap_block->dirty = true; 294 295 /* Save bitmap */ 296 rc = block_put(bitmap_block); 297 if (rc != EOK) { 298 return rc; 299 } 300 301 return EOK; 302 } 303 304 /** Initialize i-node bitmap in block group. 305 * 306 * @param bg_ref reference to block group 307 * @return error code 308 */ 309 static int ext4_filesystem_init_inode_bitmap(ext4_block_group_ref_t *bg_ref) 310 { 311 int rc; 312 313 /* Load bitmap */ 314 uint32_t bitmap_block_addr = ext4_block_group_get_inode_bitmap( 315 bg_ref->block_group, bg_ref->fs->superblock); 316 block_t *bitmap_block; 317 318 rc = block_get(&bitmap_block, bg_ref->fs->device, 319 bitmap_block_addr, BLOCK_FLAGS_NOREAD); 320 if (rc != EOK) { 321 return rc; 322 } 323 324 uint8_t *bitmap = bitmap_block->data; 325 326 /* Initialize all bitmap bits to zero */ 327 uint32_t block_size = ext4_superblock_get_block_size(bg_ref->fs->superblock); 328 uint32_t inodes_per_group = 329 ext4_superblock_get_inodes_per_group(bg_ref->fs->superblock); 330 memset(bitmap, 0, (inodes_per_group + 7) / 8); 331 332 uint32_t start_bit = inodes_per_group; 333 uint32_t end_bit = block_size * 8; 334 335 uint32_t i; 336 for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++) { 337 ext4_bitmap_set_bit(bitmap, i); 338 } 339 340 if (i < end_bit) { 341 memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3); 342 } 343 344 bitmap_block->dirty = true; 345 346 /* Save bitmap */ 347 rc = block_put(bitmap_block); 348 if (rc != EOK) { 349 return rc; 350 } 351 352 return EOK; 353 } 354 355 /** Initialize i-node table in block group. 356 * 357 * @param bg_ref reference to block group 358 * @return error code 359 */static int ext4_filesystem_init_inode_table(ext4_block_group_ref_t *bg_ref) 360 { 361 int rc; 362 363 ext4_superblock_t *sb = bg_ref->fs->superblock; 364 365 uint32_t inode_size = ext4_superblock_get_inode_size(sb); 366 uint32_t block_size = ext4_superblock_get_block_size(sb); 367 uint32_t inodes_per_block = block_size / inode_size; 368 369 uint32_t inodes_in_group = 370 ext4_superblock_get_inodes_in_group(sb, bg_ref->index); 371 372 uint32_t table_blocks = inodes_in_group / inodes_per_block; 373 374 if (inodes_in_group % inodes_per_block) { 375 table_blocks++; 376 } 377 378 /* Compute initialization bounds */ 379 uint32_t first_block = ext4_block_group_get_inode_table_first_block( 380 bg_ref->block_group, sb); 381 382 uint32_t last_block = first_block + table_blocks - 1; 383 384 /* Initialization of all itable blocks */ 385 for (uint32_t fblock = first_block; fblock <= last_block; ++fblock) { 386 block_t *block; 387 rc = block_get(&block, bg_ref->fs->device, fblock, BLOCK_FLAGS_NOREAD); 388 if (rc != EOK) { 389 return rc; 390 } 391 392 memset(block->data, 0, block_size); 393 block->dirty = true; 394 395 rc = block_put(block); 396 if (rc != EOK) { 397 return rc; 398 } 203 399 } 204 400 … … 249 445 250 446 *ref = newref; 447 448 if (ext4_block_group_has_flag(newref->block_group, 449 EXT4_BLOCK_GROUP_BLOCK_UNINIT)) { 450 451 rc = ext4_filesystem_init_block_bitmap(newref); 452 if (rc != EOK) { 453 block_put(newref->block); 454 free(newref); 455 return rc; 456 } 457 ext4_block_group_clear_flag(newref->block_group, 458 EXT4_BLOCK_GROUP_BLOCK_UNINIT); 459 460 newref->dirty = true; 461 } 462 463 if (ext4_block_group_has_flag(newref->block_group, 464 EXT4_BLOCK_GROUP_INODE_UNINIT)) { 465 466 rc = ext4_filesystem_init_inode_bitmap(newref); 467 if (rc != EOK) { 468 block_put(newref->block); 469 free(newref); 470 return rc; 471 } 472 473 ext4_block_group_clear_flag(newref->block_group, 474 EXT4_BLOCK_GROUP_INODE_UNINIT); 475 476 ext4_block_group_set_itable_unused(newref->block_group, 477 newref->fs->superblock, 0); 478 479 480 if (! ext4_block_group_has_flag(newref->block_group, 481 EXT4_BLOCK_GROUP_ITABLE_ZEROED)) { 482 483 rc = ext4_filesystem_init_inode_table(newref); 484 if (rc != EOK) { 485 return rc; 486 } 487 488 ext4_block_group_set_flag(newref->block_group, 489 EXT4_BLOCK_GROUP_ITABLE_ZEROED); 490 491 } 492 newref->dirty = true; 493 494 } 251 495 252 496 return EOK; … … 1168 1412 int ext4_filesystem_add_orphan(ext4_inode_ref_t *inode_ref) 1169 1413 { 1170 1171 EXT4FS_DBG("adding orphan \%u", inode_ref->index);1172 1173 1414 uint32_t next_orphan = ext4_superblock_get_last_orphan( 1174 1415 inode_ref->fs->superblock); … … 1192 1433 int ext4_filesystem_delete_orphan(ext4_inode_ref_t *inode_ref) 1193 1434 { 1194 1195 EXT4FS_DBG("adding orphan \%u", inode_ref->index);1196 1197 1435 int rc; 1198 1436
Note:
See TracChangeset
for help on using the changeset viewer.