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:
parent
2c8838fec4
commit
dae50f6c50
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user