code:bmap - ikarishinjieva/unixV6-code-analyze-chs GitHub Wiki
- 给定文件中相应的块号返回该块的实际物理块号
- 传入两个参数,ip,nb
- ip:文件对应的内存inode
- nb:指定的在文件中的相应块号
6407
6408 /* Bmap defines the structure of file system storage
6409 * by returning the physical block number on a device given
6410 * the inode and the logical block number in a file.
6411 * When convenient, it also leaves the physical
6412 * block number of the next block of the file in rablock
6413 * for use in read-ahead.
6414 */
6415 bmap(ip, bn)
6416 struct inode *ip;
6417 int bn;
6418 {
6419 register *bp, *bap, nb;
6420 int *nbp, d, i;
6421
6422 d = ip->i_dev;
6423 if(bn & ~077777) {
6424 u.u_error = EFBIG;
6425 return(0);
6426 }
6427 if((ip->i_mode&ILARG) == 0) {
6428
- 判断是否含ILARG标志,包含表明为大文件.详见ino.h
6429 /* small file algorithm */
6430
6431 if((bn & ~7) != 0) {
6432
- 判断块号是否大于七,(小于则仍为小型文件,大于表明要进行扩展)
6433 /* convert small to large */
6434
6435 if ((bp = alloc(d)) == NULL)
6436 return(NULL);
6437 bap = bp->b_addr;
6438 for(i=0; i<8; i++) {
6439 *bap++ = ip->i_addr[i];
6440 ip->i_addr[i] = 0;
6441 }
6442 ip->i_addr[0] = bp->b_blkno;
6443 bdwrite(bp);
6444 ip->i_mode =| ILARG;
- 此处之所以要写将bp写回是因为在调用alloc(d)时清空了bp的内容,此时bp的内容与磁盘上对应块的内容不同,于是采取延迟写策略写回磁盘
6445 goto large;
6446 }
6447 nb = ip->i_addr[bn];
6448 if(nb == 0 && (bp = alloc(d)) != NULL) {
6449 bdwrite(bp);
6450 nb = bp->b_blkno;
6451 ip->i_addr[bn] = nb;
6452 ip->i_flag =| IUPD;
6453 }
6454 rablock = 0;
6455 if (bn<7)
6456 rablock = ip->i_addr[bn+1];
6457 return(nb);
- 如果bn指示的块号小于7,则将预读块置为其下一块的物理地址.关于rablock的定义,见systm.h第235行
6458 }
6459
6460 /* large file algorithm */
6461
6462 large:
6463 i = bn>>8;
6464 if(bn & 0174000)
6465 i = 7;
6466 if((nb=ip->i_addr[i]) == 0) {
- 若bn >= 8*256,则(i = bn>>8) >= 8,此时将i置为7
6467 ip->i_flag =| IUPD;
6468 if ((bp = alloc(d)) == NULL)
6469 return(NULL);
6470 ip->i_addr[i] = bp->b_blkno;
6471 } else
6472 bp = bread(d, nb);
6473 bap = bp->b_addr;
6474
6475 /* "huge" fetch of double indirect block */
6476
6477 if(i == 7) {
6478 i = ((bn>>8) & 0377) - 7;
6479 if((nb=bap[i]) == 0) {
6480 if((nbp = alloc(d)) == NULL) {
6481 brelse(bp);
6482 return(NULL);
6483 }
6484 bap[i] = nbp->b_blkno;
6485 bdwrite(bp);
6486 } else {
- 由于bp的内容已与磁盘中对应块中内容不符,故需延迟写回磁盘以更新
6487 brelse(bp);
6488 nbp = bread(d, nb);
6489 }
6490 bp = nbp;
6491 bap = bp->b_addr;
6492 }
6493
6494 /* normal indirect fetch */
6495
6496 i = bn & 0377;
6497 if((nb=bap[i]) == 0 && (nbp = alloc(d)) != NULL) {
6498 nb = nbp->b_blkno;
6499 bap[i] = nb;
6500 bdwrite(nbp);
6501 bdwrite(bp);
6502 } else
- 由于bp,nbp的内容已与磁盘中对应块中内容不符,故需延迟写回磁盘以更新
6503 brelse(bp);
6504 rablock = 0;
6505 if(i < 255)
6506 rablock = bap[i+1];
6507 return(nb);
- 如果bn指示的块号小于255,则将预读块置为其下一块的物理地址.关于rablock的定义,见systm.h第235行
6508 }
6509 /* ------------------------- */