aboutsummaryrefslogtreecommitdiffstats
path: root/fs/bfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/bfs/inode.c')
-rw-r--r--fs/bfs/inode.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index 0ed57b5ee012..cc4062d12ca2 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -213,6 +213,9 @@ static void bfs_put_super(struct super_block *s)
213{ 213{
214 struct bfs_sb_info *info = BFS_SB(s); 214 struct bfs_sb_info *info = BFS_SB(s);
215 215
216 if (!info)
217 return;
218
216 brelse(info->si_sbh); 219 brelse(info->si_sbh);
217 mutex_destroy(&info->bfs_lock); 220 mutex_destroy(&info->bfs_lock);
218 kfree(info->si_imap); 221 kfree(info->si_imap);
@@ -327,6 +330,7 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
327 unsigned i, imap_len; 330 unsigned i, imap_len;
328 struct bfs_sb_info *info; 331 struct bfs_sb_info *info;
329 long ret = -EINVAL; 332 long ret = -EINVAL;
333 unsigned long i_sblock, i_eblock, i_eoff, s_size;
330 334
331 info = kzalloc(sizeof(*info), GFP_KERNEL); 335 info = kzalloc(sizeof(*info), GFP_KERNEL);
332 if (!info) 336 if (!info)
@@ -350,6 +354,12 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
350 354
351 s->s_magic = BFS_MAGIC; 355 s->s_magic = BFS_MAGIC;
352 info->si_sbh = bh; 356 info->si_sbh = bh;
357
358 if (le32_to_cpu(bfs_sb->s_start) > le32_to_cpu(bfs_sb->s_end)) {
359 printf("Superblock is corrupted\n");
360 goto out;
361 }
362
353 info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE) / 363 info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE) /
354 sizeof(struct bfs_inode) 364 sizeof(struct bfs_inode)
355 + BFS_ROOT_INO - 1; 365 + BFS_ROOT_INO - 1;
@@ -380,6 +390,18 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
380 - le32_to_cpu(bfs_sb->s_start)) >> BFS_BSIZE_BITS; 390 - le32_to_cpu(bfs_sb->s_start)) >> BFS_BSIZE_BITS;
381 info->si_freei = 0; 391 info->si_freei = 0;
382 info->si_lf_eblk = 0; 392 info->si_lf_eblk = 0;
393
394 /* can we read the last block? */
395 bh = sb_bread(s, info->si_blocks - 1);
396 if (!bh) {
397 printf("Last block not available: %lu\n", info->si_blocks - 1);
398 iput(inode);
399 ret = -EIO;
400 kfree(info->si_imap);
401 goto out;
402 }
403 brelse(bh);
404
383 bh = NULL; 405 bh = NULL;
384 for (i = BFS_ROOT_INO; i <= info->si_lasti; i++) { 406 for (i = BFS_ROOT_INO; i <= info->si_lasti; i++) {
385 struct bfs_inode *di; 407 struct bfs_inode *di;
@@ -397,6 +419,29 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
397 419
398 di = (struct bfs_inode *)bh->b_data + off; 420 di = (struct bfs_inode *)bh->b_data + off;
399 421
422 /* test if filesystem is not corrupted */
423
424 i_eoff = le32_to_cpu(di->i_eoffset);
425 i_sblock = le32_to_cpu(di->i_sblock);
426 i_eblock = le32_to_cpu(di->i_eblock);
427 s_size = le32_to_cpu(bfs_sb->s_end);
428
429 if (i_sblock > info->si_blocks ||
430 i_eblock > info->si_blocks ||
431 i_sblock > i_eblock ||
432 i_eoff > s_size ||
433 i_sblock * BFS_BSIZE > i_eoff) {
434
435 printf("Inode 0x%08x corrupted\n", i);
436
437 brelse(bh);
438 s->s_root = NULL;
439 kfree(info->si_imap);
440 kfree(info);
441 s->s_fs_info = NULL;
442 return -EIO;
443 }
444
400 if (!di->i_ino) { 445 if (!di->i_ino) {
401 info->si_freei++; 446 info->si_freei++;
402 continue; 447 continue;