Directory Resolution

// linux/fs/open.c int sys_open(const char* filename, int flag) { i=open_namei(filename,flag,&inode); // ... }
int open_namei(...) { dir=dir_namei(pathname,&namelen,&basename);
static struct m_inode *dir_namei() { dir=get_dir(pathname); }
static struct m_inode *get_dir(const char *pathname) { if((c=get_fs_byte(pathname))==‘/’){ inode=current->root; pathname++; } else if(c) inode=current->pwd; while(1){ //函数的正确出口 if(!c) return inode; bh=find_entry(&inode,thisname,namelen,&de); int inr=de->inode; int idev=inode->i_dev; inode=iget(idev,inr); //根据目录项读取下一层inode } // ... }
  • root:找到根目录;
  • find_entry:从目录中读取目录项;
  • inr:是目录项中的索引节点号;
  • iget:再读下一层目录

从根目录开始解析

void init(void) { setup((void *) &drive_info); // ...
// kernel/hd.c sys_setup(void * BIOS) { hd_info[drive].head = *(2+BIOS); hd_info[drive].sect = *(14+BIOS); mount_root(); ... }
// fs/super.c void mount_root(void) { mi=iget(ROOT_DEV,ROOT_INO)); current->root = mi; }

读取inode

struct m_inode * iget(int dev, int nr) { struct m_inode *inode = get_empty_inode(); inode->i_dev=dev; inode->i_num=nr; read_inode(inode); return inode; }
static void read_inode(struct m_inode *inode) { struct super_block *sb=get_super(inode->i_dev); lock_inode(inode); block=2+sb->s_imap_blocks+sb->s_zmap_blocks+ (inode->i_num-1)/INODES_PER_BLOCK; bh=bread(inode->i_dev,block); inode=bh->data[(inode->i_num-1)%INODES_PER_BLOCK]; unlock_inode(inode); }

开始目录解析

struct dir_entry { unsigned short inode; //i节点号 char name[NAME_LEN]; //文件名 }
// fs/namei.c static struct buffer_head *find_entry(struct m_inode **dir, char *name, ..., struct dir_entry ** res_dir) { int entries=(*dir)->i_size/(sizeof(struct dir_entry)); int block=(*dir)->i_zone[0]; *bh=bread((*dir)->i_dev, block); struct dir_entry *de =bh->b_data; while(i<entries) { if((char*)de>=BLOCK_SIZE+bh->b_data){ brelse(bh); block=bmap(*dir,i/DIR_ENTRIES_PER_BLOCK); bh=bread((*dir)->i_dev,block); de=(struct dir_entry*)bh->b_data; } //读入下一块上的目录项继续match if(match(namelen,name,de)){ *res_dir=de; return bh; } de++; i++; } }