mirror of
https://git.FreeBSD.org/src.git
synced 2024-10-19 02:29:40 +00:00
Fix fsck_ufs segfault when it needs to rerun.
The segfault was being hit in the rerun of Pass 1 in ginode() when trying to get an inode that needs to be repaired. When the first run of fsck_ffs finishes it clears the inode cache, but ginode() was failing to check properly and tried to access the deallocated cache entry. Reported by: Peter Holm Reviewed by: Chuck Silvers Tested by: Peter Holm and Chuck Silvers MFC after: 3 days Sponsored by: Netflix
This commit is contained in:
parent
677cb9722a
commit
5c9e9eb7a2
@ -416,14 +416,14 @@ void
|
|||||||
ginode(ino_t inumber, struct inode *ip)
|
ginode(ino_t inumber, struct inode *ip)
|
||||||
{
|
{
|
||||||
ufs2_daddr_t iblk;
|
ufs2_daddr_t iblk;
|
||||||
static ino_t startinum = -1;
|
|
||||||
|
|
||||||
if (inumber < UFS_ROOTINO || inumber > maxino)
|
if (inumber < UFS_ROOTINO || inumber > maxino)
|
||||||
errx(EEXIT, "bad inode number %ju to ginode",
|
errx(EEXIT, "bad inode number %ju to ginode",
|
||||||
(uintmax_t)inumber);
|
(uintmax_t)inumber);
|
||||||
ip->i_number = inumber;
|
ip->i_number = inumber;
|
||||||
if (startinum != -1 &&
|
if (icachebp != NULL &&
|
||||||
inumber >= startinum && inumber < startinum + INOPB(&sblock)) {
|
inumber >= icachebp->b_index &&
|
||||||
|
inumber < icachebp->b_index + INOPB(&sblock)) {
|
||||||
/* take an additional reference for the returned inode */
|
/* take an additional reference for the returned inode */
|
||||||
icachebp->b_refcnt++;
|
icachebp->b_refcnt++;
|
||||||
} else {
|
} else {
|
||||||
@ -433,14 +433,14 @@ ginode(ino_t inumber, struct inode *ip)
|
|||||||
brelse(icachebp);
|
brelse(icachebp);
|
||||||
icachebp = getdatablk(iblk, sblock.fs_bsize, BT_INODES);
|
icachebp = getdatablk(iblk, sblock.fs_bsize, BT_INODES);
|
||||||
if (icachebp->b_errs != 0) {
|
if (icachebp->b_errs != 0) {
|
||||||
|
icachebp = NULL;
|
||||||
ip->i_bp = NULL;
|
ip->i_bp = NULL;
|
||||||
ip->i_dp = &zino;
|
ip->i_dp = &zino;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
startinum = rounddown(inumber, INOPB(&sblock));
|
|
||||||
/* take a cache-hold reference on new icachebp */
|
/* take a cache-hold reference on new icachebp */
|
||||||
icachebp->b_refcnt++;
|
icachebp->b_refcnt++;
|
||||||
icachebp->b_index = startinum;
|
icachebp->b_index = rounddown(inumber, INOPB(&sblock));
|
||||||
}
|
}
|
||||||
ip->i_bp = icachebp;
|
ip->i_bp = icachebp;
|
||||||
if (sblock.fs_magic == FS_UFS1_MAGIC) {
|
if (sblock.fs_magic == FS_UFS1_MAGIC) {
|
||||||
|
Loading…
Reference in New Issue
Block a user