aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysv/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysv/super.c')
-rw-r--r--fs/sysv/super.c74
1 files changed, 51 insertions, 23 deletions
diff --git a/fs/sysv/super.c b/fs/sysv/super.c
index 5a903da54551..a0b0cda6927e 100644
--- a/fs/sysv/super.c
+++ b/fs/sysv/super.c
@@ -347,7 +347,6 @@ static int complete_read_super(struct super_block *sb, int silent, int size)
347 sb->s_flags |= MS_RDONLY; 347 sb->s_flags |= MS_RDONLY;
348 if (sbi->s_truncate) 348 if (sbi->s_truncate)
349 sb->s_root->d_op = &sysv_dentry_operations; 349 sb->s_root->d_op = &sysv_dentry_operations;
350 sb->s_dirt = 1;
351 return 1; 350 return 1;
352} 351}
353 352
@@ -435,12 +434,46 @@ Ebadsize:
435 goto failed; 434 goto failed;
436} 435}
437 436
438static int v7_fill_super(struct super_block *sb, void *data, int silent) 437static int v7_sanity_check(struct super_block *sb, struct buffer_head *bh)
439{ 438{
440 struct sysv_sb_info *sbi;
441 struct buffer_head *bh, *bh2 = NULL;
442 struct v7_super_block *v7sb; 439 struct v7_super_block *v7sb;
443 struct sysv_inode *v7i; 440 struct sysv_inode *v7i;
441 struct buffer_head *bh2;
442 struct sysv_sb_info *sbi;
443
444 sbi = sb->s_fs_info;
445
446 /* plausibility check on superblock */
447 v7sb = (struct v7_super_block *) bh->b_data;
448 if (fs16_to_cpu(sbi, v7sb->s_nfree) > V7_NICFREE ||
449 fs16_to_cpu(sbi, v7sb->s_ninode) > V7_NICINOD ||
450 fs32_to_cpu(sbi, v7sb->s_fsize) > V7_MAXSIZE)
451 return 0;
452
453 /* plausibility check on root inode: it is a directory,
454 with a nonzero size that is a multiple of 16 */
455 bh2 = sb_bread(sb, 2);
456 if (bh2 == NULL)
457 return 0;
458
459 v7i = (struct sysv_inode *)(bh2->b_data + 64);
460 if ((fs16_to_cpu(sbi, v7i->i_mode) & ~0777) != S_IFDIR ||
461 (fs32_to_cpu(sbi, v7i->i_size) == 0) ||
462 (fs32_to_cpu(sbi, v7i->i_size) & 017) ||
463 (fs32_to_cpu(sbi, v7i->i_size) > V7_NFILES *
464 sizeof(struct sysv_dir_entry))) {
465 brelse(bh2);
466 return 0;
467 }
468
469 brelse(bh2);
470 return 1;
471}
472
473static int v7_fill_super(struct super_block *sb, void *data, int silent)
474{
475 struct sysv_sb_info *sbi;
476 struct buffer_head *bh;
444 477
445 if (440 != sizeof (struct v7_super_block)) 478 if (440 != sizeof (struct v7_super_block))
446 panic("V7 FS: bad super-block size"); 479 panic("V7 FS: bad super-block size");
@@ -454,7 +487,6 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent)
454 sbi->s_sb = sb; 487 sbi->s_sb = sb;
455 sbi->s_block_base = 0; 488 sbi->s_block_base = 0;
456 sbi->s_type = FSTYPE_V7; 489 sbi->s_type = FSTYPE_V7;
457 sbi->s_bytesex = BYTESEX_PDP;
458 sb->s_fs_info = sbi; 490 sb->s_fs_info = sbi;
459 491
460 sb_set_blocksize(sb, 512); 492 sb_set_blocksize(sb, 512);
@@ -466,32 +498,27 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent)
466 goto failed; 498 goto failed;
467 } 499 }
468 500
469 /* plausibility check on superblock */ 501 /* Try PDP-11 UNIX */
470 v7sb = (struct v7_super_block *) bh->b_data; 502 sbi->s_bytesex = BYTESEX_PDP;
471 if (fs16_to_cpu(sbi, v7sb->s_nfree) > V7_NICFREE || 503 if (v7_sanity_check(sb, bh))
472 fs16_to_cpu(sbi, v7sb->s_ninode) > V7_NICINOD || 504 goto detected;
473 fs32_to_cpu(sbi, v7sb->s_time) == 0)
474 goto failed;
475 505
476 /* plausibility check on root inode: it is a directory, 506 /* Try PC/IX, v7/x86 */
477 with a nonzero size that is a multiple of 16 */ 507 sbi->s_bytesex = BYTESEX_LE;
478 if ((bh2 = sb_bread(sb, 2)) == NULL) 508 if (v7_sanity_check(sb, bh))
479 goto failed; 509 goto detected;
480 v7i = (struct sysv_inode *)(bh2->b_data + 64);
481 if ((fs16_to_cpu(sbi, v7i->i_mode) & ~0777) != S_IFDIR ||
482 (fs32_to_cpu(sbi, v7i->i_size) == 0) ||
483 (fs32_to_cpu(sbi, v7i->i_size) & 017) != 0)
484 goto failed;
485 brelse(bh2);
486 bh2 = NULL;
487 510
511 goto failed;
512
513detected:
488 sbi->s_bh1 = bh; 514 sbi->s_bh1 = bh;
489 sbi->s_bh2 = bh; 515 sbi->s_bh2 = bh;
490 if (complete_read_super(sb, silent, 1)) 516 if (complete_read_super(sb, silent, 1))
491 return 0; 517 return 0;
492 518
493failed: 519failed:
494 brelse(bh2); 520 printk(KERN_ERR "VFS: could not find a valid V7 on %s.\n",
521 sb->s_id);
495 brelse(bh); 522 brelse(bh);
496 kfree(sbi); 523 kfree(sbi);
497 return -EINVAL; 524 return -EINVAL;
@@ -560,4 +587,5 @@ static void __exit exit_sysv_fs(void)
560 587
561module_init(init_sysv_fs) 588module_init(init_sysv_fs)
562module_exit(exit_sysv_fs) 589module_exit(exit_sysv_fs)
590MODULE_ALIAS("v7");
563MODULE_LICENSE("GPL"); 591MODULE_LICENSE("GPL");