diff options
Diffstat (limited to 'fs/ubifs/super.c')
-rw-r--r-- | fs/ubifs/super.c | 109 |
1 files changed, 88 insertions, 21 deletions
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 9a9220333b3b..8780efbf40ac 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -401,6 +401,16 @@ static int ubifs_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
401 | else if (c->mount_opts.unmount_mode == 1) | 401 | else if (c->mount_opts.unmount_mode == 1) |
402 | seq_printf(s, ",norm_unmount"); | 402 | seq_printf(s, ",norm_unmount"); |
403 | 403 | ||
404 | if (c->mount_opts.bulk_read == 2) | ||
405 | seq_printf(s, ",bulk_read"); | ||
406 | else if (c->mount_opts.bulk_read == 1) | ||
407 | seq_printf(s, ",no_bulk_read"); | ||
408 | |||
409 | if (c->mount_opts.chk_data_crc == 2) | ||
410 | seq_printf(s, ",chk_data_crc"); | ||
411 | else if (c->mount_opts.chk_data_crc == 1) | ||
412 | seq_printf(s, ",no_chk_data_crc"); | ||
413 | |||
404 | return 0; | 414 | return 0; |
405 | } | 415 | } |
406 | 416 | ||
@@ -408,13 +418,26 @@ static int ubifs_sync_fs(struct super_block *sb, int wait) | |||
408 | { | 418 | { |
409 | struct ubifs_info *c = sb->s_fs_info; | 419 | struct ubifs_info *c = sb->s_fs_info; |
410 | int i, ret = 0, err; | 420 | int i, ret = 0, err; |
421 | long long bud_bytes; | ||
411 | 422 | ||
412 | if (c->jheads) | 423 | if (c->jheads) { |
413 | for (i = 0; i < c->jhead_cnt; i++) { | 424 | for (i = 0; i < c->jhead_cnt; i++) { |
414 | err = ubifs_wbuf_sync(&c->jheads[i].wbuf); | 425 | err = ubifs_wbuf_sync(&c->jheads[i].wbuf); |
415 | if (err && !ret) | 426 | if (err && !ret) |
416 | ret = err; | 427 | ret = err; |
417 | } | 428 | } |
429 | |||
430 | /* Commit the journal unless it has too little data */ | ||
431 | spin_lock(&c->buds_lock); | ||
432 | bud_bytes = c->bud_bytes; | ||
433 | spin_unlock(&c->buds_lock); | ||
434 | if (bud_bytes > c->leb_size) { | ||
435 | err = ubifs_run_commit(c); | ||
436 | if (err) | ||
437 | return err; | ||
438 | } | ||
439 | } | ||
440 | |||
418 | /* | 441 | /* |
419 | * We ought to call sync for c->ubi but it does not have one. If it had | 442 | * We ought to call sync for c->ubi but it does not have one. If it had |
420 | * it would in turn call mtd->sync, however mtd operations are | 443 | * it would in turn call mtd->sync, however mtd operations are |
@@ -538,6 +561,18 @@ static int init_constants_early(struct ubifs_info *c) | |||
538 | * calculations when reporting free space. | 561 | * calculations when reporting free space. |
539 | */ | 562 | */ |
540 | c->leb_overhead = c->leb_size % UBIFS_MAX_DATA_NODE_SZ; | 563 | c->leb_overhead = c->leb_size % UBIFS_MAX_DATA_NODE_SZ; |
564 | /* Buffer size for bulk-reads */ | ||
565 | c->bulk_read_buf_size = UBIFS_MAX_BULK_READ * UBIFS_MAX_DATA_NODE_SZ; | ||
566 | if (c->bulk_read_buf_size > c->leb_size) | ||
567 | c->bulk_read_buf_size = c->leb_size; | ||
568 | if (c->bulk_read_buf_size > 128 * 1024) { | ||
569 | /* Check if we can kmalloc more than 128KiB */ | ||
570 | void *try = kmalloc(c->bulk_read_buf_size, GFP_KERNEL); | ||
571 | |||
572 | kfree(try); | ||
573 | if (!try) | ||
574 | c->bulk_read_buf_size = 128 * 1024; | ||
575 | } | ||
541 | return 0; | 576 | return 0; |
542 | } | 577 | } |
543 | 578 | ||
@@ -840,17 +875,29 @@ static int check_volume_empty(struct ubifs_info *c) | |||
840 | * | 875 | * |
841 | * Opt_fast_unmount: do not run a journal commit before un-mounting | 876 | * Opt_fast_unmount: do not run a journal commit before un-mounting |
842 | * Opt_norm_unmount: run a journal commit before un-mounting | 877 | * Opt_norm_unmount: run a journal commit before un-mounting |
878 | * Opt_bulk_read: enable bulk-reads | ||
879 | * Opt_no_bulk_read: disable bulk-reads | ||
880 | * Opt_chk_data_crc: check CRCs when reading data nodes | ||
881 | * Opt_no_chk_data_crc: do not check CRCs when reading data nodes | ||
843 | * Opt_err: just end of array marker | 882 | * Opt_err: just end of array marker |
844 | */ | 883 | */ |
845 | enum { | 884 | enum { |
846 | Opt_fast_unmount, | 885 | Opt_fast_unmount, |
847 | Opt_norm_unmount, | 886 | Opt_norm_unmount, |
887 | Opt_bulk_read, | ||
888 | Opt_no_bulk_read, | ||
889 | Opt_chk_data_crc, | ||
890 | Opt_no_chk_data_crc, | ||
848 | Opt_err, | 891 | Opt_err, |
849 | }; | 892 | }; |
850 | 893 | ||
851 | static const match_table_t tokens = { | 894 | static const match_table_t tokens = { |
852 | {Opt_fast_unmount, "fast_unmount"}, | 895 | {Opt_fast_unmount, "fast_unmount"}, |
853 | {Opt_norm_unmount, "norm_unmount"}, | 896 | {Opt_norm_unmount, "norm_unmount"}, |
897 | {Opt_bulk_read, "bulk_read"}, | ||
898 | {Opt_no_bulk_read, "no_bulk_read"}, | ||
899 | {Opt_chk_data_crc, "chk_data_crc"}, | ||
900 | {Opt_no_chk_data_crc, "no_chk_data_crc"}, | ||
854 | {Opt_err, NULL}, | 901 | {Opt_err, NULL}, |
855 | }; | 902 | }; |
856 | 903 | ||
@@ -888,6 +935,22 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options, | |||
888 | c->mount_opts.unmount_mode = 1; | 935 | c->mount_opts.unmount_mode = 1; |
889 | c->fast_unmount = 0; | 936 | c->fast_unmount = 0; |
890 | break; | 937 | break; |
938 | case Opt_bulk_read: | ||
939 | c->mount_opts.bulk_read = 2; | ||
940 | c->bulk_read = 1; | ||
941 | break; | ||
942 | case Opt_no_bulk_read: | ||
943 | c->mount_opts.bulk_read = 1; | ||
944 | c->bulk_read = 0; | ||
945 | break; | ||
946 | case Opt_chk_data_crc: | ||
947 | c->mount_opts.chk_data_crc = 2; | ||
948 | c->no_chk_data_crc = 0; | ||
949 | break; | ||
950 | case Opt_no_chk_data_crc: | ||
951 | c->mount_opts.chk_data_crc = 1; | ||
952 | c->no_chk_data_crc = 1; | ||
953 | break; | ||
891 | default: | 954 | default: |
892 | ubifs_err("unrecognized mount option \"%s\" " | 955 | ubifs_err("unrecognized mount option \"%s\" " |
893 | "or missing value", p); | 956 | "or missing value", p); |
@@ -996,6 +1059,8 @@ static int mount_ubifs(struct ubifs_info *c) | |||
996 | goto out_free; | 1059 | goto out_free; |
997 | } | 1060 | } |
998 | 1061 | ||
1062 | c->always_chk_crc = 1; | ||
1063 | |||
999 | err = ubifs_read_superblock(c); | 1064 | err = ubifs_read_superblock(c); |
1000 | if (err) | 1065 | if (err) |
1001 | goto out_free; | 1066 | goto out_free; |
@@ -1032,8 +1097,6 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1032 | 1097 | ||
1033 | /* Create background thread */ | 1098 | /* Create background thread */ |
1034 | c->bgt = kthread_create(ubifs_bg_thread, c, c->bgt_name); | 1099 | c->bgt = kthread_create(ubifs_bg_thread, c, c->bgt_name); |
1035 | if (!c->bgt) | ||
1036 | c->bgt = ERR_PTR(-EINVAL); | ||
1037 | if (IS_ERR(c->bgt)) { | 1100 | if (IS_ERR(c->bgt)) { |
1038 | err = PTR_ERR(c->bgt); | 1101 | err = PTR_ERR(c->bgt); |
1039 | c->bgt = NULL; | 1102 | c->bgt = NULL; |
@@ -1139,24 +1202,28 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1139 | if (err) | 1202 | if (err) |
1140 | goto out_infos; | 1203 | goto out_infos; |
1141 | 1204 | ||
1205 | c->always_chk_crc = 0; | ||
1206 | |||
1142 | ubifs_msg("mounted UBI device %d, volume %d, name \"%s\"", | 1207 | ubifs_msg("mounted UBI device %d, volume %d, name \"%s\"", |
1143 | c->vi.ubi_num, c->vi.vol_id, c->vi.name); | 1208 | c->vi.ubi_num, c->vi.vol_id, c->vi.name); |
1144 | if (mounted_read_only) | 1209 | if (mounted_read_only) |
1145 | ubifs_msg("mounted read-only"); | 1210 | ubifs_msg("mounted read-only"); |
1146 | x = (long long)c->main_lebs * c->leb_size; | 1211 | x = (long long)c->main_lebs * c->leb_size; |
1147 | ubifs_msg("file system size: %lld bytes (%lld KiB, %lld MiB, %d LEBs)", | 1212 | ubifs_msg("file system size: %lld bytes (%lld KiB, %lld MiB, %d " |
1148 | x, x >> 10, x >> 20, c->main_lebs); | 1213 | "LEBs)", x, x >> 10, x >> 20, c->main_lebs); |
1149 | x = (long long)c->log_lebs * c->leb_size + c->max_bud_bytes; | 1214 | x = (long long)c->log_lebs * c->leb_size + c->max_bud_bytes; |
1150 | ubifs_msg("journal size: %lld bytes (%lld KiB, %lld MiB, %d LEBs)", | 1215 | ubifs_msg("journal size: %lld bytes (%lld KiB, %lld MiB, %d " |
1151 | x, x >> 10, x >> 20, c->log_lebs + c->max_bud_cnt); | 1216 | "LEBs)", x, x >> 10, x >> 20, c->log_lebs + c->max_bud_cnt); |
1152 | ubifs_msg("default compressor: %s", ubifs_compr_name(c->default_compr)); | 1217 | ubifs_msg("media format: %d (latest is %d)", |
1153 | ubifs_msg("media format %d, latest format %d", | ||
1154 | c->fmt_version, UBIFS_FORMAT_VERSION); | 1218 | c->fmt_version, UBIFS_FORMAT_VERSION); |
1219 | ubifs_msg("default compressor: %s", ubifs_compr_name(c->default_compr)); | ||
1220 | ubifs_msg("reserved for root: %llu bytes (%llu KiB)", | ||
1221 | c->report_rp_size, c->report_rp_size >> 10); | ||
1155 | 1222 | ||
1156 | dbg_msg("compiled on: " __DATE__ " at " __TIME__); | 1223 | dbg_msg("compiled on: " __DATE__ " at " __TIME__); |
1157 | dbg_msg("min. I/O unit size: %d bytes", c->min_io_size); | 1224 | dbg_msg("min. I/O unit size: %d bytes", c->min_io_size); |
1158 | dbg_msg("LEB size: %d bytes (%d KiB)", | 1225 | dbg_msg("LEB size: %d bytes (%d KiB)", |
1159 | c->leb_size, c->leb_size / 1024); | 1226 | c->leb_size, c->leb_size >> 10); |
1160 | dbg_msg("data journal heads: %d", | 1227 | dbg_msg("data journal heads: %d", |
1161 | c->jhead_cnt - NONDATA_JHEADS_CNT); | 1228 | c->jhead_cnt - NONDATA_JHEADS_CNT); |
1162 | dbg_msg("UUID: %02X%02X%02X%02X-%02X%02X" | 1229 | dbg_msg("UUID: %02X%02X%02X%02X-%02X%02X" |
@@ -1282,6 +1349,7 @@ static int ubifs_remount_rw(struct ubifs_info *c) | |||
1282 | 1349 | ||
1283 | mutex_lock(&c->umount_mutex); | 1350 | mutex_lock(&c->umount_mutex); |
1284 | c->remounting_rw = 1; | 1351 | c->remounting_rw = 1; |
1352 | c->always_chk_crc = 1; | ||
1285 | 1353 | ||
1286 | /* Check for enough free space */ | 1354 | /* Check for enough free space */ |
1287 | if (ubifs_calc_available(c, c->min_idx_lebs) <= 0) { | 1355 | if (ubifs_calc_available(c, c->min_idx_lebs) <= 0) { |
@@ -1345,20 +1413,20 @@ static int ubifs_remount_rw(struct ubifs_info *c) | |||
1345 | 1413 | ||
1346 | /* Create background thread */ | 1414 | /* Create background thread */ |
1347 | c->bgt = kthread_create(ubifs_bg_thread, c, c->bgt_name); | 1415 | c->bgt = kthread_create(ubifs_bg_thread, c, c->bgt_name); |
1348 | if (!c->bgt) | ||
1349 | c->bgt = ERR_PTR(-EINVAL); | ||
1350 | if (IS_ERR(c->bgt)) { | 1416 | if (IS_ERR(c->bgt)) { |
1351 | err = PTR_ERR(c->bgt); | 1417 | err = PTR_ERR(c->bgt); |
1352 | c->bgt = NULL; | 1418 | c->bgt = NULL; |
1353 | ubifs_err("cannot spawn \"%s\", error %d", | 1419 | ubifs_err("cannot spawn \"%s\", error %d", |
1354 | c->bgt_name, err); | 1420 | c->bgt_name, err); |
1355 | return err; | 1421 | goto out; |
1356 | } | 1422 | } |
1357 | wake_up_process(c->bgt); | 1423 | wake_up_process(c->bgt); |
1358 | 1424 | ||
1359 | c->orph_buf = vmalloc(c->leb_size); | 1425 | c->orph_buf = vmalloc(c->leb_size); |
1360 | if (!c->orph_buf) | 1426 | if (!c->orph_buf) { |
1361 | return -ENOMEM; | 1427 | err = -ENOMEM; |
1428 | goto out; | ||
1429 | } | ||
1362 | 1430 | ||
1363 | /* Check for enough log space */ | 1431 | /* Check for enough log space */ |
1364 | lnum = c->lhead_lnum + 1; | 1432 | lnum = c->lhead_lnum + 1; |
@@ -1385,6 +1453,7 @@ static int ubifs_remount_rw(struct ubifs_info *c) | |||
1385 | dbg_gen("re-mounted read-write"); | 1453 | dbg_gen("re-mounted read-write"); |
1386 | c->vfs_sb->s_flags &= ~MS_RDONLY; | 1454 | c->vfs_sb->s_flags &= ~MS_RDONLY; |
1387 | c->remounting_rw = 0; | 1455 | c->remounting_rw = 0; |
1456 | c->always_chk_crc = 0; | ||
1388 | mutex_unlock(&c->umount_mutex); | 1457 | mutex_unlock(&c->umount_mutex); |
1389 | return 0; | 1458 | return 0; |
1390 | 1459 | ||
@@ -1400,6 +1469,7 @@ out: | |||
1400 | c->ileb_buf = NULL; | 1469 | c->ileb_buf = NULL; |
1401 | ubifs_lpt_free(c, 1); | 1470 | ubifs_lpt_free(c, 1); |
1402 | c->remounting_rw = 0; | 1471 | c->remounting_rw = 0; |
1472 | c->always_chk_crc = 0; | ||
1403 | mutex_unlock(&c->umount_mutex); | 1473 | mutex_unlock(&c->umount_mutex); |
1404 | return err; | 1474 | return err; |
1405 | } | 1475 | } |
@@ -1408,12 +1478,9 @@ out: | |||
1408 | * commit_on_unmount - commit the journal when un-mounting. | 1478 | * commit_on_unmount - commit the journal when un-mounting. |
1409 | * @c: UBIFS file-system description object | 1479 | * @c: UBIFS file-system description object |
1410 | * | 1480 | * |
1411 | * This function is called during un-mounting and it commits the journal unless | 1481 | * This function is called during un-mounting and re-mounting, and it commits |
1412 | * the "fast unmount" mode is enabled. It also avoids committing the journal if | 1482 | * the journal unless the "fast unmount" mode is enabled. It also avoids |
1413 | * it contains too few data. | 1483 | * committing the journal if it contains too few data. |
1414 | * | ||
1415 | * Sometimes recovery requires the journal to be committed at least once, and | ||
1416 | * this function takes care about this. | ||
1417 | */ | 1484 | */ |
1418 | static void commit_on_unmount(struct ubifs_info *c) | 1485 | static void commit_on_unmount(struct ubifs_info *c) |
1419 | { | 1486 | { |