1.3.2 得到文件的逻辑块号
继续走,233行,设置map_bh的b_page字段为当前page。随后进入循环,对于页中的每一块,调用ext2文件系统的get_block函数,作为参数传递page的inode、相对于文件起始位置的块索引block_in_file、map_bh进去,最后返回相对于磁盘分区开始位置的逻辑块号,即相对于磁盘或分区开始位置的块索引,存放在结果参数map_bh的b_blocknr字段中。所以这里我们重点关注get_block的原型,ext2_get_block函数,来自fs/ext2/inode.c:
547int ext2_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) 548{ 549 int err = -EIO; 550 int offsets[4]; 551 Indirect chain[4]; 552 Indirect *partial; 553 unsigned long goal; 554 int left; 555 int boundary = 0; 556 int depth = ext2_block_to_path(inode, iblock, offsets, &boundary); 557 558 if (depth == 0) 559 goto out; 560 561reread: 562 partial = ext2_get_branch(inode, depth, offsets, chain, &err); 563 564 /* Simplest case - block found, no allocation needed */ 565 if (!partial) { 566got_it: 567 map_bh(bh_result, inode->i_sb, le32_to_cpu(chain[depth-1].key)); 568 if (boundary) 569 set_buffer_boundary(bh_result); 570 /* Clean up and exit */ 571 partial = chain+depth-1; /* the whole chain */ 572 goto cleanup; 573 } 574 575 /* Next simple case - plain lookup or failed read of indirect block */ 576 if (!create || err == -EIO) { 577cleanup: 578 while (partial > chain) { 579 brelse(partial->bh); 580 partial--; 581 } 582out: 583 return err; 584 } 585 586 /* 587 * Indirect block might be removed by truncate while we were 588 * reading it. Handling of that case (forget what we've got and 589 * reread) is taken out of the main path. 590 */ |