code:bmap - ikarishinjieva/unixV6-code-analyze-chs GitHub Wiki

Table of Contents

Source

  • 给定文件中相应的块号返回该块的实际物理块号
  • 传入两个参数,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) {

  • 判断是否含ILARG标志,包含表明为大文件.详见ino.h
6428

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);

  • 此处之所以要写将bp写回是因为在调用alloc(d)时清空了bp的内容,此时bp的内容与磁盘上对应块的内容不同,于是采取延迟写策略写回磁盘
6444           ip->i_mode =| ILARG;

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];

  • 如果bn指示的块号小于7,则将预读块置为其下一块的物理地址.关于rablock的定义,见systm.h第235行
6457          return(nb);

6458     }

6459

6460 /* large file algorithm */

6461

6462      large:

6463     i = bn>>8;

6464     if(bn & 0174000)

6465          i = 7;

  • 若bn >= 8*256,则(i = bn>>8) >= 8,此时将i置为7
6466     if((nb=ip->i_addr[i]) == 0) {

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);

  • 由于bp的内容已与磁盘中对应块中内容不符,故需延迟写回磁盘以更新
6486          } else {

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);

  • 由于bp,nbp的内容已与磁盘中对应块中内容不符,故需延迟写回磁盘以更新
6502     } else

6503          brelse(bp);

6504     rablock = 0;

6505     if(i < 255)

6506          rablock = bap[i+1];

  • 如果bn指示的块号小于255,则将预读块置为其下一块的物理地址.关于rablock的定义,见systm.h第235行
6507     return(nb);

6508 }

6509 /* ------------------------- */

Extend

附图

Ref

文件系统

Caller

⚠️ **GitHub.com Fallback** ⚠️