加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

UBIFS文件系统分析2 - master node管理

发布时间:2020-12-15 06:29:19 所属栏目:百科 来源:网络整理
导读:master node用来记录管理所有on-flash上位置不固定的结构。 UBIFS把master node内容重复的写入LEB1和LEB2中,这样可以保证任何时刻都有一个有效的master node存在。master node大小为512 bytes,顺序的占用LEB的page,如果整个LEB都被master node写满,那么

master node用来记录管理所有on-flash上位置不固定的结构。

UBIFS把master node内容重复的写入LEB1和LEB2中,这样可以保证任何时刻都有一个有效的master node存在。master node大小为512 bytes,顺序的占用LEB的page,如果整个LEB都被master node写满,那么执行unmap操作,分配一个新空LEB。注意unmap LEB1 LEB2操作也要顺序的进行,如果同时unmap两个master LEB,系统就暂时的处于无有效master node的状态。

一个master LEB可能存在master node的多个版本,LEB内最后一个master node是有效的。

master node on-flash结构

struct ubifs_mst_node {
??? struct ubifs_ch ch;
??? __le64 highest_inum;
??? __le64 cmt_no;
??? __le32 flags;
??? __le32 log_lnum;
??? __le32 root_lnum;
??? __le32 root_offs;
??? __le32 root_len;
??? __le32 gc_lnum;
??? __le32 ihead_lnum;
??? __le32 ihead_offs;
??? __le64 index_size;
??? __le64 total_free;
??? __le64 total_dirty;
??? __le64 total_used;
??? __le64 total_dead;
??? __le64 total_dark;
??? __le32 lpt_lnum;
??? __le32 lpt_offs;
??? __le32 nhead_lnum;
??? __le32 nhead_offs;
??? __le32 ltab_lnum;
??? __le32 ltab_offs;
??? __le32 lsave_lnum;
??? __le32 lsave_offs;
??? __le32 lscan_lnum;
??? __le32 empty_lebs;
??? __le32 idx_lebs;
??? __le32 leb_cnt;
??? __u8 padding[344];
} __attribute__ ((packed));

@highest_inum: 当前inode number,每创建一个新文件highest_inum都会加1,
ubifs的inode number是不能复用的,比如file1的ino是100,之后即便删除了file1,但是ino 100在整个文件系统的生命周期内再也不能使用了.
@cmt_no: 文件系统最后一个commit number
@log_lnum: log area开始的LEB number
@root_lnum: root index node所在的LEB number
@root_offs: root index node在LEB内的偏移
@root_len: root index node的长度
@gc_lnum: UBIFS为garbage collection保留的LEB number,如果没有设置,那么在系统mount时,要进行分配.
@ihead_lnum: 记录可写入index node的LEB number,ihead_lnum存在的目的是index node和non-index node要写在不同的LEB中.
@ihead_offs: ihead_lnum内的偏移量
@index_len: index在flash上的大小
@total_free: free space是擦除块尾部可写的空间大小,total_free则是LPT所管理的LEB空闲空间总和
@total_dirty: dirty space是废弃的和paddings节点,有可能被GC处理的空间大小. total dirty是LPT所管理LEB的dirty空间总和
@total_used: total used space in bytes (includes only data LEBs)
@total_dead: total dead space in bytes (includes only data LEBs)
@total_dark: total dark space in bytes (includes only data LEBs)
@lpt_lnum: LPT root nnode所在的LEB number
@lpt_offs: LPT root nnode在LEB内的偏移量
@nhead_lnum: 记录当前可写入LPT nnode的擦除块
@nhead_offs: nhead_lnum内的偏移量
@ltab_lnum: LTP自身lprops table所在的LEB
@ltab_offs:
@lsave_lnum: 仅big model有效,lsave table内保存着一些重要的LEBs,重要LEBs是指(重要性从高到低):empty,freeable,freeable index,dirty index,dirty or free,有了这个表,我们就可以在mount时把这些LEB的pnode读入内存,以防止扫描整个LPT; 对于small model,系统假定扫描LPT代价很小;
@lsave_offs: offset of lsave_lnum
@lcan_lnum: 最后一次LPT scan的LEB number
@empty_lebs: empty LEBs 数目
@idx_lebs: 是当前index使用的LEBs数目,这个数目可能很大,因为UBIFS在还有空闲空间的情况下,并不对index lebs做合并. 也就是说index lebs占用了很多空间,但是又包含了很多dirty space.
@leb_cnt: 文件系统使用的LEB数目
@padding[344]: master node对齐为512 bytes

