diff options
author | Evgeniy Dushistov <dushistov@mail.ru> | 2006-02-03 06:04:04 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-02-03 11:32:04 -0500 |
commit | e295cfcb2907ae4c5df57f5d4ada1ce6f3ae4657 (patch) | |
tree | a28ca6bf5ba0c3e1e03e12eb5067727028bb6452 | |
parent | 19dfe31c29e0ebb88cf1cd2211da3e2ff2a26d52 (diff) |
[PATCH] ufs: fix oops with `ufs1' type
"rm" command, on file system with "ufs1" type cause system hang up. This
is, in fact, not so bad as it seems to be, because of after that in "kernel
control path" there are 3-4 places which may cause "oops".
So the first patch fix oopses, and the second patch fix "kernel hang up".
"oops" appears because of reading of group's summary info partly wrong, and
access to not first group's summary info cause "oops".
Signed-off-by: Evgeniy Dushistov <dushistov@mail.ru>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | fs/ufs/super.c | 10 | ||||
-rw-r--r-- | include/linux/ufs_fs.h | 3 | ||||
-rw-r--r-- | include/linux/ufs_fs_sb.h | 2 |
3 files changed, 8 insertions, 7 deletions
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index d4aacee593ff..e9055ef7f5ac 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c | |||
@@ -388,7 +388,8 @@ static int ufs_parse_options (char * options, unsigned * mount_options) | |||
388 | /* | 388 | /* |
389 | * Read on-disk structures associated with cylinder groups | 389 | * Read on-disk structures associated with cylinder groups |
390 | */ | 390 | */ |
391 | static int ufs_read_cylinder_structures (struct super_block *sb) { | 391 | static int ufs_read_cylinder_structures (struct super_block *sb) |
392 | { | ||
392 | struct ufs_sb_info * sbi = UFS_SB(sb); | 393 | struct ufs_sb_info * sbi = UFS_SB(sb); |
393 | struct ufs_sb_private_info * uspi; | 394 | struct ufs_sb_private_info * uspi; |
394 | struct ufs_super_block *usb; | 395 | struct ufs_super_block *usb; |
@@ -415,6 +416,7 @@ static int ufs_read_cylinder_structures (struct super_block *sb) { | |||
415 | base = space = kmalloc(size, GFP_KERNEL); | 416 | base = space = kmalloc(size, GFP_KERNEL); |
416 | if (!base) | 417 | if (!base) |
417 | goto failed; | 418 | goto failed; |
419 | sbi->s_csp = (struct ufs_csum *)space; | ||
418 | for (i = 0; i < blks; i += uspi->s_fpb) { | 420 | for (i = 0; i < blks; i += uspi->s_fpb) { |
419 | size = uspi->s_bsize; | 421 | size = uspi->s_bsize; |
420 | if (i + uspi->s_fpb > blks) | 422 | if (i + uspi->s_fpb > blks) |
@@ -430,7 +432,6 @@ static int ufs_read_cylinder_structures (struct super_block *sb) { | |||
430 | goto failed; | 432 | goto failed; |
431 | 433 | ||
432 | ubh_ubhcpymem (space, ubh, size); | 434 | ubh_ubhcpymem (space, ubh, size); |
433 | sbi->s_csp[ufs_fragstoblks(i)]=(struct ufs_csum *)space; | ||
434 | 435 | ||
435 | space += size; | 436 | space += size; |
436 | ubh_brelse (ubh); | 437 | ubh_brelse (ubh); |
@@ -486,7 +487,8 @@ failed: | |||
486 | * Put on-disk structures associated with cylinder groups and | 487 | * Put on-disk structures associated with cylinder groups and |
487 | * write them back to disk | 488 | * write them back to disk |
488 | */ | 489 | */ |
489 | static void ufs_put_cylinder_structures (struct super_block *sb) { | 490 | static void ufs_put_cylinder_structures (struct super_block *sb) |
491 | { | ||
490 | struct ufs_sb_info * sbi = UFS_SB(sb); | 492 | struct ufs_sb_info * sbi = UFS_SB(sb); |
491 | struct ufs_sb_private_info * uspi; | 493 | struct ufs_sb_private_info * uspi; |
492 | struct ufs_buffer_head * ubh; | 494 | struct ufs_buffer_head * ubh; |
@@ -499,7 +501,7 @@ static void ufs_put_cylinder_structures (struct super_block *sb) { | |||
499 | 501 | ||
500 | size = uspi->s_cssize; | 502 | size = uspi->s_cssize; |
501 | blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift; | 503 | blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift; |
502 | base = space = (char*) sbi->s_csp[0]; | 504 | base = space = (char*) sbi->s_csp; |
503 | for (i = 0; i < blks; i += uspi->s_fpb) { | 505 | for (i = 0; i < blks; i += uspi->s_fpb) { |
504 | size = uspi->s_bsize; | 506 | size = uspi->s_bsize; |
505 | if (i + uspi->s_fpb > blks) | 507 | if (i + uspi->s_fpb > blks) |
diff --git a/include/linux/ufs_fs.h b/include/linux/ufs_fs.h index 7a6babeca256..f26118ea1c58 100644 --- a/include/linux/ufs_fs.h +++ b/include/linux/ufs_fs.h | |||
@@ -502,8 +502,7 @@ struct ufs_super_block { | |||
502 | /* | 502 | /* |
503 | * Convert cylinder group to base address of its global summary info. | 503 | * Convert cylinder group to base address of its global summary info. |
504 | */ | 504 | */ |
505 | #define fs_cs(indx) \ | 505 | #define fs_cs(indx) s_csp[(indx)] |
506 | s_csp[(indx) >> uspi->s_csshift][(indx) & ~uspi->s_csmask] | ||
507 | 506 | ||
508 | /* | 507 | /* |
509 | * Cylinder group block for a file system. | 508 | * Cylinder group block for a file system. |
diff --git a/include/linux/ufs_fs_sb.h b/include/linux/ufs_fs_sb.h index c1be4c226486..8ff13c160f3d 100644 --- a/include/linux/ufs_fs_sb.h +++ b/include/linux/ufs_fs_sb.h | |||
@@ -25,7 +25,7 @@ struct ufs_csum; | |||
25 | 25 | ||
26 | struct ufs_sb_info { | 26 | struct ufs_sb_info { |
27 | struct ufs_sb_private_info * s_uspi; | 27 | struct ufs_sb_private_info * s_uspi; |
28 | struct ufs_csum * s_csp[UFS_MAXCSBUFS]; | 28 | struct ufs_csum * s_csp; |
29 | unsigned s_bytesex; | 29 | unsigned s_bytesex; |
30 | unsigned s_flags; | 30 | unsigned s_flags; |
31 | struct buffer_head ** s_ucg; | 31 | struct buffer_head ** s_ucg; |