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.
This commit is contained in:
Bruce Evans 1998-05-16 17:47:44 +00:00
parent 2c8838fec4
commit dae50f6c50
2 changed files with 28 additions and 6 deletions

View File

@ -911,18 +911,30 @@ ext2_vget(mp, ino, vpp)
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 @@ ext2_vget(mp, ino, vpp)
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

View File

@ -911,18 +911,30 @@ ext2_vget(mp, ino, vpp)
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 @@ ext2_vget(mp, ino, vpp)
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