UBIFS: add R/O compatibility

Now UBIFS is supported by u-boot. If we ever decide to change the
media format, then people will have to upgrade their u-boots to
mount new format images. However, very often it is possible to
preserve R/O forward-compatibility, even though the write
forward-compatibility is not preserved.

This patch introduces a new super-block field which stores the
R/O compatibility version.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Acked-by: Adrian Hunter <Adrian.Hunter@nokia.com>

+72 -11
+29 -6
fs/ubifs/sb.c
··· 193 if (tmp64 > DEFAULT_MAX_RP_SIZE) 194 tmp64 = DEFAULT_MAX_RP_SIZE; 195 sup->rp_size = cpu_to_le64(tmp64); 196 197 err = ubifs_write_node(c, sup, UBIFS_SB_NODE_SZ, 0, 0, UBI_LONGTERM); 198 kfree(sup); ··· 533 if (IS_ERR(sup)) 534 return PTR_ERR(sup); 535 536 /* 537 * The software supports all previous versions but not future versions, 538 * due to the unavailability of time-travelling equipment. 539 */ 540 - c->fmt_version = le32_to_cpu(sup->fmt_version); 541 if (c->fmt_version > UBIFS_FORMAT_VERSION) { 542 - ubifs_err("on-flash format version is %d, but software only " 543 - "supports up to version %d", c->fmt_version, 544 - UBIFS_FORMAT_VERSION); 545 - err = -EINVAL; 546 - goto out; 547 } 548 549 if (c->fmt_version < 3) {
··· 193 if (tmp64 > DEFAULT_MAX_RP_SIZE) 194 tmp64 = DEFAULT_MAX_RP_SIZE; 195 sup->rp_size = cpu_to_le64(tmp64); 196 + sup->ro_compat_version = cpu_to_le32(UBIFS_RO_COMPAT_VERSION); 197 198 err = ubifs_write_node(c, sup, UBIFS_SB_NODE_SZ, 0, 0, UBI_LONGTERM); 199 kfree(sup); ··· 532 if (IS_ERR(sup)) 533 return PTR_ERR(sup); 534 535 + c->fmt_version = le32_to_cpu(sup->fmt_version); 536 + c->ro_compat_version = le32_to_cpu(sup->ro_compat_version); 537 + 538 /* 539 * The software supports all previous versions but not future versions, 540 * due to the unavailability of time-travelling equipment. 541 */ 542 if (c->fmt_version > UBIFS_FORMAT_VERSION) { 543 + struct super_block *sb = c->vfs_sb; 544 + int mounting_ro = sb->s_flags & MS_RDONLY; 545 + 546 + ubifs_assert(!c->ro_media || mounting_ro); 547 + if (!mounting_ro || 548 + c->ro_compat_version > UBIFS_RO_COMPAT_VERSION) { 549 + ubifs_err("on-flash format version is w%d/r%d, but " 550 + "software only supports up to version " 551 + "w%d/r%d", c->fmt_version, 552 + c->ro_compat_version, UBIFS_FORMAT_VERSION, 553 + UBIFS_RO_COMPAT_VERSION); 554 + if (c->ro_compat_version <= UBIFS_RO_COMPAT_VERSION) { 555 + ubifs_msg("only R/O mounting is possible"); 556 + err = -EROFS; 557 + } else 558 + err = -EINVAL; 559 + goto out; 560 + } 561 + 562 + /* 563 + * The FS is mounted R/O, and the media format is 564 + * R/O-compatible with the UBIFS implementation, so we can 565 + * mount. 566 + */ 567 + c->rw_incompat = 1; 568 } 569 570 if (c->fmt_version < 3) {
+12 -2
fs/ubifs/super.c
··· 1351 x = (long long)c->log_lebs * c->leb_size + c->max_bud_bytes; 1352 ubifs_msg("journal size: %lld bytes (%lld KiB, %lld MiB, %d " 1353 "LEBs)", x, x >> 10, x >> 20, c->log_lebs + c->max_bud_cnt); 1354 - ubifs_msg("media format: %d (latest is %d)", 1355 - c->fmt_version, UBIFS_FORMAT_VERSION); 1356 ubifs_msg("default compressor: %s", ubifs_compr_name(c->default_compr)); 1357 ubifs_msg("reserved for root: %llu bytes (%llu KiB)", 1358 c->report_rp_size, c->report_rp_size >> 10); ··· 1492 static int ubifs_remount_rw(struct ubifs_info *c) 1493 { 1494 int err, lnum; 1495 1496 mutex_lock(&c->umount_mutex); 1497 dbg_save_space_info(c);
··· 1351 x = (long long)c->log_lebs * c->leb_size + c->max_bud_bytes; 1352 ubifs_msg("journal size: %lld bytes (%lld KiB, %lld MiB, %d " 1353 "LEBs)", x, x >> 10, x >> 20, c->log_lebs + c->max_bud_cnt); 1354 + ubifs_msg("media format: w%d/r%d (latest is w%d/r%d)", 1355 + c->fmt_version, c->ro_compat_version, 1356 + UBIFS_FORMAT_VERSION, UBIFS_RO_COMPAT_VERSION); 1357 ubifs_msg("default compressor: %s", ubifs_compr_name(c->default_compr)); 1358 ubifs_msg("reserved for root: %llu bytes (%llu KiB)", 1359 c->report_rp_size, c->report_rp_size >> 10); ··· 1491 static int ubifs_remount_rw(struct ubifs_info *c) 1492 { 1493 int err, lnum; 1494 + 1495 + if (c->rw_incompat) { 1496 + ubifs_err("the file-system is not R/W-compatible"); 1497 + ubifs_msg("on-flash format version is w%d/r%d, but software " 1498 + "only supports up to version w%d/r%d", c->fmt_version, 1499 + c->ro_compat_version, UBIFS_FORMAT_VERSION, 1500 + UBIFS_RO_COMPAT_VERSION); 1501 + return -EROFS; 1502 + } 1503 1504 mutex_lock(&c->umount_mutex); 1505 dbg_save_space_info(c);
+27 -3
fs/ubifs/ubifs-media.h
··· 36 /* UBIFS node magic number (must not have the padding byte first or last) */ 37 #define UBIFS_NODE_MAGIC 0x06101831 38 39 - /* UBIFS on-flash format version */ 40 #define UBIFS_FORMAT_VERSION 4 41 42 /* Minimum logical eraseblock size in bytes */ 43 #define UBIFS_MIN_LEB_SZ (15*1024) ··· 75 76 /* 77 * If compressed data length is less than %UBIFS_MIN_COMPRESS_DIFF bytes 78 - * shorter than uncompressed data length, UBIFS preferes to leave this data 79 * node uncompress, because it'll be read faster. 80 */ 81 #define UBIFS_MIN_COMPRESS_DIFF 64 ··· 608 * @padding2: reserved for future, zeroes 609 * @time_gran: time granularity in nanoseconds 610 * @uuid: UUID generated when the file system image was created 611 */ 612 struct ubifs_sb_node { 613 struct ubifs_ch ch; ··· 635 __le64 rp_size; 636 __le32 time_gran; 637 __u8 uuid[16]; 638 - __u8 padding2[3972]; 639 } __attribute__ ((packed)); 640 641 /**
··· 36 /* UBIFS node magic number (must not have the padding byte first or last) */ 37 #define UBIFS_NODE_MAGIC 0x06101831 38 39 + /* 40 + * UBIFS on-flash format version. This version is increased when the on-flash 41 + * format is changing. If this happens, UBIFS is will support older versions as 42 + * well. But older UBIFS code will not support newer formats. Format changes 43 + * will be rare and only when absolutely necessary, e.g. to fix a bug or to add 44 + * a new feature. 45 + * 46 + * UBIFS went into mainline kernel with format version 4. The older formats 47 + * were development formats. 48 + */ 49 #define UBIFS_FORMAT_VERSION 4 50 + 51 + /* 52 + * Read-only compatibility version. If the UBIFS format is changed, older UBIFS 53 + * implementations will not be able to mount newer formats in read-write mode. 54 + * However, depending on the change, it may be possible to mount newer formats 55 + * in R/O mode. This is indicated by the R/O compatibility version which is 56 + * stored in the super-block. 57 + * 58 + * This is needed to support boot-loaders which only need R/O mounting. With 59 + * this flag it is possible to do UBIFS format changes without a need to update 60 + * boot-loaders. 61 + */ 62 + #define UBIFS_RO_COMPAT_VERSION 0 63 64 /* Minimum logical eraseblock size in bytes */ 65 #define UBIFS_MIN_LEB_SZ (15*1024) ··· 53 54 /* 55 * If compressed data length is less than %UBIFS_MIN_COMPRESS_DIFF bytes 56 + * shorter than uncompressed data length, UBIFS prefers to leave this data 57 * node uncompress, because it'll be read faster. 58 */ 59 #define UBIFS_MIN_COMPRESS_DIFF 64 ··· 586 * @padding2: reserved for future, zeroes 587 * @time_gran: time granularity in nanoseconds 588 * @uuid: UUID generated when the file system image was created 589 + * @ro_compat_version: UBIFS R/O compatibility version 590 */ 591 struct ubifs_sb_node { 592 struct ubifs_ch ch; ··· 612 __le64 rp_size; 613 __le32 time_gran; 614 __u8 uuid[16]; 615 + __le32 ro_compat_version; 616 + __u8 padding2[3968]; 617 } __attribute__ ((packed)); 618 619 /**
+4
fs/ubifs/ubifs.h
··· 934 * by @commit_sem 935 * @cnt_lock: protects @highest_inum and @max_sqnum counters 936 * @fmt_version: UBIFS on-flash format version 937 * @uuid: UUID from super block 938 * 939 * @lhead_lnum: log head logical eraseblock number ··· 967 * recovery) 968 * @bulk_read: enable bulk-reads 969 * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc) 970 * 971 * @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and 972 * @calc_idx_sz ··· 1181 unsigned long long cmt_no; 1182 spinlock_t cnt_lock; 1183 int fmt_version; 1184 unsigned char uuid[16]; 1185 1186 int lhead_lnum; ··· 1210 unsigned int no_chk_data_crc:1; 1211 unsigned int bulk_read:1; 1212 unsigned int default_compr:2; 1213 1214 struct mutex tnc_mutex; 1215 struct ubifs_zbranch zroot;
··· 934 * by @commit_sem 935 * @cnt_lock: protects @highest_inum and @max_sqnum counters 936 * @fmt_version: UBIFS on-flash format version 937 + * @ro_compat_version: R/O compatibility version 938 * @uuid: UUID from super block 939 * 940 * @lhead_lnum: log head logical eraseblock number ··· 966 * recovery) 967 * @bulk_read: enable bulk-reads 968 * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc) 969 + * @rw_incompat: the media is not R/W compatible 970 * 971 * @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and 972 * @calc_idx_sz ··· 1179 unsigned long long cmt_no; 1180 spinlock_t cnt_lock; 1181 int fmt_version; 1182 + int ro_compat_version; 1183 unsigned char uuid[16]; 1184 1185 int lhead_lnum; ··· 1207 unsigned int no_chk_data_crc:1; 1208 unsigned int bulk_read:1; 1209 unsigned int default_compr:2; 1210 + unsigned int rw_incompat:1; 1211 1212 struct mutex tnc_mutex; 1213 struct ubifs_zbranch zroot;