patch for UFS super.c (untested)

Bill Hawes (whawes@star.net)
Sat, 05 Sep 1998 21:24:24 -0400


This is a multi-part message in MIME format.
--------------EBD2296AF8042EC89DCC4253
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

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
--------------EBD2296AF8042EC89DCC4253
Content-Type: text/plain; charset=us-ascii; name="ufs_120-patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="ufs_120-patch"

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

--------------EBD2296AF8042EC89DCC4253--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/faq.html