UBIFS文件系统分析3 - 超级块管理

UBIFS superblock存储在volume的第一个LEB,在UBIFS运行期间superblock几乎不会改变,只有一种情况会导致superblock node被重写,就是自动resize时。之所以需要自动resize,是因为创建ubifs文件系统镜像时,并不知道将要mount的UBI bolume的大小,所以当我们将UBIFS镜像安装到UBI上时,UBI的尺寸可能大于UBIFS镜像所需要的最大空间,此时就需要把UBIFS resize以适合UBI volume,以更好的利用UBI空间。

superblock 磁盘结构保存着文件系统大部分尺寸参数
struct ubifs_sb_node {
    struct ubifs_ch ch;
    __u8 padding[2];
    __u8 key_hash;
    __u8 key_fmt;
    __le32 flags;
    __le32 min_io_size;
    __le32 leb_size;
    __le32 leb_cnt;
    __le32 max_leb_cnt;
    __le64 max_bud_bytes;
    __le32 log_lebs;
    __le32 lpt_lebs;
    __le32 orph_lebs;
    __le32 jhead_cnt;
    __le32 fanout;
    __le32 lsave_cnt;
    __le32 fmt_version;
    __le16 default_compr;
    __u8 padding1[2];
    __le32 rp_uid;
    __le32 rp_gid;
    __le64 rp_size;
    __le32 time_gran;
    __u8 uuid[16];
    __le32 ro_compat_version;
    __u8 padding2[3968];
} __attribute__ ((packed));

@key_hash:文件系统生成key的hash函数类型
@key_fmt: 文件系统key的格式,ubifs当前只有一种64bits key格式:32bit ino + 3bits key type + 29bits hash
@min_io_size:文件系统最小读写单元
@leb_size:Logical erased block尺寸
@leb_cnt:文件系统实际的leb count
@max_leb_cnt:文件系统允许使用的最大leb count
@log_lebs:log area 占用的逻辑LEB数目
@lpt_lebs: lprops table占用的逻辑LEB数目
@orph_lebs: orphan area占用的逻辑LEB数目
@jhead_cnt:journal head记录下一个节点写到flash上的位置,UBIFS采用多线程journal来写入两种主要的heads:base head和data head.jhead_cnt记录这个数目.
@fanout:ubifs文件系统树的最大扇出数.
@lsave_cnt:LPT save table中LEB Numbers的数目,
@fmt_version:UBIFS on flash format version.

fs/ubifs/sb.c

499 /**
500  * ubifs_write_sb_node - write superblock node.
501  * @c: UBIFS file-system description object
502  * @sup: superblock node read with 'ubifs_read_sb_node()'
503  *  
504  * This function returns %0 on success and a negative error code on failure.
505  */
506 int ubifs_write_sb_node(struct ubifs_info *c, struct ubifs_sb_node *sup)
507 {
508     int len = ALIGN(UBIFS_SB_NODE_SZ, c->min_io_size);
509     
510     ubifs_prepare_node(c, sup, UBIFS_SB_NODE_SZ, 1);
511     return ubifs_leb_change(c, UBIFS_SB_LNUM, sup, len, UBI_LONGTERM);
512 }
superblock只使用擦除块第一个page,并不会使用其他的page,这是因为superblock修改很少,不需要考虑利用其他的page

514 /**
515  * ubifs_read_superblock - read superblock.
516  * @c: UBIFS file-system description object
517  *
518  * This function finds, reads and checks the superblock. If an empty UBI volume
519  * is being mounted, this function creates default superblock. Returns zero in
520  * case of success, and a negative error code in case of failure.
521  */
522 int ubifs_read_superblock(struct ubifs_info *c)
523 {
524     int err, sup_flags;
525     struct ubifs_sb_node *sup;
526
527     if (c->empty) {
528         err = create_default_filesystem(c);
529         if (err)
530             return err;
531     }
532
533     sup = ubifs_read_sb_node(c);
534     if (IS_ERR(sup))
535         return PTR_ERR(sup);
536
       ...........
622
623     /* Automatically increase file system size to the maximum size */
624     c->old_leb_cnt = c->leb_cnt;
625     if (c->leb_cnt < c->vi.size && c->leb_cnt < c->max_leb_cnt) {
626         c->leb_cnt = min_t(int, c->max_leb_cnt, c->vi.size);
627         if (c->vfs_sb->s_flags & MS_RDONLY)
628             dbg_mnt("Auto resizing (ro) from %d LEBs to %d LEBs",
629                 c->old_leb_cnt, c->leb_cnt);
630         else {
631             dbg_mnt("Auto resizing (sb) from %d LEBs to %d LEBs",
632                 c->old_leb_cnt, c->leb_cnt);
633             sup->leb_cnt = cpu_to_le32(c->leb_cnt);
634             err = ubifs_write_sb_node(c, sup);
635             if (err)
636                 goto out;
637             c->old_leb_cnt = c->leb_cnt;
638         }
639     }
640
641     c->log_bytes = (long long)c->log_lebs * c->leb_size;
642     c->log_last = UBIFS_LOG_LNUM + c->log_lebs - 1;
643     c->lpt_first = UBIFS_LOG_LNUM + c->log_lebs;
644     c->lpt_last = c->lpt_first + c->lpt_lebs - 1;
645     c->orph_first = c->lpt_last + 1;
646     c->orph_last = c->orph_first + c->orph_lebs - 1;
647     c->main_lebs = c->leb_cnt - UBIFS_SB_LEBS - UBIFS_MST_LEBS;
648     c->main_lebs -= c->log_lebs + c->lpt_lebs + c->orph_lebs;
649     c->main_first = c->leb_cnt - c->main_lebs;
650
651     err = validate_sb(c, sup);
652 out:
653     kfree(sup);
654     return err;
655 }

527 ~ 531 c->empty表示要mount的UBI volume 是empty,那么create_default_filesystem创建一个缺省的文件系统
533 读取superblock on-flash结构
623 ~ 639 如果镜像的leb_cnt小于volume的可用尺寸,那么resize文件系统,使其利用volume的所有可用空间,更新on-flash superblock,这也是UBIFS文件系统唯一修改superblock的地方。
641 ~ 649 可以看到ubifs各个area的起始位置和大小
651 最后对superblock中的参数进行验证
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值