Commit e295cfcb2907ae4c5df57f5d4ada1ce6f3ae4657

Authored by Evgeniy Dushistov
Committed by Linus Torvalds
1 parent 19dfe31c29

[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>

Showing 3 changed files with 8 additions and 7 deletions Side-by-side Diff

... ... @@ -388,7 +388,8 @@
388 388 /*
389 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 393 struct ufs_sb_info * sbi = UFS_SB(sb);
393 394 struct ufs_sb_private_info * uspi;
394 395 struct ufs_super_block *usb;
... ... @@ -415,6 +416,7 @@
415 416 base = space = kmalloc(size, GFP_KERNEL);
416 417 if (!base)
417 418 goto failed;
  419 + sbi->s_csp = (struct ufs_csum *)space;
418 420 for (i = 0; i < blks; i += uspi->s_fpb) {
419 421 size = uspi->s_bsize;
420 422 if (i + uspi->s_fpb > blks)
... ... @@ -430,7 +432,6 @@
430 432 goto failed;
431 433  
432 434 ubh_ubhcpymem (space, ubh, size);
433   - sbi->s_csp[ufs_fragstoblks(i)]=(struct ufs_csum *)space;
434 435  
435 436 space += size;
436 437 ubh_brelse (ubh);
... ... @@ -486,7 +487,8 @@
486 487 * Put on-disk structures associated with cylinder groups and
487 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 492 struct ufs_sb_info * sbi = UFS_SB(sb);
491 493 struct ufs_sb_private_info * uspi;
492 494 struct ufs_buffer_head * ubh;
... ... @@ -499,7 +501,7 @@
499 501  
500 502 size = uspi->s_cssize;
501 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 505 for (i = 0; i < blks; i += uspi->s_fpb) {
504 506 size = uspi->s_bsize;
505 507 if (i + uspi->s_fpb > blks)
include/linux/ufs_fs.h
... ... @@ -502,8 +502,7 @@
502 502 /*
503 503 * Convert cylinder group to base address of its global summary info.
504 504 */
505   -#define fs_cs(indx) \
506   - s_csp[(indx) >> uspi->s_csshift][(indx) & ~uspi->s_csmask]
  505 +#define fs_cs(indx) s_csp[(indx)]
507 506  
508 507 /*
509 508 * Cylinder group block for a file system.
include/linux/ufs_fs_sb.h
... ... @@ -25,7 +25,7 @@
25 25  
26 26 struct ufs_sb_info {
27 27 struct ufs_sb_private_info * s_uspi;
28   - struct ufs_csum * s_csp[UFS_MAXCSBUFS];
  28 + struct ufs_csum * s_csp;
29 29 unsigned s_bytesex;
30 30 unsigned s_flags;
31 31 struct buffer_head ** s_ucg;