免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2421 | 回复: 3
打印 上一主题 下一主题

ext2文件系统 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-09-29 15:13 |只看该作者 |倒序浏览
static int ext2_fill_super(struct super_block *sb, void *data, int silent)这个函数里面,刚开始是不知道blocksize,那么怎么能正确的读到ext2_super_size?
如果能正确的读到了,后面为什么发现块大小不对的时候为什么要重新读一次?

谢谢。

论坛徽章:
0
2 [报告]
发表于 2011-09-29 17:34 |只看该作者
我是这样理解的,因为刚开始不知道blocksize,所以ext2_fill_super会比较磁盘本身最小扇区大小和默认大小,获取合适的block size,然后试图去读磁盘,如下:
  1.         if (blocksize != BLOCK_SIZE) {
  2.                 logic_sb_block = (sb_block*BLOCK_SIZE) / blocksize;
  3.                 offset = (sb_block*BLOCK_SIZE) % blocksize;
  4.         } else {
  5.                 logic_sb_block = sb_block;
  6.         }

  7.         if (!(bh = sb_bread(sb, logic_sb_block))) {
  8.                 printk ("EXT2-fs: unable to read superblock\n");
  9.                 goto failed_sbi;
复制代码
并且需要对读取出来的super block进行校验,因为super block在磁盘上的存储就是按照定义中排列的,所以可以对读出来的数据直接进行校验:
  1.         if (sb->s_magic != EXT2_SUPER_MAGIC)
  2.                 goto cantfind_ext2
复制代码
(通过magic来验证,万一这个扇区存储的不是super block,而magic值又恰巧一样呢?)
如果magic number通过校验了,那就是合法值。而有可能真实的磁盘扇区大小与这个大小不同,而super block的大小是1024字节,如果大于磁盘扇区的大小,
那么读取的super block信息便不完整,因此必须使用真实的磁盘扇区大小来获取super block的完整信息。

论坛徽章:
0
3 [报告]
发表于 2011-09-30 10:05 |只看该作者
回复 2# SharkBones


但是上面会设置uid和gid:
  1. sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
  2. sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
复制代码
而且这两个参数是再magic后面的,并且在重新读取ext2_super_block以后不会重新设置这两个值,那么这两个值会不会出错?

论坛徽章:
0
4 [报告]
发表于 2011-09-30 21:20 |只看该作者
  1.         sbi->s_blockgroup_lock =
  2.                 kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL);
  3.         if (!sbi->s_blockgroup_lock) {
  4.                 kfree(sbi);
  5.                 return -ENOMEM;
  6.         }
  7.         sb->s_fs_info = sbi;
复制代码
super block info会赋值给sb的s_fs_info域,在parse_options中会对上面赋予的默认值进行校验:
  1.                 case Opt_resuid:
  2.                         if (match_int(&args[0], &option))
  3.                                 return 0;
  4.                         sbi->s_resuid = option;
  5.                         break;
  6.                 case Opt_resgid:
  7.                         if (match_int(&args[0], &option))
  8.                                 return 0;
  9.                         sbi->s_resgid = option;
  10.                         break;
复制代码
如果这两个值出错,就会与传入的option值不同,从而被修正为正确的值。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP