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

Table of Contents

Source

  • 得到 指定设备 指定inode号 的inode块(并置锁)
  • 若该inode装载某子文件系统,则返回该子文件系统的超级块
  • 共传入2个参数 dev ino
    • dev : 指定设备的设备号
    • ino : 指定inode的编号
  • 返回值
    • 若出错,则返回NULL
    • 否则,返回 指向 得到的内存INDOE 的指针

7258

7259 /*

7260  * Look up an inode by device,inumber.

7261  * If it is in core (in the inode structure),

7262  * honor the locking protocol.

7263  * If it is not in core, read it in from the

7264  * specified device.

7265  * If the inode is mounted on, perform

7266  * the indicated indirection.

7267  * In all cases, a pointer to a locked

7268  * inode structure is returned.

7269  *

7270  * printf warning: no inodes -- if the inode

7271  * structure is full

7272  * panic: no imt -- if the mounted file

7273  * system is not in the mount table.

7274  * "cannot happen"

7275  */

7276 iget(dev, ino)

7277 {

7278     register struct inode *p;

7279     register *ip2;

7280     int *ip1;

7281     register struct mount *ip;

7282

7283 loop:

7284     ip = NULL;

7285     for(p = &inode[0]; p< &inode[NINODE]; p++) {

7286          if(dev==p->i_dev && ino==p->i_number) {

7287           if((p->i_flag&ILOCK) != 0) {

7288                p->i_flag =| IWANT;

7289                sleep(p, PINOD);

7290                goto loop;

7291           }

7292           if((p->i_flag&IMOUNT) != 0) {

7293                for (ip = &mount[0];

7294                         ip < &mount[NMOUNT]; ip++)

7295                     if (ip->m_inodp == p) {

7296                         dev = ip->m_dev;

7297                         ino = ROOTINO;

7298                         goto loop;

7299                     }

  • 若 指定寻找的INODE 装载了 子文件系统
  • 则 重新调用 iget,返回该子文件系统的 超级块
7300                panic("no imt");

7301           }

7302           p->i_count++;

7303           p->i_flag =| ILOCK;

7304           return(p);

7305          }

7306          if(ip==NULL && p->i_count==0)

7307          ip = p;

  • 7306 - 7307 在循环中 用于寻找INODE数组中第一个 可用元素(空闲INODE),用于写入新的INODE信息
7308     }

7309     if((p=ip) == NULL) {

7310          printf("Inode table overflow \n");

7311          u.u_error = ENFILE;

7312          return(NULL);

7313     }

  • 若找不到INODE数组中 可用元素(空闲INODE)
  • 则输出错误信息,抛出错误,并返回NULL
7314     p->i_dev = dev;

7315     p->i_number = ino;

7316     p->i_flag = ILOCK;

7317     p->i_count++;

7318     p->i_lastr = -1;

7319     ip = bread(dev, ldiv(ino+31,16));

7320     /*

7321      * Check I/O errors

7322      */

7323     if (ip->b_flags&B_ERROR) {

7324          brelse(ip);

7325          iput(p);

7326          return(NULL);

7327     }

7328     ip1 = ip->b_addr + 32*lrem(ino+31, 16);

  • 由于inode区是从磁盘的第2块开始的,参看文件系统
  • rp->i_number表示磁盘上对应INODE在磁盘inode区的号码,且从1开始计数
  • 故(i_number + 31)%16表示该磁盘inode在所在磁盘块中是第几块,再乘以32(ionde结构所含字节数)即表明该inode在块中的相对偏移地址
  • ip1为ip中该INODE的起始地址
7329     ip2 = &p->i_mode;
  • ip2为内存块的起始地址
7330     while(ip2 < &p->i_addr[8])

7331          *ip2++ = *ip1++;

7332     brelse(ip);

  • 将缓存中的信息复制到内存inode中
  • 释放缓存
7333     return(p);

7334 }

7335 /* ------------------------- */

Extend

附图

Ref

Caller

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