From 4b8db8388e9d37e4096a96da8c3e6e8abaa62dec Mon Sep 17 00:00:00 2001 From: perseant Date: Wed, 8 Jun 2005 19:09:55 +0000 Subject: [PATCH] Use the correct method to create a new inode, when we allocate lost+found. Correct uninitialized variable issues in pass6.c and dir.c (PR#30411 and PR#30394, respectively). --- sbin/fsck_lfs/Makefile | 5 +-- sbin/fsck_lfs/dir.c | 7 ++- sbin/fsck_lfs/inode.c | 10 ++++- sbin/fsck_lfs/lfs.c | 97 +++++++++++++++++++++++++++++++++++++++++- sbin/fsck_lfs/lfs.h | 4 +- sbin/fsck_lfs/pass0.c | 12 ++++-- sbin/fsck_lfs/pass6.c | 74 ++++++-------------------------- sbin/fsck_lfs/setup.c | 4 +- 8 files changed, 135 insertions(+), 78 deletions(-) diff --git a/sbin/fsck_lfs/Makefile b/sbin/fsck_lfs/Makefile index 5b3f77b6c26b..5f354ceed79a 100644 --- a/sbin/fsck_lfs/Makefile +++ b/sbin/fsck_lfs/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.9 2005/06/03 18:02:03 lukem Exp $ +# $NetBSD: Makefile,v 1.10 2005/06/08 19:09:55 perseant Exp $ # @(#)Makefile 8.1 (Berkeley) 6/5/93 .include @@ -12,7 +12,4 @@ FSCK= ${NETBSDSRCDIR}/sbin/fsck .PATH: ${NETBSDSRCDIR}/sys/ufs/lfs ${FSCK} CPPFLAGS+=-I${FSCK} # -DNDEBUG # -DVERBOSE_BLOCKMAP -COPTS.dir.c+= -Wno-uninitialized # XXX: PR 30394 -COPTS.pass6.c+= -Wno-uninitialized # XXX: PR 30411 - .include diff --git a/sbin/fsck_lfs/dir.c b/sbin/fsck_lfs/dir.c index f3a4f5a9b3d9..cdbba8027599 100644 --- a/sbin/fsck_lfs/dir.c +++ b/sbin/fsck_lfs/dir.c @@ -1,4 +1,4 @@ -/* $NetBSD: dir.c,v 1.14 2005/01/19 19:41:59 xtraeme Exp $ */ +/* $NetBSD: dir.c,v 1.15 2005/06/08 19:09:55 perseant Exp $ */ /* * Copyright (c) 1980, 1986, 1993 @@ -541,7 +541,7 @@ makeentry(ino_t parent, ino_t ino, char *name) static int expanddir(struct uvnode *vp, struct ufs1_dinode *dp, char *name) { - daddr_t lastbn, newblk; + daddr_t lastbn; struct ubuf *bp; char *cp, firstblk[DIRBLKSIZ]; @@ -559,7 +559,7 @@ expanddir(struct uvnode *vp, struct ufs1_dinode *dp, char *name) if (bp->b_flags & B_ERROR) goto bad; memcpy(firstblk, bp->b_data, DIRBLKSIZ); - bread(vp, newblk, fs->lfs_bsize, NOCRED, &bp); + bread(vp, lastbn, fs->lfs_bsize, NOCRED, &bp); if (bp->b_flags & B_ERROR) goto bad; memcpy(bp->b_data, firstblk, DIRBLKSIZ); @@ -586,7 +586,6 @@ bad: dp->di_db[lastbn + 1] = 0; dp->di_size -= fs->lfs_bsize; dp->di_blocks -= btofsb(fs, fs->lfs_bsize); - freeblk(newblk, fs->lfs_frag); return (0); } diff --git a/sbin/fsck_lfs/inode.c b/sbin/fsck_lfs/inode.c index e528c6b2ed55..57304d022838 100644 --- a/sbin/fsck_lfs/inode.c +++ b/sbin/fsck_lfs/inode.c @@ -1,4 +1,4 @@ -/* $NetBSD: inode.c,v 1.26 2005/03/25 20:16:37 perseant Exp $ */ +/* $NetBSD: inode.c,v 1.27 2005/06/08 19:09:55 perseant Exp $ */ /*- * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. @@ -322,6 +322,7 @@ iblock(struct inodesc *idesc, long ilevel, u_int64_t isize) brelse(bp); return (KEEPON); } + /* * Check that a block in a legal block number. * Return 0 if in range, 1 if out of range. @@ -343,6 +344,7 @@ chkrange(daddr_t blk, int cnt) } return (0); } + /* * Routines to maintain information about directory inodes. * This is built during the first pass and used during the @@ -564,6 +566,7 @@ blkerror(ino_t ino, char *type, daddr_t blk) /* NOTREACHED */ } } + /* * allocate an unused inode */ @@ -596,7 +599,9 @@ allocino(ino_t request, int type) default: return (0); } - vp = vget(fs, ino); + vp = lfs_valloc(fs, ino); + if (vp == NULL) + return (0); dp = (VTOI(vp)->i_din.ffs1_din); bp = getblk(vp, 0, fs->lfs_fsize); VOP_BWRITE(bp); @@ -611,6 +616,7 @@ allocino(ino_t request, int type) typemap[ino] = IFTODT(type); return (ino); } + /* * deallocate an inode */ diff --git a/sbin/fsck_lfs/lfs.c b/sbin/fsck_lfs/lfs.c index eeedafd5e10c..ae1c3f2ed7ab 100644 --- a/sbin/fsck_lfs/lfs.c +++ b/sbin/fsck_lfs/lfs.c @@ -1,4 +1,4 @@ -/* $NetBSD: lfs.c,v 1.15 2005/06/07 09:08:07 he Exp $ */ +/* $NetBSD: lfs.c,v 1.16 2005/06/08 19:09:55 perseant Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. * All rights reserved. @@ -812,3 +812,98 @@ call_panic(const char *fmt, ...) panic_func(1, fmt, ap); va_end(ap); } + +/* Allocate a new inode. */ +struct uvnode * +lfs_valloc(struct lfs *fs, ino_t ino) +{ + struct ubuf *bp, *cbp; + struct ifile *ifp; + ino_t new_ino; + int error; + int new_gen; + CLEANERINFO *cip; + + /* Get the head of the freelist. */ + LFS_GET_HEADFREE(fs, cip, cbp, &new_ino); + + /* + * Remove the inode from the free list and write the new start + * of the free list into the superblock. + */ + LFS_IENTRY(ifp, fs, new_ino, bp); + if (ifp->if_daddr != LFS_UNUSED_DADDR) + panic("lfs_valloc: inuse inode %d on the free list", new_ino); + LFS_PUT_HEADFREE(fs, cip, cbp, ifp->if_nextfree); + + new_gen = ifp->if_version; /* version was updated by vfree */ + brelse(bp); + + /* Extend IFILE so that the next lfs_valloc will succeed. */ + if (fs->lfs_freehd == LFS_UNUSED_INUM) { + if ((error = extend_ifile(fs)) != 0) { + LFS_PUT_HEADFREE(fs, cip, cbp, new_ino); + return NULL; + } + } + + /* Set superblock modified bit and increment file count. */ + sbdirty(); + ++fs->lfs_nfiles; + + return lfs_raw_vget(fs, ino, fs->lfs_devvp->v_fd, 0x0); +} + +/* + * Add a new block to the Ifile, to accommodate future file creations. + */ +int +extend_ifile(struct lfs *fs) +{ + struct uvnode *vp; + struct inode *ip; + IFILE *ifp; + IFILE_V1 *ifp_v1; + struct ubuf *bp, *cbp; + daddr_t i, blkno, max; + ino_t oldlast; + CLEANERINFO *cip; + + vp = fs->lfs_ivnode; + ip = VTOI(vp); + blkno = lblkno(fs, ip->i_ffs1_size); + + bp = getblk(vp, blkno, fs->lfs_bsize); /* XXX VOP_BALLOC() */ + ip->i_ffs1_size += fs->lfs_bsize; + + i = (blkno - fs->lfs_segtabsz - fs->lfs_cleansz) * + fs->lfs_ifpb; + LFS_GET_HEADFREE(fs, cip, cbp, &oldlast); + LFS_PUT_HEADFREE(fs, cip, cbp, i); + max = i + fs->lfs_ifpb; + fs->lfs_bfree -= btofsb(fs, fs->lfs_bsize); + + if (fs->lfs_version == 1) { + for (ifp_v1 = (IFILE_V1 *)bp->b_data; i < max; ++ifp_v1) { + ifp_v1->if_version = 1; + ifp_v1->if_daddr = LFS_UNUSED_DADDR; + ifp_v1->if_nextfree = ++i; + } + ifp_v1--; + ifp_v1->if_nextfree = oldlast; + } else { + for (ifp = (IFILE *)bp->b_data; i < max; ++ifp) { + ifp->if_version = 1; + ifp->if_daddr = LFS_UNUSED_DADDR; + ifp->if_nextfree = ++i; + } + ifp--; + ifp->if_nextfree = oldlast; + } + LFS_PUT_TAILFREE(fs, cip, cbp, max - 1); + + LFS_BWRITE_LOG(bp); + + return 0; +} + diff --git a/sbin/fsck_lfs/lfs.h b/sbin/fsck_lfs/lfs.h index 5ceb6b092537..cdd572fa62d4 100644 --- a/sbin/fsck_lfs/lfs.h +++ b/sbin/fsck_lfs/lfs.h @@ -1,4 +1,4 @@ -/* $NetBSD: lfs.h,v 1.5 2005/04/01 23:45:59 he Exp $ */ +/* $NetBSD: lfs.h,v 1.6 2005/06/08 19:09:55 perseant Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. * All rights reserved. @@ -89,3 +89,5 @@ ufs_daddr_t try_verify(struct lfs *, struct uvnode *, ufs_daddr_t, int); struct ufs1_dinode *lfs_ifind(struct lfs *, ino_t, struct ubuf *); void call_panic(const char *, ...); void my_vpanic(int, const char *, va_list); +int extend_ifile(struct lfs *); +struct uvnode *lfs_valloc(struct lfs *, ino_t); diff --git a/sbin/fsck_lfs/pass0.c b/sbin/fsck_lfs/pass0.c index 44919b2eca7e..9b67f0d60099 100644 --- a/sbin/fsck_lfs/pass0.c +++ b/sbin/fsck_lfs/pass0.c @@ -1,4 +1,4 @@ -/* $NetBSD: pass0.c,v 1.20 2005/04/11 23:19:24 perseant Exp $ */ +/* $NetBSD: pass0.c,v 1.21 2005/06/08 19:09:55 perseant Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc. @@ -89,7 +89,6 @@ #include "fsutil.h" extern int fake_cleanseg; -int extend_ifile(void); /* * Pass 0. Check the LFS partial segments for valid checksums, correcting @@ -269,8 +268,13 @@ pass0(void) if (fs->lfs_freehd == 0) { pwarn("%sree list head is 0x0\n", preen ? "f" : "F"); - if (preen || reply("FIX")) - extend_ifile(); + if (preen || reply("FIX")) { + extend_ifile(fs); + reset_maxino(((VTOI(fs->lfs_ivnode)->i_ffs1_size >> + fs->lfs_bsize) - + fs->lfs_segtabsz - fs->lfs_cleansz) * + fs->lfs_ifpb); + } } /* diff --git a/sbin/fsck_lfs/pass6.c b/sbin/fsck_lfs/pass6.c index ead456635659..f41c46f51093 100644 --- a/sbin/fsck_lfs/pass6.c +++ b/sbin/fsck_lfs/pass6.c @@ -1,4 +1,4 @@ -/* $NetBSD: pass6.c,v 1.7 2005/04/23 20:21:03 perseant Exp $ */ +/* $NetBSD: pass6.c,v 1.8 2005/06/08 19:09:55 perseant Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -66,7 +66,6 @@ extern u_int32_t cksum(void *, size_t); extern u_int32_t lfs_sb_cksum(struct dlfs *); -int extend_ifile(void); extern ufs_daddr_t badblk; extern SEGUSE *seg_table; @@ -90,7 +89,7 @@ rfw_update_single(struct uvnode *vp, daddr_t lbn, ufs_daddr_t ndaddr, int size) struct inode *ip; daddr_t daddr, ooff; int num, error; - int i, bb, osize, obb; + int i, bb, osize = 0, obb = 0; u_int32_t oldsn, sn; ip = VTOI(vp); @@ -166,7 +165,7 @@ rfw_update_single(struct uvnode *vp, daddr_t lbn, ufs_daddr_t ndaddr, int size) setbmap(daddr + i); /* Check bfree accounting as well */ - if (daddr < 0) { + if (daddr <= 0) { fs->lfs_bfree -= btofsb(fs, size); } else if (size != osize) { fs->lfs_bfree -= (bb - obb); @@ -290,60 +289,6 @@ pass6check(struct inodesc * idesc) return pass1check(idesc); } -/* - * Add a new block to the Ifile, to accommodate future file creations. - */ -int -extend_ifile(void) -{ - struct uvnode *vp; - struct inode *ip; - IFILE *ifp; - IFILE_V1 *ifp_v1; - struct ubuf *bp, *cbp; - daddr_t i, blkno, max; - ino_t oldlast; - CLEANERINFO *cip; - - vp = fs->lfs_ivnode; - ip = VTOI(vp); - blkno = lblkno(fs, ip->i_ffs1_size); - - bp = getblk(vp, blkno, fs->lfs_bsize); /* XXX VOP_BALLOC() */ - ip->i_ffs1_size += fs->lfs_bsize; - - i = (blkno - fs->lfs_segtabsz - fs->lfs_cleansz) * - fs->lfs_ifpb; - LFS_GET_HEADFREE(fs, cip, cbp, &oldlast); - LFS_PUT_HEADFREE(fs, cip, cbp, i); - max = i + fs->lfs_ifpb; - reset_maxino(max); - fs->lfs_bfree -= btofsb(fs, fs->lfs_bsize); - - if (fs->lfs_version == 1) { - for (ifp_v1 = (IFILE_V1 *)bp->b_data; i < max; ++ifp_v1) { - ifp_v1->if_version = 1; - ifp_v1->if_daddr = LFS_UNUSED_DADDR; - ifp_v1->if_nextfree = ++i; - } - ifp_v1--; - ifp_v1->if_nextfree = oldlast; - } else { - for (ifp = (IFILE *)bp->b_data; i < max; ++ifp) { - ifp->if_version = 1; - ifp->if_daddr = LFS_UNUSED_DADDR; - ifp->if_nextfree = ++i; - } - ifp--; - ifp->if_nextfree = oldlast; - } - LFS_PUT_TAILFREE(fs, cip, cbp, max - 1); - - LFS_BWRITE_LOG(bp); - - return 0; -} - /* * Give a previously allocated inode a new address; do segment * accounting if necessary. @@ -389,8 +334,12 @@ alloc_inode(ino_t thisino, ufs_daddr_t daddr) SEGUSE *sup; struct ubuf *bp; - while (thisino >= maxino) - extend_ifile(); + while (thisino >= maxino) { + extend_ifile(fs); + reset_maxino(((VTOI(fs->lfs_ivnode)->i_ffs1_size >> + fs->lfs_bsize) - fs->lfs_segtabsz - + fs->lfs_cleansz) * fs->lfs_ifpb); + } LFS_IENTRY(ifp, fs, thisino, bp); nextfree = ifp->if_nextfree; @@ -402,7 +351,10 @@ alloc_inode(ino_t thisino, ufs_daddr_t daddr) fs->lfs_freehd = nextfree; sbdirty(); if (nextfree == 0) { - extend_ifile(); + extend_ifile(fs); + reset_maxino(((VTOI(fs->lfs_ivnode)->i_ffs1_size >> + fs->lfs_bsize) - fs->lfs_segtabsz - + fs->lfs_cleansz) * fs->lfs_ifpb); } } else { /* Search the free list for this inode */ diff --git a/sbin/fsck_lfs/setup.c b/sbin/fsck_lfs/setup.c index d69bd3952cea..67f92b98f11b 100644 --- a/sbin/fsck_lfs/setup.c +++ b/sbin/fsck_lfs/setup.c @@ -1,4 +1,4 @@ -/* $NetBSD: setup.c,v 1.23 2005/05/24 06:51:49 agc Exp $ */ +/* $NetBSD: setup.c,v 1.24 2005/06/08 19:09:55 perseant Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -150,6 +150,8 @@ reset_maxino(ino_t len) memset(typemap + maxino, 0, (len - maxino) * sizeof(char)); memset(lncntp + maxino, 0, (len - maxino) * sizeof(int16_t)); + maxino = len; + return; }