hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/nilfs2/the_nilfs.c
....@@ -13,6 +13,7 @@
1313 #include <linux/blkdev.h>
1414 #include <linux/backing-dev.h>
1515 #include <linux/random.h>
16
+#include <linux/log2.h>
1617 #include <linux/crc32.h>
1718 #include "nilfs.h"
1819 #include "segment.h"
....@@ -86,7 +87,6 @@
8687 {
8788 might_sleep();
8889 if (nilfs_init(nilfs)) {
89
- nilfs_sysfs_delete_device_group(nilfs);
9090 brelse(nilfs->ns_sbh[0]);
9191 brelse(nilfs->ns_sbh[1]);
9292 }
....@@ -183,13 +183,41 @@
183183 nilfs_get_segnum_of_block(nilfs, nilfs->ns_last_pseg);
184184 nilfs->ns_cno = nilfs->ns_last_cno + 1;
185185 if (nilfs->ns_segnum >= nilfs->ns_nsegments) {
186
- nilfs_msg(nilfs->ns_sb, KERN_ERR,
186
+ nilfs_err(nilfs->ns_sb,
187187 "pointed segment number is out of range: segnum=%llu, nsegments=%lu",
188188 (unsigned long long)nilfs->ns_segnum,
189189 nilfs->ns_nsegments);
190190 ret = -EINVAL;
191191 }
192192 return ret;
193
+}
194
+
195
+/**
196
+ * nilfs_get_blocksize - get block size from raw superblock data
197
+ * @sb: super block instance
198
+ * @sbp: superblock raw data buffer
199
+ * @blocksize: place to store block size
200
+ *
201
+ * nilfs_get_blocksize() calculates the block size from the block size
202
+ * exponent information written in @sbp and stores it in @blocksize,
203
+ * or aborts with an error message if it's too large.
204
+ *
205
+ * Return Value: On success, 0 is returned. If the block size is too
206
+ * large, -EINVAL is returned.
207
+ */
208
+static int nilfs_get_blocksize(struct super_block *sb,
209
+ struct nilfs_super_block *sbp, int *blocksize)
210
+{
211
+ unsigned int shift_bits = le32_to_cpu(sbp->s_log_block_size);
212
+
213
+ if (unlikely(shift_bits >
214
+ ilog2(NILFS_MAX_BLOCK_SIZE) - BLOCK_SIZE_BITS)) {
215
+ nilfs_err(sb, "too large filesystem blocksize: 2 ^ %u KiB",
216
+ shift_bits);
217
+ return -EINVAL;
218
+ }
219
+ *blocksize = BLOCK_SIZE << shift_bits;
220
+ return 0;
193221 }
194222
195223 /**
....@@ -210,12 +238,12 @@
210238 int err;
211239
212240 if (!valid_fs) {
213
- nilfs_msg(sb, KERN_WARNING, "mounting unchecked fs");
241
+ nilfs_warn(sb, "mounting unchecked fs");
214242 if (s_flags & SB_RDONLY) {
215
- nilfs_msg(sb, KERN_INFO,
216
- "recovery required for readonly filesystem");
217
- nilfs_msg(sb, KERN_INFO,
218
- "write access will be enabled during recovery");
243
+ nilfs_info(sb,
244
+ "recovery required for readonly filesystem");
245
+ nilfs_info(sb,
246
+ "write access will be enabled during recovery");
219247 }
220248 }
221249
....@@ -230,12 +258,11 @@
230258 goto scan_error;
231259
232260 if (!nilfs_valid_sb(sbp[1])) {
233
- nilfs_msg(sb, KERN_WARNING,
234
- "unable to fall back to spare super block");
261
+ nilfs_warn(sb,
262
+ "unable to fall back to spare super block");
235263 goto scan_error;
236264 }
237
- nilfs_msg(sb, KERN_INFO,
238
- "trying rollback from an earlier position");
265
+ nilfs_info(sb, "trying rollback from an earlier position");
239266
240267 /*
241268 * restore super block with its spare and reconfigure
....@@ -246,11 +273,15 @@
246273 nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime);
247274
248275 /* verify consistency between two super blocks */
249
- blocksize = BLOCK_SIZE << le32_to_cpu(sbp[0]->s_log_block_size);
276
+ err = nilfs_get_blocksize(sb, sbp[0], &blocksize);
277
+ if (err)
278
+ goto scan_error;
279
+
250280 if (blocksize != nilfs->ns_blocksize) {
251
- nilfs_msg(sb, KERN_WARNING,
252
- "blocksize differs between two super blocks (%d != %d)",
253
- blocksize, nilfs->ns_blocksize);
281
+ nilfs_warn(sb,
282
+ "blocksize differs between two super blocks (%d != %d)",
283
+ blocksize, nilfs->ns_blocksize);
284
+ err = -EINVAL;
254285 goto scan_error;
255286 }
256287
....@@ -269,10 +300,13 @@
269300
270301 err = nilfs_load_super_root(nilfs, sb, ri.ri_super_root);
271302 if (unlikely(err)) {
272
- nilfs_msg(sb, KERN_ERR, "error %d while loading super root",
273
- err);
303
+ nilfs_err(sb, "error %d while loading super root", err);
274304 goto failed;
275305 }
306
+
307
+ err = nilfs_sysfs_create_device_group(sb);
308
+ if (unlikely(err))
309
+ goto sysfs_error;
276310
277311 if (valid_fs)
278312 goto skip_recovery;
....@@ -281,28 +315,28 @@
281315 __u64 features;
282316
283317 if (nilfs_test_opt(nilfs, NORECOVERY)) {
284
- nilfs_msg(sb, KERN_INFO,
285
- "norecovery option specified, skipping roll-forward recovery");
318
+ nilfs_info(sb,
319
+ "norecovery option specified, skipping roll-forward recovery");
286320 goto skip_recovery;
287321 }
288322 features = le64_to_cpu(nilfs->ns_sbp[0]->s_feature_compat_ro) &
289323 ~NILFS_FEATURE_COMPAT_RO_SUPP;
290324 if (features) {
291
- nilfs_msg(sb, KERN_ERR,
325
+ nilfs_err(sb,
292326 "couldn't proceed with recovery because of unsupported optional features (%llx)",
293327 (unsigned long long)features);
294328 err = -EROFS;
295329 goto failed_unload;
296330 }
297331 if (really_read_only) {
298
- nilfs_msg(sb, KERN_ERR,
332
+ nilfs_err(sb,
299333 "write access unavailable, cannot proceed");
300334 err = -EROFS;
301335 goto failed_unload;
302336 }
303337 sb->s_flags &= ~SB_RDONLY;
304338 } else if (nilfs_test_opt(nilfs, NORECOVERY)) {
305
- nilfs_msg(sb, KERN_ERR,
339
+ nilfs_err(sb,
306340 "recovery cancelled because norecovery option was specified for a read/write mount");
307341 err = -EINVAL;
308342 goto failed_unload;
....@@ -318,12 +352,12 @@
318352 up_write(&nilfs->ns_sem);
319353
320354 if (err) {
321
- nilfs_msg(sb, KERN_ERR,
355
+ nilfs_err(sb,
322356 "error %d updating super block. recovery unfinished.",
323357 err);
324358 goto failed_unload;
325359 }
326
- nilfs_msg(sb, KERN_INFO, "recovery complete");
360
+ nilfs_info(sb, "recovery complete");
327361
328362 skip_recovery:
329363 nilfs_clear_recovery_info(&ri);
....@@ -331,10 +365,13 @@
331365 return 0;
332366
333367 scan_error:
334
- nilfs_msg(sb, KERN_ERR, "error %d while searching super root", err);
368
+ nilfs_err(sb, "error %d while searching super root", err);
335369 goto failed;
336370
337371 failed_unload:
372
+ nilfs_sysfs_delete_device_group(nilfs);
373
+
374
+ sysfs_error:
338375 iput(nilfs->ns_cpfile);
339376 iput(nilfs->ns_sufile);
340377 iput(nilfs->ns_dat);
....@@ -368,6 +405,18 @@
368405 100));
369406 }
370407
408
+/**
409
+ * nilfs_max_segment_count - calculate the maximum number of segments
410
+ * @nilfs: nilfs object
411
+ */
412
+static u64 nilfs_max_segment_count(struct the_nilfs *nilfs)
413
+{
414
+ u64 max_count = U64_MAX;
415
+
416
+ do_div(max_count, nilfs->ns_blocks_per_segment);
417
+ return min_t(u64, max_count, ULONG_MAX);
418
+}
419
+
371420 void nilfs_set_nsegments(struct the_nilfs *nilfs, unsigned long nsegs)
372421 {
373422 nilfs->ns_nsegments = nsegs;
....@@ -377,8 +426,10 @@
377426 static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
378427 struct nilfs_super_block *sbp)
379428 {
429
+ u64 nsegments, nblocks;
430
+
380431 if (le32_to_cpu(sbp->s_rev_level) < NILFS_MIN_SUPP_REV) {
381
- nilfs_msg(nilfs->ns_sb, KERN_ERR,
432
+ nilfs_err(nilfs->ns_sb,
382433 "unsupported revision (superblock rev.=%d.%d, current rev.=%d.%d). Please check the version of mkfs.nilfs(2).",
383434 le32_to_cpu(sbp->s_rev_level),
384435 le16_to_cpu(sbp->s_minor_rev_level),
....@@ -391,13 +442,11 @@
391442
392443 nilfs->ns_inode_size = le16_to_cpu(sbp->s_inode_size);
393444 if (nilfs->ns_inode_size > nilfs->ns_blocksize) {
394
- nilfs_msg(nilfs->ns_sb, KERN_ERR,
395
- "too large inode size: %d bytes",
445
+ nilfs_err(nilfs->ns_sb, "too large inode size: %d bytes",
396446 nilfs->ns_inode_size);
397447 return -EINVAL;
398448 } else if (nilfs->ns_inode_size < NILFS_MIN_INODE_SIZE) {
399
- nilfs_msg(nilfs->ns_sb, KERN_ERR,
400
- "too small inode size: %d bytes",
449
+ nilfs_err(nilfs->ns_sb, "too small inode size: %d bytes",
401450 nilfs->ns_inode_size);
402451 return -EINVAL;
403452 }
....@@ -406,8 +455,7 @@
406455
407456 nilfs->ns_blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment);
408457 if (nilfs->ns_blocks_per_segment < NILFS_SEG_MIN_BLOCKS) {
409
- nilfs_msg(nilfs->ns_sb, KERN_ERR,
410
- "too short segment: %lu blocks",
458
+ nilfs_err(nilfs->ns_sb, "too short segment: %lu blocks",
411459 nilfs->ns_blocks_per_segment);
412460 return -EINVAL;
413461 }
....@@ -417,13 +465,41 @@
417465 le32_to_cpu(sbp->s_r_segments_percentage);
418466 if (nilfs->ns_r_segments_percentage < 1 ||
419467 nilfs->ns_r_segments_percentage > 99) {
420
- nilfs_msg(nilfs->ns_sb, KERN_ERR,
468
+ nilfs_err(nilfs->ns_sb,
421469 "invalid reserved segments percentage: %lu",
422470 nilfs->ns_r_segments_percentage);
423471 return -EINVAL;
424472 }
425473
426
- nilfs_set_nsegments(nilfs, le64_to_cpu(sbp->s_nsegments));
474
+ nsegments = le64_to_cpu(sbp->s_nsegments);
475
+ if (nsegments > nilfs_max_segment_count(nilfs)) {
476
+ nilfs_err(nilfs->ns_sb,
477
+ "segment count %llu exceeds upper limit (%llu segments)",
478
+ (unsigned long long)nsegments,
479
+ (unsigned long long)nilfs_max_segment_count(nilfs));
480
+ return -EINVAL;
481
+ }
482
+
483
+ nblocks = (u64)i_size_read(nilfs->ns_sb->s_bdev->bd_inode) >>
484
+ nilfs->ns_sb->s_blocksize_bits;
485
+ if (nblocks) {
486
+ u64 min_block_count = nsegments * nilfs->ns_blocks_per_segment;
487
+ /*
488
+ * To avoid failing to mount early device images without a
489
+ * second superblock, exclude that block count from the
490
+ * "min_block_count" calculation.
491
+ */
492
+
493
+ if (nblocks < min_block_count) {
494
+ nilfs_err(nilfs->ns_sb,
495
+ "total number of segment blocks %llu exceeds device size (%llu blocks)",
496
+ (unsigned long long)min_block_count,
497
+ (unsigned long long)nblocks);
498
+ return -EINVAL;
499
+ }
500
+ }
501
+
502
+ nilfs_set_nsegments(nilfs, nsegments);
427503 nilfs->ns_crc_seed = le32_to_cpu(sbp->s_crc_seed);
428504 return 0;
429505 }
....@@ -448,11 +524,33 @@
448524 return crc == le32_to_cpu(sbp->s_sum);
449525 }
450526
451
-static int nilfs_sb2_bad_offset(struct nilfs_super_block *sbp, u64 offset)
527
+/**
528
+ * nilfs_sb2_bad_offset - check the location of the second superblock
529
+ * @sbp: superblock raw data buffer
530
+ * @offset: byte offset of second superblock calculated from device size
531
+ *
532
+ * nilfs_sb2_bad_offset() checks if the position on the second
533
+ * superblock is valid or not based on the filesystem parameters
534
+ * stored in @sbp. If @offset points to a location within the segment
535
+ * area, or if the parameters themselves are not normal, it is
536
+ * determined to be invalid.
537
+ *
538
+ * Return Value: true if invalid, false if valid.
539
+ */
540
+static bool nilfs_sb2_bad_offset(struct nilfs_super_block *sbp, u64 offset)
452541 {
453
- return offset < ((le64_to_cpu(sbp->s_nsegments) *
454
- le32_to_cpu(sbp->s_blocks_per_segment)) <<
455
- (le32_to_cpu(sbp->s_log_block_size) + 10));
542
+ unsigned int shift_bits = le32_to_cpu(sbp->s_log_block_size);
543
+ u32 blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment);
544
+ u64 nsegments = le64_to_cpu(sbp->s_nsegments);
545
+ u64 index;
546
+
547
+ if (blocks_per_segment < NILFS_SEG_MIN_BLOCKS ||
548
+ shift_bits > ilog2(NILFS_MAX_BLOCK_SIZE) - BLOCK_SIZE_BITS)
549
+ return true;
550
+
551
+ index = offset >> (shift_bits + BLOCK_SIZE_BITS);
552
+ do_div(index, blocks_per_segment);
553
+ return index < nsegments;
456554 }
457555
458556 static void nilfs_release_super_block(struct the_nilfs *nilfs)
....@@ -494,8 +592,14 @@
494592 {
495593 struct nilfs_super_block **sbp = nilfs->ns_sbp;
496594 struct buffer_head **sbh = nilfs->ns_sbh;
497
- u64 sb2off = NILFS_SB2_OFFSET_BYTES(nilfs->ns_bdev->bd_inode->i_size);
595
+ u64 sb2off, devsize = nilfs->ns_bdev->bd_inode->i_size;
498596 int valid[2], swp = 0;
597
+
598
+ if (devsize < NILFS_SEG_MIN_BLOCKS * NILFS_MIN_BLOCK_SIZE + 4096) {
599
+ nilfs_err(sb, "device size too small");
600
+ return -EINVAL;
601
+ }
602
+ sb2off = NILFS_SB2_OFFSET_BYTES(devsize);
499603
500604 sbp[0] = nilfs_read_super_block(sb, NILFS_SB_OFFSET_BYTES, blocksize,
501605 &sbh[0]);
....@@ -503,16 +607,16 @@
503607
504608 if (!sbp[0]) {
505609 if (!sbp[1]) {
506
- nilfs_msg(sb, KERN_ERR, "unable to read superblock");
610
+ nilfs_err(sb, "unable to read superblock");
507611 return -EIO;
508612 }
509
- nilfs_msg(sb, KERN_WARNING,
510
- "unable to read primary superblock (blocksize = %d)",
511
- blocksize);
613
+ nilfs_warn(sb,
614
+ "unable to read primary superblock (blocksize = %d)",
615
+ blocksize);
512616 } else if (!sbp[1]) {
513
- nilfs_msg(sb, KERN_WARNING,
514
- "unable to read secondary superblock (blocksize = %d)",
515
- blocksize);
617
+ nilfs_warn(sb,
618
+ "unable to read secondary superblock (blocksize = %d)",
619
+ blocksize);
516620 }
517621
518622 /*
....@@ -534,14 +638,14 @@
534638 }
535639 if (!valid[swp]) {
536640 nilfs_release_super_block(nilfs);
537
- nilfs_msg(sb, KERN_ERR, "couldn't find nilfs on the device");
641
+ nilfs_err(sb, "couldn't find nilfs on the device");
538642 return -EINVAL;
539643 }
540644
541645 if (!valid[!swp])
542
- nilfs_msg(sb, KERN_WARNING,
543
- "broken superblock, retrying with spare superblock (blocksize = %d)",
544
- blocksize);
646
+ nilfs_warn(sb,
647
+ "broken superblock, retrying with spare superblock (blocksize = %d)",
648
+ blocksize);
545649 if (swp)
546650 nilfs_swap_super_block(nilfs);
547651
....@@ -575,7 +679,7 @@
575679
576680 blocksize = sb_min_blocksize(sb, NILFS_MIN_BLOCK_SIZE);
577681 if (!blocksize) {
578
- nilfs_msg(sb, KERN_ERR, "unable to set blocksize");
682
+ nilfs_err(sb, "unable to set blocksize");
579683 err = -EINVAL;
580684 goto out;
581685 }
....@@ -591,10 +695,12 @@
591695 if (err)
592696 goto failed_sbh;
593697
594
- blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
595
- if (blocksize < NILFS_MIN_BLOCK_SIZE ||
596
- blocksize > NILFS_MAX_BLOCK_SIZE) {
597
- nilfs_msg(sb, KERN_ERR,
698
+ err = nilfs_get_blocksize(sb, sbp, &blocksize);
699
+ if (err)
700
+ goto failed_sbh;
701
+
702
+ if (blocksize < NILFS_MIN_BLOCK_SIZE) {
703
+ nilfs_err(sb,
598704 "couldn't mount because of unsupported filesystem blocksize %d",
599705 blocksize);
600706 err = -EINVAL;
....@@ -604,7 +710,7 @@
604710 int hw_blocksize = bdev_logical_block_size(sb->s_bdev);
605711
606712 if (blocksize < hw_blocksize) {
607
- nilfs_msg(sb, KERN_ERR,
713
+ nilfs_err(sb,
608714 "blocksize %d too small for device (sector-size = %d)",
609715 blocksize, hw_blocksize);
610716 err = -EINVAL;
....@@ -636,10 +742,6 @@
636742 nilfs->ns_mount_state = le16_to_cpu(sbp->s_state);
637743
638744 err = nilfs_store_log_cursor(nilfs, sbp);
639
- if (err)
640
- goto failed_sbh;
641
-
642
- err = nilfs_sysfs_create_device_group(sb);
643745 if (err)
644746 goto failed_sbh;
645747
....@@ -695,9 +797,7 @@
695797 {
696798 unsigned long ncleansegs;
697799
698
- down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
699800 ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile);
700
- up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
701801 *nblocks = (sector_t)ncleansegs * nilfs->ns_blocks_per_segment;
702802 return 0;
703803 }