fs/ubifs/master.c
?? ?27?? ?/**
??? 28?? ? * scan_for_master - search the valid master node.
??? 29?? ? * @c: UBIFS file-system description object
??? 30?? ? *
??? 31?? ? * This function scans the master node LEBs and search for the latest master
??? 32?? ? * node. Returns zero in case of success,%-EUCLEAN if there master area is
??? 33?? ? * corrupted and requires recovery,and a negative error code in case of
??? 34?? ? * failure.
??? 35?? ? */
??? 36?? ?static int scan_for_master(struct ubifs_info *c)
??? 37?? ?{
??? 38?? ??? ?struct ubifs_scan_leb *sleb;
??? 39?? ??? ?struct ubifs_scan_node *snod;
??? 40?? ??? ?int lnum,offs = 0,nodes_cnt;
??? 41?? ?
??? 42?? ??? ?lnum = UBIFS_MST_LNUM;
??? 43?? ?
??? 44?? ??? ?sleb = ubifs_scan(c,lnum,c->sbuf,1);
??? 45?? ??? ?if (IS_ERR(sleb))
??? 46?? ??? ??? ?return PTR_ERR(sleb);
??? 47?? ??? ?nodes_cnt = sleb->nodes_cnt;
??? 48?? ??? ?if (nodes_cnt > 0) {
??? 49?? ??? ??? ?snod = list_entry(sleb->nodes.prev,struct ubifs_scan_node,
??? 50?? ??? ??? ??? ??? ?? list);
??? 51?? ??? ??? ?if (snod->type != UBIFS_MST_NODE)
??? 52?? ??? ??? ??? ?goto out_dump;
??? 53?? ??? ??? ?memcpy(c->mst_node,snod->node,snod->len);
??? 54?? ??? ??? ?offs = snod->offs;
??? 55?? ??? ?}
??? 56?? ??? ?ubifs_scan_destroy(sleb);
??? 57?? ?
??? 58?? ??? ?lnum += 1;
??? 59?? ?
??? 60?? ??? ?sleb = ubifs_scan(c,1);
??? 61?? ??? ?if (IS_ERR(sleb))
??? 62?? ??? ??? ?return PTR_ERR(sleb);
??? 63?? ??? ?if (sleb->nodes_cnt != nodes_cnt)
??? 64?? ??? ??? ?goto out;
??? 65?? ??? ?if (!sleb->nodes_cnt)
??? 66?? ??? ??? ?goto out;
??? 67?? ??? ?snod = list_entry(sleb->nodes.prev,list);
??? 68?? ??? ?if (snod->type != UBIFS_MST_NODE)
??? 69?? ??? ??? ?goto out_dump;
??? 70?? ??? ?if (snod->offs != offs)
??? 71?? ??? ??? ?goto out;
??? 72?? ??? ?if (memcmp((void *)c->mst_node + UBIFS_CH_SZ,
??? 73?? ??? ??? ??? (void *)snod->node + UBIFS_CH_SZ,
??? 74?? ??? ??? ??? UBIFS_MST_NODE_SZ - UBIFS_CH_SZ))
??? 75?? ??? ??? ?goto out;
??? 76?? ??? ?c->mst_offs = offs;
??? 77?? ??? ?ubifs_scan_destroy(sleb);
??? 78?? ??? ?return 0;
??? 79?? ?
??? 80?? ?out:
??? 81?? ??? ?ubifs_scan_destroy(sleb);
??? 82?? ??? ?return -EUCLEAN;
??? 83?? ?
??? 84?? ?out_dump:
??? 85?? ??? ?ubifs_err("unexpected node type %d master LEB %d:%d",
??? 86?? ??? ??? ?? snod->type,snod->offs);
??? 87?? ??? ?ubifs_scan_destroy(sleb);
??? 88?? ??? ?return -EINVAL;
??? 89?? ?}
这个函数扫描master node所在的LEB,找到有效的master node,把master node的内容复制到ubifs_info->mst_node成员变量中
44 扫描master LEB,生成UBIFS scanned LEB information,结果保存在sleb中
47~56 找到最后一个snode,如果node类型为MASTER NODE,那么把这个node的内容复制到c->mst_node中
58 准备扫描backup master node
60 ~ 77 确保第二个master LEB内的master node和第一个master LEB内相同
78 返回0表示扫描成功


