/* * Ok, we do readpage, to be able to execute programs. Unfortunately, * we can't use bmap, since we may have looser alignments. */ static int romfs_readpage(struct file *file, struct page * page) { struct inode *inode = page->mapping->host; unsigned long offset, avail, readlen; void *buf; int result = -EIO; page_cache_get(page); lock_kernel(); buf = kmap(page); if (!buf) goto err_out; /* 32 bit warning -- but not for us :) */ offset = page->index << PAGE_CACHE_SHIFT; //inode->i_size只有普通文件&符号链接文件 if (offset < inode->i_size) { //avail表明剩余的字节数 avail = inode->i_size-offset; //读取一页还是avail readlen = min_t(unsigned long, avail, PAGE_SIZE); if (romfs_copyfrom(inode, buf, inode->u.romfs_i.i_dataoffset+offset, readlen) == readlen) { //页面尾部填充零 if (readlen < PAGE_SIZE) { memset(buf + readlen,0,PAGE_SIZE-readlen); } SetPageUptodate(page); result = 0; } } //错误处理 if (result) { memset(buf, 0, PAGE_SIZE); SetPageError(page); } flush_dcache_page(page); UnlockPage(page); kunmap(page); err_out: page_cache_release(page); unlock_kernel(); return result; } /* Mapping from our types to the kernel */ static struct address_space_operations romfs_aops = { readpage: romfs_readpage }; static struct file_operations romfs_dir_operations = { read: generic_read_dir, readdir: romfs_readdir, }; static struct inode_operations romfs_dir_inode_operations = { lookup: romfs_lookup, }; //权限映射表 static mode_t romfs_modemap[] = { 0, S_IFDIR+0644, S_IFREG+0644, S_IFLNK+0777, S_IFBLK+0600, S_IFCHR+0600, S_IFSOCK+0644, S_IFIFO+0644 }; static void romfs_read_inode(struct inode *i) { int nextfh, ino; struct romfs_inode ri; ino = i->i_ino & ROMFH_MASK; i->i_mode = 0; /* Loop for finding the real hard link */ for(;;) { //根据ino作为offset获取16字节的文件头 if (romfs_copyfrom(i, &ri, ino, ROMFH_SIZE) <= 0) { printk("romfs: read error for inode 0x%x\n", ino); return; } /* XXX: do romfs_checksum here too (with name) */ nextfh = ntohl(ri.next); //当前文件节点是否是硬链接 if ((nextfh & ROMFH_TYPE) != ROMFH_HRD) break; //如果是硬链接,spec.info保存对应的地址 //由于ino和offset一致,所以重新读取节点 ino = ntohl(ri.spec) & ROMFH_MASK; } //到此只是得到了文件头信息 i->i_nlink = 1; /* Hard to decide.. */ i->i_size = ntohl(ri.size); i->i_mtime = i->i_atime = i->i_ctime = 0; i->i_uid = i->i_gid = 0; |