diff options
author | bde <bde@FreeBSD.org> | 1998-05-16 17:47:44 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1998-05-16 17:47:44 +0000 |
commit | 23eca1d888110be853b1dcfff2009be85c6c9961 (patch) | |
tree | 4bc75f7f61298fc812110d26945c71c844af9d7c /sys/gnu/ext2fs/ext2_vfsops.c | |
parent | de251f69b396dae552514c9f38716cfac10918d0 (diff) | |
download | FreeBSD-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/ext2fs/ext2_vfsops.c')
-rw-r--r-- | sys/gnu/ext2fs/ext2_vfsops.c | 17 |
1 files changed, 14 insertions, 3 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 |