??? 90?? ?
??? 91?? ?/**
??? 92?? ? * validate_master - validate master node.
??? 93?? ? * @c: UBIFS file-system description object
??? 94?? ? *
??? 95?? ? * This function validates data which was read from master node. Returns zero
??? 96?? ? * if the data is all right and %-EINVAL if not.
??? 97?? ? */
??? 98?? ?static int validate_master(const struct ubifs_info *c)
??? 99?? ?{
?? 100?? ??? ?long long main_sz;
?? 101?? ??? ?int err;
?? 102?? ?
?? 103?? ??? ?if (c->max_sqnum >= SQNUM_WATERMARK) {
?? 104?? ??? ??? ?err = 1;
?? 105?? ??? ??? ?goto out;
?? 106?? ??? ?}
?? 107?? ?
?? 108?? ??? ?if (c->cmt_no >= c->max_sqnum) {
?? 109?? ??? ??? ?err = 2;
?? 110?? ??? ??? ?goto out;
?? 111?? ??? ?}
?? 112?? ?
?? 113?? ??? ?if (c->highest_inum >= INUM_WATERMARK) {
?? 114?? ??? ??? ?err = 3;
?? 115?? ??? ??? ?goto out;
?? 116?? ??? ?}
?? 117?? ?
?? 118?? ??? ?if (c->lhead_lnum < UBIFS_LOG_LNUM ||
?? 119?? ??? ???? c->lhead_lnum >= UBIFS_LOG_LNUM + c->log_lebs ||
?? 120?? ??? ???? c->lhead_offs < 0 || c->lhead_offs >= c->leb_size ||
?? 121?? ??? ???? c->lhead_offs & (c->min_io_size - 1)) {
?? 122?? ??? ??? ?err = 4;
?? 123?? ??? ??? ?goto out;
?? 124?? ??? ?}
?? 125?? ?
?? 126?? ??? ?if (c->zroot.lnum >= c->leb_cnt || c->zroot.lnum < c->main_first ||
?? 127?? ??? ???? c->zroot.offs >= c->leb_size || c->zroot.offs & 7) {
?? 128?? ??? ??? ?err = 5;
?? 129?? ??? ??? ?goto out;
?? 130?? ??? ?}
?? 131?? ?
?? 132?? ??? ?if (c->zroot.len < c->ranges[UBIFS_IDX_NODE].min_len ||
?? 133?? ??? ???? c->zroot.len > c->ranges[UBIFS_IDX_NODE].max_len) {
?? 134?? ??? ??? ?err = 6;
?? 135?? ??? ??? ?goto out;
?? 136?? ??? ?}
?? 137?? ?
?? 138?? ??? ?if (c->gc_lnum >= c->leb_cnt || c->gc_lnum < c->main_first) {
?? 139?? ??? ??? ?err = 7;
?? 140?? ??? ??? ?goto out;
?? 141?? ??? ?}
?? 142?? ?
?? 143?? ??? ?if (c->ihead_lnum >= c->leb_cnt || c->ihead_lnum < c->main_first ||
?? 144?? ??? ???? c->ihead_offs % c->min_io_size || c->ihead_offs < 0 ||
?? 145?? ??? ???? c->ihead_offs > c->leb_size || c->ihead_offs & 7) {
?? 146?? ??? ??? ?err = 8;
?? 147?? ??? ??? ?goto out;
?? 148?? ??? ?}
?? 149?? ?
?? 150?? ??? ?main_sz = (long long)c->main_lebs * c->leb_size;
?? 151?? ??? ?if (c->old_idx_sz & 7 || c->old_idx_sz >= main_sz) {
?? 152?? ??? ??? ?err = 9;
?? 153?? ??? ??? ?goto out;
?? 154?? ??? ?}
?? 155?? ?
?? 156?? ??? ?if (c->lpt_lnum < c->lpt_first || c->lpt_lnum > c->lpt_last ||
?? 157?? ??? ???? c->lpt_offs < 0 || c->lpt_offs + c->nnode_sz > c->leb_size) {
?? 158?? ??? ??? ?err = 10;
?? 159?? ??? ??? ?goto out;
?? 160?? ??? ?}
?? 161?? ?
?? 162?? ??? ?if (c->nhead_lnum < c->lpt_first || c->nhead_lnum > c->lpt_last ||
?? 163?? ??? ???? c->nhead_offs < 0 || c->nhead_offs % c->min_io_size ||
?? 164?? ??? ???? c->nhead_offs > c->leb_size) {
?? 165?? ??? ??? ?err = 11;
?? 166?? ??? ??? ?goto out;
?? 167?? ??? ?}
?? 168?? ?
?? 169?? ??? ?if (c->ltab_lnum < c->lpt_first || c->ltab_lnum > c->lpt_last ||
?? 170?? ??? ???? c->ltab_offs < 0 ||
?? 171?? ??? ???? c->ltab_offs + c->ltab_sz > c->leb_size) {
?? 172?? ??? ??? ?err = 12;
?? 173?? ??? ??? ?goto out;
?? 174?? ??? ?}
?? 175?? ?
?? 176?? ??? ?if (c->big_lpt && (c->lsave_lnum < c->lpt_first ||
?? 177?? ??? ???? c->lsave_lnum > c->lpt_last || c->lsave_offs < 0 ||
?? 178?? ??? ???? c->lsave_offs + c->lsave_sz > c->leb_size)) {
?? 179?? ??? ??? ?err = 13;
?? 180?? ??? ??? ?goto out;
?? 181?? ??? ?}
?? 182?? ?
?? 183?? ??? ?if (c->lscan_lnum < c->main_first || c->lscan_lnum >= c->leb_cnt) {
?? 184?? ??? ??? ?err = 14;
?? 185?? ??? ??? ?goto out;
?? 186?? ??? ?}
?? 187?? ?
?? 188?? ??? ?if (c->lst.empty_lebs < 0 || c->lst.empty_lebs > c->main_lebs - 2) {
?? 189?? ??? ??? ?err = 15;
?? 190?? ??? ??? ?goto out;
?? 191?? ??? ?}
?? 192?? ?
?? 193?? ??? ?if (c->lst.idx_lebs < 0 || c->lst.idx_lebs > c->main_lebs - 1) {
?? 194?? ??? ??? ?err = 16;
?? 195?? ??? ??? ?goto out;
?? 196?? ??? ?}
?? 197?? ?
?? 198?? ??? ?if (c->lst.total_free < 0 || c->lst.total_free > main_sz ||
?? 199?? ??? ???? c->lst.total_free & 7) {
?? 200?? ??? ??? ?err = 17;
?? 201?? ??? ??? ?goto out;
?? 202?? ??? ?}
?? 203?? ?
?? 204?? ??? ?if (c->lst.total_dirty < 0 || (c->lst.total_dirty & 7)) {
?? 205?? ??? ??? ?err = 18;
?? 206?? ??? ??? ?goto out;
?? 207?? ??? ?}
?? 208?? ?
?? 209?? ??? ?if (c->lst.total_used < 0 || (c->lst.total_used & 7)) {
?? 210?? ??? ??? ?err = 19;
?? 211?? ??? ??? ?goto out;
?? 212?? ??? ?}
?? 213?? ?
?? 214?? ??? ?if (c->lst.total_free + c->lst.total_dirty +
?? 215?? ??? ???? c->lst.total_used > main_sz) {
?? 216?? ??? ??? ?err = 20;
?? 217?? ??? ??? ?goto out;
?? 218?? ??? ?}
?? 219?? ?
?? 220?? ??? ?if (c->lst.total_dead + c->lst.total_dark +
?? 221?? ??? ???? c->lst.total_used + c->old_idx_sz > main_sz) {
?? 222?? ??? ??? ?err = 21;
?? 223?? ??? ??? ?goto out;
?? 224?? ??? ?}
?? 225?? ?
?? 226?? ??? ?if (c->lst.total_dead < 0 ||
?? 227?? ??? ???? c->lst.total_dead > c->lst.total_free + c->lst.total_dirty ||
?? 228?? ??? ???? c->lst.total_dead & 7) {
?? 229?? ??? ??? ?err = 22;
?? 230?? ??? ??? ?goto out;
?? 231?? ??? ?}
?? 232?? ?
?? 233?? ??? ?if (c->lst.total_dark < 0 ||
?? 234?? ??? ???? c->lst.total_dark > c->lst.total_free + c->lst.total_dirty ||
?? 235?? ??? ???? c->lst.total_dark & 7) {
?? 236?? ??? ??? ?err = 23;
?? 237?? ??? ??? ?goto out;
?? 238?? ??? ?}
?? 239?? ?
?? 240?? ??? ?return 0;
?? 241?? ?
?? 242?? ?out:
?? 243?? ??? ?ubifs_err("bad master node at offset %d error %d",c->mst_offs,err);
?? 244?? ??? ?dbg_dump_node(c,c->mst_node);
?? 245?? ??? ?return -EINVAL;
?? 246?? ?}

