summaryrefslogtreecommitdiffstats
path: root/sys/gnu
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1998-05-16 17:47:44 +0000
committerbde <bde@FreeBSD.org>1998-05-16 17:47:44 +0000
commit23eca1d888110be853b1dcfff2009be85c6c9961 (patch)
tree4bc75f7f61298fc812110d26945c71c844af9d7c /sys/gnu
parentde251f69b396dae552514c9f38716cfac10918d0 (diff)
downloadFreeBSD-src-23eca1d888110be853b1dcfff2009be85c6c9961.zip
FreeBSD-src-23eca1d888110be853b1dcfff2009be85c6c9961.tar.gz
Don't use "ffs" in an ext2fs sleep message string.
Don't forget to clear the inode hash lock before returning from ext2_vget() after getnewvnode() fails. Obtained from: rev.1.24 of ffs_vfsops.c (the original patch for the getnewvnode() race). Forgotten in: rev.1.4 here. Removed a duplicate comment. Duplicated in: rev.1.4 here. Fixed the MALLOC() vs getnewvnode() race in ext2_vget(). Obtained from: rev.1.39 of ffs_vfsops.c.
Diffstat (limited to 'sys/gnu')
-rw-r--r--sys/gnu/ext2fs/ext2_vfsops.c17
-rw-r--r--sys/gnu/fs/ext2fs/ext2_vfsops.c17
2 files changed, 28 insertions, 6 deletions
diff --git a/sys/gnu/ext2fs/ext2_vfsops.c b/sys/gnu/ext2fs/ext2_vfsops.c
index 8351a3a..3dcabcb 100644
--- a/sys/gnu/ext2fs/ext2_vfsops.c
+++ b/sys/gnu/ext2fs/ext2_vfsops.c
@@ -911,18 +911,30 @@ restart:
if (ext2fs_inode_hash_lock) {
while (ext2fs_inode_hash_lock) {
ext2fs_inode_hash_lock = -1;
- tsleep(&ext2fs_inode_hash_lock, PVM, "ffsvgt", 0);
+ tsleep(&ext2fs_inode_hash_lock, PVM, "e2vget", 0);
}
goto restart;
}
ext2fs_inode_hash_lock = 1;
+ /*
+ * If this MALLOC() is performed after the getnewvnode()
+ * it might block, leaving a vnode with a NULL v_data to be
+ * found by ext2_sync() if a sync happens to fire right then,
+ * which will cause a panic because ext2_sync() blindly
+ * dereferences vp->v_data (as well it should).
+ */
+ MALLOC(ip, struct inode *, sizeof(struct inode), M_EXT2NODE, M_WAITOK);
+
/* Allocate a new vnode/inode. */
if (error = getnewvnode(VT_UFS, mp, ext2_vnodeop_p, &vp)) {
+ if (ext2fs_inode_hash_lock < 0)
+ wakeup(&ext2fs_inode_hash_lock);
+ ext2fs_inode_hash_lock = 0;
*vpp = NULL;
+ FREE(ip, M_EXT2NODE);
return (error);
}
- MALLOC(ip, struct inode *, sizeof(struct inode), M_EXT2NODE, M_WAITOK);
bzero((caddr_t)ip, sizeof(struct inode));
vp->v_data = ip;
ip->i_vnode = vp;
@@ -946,7 +958,6 @@ restart:
ext2fs_inode_hash_lock = 0;
/* Read in the disk contents for the inode, copy into the inode. */
- /* Read in the disk contents for the inode, copy into the inode. */
#if 0
printf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
#endif
diff --git a/sys/gnu/fs/ext2fs/ext2_vfsops.c b/sys/gnu/fs/ext2fs/ext2_vfsops.c
index 8351a3a..3dcabcb 100644
--- a/sys/gnu/fs/ext2fs/ext2_vfsops.c
+++ b/sys/gnu/fs/ext2fs/ext2_vfsops.c
@@ -911,18 +911,30 @@ restart:
if (ext2fs_inode_hash_lock) {
while (ext2fs_inode_hash_lock) {
ext2fs_inode_hash_lock = -1;
- tsleep(&ext2fs_inode_hash_lock, PVM, "ffsvgt", 0);
+ tsleep(&ext2fs_inode_hash_lock, PVM, "e2vget", 0);
}
goto restart;
}
ext2fs_inode_hash_lock = 1;
+ /*
+ * If this MALLOC() is performed after the getnewvnode()
+ * it might block, leaving a vnode with a NULL v_data to be
+ * found by ext2_sync() if a sync happens to fire right then,
+ * which will cause a panic because ext2_sync() blindly
+ * dereferences vp->v_data (as well it should).
+ */
+ MALLOC(ip, struct inode *, sizeof(struct inode), M_EXT2NODE, M_WAITOK);
+
/* Allocate a new vnode/inode. */
if (error = getnewvnode(VT_UFS, mp, ext2_vnodeop_p, &vp)) {
+ if (ext2fs_inode_hash_lock < 0)
+ wakeup(&ext2fs_inode_hash_lock);
+ ext2fs_inode_hash_lock = 0;
*vpp = NULL;
+ FREE(ip, M_EXT2NODE);
return (error);
}
- MALLOC(ip, struct inode *, sizeof(struct inode), M_EXT2NODE, M_WAITOK);
bzero((caddr_t)ip, sizeof(struct inode));
vp->v_data = ip;
ip->i_vnode = vp;
@@ -946,7 +958,6 @@ restart:
ext2fs_inode_hash_lock = 0;
/* Read in the disk contents for the inode, copy into the inode. */
- /* Read in the disk contents for the inode, copy into the inode. */
#if 0
printf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
#endif
OpenPOWER on IntegriCloud