lkml.org 
[lkml]   [1998]   [Sep]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subjectpatch for UFS super.c (untested)
I looked at the fs/ufs/super.c code a bit and spotted a couple of
problems that might account for reports of trouble with certain CDs.

The failure cleanup code in the read_super routine releases its data
structures in the wrong order, so if something gets trashed in the freed
area, bad things could happen. The patch reorders the cleanup.

Also, there were no tests for failures of iget() and d_alloc_root(), so
I added those.

The patch hasn't been tested or even compiled, but it might work :-)

Regards,
Bill--- linux-2.1.120/fs/ufs/super.c.old Sat Sep 5 10:52:51 1998
+++ linux-2.1.120/fs/ufs/super.c Sat Sep 5 21:05:26 1998
@@ -142,6 +142,7 @@
struct ufs_super_block_second * usb2;
struct ufs_super_block_third * usb3;
struct ufs_buffer_head * ubh;
+ struct inode * root_inode;
unsigned char * base, * space;
unsigned size, blks, i;
unsigned block_size, super_block_size;
@@ -151,7 +152,6 @@

UFSD(("ENTER\n"))

- uspi = NULL;
ubh = NULL;
base = space = NULL;
sb->u.ufs_sb.s_ucg = NULL;
@@ -230,15 +230,12 @@
ubh = NULL;
uspi->s_sbbase = offsets[i];
goto again;
- } else {
- printk("ufs_read_super: "
- "super block location not in "
- "{ 0, 96, 160} "
- "or bad magic number\n");
- goto failed;
}
- magic_found:
+ printk("ufs_read_super: super block location not in { 0, 96, 160} "
+ "or bad magic number\n");
+ goto failed;

+ magic_found:
/*
* Check block and fragment sizes
*/
@@ -419,8 +416,6 @@
sb->u.ufs_sb.s_rename_lock = 0;
sb->u.ufs_sb.s_rename_wait = NULL;

- sb->s_root = d_alloc_root(iget(sb, UFS_ROOTINO), NULL);
-
/*
* Read cs structures from (usually) first data block
* on the device.
@@ -474,15 +469,23 @@
}
sb->u.ufs_sb.s_cg_loaded = 0;

+ /*
+ * OK so far ... get our root inode and dentry.
+ */
+ root_inode = iget(sb, UFS_ROOTINO);
+ if (!root_inode)
+ goto failed;
+ sb->s_root = d_alloc_root(root_inode, NULL);
+ if (!sb->s_root)
+ goto failed_iput;
+
unlock_super(sb);
UFSD(("EXIT\n"))
return(sb);

+failed_iput:
+ iput(root_inode);
failed:
- if (ubh) ubh_brelse2 (ubh);
- if (uspi) kfree (uspi);
- if (base) kfree (base);
-
if (sb->u.ufs_sb.s_ucg) {
for (i = 0; i < uspi->s_ncg; i++)
if (sb->u.ufs_sb.s_ucg[i]) brelse (sb->u.ufs_sb.s_ucg[i]);
@@ -490,6 +493,13 @@
for (i = 0; i < UFS_MAX_GROUP_LOADED; i++)
if (sb->u.ufs_sb.s_ucpi[i]) kfree (sb->u.ufs_sb.s_ucpi[i]);
}
+ if (base)
+ kfree (base);
+ if (ubh)
+ ubh_brelse2 (ubh);
+ /* free this one last */
+ if (uspi)
+ kfree (uspi);
sb->s_dev = 0;
unlock_super (sb);
MOD_DEC_USE_COUNT;
\
 
 \ /
  Last update: 2005-03-22 13:44    [W:0.025 / U:0.532 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site