这个函数验证那些从master获取来的一些数值
103 检查max_sqnum,不能大于SQNUM_WATERMARK,max_sqnum是64bit的,系统不可能超过这个界限
113 检查highest_inum,系统支持的最高inode number,ubifs不能支持inode number复用,highest_inum是64bit,理论上也不大可能超过这个界限


?? 247?? ?
?? 248?? ?/**
?? 249?? ? * ubifs_read_master - read master node.
?? 250?? ? * @c: UBIFS file-system description object
?? 251?? ? *
?? 252?? ? * This function finds and reads the master node during file-system mount. If
?? 253?? ? * the flash is empty,it creates default master node as well. Returns zero in
?? 254?? ? * case of success and a negative error code in case of failure.
?? 255?? ? */
?? 256?? ?int ubifs_read_master(struct ubifs_info *c)
?? 257?? ?{
?? 258?? ??? ?int err,old_leb_cnt;
?? 259?? ?
?? 260?? ??? ?c->mst_node = kzalloc(c->mst_node_alsz,GFP_KERNEL);
?? 261?? ??? ?if (!c->mst_node)
?? 262?? ??? ??? ?return -ENOMEM;
?? 263?? ?
?? 264?? ??? ?err = scan_for_master(c);
?? 265?? ??? ?if (err) {
?? 266?? ??? ??? ?if (err == -EUCLEAN)
?? 267?? ??? ??? ??? ?err = ubifs_recover_master_node(c);
?? 268?? ??? ??? ?if (err)
?? 269?? ??? ??? ??? ?/*
?? 270?? ??? ??? ??? ? * Note,we do not free 'c->mst_node' here because the
?? 271?? ??? ??? ??? ? * unmount routine will take care of this.
?? 272?? ??? ??? ??? ? */
?? 273?? ??? ??? ??? ?return err;
?? 274?? ??? ?}
?? 275?? ?
?? 276?? ??? ?/* Make sure that the recovery flag is clear */
?? 277?? ??? ?c->mst_node->flags &= cpu_to_le32(~UBIFS_MST_RCVRY);
?? 278?? ?
?? 279?? ??? ?c->max_sqnum?????? = le64_to_cpu(c->mst_node->ch.sqnum);
?? 280?? ??? ?c->highest_inum??? = le64_to_cpu(c->mst_node->highest_inum);
?? 281?? ??? ?c->cmt_no????????? = le64_to_cpu(c->mst_node->cmt_no);
?? 282?? ??? ?c->zroot.lnum????? = le32_to_cpu(c->mst_node->root_lnum);
?? 283?? ??? ?c->zroot.offs????? = le32_to_cpu(c->mst_node->root_offs);
?? 284?? ??? ?c->zroot.len?????? = le32_to_cpu(c->mst_node->root_len);
?? 285?? ??? ?c->lhead_lnum????? = le32_to_cpu(c->mst_node->log_lnum);
?? 286?? ??? ?c->gc_lnum???????? = le32_to_cpu(c->mst_node->gc_lnum);
?? 287?? ??? ?c->ihead_lnum????? = le32_to_cpu(c->mst_node->ihead_lnum);
?? 288?? ??? ?c->ihead_offs????? = le32_to_cpu(c->mst_node->ihead_offs);
?? 289?? ??? ?c->old_idx_sz????? = le64_to_cpu(c->mst_node->index_size);
?? 290?? ??? ?c->lpt_lnum??????? = le32_to_cpu(c->mst_node->lpt_lnum);
?? 291?? ??? ?c->lpt_offs??????? = le32_to_cpu(c->mst_node->lpt_offs);
?? 292?? ??? ?c->nhead_lnum????? = le32_to_cpu(c->mst_node->nhead_lnum);
?? 293?? ??? ?c->nhead_offs????? = le32_to_cpu(c->mst_node->nhead_offs);
?? 294?? ??? ?c->ltab_lnum?????? = le32_to_cpu(c->mst_node->ltab_lnum);
?? 295?? ??? ?c->ltab_offs?????? = le32_to_cpu(c->mst_node->ltab_offs);
?? 296?? ??? ?c->lsave_lnum????? = le32_to_cpu(c->mst_node->lsave_lnum);
?? 297?? ??? ?c->lsave_offs????? = le32_to_cpu(c->mst_node->lsave_offs);
?? 298?? ??? ?c->lscan_lnum????? = le32_to_cpu(c->mst_node->lscan_lnum);
?? 299?? ??? ?c->lst.empty_lebs? = le32_to_cpu(c->mst_node->empty_lebs);
?? 300?? ??? ?c->lst.idx_lebs??? = le32_to_cpu(c->mst_node->idx_lebs);
?? 301?? ??? ?old_leb_cnt??????? = le32_to_cpu(c->mst_node->leb_cnt);
?? 302?? ??? ?c->lst.total_free? = le64_to_cpu(c->mst_node->total_free);
?? 303?? ??? ?c->lst.total_dirty = le64_to_cpu(c->mst_node->total_dirty);
?? 304?? ??? ?c->lst.total_used? = le64_to_cpu(c->mst_node->total_used);
?? 305?? ??? ?c->lst.total_dead? = le64_to_cpu(c->mst_node->total_dead);
?? 306?? ??? ?c->lst.total_dark? = le64_to_cpu(c->mst_node->total_dark);
?? 307?? ?
?? 308?? ??? ?c->calc_idx_sz = c->old_idx_sz;
?? 309?? ?
?? 310?? ??? ?if (c->mst_node->flags & cpu_to_le32(UBIFS_MST_NO_ORPHS))
?? 311?? ??? ??? ?c->no_orphs = 1;
?? 312?? ?
?? 313?? ??? ?if (old_leb_cnt != c->leb_cnt) {
?? 314?? ??? ??? ?/* The file system has been resized */
?? 315?? ??? ??? ?int growth = c->leb_cnt - old_leb_cnt;
?? 316?? ?
?? 317?? ??? ??? ?if (c->leb_cnt < old_leb_cnt ||
?? 318?? ??? ??? ???? c->leb_cnt < UBIFS_MIN_LEB_CNT) {
?? 319?? ??? ??? ??? ?ubifs_err("bad leb_cnt on master node");
?? 320?? ??? ??? ??? ?dbg_dump_node(c,c->mst_node);
?? 321?? ??? ??? ??? ?return -EINVAL;
?? 322?? ??? ??? ?}
?? 323?? ?
?? 324?? ??? ??? ?dbg_mnt("Auto resizing (master) from %d LEBs to %d LEBs",
?? 325?? ??? ??? ??? ?old_leb_cnt,c->leb_cnt);
?? 326?? ??? ??? ?c->lst.empty_lebs += growth;
?? 327?? ??? ??? ?c->lst.total_free += growth * (long long)c->leb_size;
?? 328?? ??? ??? ?c->lst.total_dark += growth * (long long)c->dark_wm;
?? 329?? ?
?? 330?? ??? ??? ?/*
?? 331?? ??? ??? ? * Reflect changes back onto the master node. N.B. the master
?? 332?? ??? ??? ? * node gets written immediately whenever mounting (or
?? 333?? ??? ??? ? * remounting) in read-write mode,so we do not need to write it
?? 334?? ??? ??? ? * here.
?? 335?? ??? ??? ? */
?? 336?? ??? ??? ?c->mst_node->leb_cnt = cpu_to_le32(c->leb_cnt);
?? 337?? ??? ??? ?c->mst_node->empty_lebs = cpu_to_le32(c->lst.empty_lebs);
?? 338?? ??? ??? ?c->mst_node->total_free = cpu_to_le64(c->lst.total_free);
?? 339?? ??? ??? ?c->mst_node->total_dark = cpu_to_le64(c->lst.total_dark);
?? 340?? ??? ?}
?? 341?? ?
?? 342?? ??? ?err = validate_master(c);
?? 343?? ??? ?if (err)
?? 344?? ??? ??? ?return err;
?? 345?? ?
?? 346?? ??? ?err = dbg_old_index_check_init(c,&c->zroot);
?? 347?? ?
?? 348?? ??? ?return err;
?? 349?? ?}
该函数从flash上读取master node,保存到ubifs_info->mst_node,并且用master node的一些值初始化ubifs_info。

