1 /* 2 * This file is part of UBIFS. 3 * 4 * Copyright (C) 2006-2008 Nokia Corporation. 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 * 8 * Authors: Artem Bityutskiy (Битюцкий Артём) 9 * Adrian Hunter 10 */ 11 12 /* This file implements reading and writing the master node */ 13 14 #include "ubifs.h" 15 #ifdef __UBOOT__ 16 #include <linux/compat.h> 17 #include <linux/err.h> 18 #include <ubi_uboot.h> 19 #endif 20 21 /** 22 * scan_for_master - search the valid master node. 23 * @c: UBIFS file-system description object 24 * 25 * This function scans the master node LEBs and search for the latest master 26 * node. Returns zero in case of success, %-EUCLEAN if there master area is 27 * corrupted and requires recovery, and a negative error code in case of 28 * failure. 29 */ 30 static int scan_for_master(struct ubifs_info *c) 31 { 32 struct ubifs_scan_leb *sleb; 33 struct ubifs_scan_node *snod; 34 int lnum, offs = 0, nodes_cnt; 35 36 lnum = UBIFS_MST_LNUM; 37 38 sleb = ubifs_scan(c, lnum, 0, c->sbuf, 1); 39 if (IS_ERR(sleb)) 40 return PTR_ERR(sleb); 41 nodes_cnt = sleb->nodes_cnt; 42 if (nodes_cnt > 0) { 43 snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node, 44 list); 45 if (snod->type != UBIFS_MST_NODE) 46 goto out_dump; 47 memcpy(c->mst_node, snod->node, snod->len); 48 offs = snod->offs; 49 } 50 ubifs_scan_destroy(sleb); 51 52 lnum += 1; 53 54 sleb = ubifs_scan(c, lnum, 0, c->sbuf, 1); 55 if (IS_ERR(sleb)) 56 return PTR_ERR(sleb); 57 if (sleb->nodes_cnt != nodes_cnt) 58 goto out; 59 if (!sleb->nodes_cnt) 60 goto out; 61 snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node, list); 62 if (snod->type != UBIFS_MST_NODE) 63 goto out_dump; 64 if (snod->offs != offs) 65 goto out; 66 if (memcmp((void *)c->mst_node + UBIFS_CH_SZ, 67 (void *)snod->node + UBIFS_CH_SZ, 68 UBIFS_MST_NODE_SZ - UBIFS_CH_SZ)) 69 goto out; 70 c->mst_offs = offs; 71 ubifs_scan_destroy(sleb); 72 return 0; 73 74 out: 75 ubifs_scan_destroy(sleb); 76 return -EUCLEAN; 77 78 out_dump: 79 ubifs_err(c, "unexpected node type %d master LEB %d:%d", 80 snod->type, lnum, snod->offs); 81 ubifs_scan_destroy(sleb); 82 return -EINVAL; 83 } 84 85 /** 86 * validate_master - validate master node. 87 * @c: UBIFS file-system description object 88 * 89 * This function validates data which was read from master node. Returns zero 90 * if the data is all right and %-EINVAL if not. 91 */ 92 static int validate_master(const struct ubifs_info *c) 93 { 94 long long main_sz; 95 int err; 96 97 if (c->max_sqnum >= SQNUM_WATERMARK) { 98 err = 1; 99 goto out; 100 } 101 102 if (c->cmt_no >= c->max_sqnum) { 103 err = 2; 104 goto out; 105 } 106 107 if (c->highest_inum >= INUM_WATERMARK) { 108 err = 3; 109 goto out; 110 } 111 112 if (c->lhead_lnum < UBIFS_LOG_LNUM || 113 c->lhead_lnum >= UBIFS_LOG_LNUM + c->log_lebs || 114 c->lhead_offs < 0 || c->lhead_offs >= c->leb_size || 115 c->lhead_offs & (c->min_io_size - 1)) { 116 err = 4; 117 goto out; 118 } 119 120 if (c->zroot.lnum >= c->leb_cnt || c->zroot.lnum < c->main_first || 121 c->zroot.offs >= c->leb_size || c->zroot.offs & 7) { 122 err = 5; 123 goto out; 124 } 125 126 if (c->zroot.len < c->ranges[UBIFS_IDX_NODE].min_len || 127 c->zroot.len > c->ranges[UBIFS_IDX_NODE].max_len) { 128 err = 6; 129 goto out; 130 } 131 132 if (c->gc_lnum >= c->leb_cnt || c->gc_lnum < c->main_first) { 133 err = 7; 134 goto out; 135 } 136 137 if (c->ihead_lnum >= c->leb_cnt || c->ihead_lnum < c->main_first || 138 c->ihead_offs % c->min_io_size || c->ihead_offs < 0 || 139 c->ihead_offs > c->leb_size || c->ihead_offs & 7) { 140 err = 8; 141 goto out; 142 } 143 144 main_sz = (long long)c->main_lebs * c->leb_size; 145 if (c->bi.old_idx_sz & 7 || c->bi.old_idx_sz >= main_sz) { 146 err = 9; 147 goto out; 148 } 149 150 if (c->lpt_lnum < c->lpt_first || c->lpt_lnum > c->lpt_last || 151 c->lpt_offs < 0 || c->lpt_offs + c->nnode_sz > c->leb_size) { 152 err = 10; 153 goto out; 154 } 155 156 if (c->nhead_lnum < c->lpt_first || c->nhead_lnum > c->lpt_last || 157 c->nhead_offs < 0 || c->nhead_offs % c->min_io_size || 158 c->nhead_offs > c->leb_size) { 159 err = 11; 160 goto out; 161 } 162 163 if (c->ltab_lnum < c->lpt_first || c->ltab_lnum > c->lpt_last || 164 c->ltab_offs < 0 || 165 c->ltab_offs + c->ltab_sz > c->leb_size) { 166 err = 12; 167 goto out; 168 } 169 170 if (c->big_lpt && (c->lsave_lnum < c->lpt_first || 171 c->lsave_lnum > c->lpt_last || c->lsave_offs < 0 || 172 c->lsave_offs + c->lsave_sz > c->leb_size)) { 173 err = 13; 174 goto out; 175 } 176 177 if (c->lscan_lnum < c->main_first || c->lscan_lnum >= c->leb_cnt) { 178 err = 14; 179 goto out; 180 } 181 182 if (c->lst.empty_lebs < 0 || c->lst.empty_lebs > c->main_lebs - 2) { 183 err = 15; 184 goto out; 185 } 186 187 if (c->lst.idx_lebs < 0 || c->lst.idx_lebs > c->main_lebs - 1) { 188 err = 16; 189 goto out; 190 } 191 192 if (c->lst.total_free < 0 || c->lst.total_free > main_sz || 193 c->lst.total_free & 7) { 194 err = 17; 195 goto out; 196 } 197 198 if (c->lst.total_dirty < 0 || (c->lst.total_dirty & 7)) { 199 err = 18; 200 goto out; 201 } 202 203 if (c->lst.total_used < 0 || (c->lst.total_used & 7)) { 204 err = 19; 205 goto out; 206 } 207 208 if (c->lst.total_free + c->lst.total_dirty + 209 c->lst.total_used > main_sz) { 210 err = 20; 211 goto out; 212 } 213 214 if (c->lst.total_dead + c->lst.total_dark + 215 c->lst.total_used + c->bi.old_idx_sz > main_sz) { 216 err = 21; 217 goto out; 218 } 219 220 if (c->lst.total_dead < 0 || 221 c->lst.total_dead > c->lst.total_free + c->lst.total_dirty || 222 c->lst.total_dead & 7) { 223 err = 22; 224 goto out; 225 } 226 227 if (c->lst.total_dark < 0 || 228 c->lst.total_dark > c->lst.total_free + c->lst.total_dirty || 229 c->lst.total_dark & 7) { 230 err = 23; 231 goto out; 232 } 233 234 return 0; 235 236 out: 237 ubifs_err(c, "bad master node at offset %d error %d", c->mst_offs, err); 238 ubifs_dump_node(c, c->mst_node); 239 return -EINVAL; 240 } 241 242 /** 243 * ubifs_read_master - read master node. 244 * @c: UBIFS file-system description object 245 * 246 * This function finds and reads the master node during file-system mount. If 247 * the flash is empty, it creates default master node as well. Returns zero in 248 * case of success and a negative error code in case of failure. 249 */ 250 int ubifs_read_master(struct ubifs_info *c) 251 { 252 int err, old_leb_cnt; 253 254 c->mst_node = kzalloc(c->mst_node_alsz, GFP_KERNEL); 255 if (!c->mst_node) 256 return -ENOMEM; 257 258 err = scan_for_master(c); 259 if (err) { 260 if (err == -EUCLEAN) 261 err = ubifs_recover_master_node(c); 262 if (err) 263 /* 264 * Note, we do not free 'c->mst_node' here because the 265 * unmount routine will take care of this. 266 */ 267 return err; 268 } 269 270 /* Make sure that the recovery flag is clear */ 271 c->mst_node->flags &= cpu_to_le32(~UBIFS_MST_RCVRY); 272 273 c->max_sqnum = le64_to_cpu(c->mst_node->ch.sqnum); 274 c->highest_inum = le64_to_cpu(c->mst_node->highest_inum); 275 c->cmt_no = le64_to_cpu(c->mst_node->cmt_no); 276 c->zroot.lnum = le32_to_cpu(c->mst_node->root_lnum); 277 c->zroot.offs = le32_to_cpu(c->mst_node->root_offs); 278 c->zroot.len = le32_to_cpu(c->mst_node->root_len); 279 c->lhead_lnum = le32_to_cpu(c->mst_node->log_lnum); 280 c->gc_lnum = le32_to_cpu(c->mst_node->gc_lnum); 281 c->ihead_lnum = le32_to_cpu(c->mst_node->ihead_lnum); 282 c->ihead_offs = le32_to_cpu(c->mst_node->ihead_offs); 283 c->bi.old_idx_sz = le64_to_cpu(c->mst_node->index_size); 284 c->lpt_lnum = le32_to_cpu(c->mst_node->lpt_lnum); 285 c->lpt_offs = le32_to_cpu(c->mst_node->lpt_offs); 286 c->nhead_lnum = le32_to_cpu(c->mst_node->nhead_lnum); 287 c->nhead_offs = le32_to_cpu(c->mst_node->nhead_offs); 288 c->ltab_lnum = le32_to_cpu(c->mst_node->ltab_lnum); 289 c->ltab_offs = le32_to_cpu(c->mst_node->ltab_offs); 290 c->lsave_lnum = le32_to_cpu(c->mst_node->lsave_lnum); 291 c->lsave_offs = le32_to_cpu(c->mst_node->lsave_offs); 292 c->lscan_lnum = le32_to_cpu(c->mst_node->lscan_lnum); 293 c->lst.empty_lebs = le32_to_cpu(c->mst_node->empty_lebs); 294 c->lst.idx_lebs = le32_to_cpu(c->mst_node->idx_lebs); 295 old_leb_cnt = le32_to_cpu(c->mst_node->leb_cnt); 296 c->lst.total_free = le64_to_cpu(c->mst_node->total_free); 297 c->lst.total_dirty = le64_to_cpu(c->mst_node->total_dirty); 298 c->lst.total_used = le64_to_cpu(c->mst_node->total_used); 299 c->lst.total_dead = le64_to_cpu(c->mst_node->total_dead); 300 c->lst.total_dark = le64_to_cpu(c->mst_node->total_dark); 301 302 c->calc_idx_sz = c->bi.old_idx_sz; 303 304 if (c->mst_node->flags & cpu_to_le32(UBIFS_MST_NO_ORPHS)) 305 c->no_orphs = 1; 306 307 if (old_leb_cnt != c->leb_cnt) { 308 /* The file system has been resized */ 309 int growth = c->leb_cnt - old_leb_cnt; 310 311 if (c->leb_cnt < old_leb_cnt || 312 c->leb_cnt < UBIFS_MIN_LEB_CNT) { 313 ubifs_err(c, "bad leb_cnt on master node"); 314 ubifs_dump_node(c, c->mst_node); 315 return -EINVAL; 316 } 317 318 dbg_mnt("Auto resizing (master) from %d LEBs to %d LEBs", 319 old_leb_cnt, c->leb_cnt); 320 c->lst.empty_lebs += growth; 321 c->lst.total_free += growth * (long long)c->leb_size; 322 c->lst.total_dark += growth * (long long)c->dark_wm; 323 324 /* 325 * Reflect changes back onto the master node. N.B. the master 326 * node gets written immediately whenever mounting (or 327 * remounting) in read-write mode, so we do not need to write it 328 * here. 329 */ 330 c->mst_node->leb_cnt = cpu_to_le32(c->leb_cnt); 331 c->mst_node->empty_lebs = cpu_to_le32(c->lst.empty_lebs); 332 c->mst_node->total_free = cpu_to_le64(c->lst.total_free); 333 c->mst_node->total_dark = cpu_to_le64(c->lst.total_dark); 334 } 335 336 err = validate_master(c); 337 if (err) 338 return err; 339 340 #ifndef __UBOOT__ 341 err = dbg_old_index_check_init(c, &c->zroot); 342 #endif 343 344 return err; 345 } 346 347 #ifndef __UBOOT__ 348 /** 349 * ubifs_write_master - write master node. 350 * @c: UBIFS file-system description object 351 * 352 * This function writes the master node. Returns zero in case of success and a 353 * negative error code in case of failure. The master node is written twice to 354 * enable recovery. 355 */ 356 int ubifs_write_master(struct ubifs_info *c) 357 { 358 int err, lnum, offs, len; 359 360 ubifs_assert(!c->ro_media && !c->ro_mount); 361 if (c->ro_error) 362 return -EROFS; 363 364 lnum = UBIFS_MST_LNUM; 365 offs = c->mst_offs + c->mst_node_alsz; 366 len = UBIFS_MST_NODE_SZ; 367 368 if (offs + UBIFS_MST_NODE_SZ > c->leb_size) { 369 err = ubifs_leb_unmap(c, lnum); 370 if (err) 371 return err; 372 offs = 0; 373 } 374 375 c->mst_offs = offs; 376 c->mst_node->highest_inum = cpu_to_le64(c->highest_inum); 377 378 err = ubifs_write_node(c, c->mst_node, len, lnum, offs); 379 if (err) 380 return err; 381 382 lnum += 1; 383 384 if (offs == 0) { 385 err = ubifs_leb_unmap(c, lnum); 386 if (err) 387 return err; 388 } 389 err = ubifs_write_node(c, c->mst_node, len, lnum, offs); 390 391 return err; 392 } 393 #endif 394