313 ~ 328 如果发现ubifs_info->leb_cnt(根据superblock中的leb_cnt初始化)不等于master node中的leb count,说明文件系统已经被resize了,需要重新设置从master node得到的系统参数

330 ~ 340 修改c->mst_node内相应的值,把改变反应到master node上


?? 351?? ?/**
?? 352?? ? * ubifs_write_master - write master node.
?? 353?? ? * @c: UBIFS file-system description object
?? 354?? ? *
?? 355?? ? * This function writes the master node. The caller has to take the
?? 356?? ? * @c->mst_mutex lock before calling this function. Returns zero in case of
?? 357?? ? * success and a negative error code in case of failure. The master node is
?? 358?? ? * written twice to enable recovery.
?? 359?? ? */
?? 360?? ?int ubifs_write_master(struct ubifs_info *c)
?? 361?? ?{
?? 362?? ??? ?int err,offs,len;
?? 363?? ?
?? 364?? ??? ?if (c->ro_media)
?? 365?? ??? ??? ?return -EROFS;
?? 366?? ?
?? 367?? ??? ?lnum = UBIFS_MST_LNUM;
?? 368?? ??? ?offs = c->mst_offs + c->mst_node_alsz;
?? 369?? ??? ?len = UBIFS_MST_NODE_SZ;
?? 370?? ?
?? 371?? ??? ?if (offs + UBIFS_MST_NODE_SZ > c->leb_size) {
?? 372?? ??? ??? ?err = ubifs_leb_unmap(c,lnum);
?? 373?? ??? ??? ?if (err)
?? 374?? ??? ??? ??? ?return err;
?? 375?? ??? ??? ?offs = 0;
?? 376?? ??? ?}
?? 377?? ?
?? 378?? ??? ?c->mst_offs = offs;
?? 379?? ??? ?c->mst_node->highest_inum = cpu_to_le64(c->highest_inum);
?? 380?? ?
?? 381?? ??? ?err = ubifs_write_node(c,c->mst_node,len,UBI_SHORTTERM);
?? 382?? ??? ?if (err)
?? 383?? ??? ??? ?return err;
?? 384?? ?
?? 385?? ??? ?lnum += 1;
?? 386?? ?
?? 387?? ??? ?if (offs == 0) {
?? 388?? ??? ??? ?err = ubifs_leb_unmap(c,lnum);
?? 389?? ??? ??? ?if (err)
?? 390?? ??? ??? ??? ?return err;
?? 391?? ??? ?}
?? 392?? ??? ?err = ubifs_write_node(c,UBI_SHORTTERM);
?? 393?? ?
?? 394?? ??? ?return err;
?? 395?? ?}
把c->mst_node写入flash,需要写两个master node

371 ~ 376 如果已经写到LEB的末尾,剩余空间不能容纳一个master node,那么unmap master LEB,分配一个新的LEB。

378 ~ 383 写入第一个master node

385 ~ 392 写入backup的master node

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读