Module Name: src Committed By: dholland Date: Wed Aug 12 18:27:01 UTC 2015
Modified Files: src/libexec/lfs_cleanerd: lfs_cleanerd.c src/sbin/fsck_lfs: lfs.c lfs_user.h pass6.c segwrite.c segwrite.h setup.c src/sys/ufs/lfs: lfs.h lfs_accessors.h lfs_debug.c lfs_rfw.c lfs_segment.c lfs_vfsops.c src/usr.sbin/dumplfs: dumplfs.c Log Message: Provide 32-bit and 64-bit versions of FINFO. This also entailed sorting out part of struct segment, as that contains a pointer into the current FINFO data. To generate a diff of this commit: cvs rdiff -u -r1.48 -r1.49 src/libexec/lfs_cleanerd/lfs_cleanerd.c cvs rdiff -u -r1.54 -r1.55 src/sbin/fsck_lfs/lfs.c cvs rdiff -u -r1.8 -r1.9 src/sbin/fsck_lfs/lfs_user.h cvs rdiff -u -r1.40 -r1.41 src/sbin/fsck_lfs/pass6.c cvs rdiff -u -r1.39 -r1.40 src/sbin/fsck_lfs/segwrite.c cvs rdiff -u -r1.5 -r1.6 src/sbin/fsck_lfs/segwrite.h cvs rdiff -u -r1.53 -r1.54 src/sbin/fsck_lfs/setup.c cvs rdiff -u -r1.177 -r1.178 src/sys/ufs/lfs/lfs.h cvs rdiff -u -r1.11 -r1.12 src/sys/ufs/lfs/lfs_accessors.h cvs rdiff -u -r1.50 -r1.51 src/sys/ufs/lfs/lfs_debug.c cvs rdiff -u -r1.27 -r1.28 src/sys/ufs/lfs/lfs_rfw.c cvs rdiff -u -r1.254 -r1.255 src/sys/ufs/lfs/lfs_segment.c cvs rdiff -u -r1.338 -r1.339 src/sys/ufs/lfs/lfs_vfsops.c cvs rdiff -u -r1.52 -r1.53 src/usr.sbin/dumplfs/dumplfs.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/libexec/lfs_cleanerd/lfs_cleanerd.c diff -u src/libexec/lfs_cleanerd/lfs_cleanerd.c:1.48 src/libexec/lfs_cleanerd/lfs_cleanerd.c:1.49 --- src/libexec/lfs_cleanerd/lfs_cleanerd.c:1.48 Wed Aug 12 18:26:26 2015 +++ src/libexec/lfs_cleanerd/lfs_cleanerd.c Wed Aug 12 18:27:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_cleanerd.c,v 1.48 2015/08/12 18:26:26 dholland Exp $ */ +/* $NetBSD: lfs_cleanerd.c,v 1.49 2015/08/12 18:27:01 dholland Exp $ */ /*- * Copyright (c) 2005 The NetBSD Foundation, Inc. @@ -546,7 +546,7 @@ parse_pseg(struct clfs *fs, daddr_t dadd * Kernels with this problem always wrote this zero-sized * finfo last, so just ignore it. */ - if (fip->fi_nblocks == 0) { + if (lfs_fi_getnblocks(fs, fip) == 0) { #ifdef REPAIR_ZERO_FINFO struct ubuf *nbp; SEGSUM *nssp; @@ -572,27 +572,27 @@ parse_pseg(struct clfs *fs, daddr_t dadd #ifdef REPAIR_ZERO_FINFO vers = -1; #else - lfs_ientry(&ifp, fs, fip->fi_ino, &ifbp); + lfs_ientry(&ifp, fs, lfs_fi_getino(fs, fip), &ifbp); vers = lfs_if_getversion(fs, ifp); brelse(ifbp, 0); #endif - if (vers != fip->fi_version) { + if (vers != lfs_fi_getversion(fs, fip)) { size_t size; /* Read all the blocks from the data summary */ - for (i = 0; i < fip->fi_nblocks; i++) { - size = (i == fip->fi_nblocks - 1) ? - fip->fi_lastlength : lfs_sb_getbsize(fs); + for (i = 0; i < lfs_fi_getnblocks(fs, fip); i++) { + size = (i == lfs_fi_getnblocks(fs, fip) - 1) ? + lfs_fi_getlastlength(fs, fip) : lfs_sb_getbsize(fs); cp = fd_ptrget(fs->clfs_devvp, daddr); ck = lfs_cksum_part(cp, sizeof(u_int32_t), ck); daddr += lfs_btofsb(fs, size); } - fip = (FINFO *)(fip->fi_blocks + fip->fi_nblocks); + fip = NEXT_FINFO(fs, fip); continue; } /* Add all the blocks from the finfos (current or not) */ - nbip = (BLOCK_INFO *)realloc(bip, (*bic + fip->fi_nblocks) * + nbip = (BLOCK_INFO *)realloc(bip, (*bic + lfs_fi_getnblocks(fs, fip)) * sizeof(*bip)); if (nbip) bip = nbip; @@ -601,14 +601,14 @@ parse_pseg(struct clfs *fs, daddr_t dadd return 0x0; } - for (i = 0; i < fip->fi_nblocks; i++) { - bip[*bic + i].bi_inode = fip->fi_ino; - bip[*bic + i].bi_lbn = fip->fi_blocks[i]; + for (i = 0; i < lfs_fi_getnblocks(fs, fip); i++) { + bip[*bic + i].bi_inode = lfs_fi_getino(fs, fip); + bip[*bic + i].bi_lbn = lfs_fi_getblock(fs, fip, i); bip[*bic + i].bi_daddr = daddr; bip[*bic + i].bi_segcreate = lfs_ss_getcreate(fs, ssp); - bip[*bic + i].bi_version = fip->fi_version; - bip[*bic + i].bi_size = (i == fip->fi_nblocks - 1) ? - fip->fi_lastlength : lfs_sb_getbsize(fs); + bip[*bic + i].bi_version = lfs_fi_getversion(fs, fip); + bip[*bic + i].bi_size = (i == lfs_fi_getnblocks(fs, fip) - 1) ? + lfs_fi_getlastlength(fs, fip) : lfs_sb_getbsize(fs); cp = fd_ptrget(fs->clfs_devvp, daddr); ck = lfs_cksum_part(cp, sizeof(u_int32_t), ck); bip[*bic + i].bi_bp = cp; @@ -618,7 +618,7 @@ parse_pseg(struct clfs *fs, daddr_t dadd check_test_pattern(bip + *bic + i); /* XXXDEBUG */ #endif } - *bic += fip->fi_nblocks; + *bic += lfs_fi_getnblocks(fs, fip); fip = NEXT_FINFO(fs, fip); } Index: src/sbin/fsck_lfs/lfs.c diff -u src/sbin/fsck_lfs/lfs.c:1.54 src/sbin/fsck_lfs/lfs.c:1.55 --- src/sbin/fsck_lfs/lfs.c:1.54 Wed Aug 12 18:26:26 2015 +++ src/sbin/fsck_lfs/lfs.c Wed Aug 12 18:27:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: lfs.c,v 1.54 2015/08/12 18:26:26 dholland Exp $ */ +/* $NetBSD: lfs.c,v 1.55 2015/08/12 18:27:01 dholland Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. * All rights reserved. @@ -768,8 +768,8 @@ check_summary(struct lfs *fs, SEGSUM *sp fp = SEGSUM_FINFOBASE(fs, sp); for (i = 0; i < lfs_ss_getnfinfo(fs, sp); i++) { - nblocks += fp->fi_nblocks; - bc += fp->fi_lastlength + ((fp->fi_nblocks - 1) + nblocks += lfs_fi_getnblocks(fs, fp); + bc += lfs_fi_getlastlength(fs, fp) + ((lfs_fi_getnblocks(fs, fp) - 1) << lfs_sb_getbshift(fs)); assert(bc >= 0); fp = NEXT_FINFO(fs, fp); @@ -811,9 +811,9 @@ check_summary(struct lfs *fs, SEGSUM *sp if (i < lfs_ss_getnfinfo(fs, sp)) { if (func) func(daddr, fp); - for (k = 0; k < fp->fi_nblocks; k++) { - len = (k == fp->fi_nblocks - 1 ? - fp->fi_lastlength + for (k = 0; k < lfs_fi_getnblocks(fs, fp); k++) { + len = (k == lfs_fi_getnblocks(fs, fp) - 1 ? + lfs_fi_getlastlength(fs, fp) : lfs_sb_getbsize(fs)); bread(devvp, LFS_FSBTODB(fs, daddr), len, 0, &bp); Index: src/sbin/fsck_lfs/lfs_user.h diff -u src/sbin/fsck_lfs/lfs_user.h:1.8 src/sbin/fsck_lfs/lfs_user.h:1.9 --- src/sbin/fsck_lfs/lfs_user.h:1.8 Wed Aug 12 18:26:26 2015 +++ src/sbin/fsck_lfs/lfs_user.h Wed Aug 12 18:27:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_user.h,v 1.8 2015/08/12 18:26:26 dholland Exp $ */ +/* $NetBSD: lfs_user.h,v 1.9 2015/08/12 18:27:01 dholland Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. * All rights reserved. @@ -33,7 +33,7 @@ struct lfs; /* XXX do these really need to be here? */ union segsum; -struct finfo; +union finfo; /* * In the fsck code we don't need lfs_unlockvp, but we don't have a mount @@ -86,7 +86,7 @@ int lfs_vop_bmap(struct uvnode *, daddr_ struct uvnode *lfs_raw_vget(struct lfs *, ino_t, int, ulfs_daddr_t); struct lfs *lfs_init(int, daddr_t, daddr_t, int, int); struct lfs *lfs_verify(struct lfs *, struct lfs *, struct uvnode *, int); -int check_summary(struct lfs *, union segsum *, ulfs_daddr_t, int, struct uvnode *, void (*)(ulfs_daddr_t, struct finfo *)); +int check_summary(struct lfs *, union segsum *, ulfs_daddr_t, int, struct uvnode *, void (*)(ulfs_daddr_t, union finfo *)); ulfs_daddr_t try_verify(struct lfs *, struct uvnode *, ulfs_daddr_t, int); struct ulfs1_dinode *lfs_ifind(struct lfs *, ino_t, struct ubuf *); void call_panic(const char *, ...); Index: src/sbin/fsck_lfs/pass6.c diff -u src/sbin/fsck_lfs/pass6.c:1.40 src/sbin/fsck_lfs/pass6.c:1.41 --- src/sbin/fsck_lfs/pass6.c:1.40 Wed Aug 12 18:26:26 2015 +++ src/sbin/fsck_lfs/pass6.c Wed Aug 12 18:27:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: pass6.c,v 1.40 2015/08/12 18:26:26 dholland Exp $ */ +/* $NetBSD: pass6.c,v 1.41 2015/08/12 18:27:01 dholland Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -262,18 +262,18 @@ pass6harvest(ulfs_daddr_t daddr, FINFO * int i; size_t size; - vp = vget(fs, fip->fi_ino); + vp = vget(fs, lfs_fi_getino(fs, fip)); if (vp && vp != fs->lfs_ivnode && - VTOI(vp)->i_ffs1_gen == fip->fi_version) { - for (i = 0; i < fip->fi_nblocks; i++) { - size = (i == fip->fi_nblocks - 1 ? - fip->fi_lastlength : lfs_sb_getbsize(fs)); + VTOI(vp)->i_ffs1_gen == lfs_fi_getversion(fs, fip)) { + for (i = 0; i < lfs_fi_getnblocks(fs, fip); i++) { + size = (i == lfs_fi_getnblocks(fs, fip) - 1 ? + lfs_fi_getlastlength(fs, fip) : lfs_sb_getbsize(fs)); if (debug) - pwarn("ino %lld lbn %lld -> 0x%lx\n", - (long long)fip->fi_ino, - (long long)fip->fi_blocks[i], - (long)daddr); - rfw_update_single(vp, fip->fi_blocks[i], daddr, size); + pwarn("ino %ju lbn %jd -> 0x%jx\n", + (uintmax_t)lfs_fi_getino(fs, fip), + (intmax_t)lfs_fi_getblock(fs, fip, i), + (intmax_t)daddr); + rfw_update_single(vp, lfs_fi_getblock(fs, fip, i), daddr, size); daddr += lfs_btofsb(fs, size); } } Index: src/sbin/fsck_lfs/segwrite.c diff -u src/sbin/fsck_lfs/segwrite.c:1.39 src/sbin/fsck_lfs/segwrite.c:1.40 --- src/sbin/fsck_lfs/segwrite.c:1.39 Wed Aug 12 18:26:27 2015 +++ src/sbin/fsck_lfs/segwrite.c Wed Aug 12 18:27:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: segwrite.c,v 1.39 2015/08/12 18:26:27 dholland Exp $ */ +/* $NetBSD: segwrite.c,v 1.40 2015/08/12 18:27:01 dholland Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. * All rights reserved. @@ -106,6 +106,9 @@ extern u_int32_t cksum(void *, size_t); extern u_int32_t lfs_sb_cksum(struct lfs *); extern int preen; +static void lfs_shellsort(struct lfs *, + struct ubuf **, union lfs_blocks *, int, int); + /* * Logical block number match routines used when traversing the dirty block * chain. @@ -198,7 +201,7 @@ void lfs_writefile(struct lfs * fs, struct segment * sp, struct uvnode * vp) { struct ubuf *bp; - struct finfo *fip; + FINFO *fip; struct inode *ip; IFILE *ifp; SEGSUM *ssp; @@ -206,10 +209,10 @@ lfs_writefile(struct lfs * fs, struct se ip = VTOI(vp); if (sp->seg_bytes_left < lfs_sb_getbsize(fs) || - sp->sum_bytes_left < sizeof(struct finfo)) + sp->sum_bytes_left < FINFOSIZE(fs) + LFS_BLKPTRSIZE(fs)) (void) lfs_writeseg(fs, sp); - sp->sum_bytes_left -= FINFOSIZE; + sp->sum_bytes_left -= FINFOSIZE(fs); ssp = (SEGSUM *)sp->segsum; lfs_ss_setnfinfo(fs, ssp, lfs_ss_getnfinfo(fs, ssp) + 1); @@ -219,10 +222,10 @@ lfs_writefile(struct lfs * fs, struct se } fip = sp->fip; - fip->fi_nblocks = 0; - fip->fi_ino = ip->i_number; - LFS_IENTRY(ifp, fs, fip->fi_ino, bp); - fip->fi_version = lfs_if_getversion(fs, ifp); + lfs_fi_setnblocks(fs, fip, 0); + lfs_fi_setino(fs, fip, ip->i_number); + LFS_IENTRY(ifp, fs, lfs_fi_getino(fs, fip), bp); + lfs_fi_setversion(fs, fip, lfs_if_getversion(fs, ifp)); brelse(bp, 0); lfs_gather(fs, sp, vp, lfs_match_data); @@ -231,11 +234,12 @@ lfs_writefile(struct lfs * fs, struct se lfs_gather(fs, sp, vp, lfs_match_tindir); fip = sp->fip; - if (fip->fi_nblocks != 0) { + if (lfs_fi_getnblocks(fs, fip) != 0) { sp->fip = NEXT_FINFO(fs, fip); - sp->start_lbp = &sp->fip->fi_blocks[0]; + lfs_blocks_fromfinfo(fs, &sp->start_lbp, sp->fip); } else { - sp->sum_bytes_left += FINFOSIZE; + /* XXX shouldn't this update sp->fip? */ + sp->sum_bytes_left += FINFOSIZE(fs); lfs_ss_setnfinfo(fs, ssp, lfs_ss_getnfinfo(fs, ssp) - 1); } } @@ -380,15 +384,15 @@ lfs_gatherblock(struct segment * sp, str sp->seg_bytes_left < bp->b_bcount) { lfs_updatemeta(sp); - version = sp->fip->fi_version; + version = lfs_fi_getversion(fs, sp->fip); (void) lfs_writeseg(fs, sp); - sp->fip->fi_version = version; - sp->fip->fi_ino = VTOI(sp->vp)->i_number; + lfs_fi_setversion(fs, sp->fip, version); + lfs_fi_setino(fs, sp->fip, VTOI(sp->vp)->i_number); /* Add the current file to the segment summary. */ ssp = (SEGSUM *)sp->segsum; lfs_ss_setnfinfo(fs, ssp, lfs_ss_getnfinfo(fs, ssp) + 1); - sp->sum_bytes_left -= FINFOSIZE; + sp->sum_bytes_left -= FINFOSIZE(fs); return 1; } @@ -397,8 +401,13 @@ lfs_gatherblock(struct segment * sp, str /* bp->b_flags &= ~B_DONE; */ *sp->cbpp++ = bp; - for (j = 0; j < blksinblk; j++) - sp->fip->fi_blocks[sp->fip->fi_nblocks++] = bp->b_lblkno + j; + for (j = 0; j < blksinblk; j++) { + unsigned bn; + + bn = lfs_fi_getnblocks(fs, sp->fip); + lfs_fi_setnblocks(fs, sp->fip, bn + 1); + lfs_fi_setblock(fs, sp->fip, bn, bp->b_lblkno + j);; + } sp->sum_bytes_left -= sizeof(ulfs_daddr_t) * blksinblk; sp->seg_bytes_left -= bp->b_bcount; @@ -533,9 +542,22 @@ lfs_updatemeta(struct segment * sp) int i, nblocks, num; int frags; int bytesleft, size; + union lfs_blocks tmpptr; + fs = sp->fs; vp = sp->vp; + + /* + * This code was cutpasted from the kernel. See the + * corresponding comment in lfs_segment.c. + */ +#if 0 nblocks = &sp->fip->fi_blocks[sp->fip->fi_nblocks] - sp->start_lbp; +#else + lfs_blocks_fromvoid(fs, &tmpptr, (void *)NEXT_FINFO(fs, sp->fip)); + nblocks = lfs_blocks_sub(fs, &tmpptr, &sp->start_lbp); + //nblocks_orig = nblocks; +#endif if (vp == NULL || nblocks == 0) return; @@ -544,7 +566,6 @@ lfs_updatemeta(struct segment * sp) * This count may be high due to oversize blocks from lfs_gop_write. * Correct for this. (XXX we should be able to keep track of these.) */ - fs = sp->fs; for (i = 0; i < nblocks; i++) { if (sp->start_bpp[i] == NULL) { printf("nblocks = %d, not %d\n", i, nblocks); @@ -558,7 +579,7 @@ lfs_updatemeta(struct segment * sp) /* * Sort the blocks. */ - lfs_shellsort(sp->start_bpp, sp->start_lbp, nblocks, lfs_sb_getbsize(fs)); + lfs_shellsort(fs, sp->start_bpp, &sp->start_lbp, nblocks, lfs_sb_getbsize(fs)); /* * Record the length of the last block in case it's a fragment. @@ -566,8 +587,8 @@ lfs_updatemeta(struct segment * sp) * indirect block will be lfs_bsize and its presence indicates * that you cannot have fragments. */ - sp->fip->fi_lastlength = ((sp->start_bpp[nblocks - 1]->b_bcount - 1) & - lfs_sb_getbmask(fs)) + 1; + lfs_fi_setlastlength(fs, sp->fip, ((sp->start_bpp[nblocks - 1]->b_bcount - 1) & + lfs_sb_getbmask(fs)) + 1); /* * Assign disk addresses, and update references to the logical @@ -575,7 +596,7 @@ lfs_updatemeta(struct segment * sp) */ for (i = nblocks; i--; ++sp->start_bpp) { sbp = *sp->start_bpp; - lbn = *sp->start_lbp; + lbn = lfs_blocks_get(fs, &sp->start_lbp, 0); sbp->b_blkno = LFS_FSBTODB(fs, lfs_sb_getoffset(fs)); @@ -597,7 +618,8 @@ lfs_updatemeta(struct segment * sp) bytesleft -= lfs_sb_getbsize(fs)) { size = MIN(bytesleft, lfs_sb_getbsize(fs)); frags = lfs_numfrags(fs, size); - lbn = *sp->start_lbp++; + lbn = lfs_blocks_get(fs, &sp->start_lbp, 0); + lfs_blocks_inc(fs, &sp->start_lbp); lfs_update_single(fs, sp, lbn, lfs_sb_getoffset(fs), size); lfs_sb_addoffset(fs, frags); } @@ -680,9 +702,9 @@ lfs_initseg(struct lfs * fs) /* Set pointer to first FINFO, initialize it. */ sp->fip = SEGSUM_FINFOBASE(fs, ssp); - sp->fip->fi_nblocks = 0; - sp->start_lbp = &sp->fip->fi_blocks[0]; - sp->fip->fi_lastlength = 0; + lfs_fi_setnblocks(fs, sp->fip, 0); + lfs_blocks_fromfinfo(fs, &sp->start_lbp, sp->fip); + lfs_fi_setlastlength(fs, sp->fip, 0); sp->seg_bytes_left -= lfs_sb_getsumsize(fs); sp->sum_bytes_left = lfs_sb_getsumsize(fs) - SEGSUM_SIZE(fs); @@ -869,8 +891,9 @@ lfs_writeseg(struct lfs * fs, struct seg /* * Our own copy of shellsort. XXX use qsort or heapsort. */ -void -lfs_shellsort(struct ubuf ** bp_array, ulfs_daddr_t * lb_array, int nmemb, int size) +static void +lfs_shellsort(struct lfs *fs, + struct ubuf ** bp_array, union lfs_blocks *lb_array, int nmemb, int size) { static int __rsshell_increments[] = {4, 1, 0}; int incr, *incrp, t1, t2; @@ -892,7 +915,8 @@ lfs_shellsort(struct ubuf ** bp_array, u incr = 0; for (t1 = 0; t1 < nmemb; t1++) { for (t2 = 0; t2 * size < bp_array[t1]->b_bcount; t2++) { - lb_array[incr++] = bp_array[t1]->b_lblkno + t2; + lfs_blocks_set(fs, lb_array, incr++, + bp_array[t1]->b_lblkno + t2); } } } Index: src/sbin/fsck_lfs/segwrite.h diff -u src/sbin/fsck_lfs/segwrite.h:1.5 src/sbin/fsck_lfs/segwrite.h:1.6 --- src/sbin/fsck_lfs/segwrite.h:1.5 Fri Jul 24 06:56:41 2015 +++ src/sbin/fsck_lfs/segwrite.h Wed Aug 12 18:27:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: segwrite.h,v 1.5 2015/07/24 06:56:41 dholland Exp $ */ +/* $NetBSD: segwrite.h,v 1.6 2015/08/12 18:27:01 dholland Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. * All rights reserved. @@ -57,8 +57,6 @@ int lfs_match_indir(struct lfs *, struct int lfs_match_dindir(struct lfs *, struct ubuf *); int lfs_match_tindir(struct lfs *, struct ubuf *); -void lfs_shellsort(struct ubuf **, int32_t *, int, int); - int ulfs_getlbns(struct lfs *, struct uvnode *, daddr_t, struct indir *, int *); int ulfs_bmaparray(struct lfs *, struct uvnode *, daddr_t, daddr_t *, struct indir *, int *); Index: src/sbin/fsck_lfs/setup.c diff -u src/sbin/fsck_lfs/setup.c:1.53 src/sbin/fsck_lfs/setup.c:1.54 --- src/sbin/fsck_lfs/setup.c:1.53 Wed Aug 12 18:26:27 2015 +++ src/sbin/fsck_lfs/setup.c Wed Aug 12 18:27:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: setup.c,v 1.53 2015/08/12 18:26:27 dholland Exp $ */ +/* $NetBSD: setup.c,v 1.54 2015/08/12 18:27:01 dholland Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -277,7 +277,7 @@ setup(const char *dev) (lfs_sb_getversion(fs) > 1 ? lfs_sb_getffshift(fs) : lfs_sb_getbshift(fs)); for (i = 0; i < lfs_ss_getnfinfo(fs, sp); i++) { - bc += fp->fi_lastlength + ((fp->fi_nblocks - 1) + bc += lfs_fi_getlastlength(fs, fp) + ((lfs_fi_getnblocks(fs, fp) - 1) << lfs_sb_getbshift(fs)); fp = NEXT_FINFO(fs, fp); } Index: src/sys/ufs/lfs/lfs.h diff -u src/sys/ufs/lfs/lfs.h:1.177 src/sys/ufs/lfs/lfs.h:1.178 --- src/sys/ufs/lfs/lfs.h:1.177 Wed Aug 12 18:26:27 2015 +++ src/sys/ufs/lfs/lfs.h Wed Aug 12 18:27:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: lfs.h,v 1.177 2015/08/12 18:26:27 dholland Exp $ */ +/* $NetBSD: lfs.h,v 1.178 2015/08/12 18:27:01 dholland Exp $ */ /* from NetBSD: dinode.h,v 1.22 2013/01/22 09:39:18 dholland Exp */ /* from NetBSD: dir.h,v 1.21 2009/07/22 04:49:19 dholland Exp */ @@ -475,17 +475,33 @@ struct segusage_v1 { /* * On-disk file information. One per file with data blocks in the segment. + * + * The FINFO structure is a header; it is followed by fi_nblocks block + * pointers, which are logical block numbers of the file. (These are the + * blocks of the file present in this segment.) */ -typedef struct finfo FINFO; -struct finfo { + +typedef struct finfo64 FINFO64; +struct finfo64 { + u_int32_t fi_nblocks; /* number of blocks */ + u_int32_t fi_version; /* version number */ + u_int64_t fi_ino; /* inode number */ + u_int32_t fi_lastlength; /* length of last block in array */ + u_int32_t fi_pad; /* unused */ +}; + +typedef struct finfo32 FINFO32; +struct finfo32 { u_int32_t fi_nblocks; /* number of blocks */ u_int32_t fi_version; /* version number */ u_int32_t fi_ino; /* inode number */ u_int32_t fi_lastlength; /* length of last block in array */ - int32_t fi_blocks[1]; /* array of logical block numbers */ }; -/* sizeof FINFO except fi_blocks */ -#define FINFOSIZE (sizeof(FINFO) - sizeof(int32_t)) + +typedef union finfo { + struct finfo64 u_64; + struct finfo32 u_32; +} FINFO; /* * Index file inode entries. @@ -974,6 +990,16 @@ typedef struct block_info_15 { int bi_size; /* size of the block (if fragment) */ } BLOCK_INFO_15; +/* + * 32/64-bit-clean pointer to block pointers. This points into + * already-existing storage; it is mostly used to access the block + * pointers following a FINFO. + */ +union lfs_blocks { + int64_t *b64; + int32_t *b32; +}; + /* In-memory description of a segment about to be written. */ struct segment { struct lfs *fs; /* file system pointer */ @@ -982,14 +1008,14 @@ struct segment { struct buf **start_bpp; /* pointer to first bp in this set */ struct buf *ibp; /* buffer pointer to inode page */ struct ulfs1_dinode *idp; /* pointer to ifile dinode */ - struct finfo *fip; /* current fileinfo pointer */ + FINFO *fip; /* current fileinfo pointer */ struct vnode *vp; /* vnode being gathered */ void *segsum; /* segment summary info */ u_int32_t ninodes; /* number of inodes in this segment */ int32_t seg_bytes_left; /* bytes left in segment */ int32_t sum_bytes_left; /* bytes left in summary block */ u_int32_t seg_number; /* number of this segment */ - int32_t *start_lbp; /* beginning lbn for this set */ + union lfs_blocks start_lbp; /* beginning lbn for this set */ #define SEGM_CKP 0x0001 /* doing a checkpoint */ #define SEGM_CLEAN 0x0002 /* cleaner call; don't sort */ Index: src/sys/ufs/lfs/lfs_accessors.h diff -u src/sys/ufs/lfs/lfs_accessors.h:1.11 src/sys/ufs/lfs/lfs_accessors.h:1.12 --- src/sys/ufs/lfs/lfs_accessors.h:1.11 Wed Aug 12 18:26:27 2015 +++ src/sys/ufs/lfs/lfs_accessors.h Wed Aug 12 18:27:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_accessors.h,v 1.11 2015/08/12 18:26:27 dholland Exp $ */ +/* $NetBSD: lfs_accessors.h,v 1.12 2015/08/12 18:27:01 dholland Exp $ */ /* from NetBSD: lfs.h,v 1.165 2015/07/24 06:59:32 dholland Exp */ /* from NetBSD: dinode.h,v 1.22 2013/01/22 09:39:18 dholland Exp */ @@ -285,13 +285,77 @@ /* XXX: move to a more suitable location in this file */ #define LFS_BLKPTRSIZE(fs) ((fs)->lfs_is64 ? sizeof(int64_t) : sizeof(int32_t)) +/* Size of an on-disk inode number. */ +/* XXX: move to a more suitable location in this file */ +#define LFS_INUMSIZE(fs) ((fs)->lfs_is64 ? sizeof(int64_t) : sizeof(int32_t)) + +/* size of a FINFO, without the block pointers */ +#define FINFOSIZE(fs) ((fs)->lfs_is64 ? sizeof(FINFO64) : sizeof(FINFO32)) + /* Full size of the provided FINFO record, including its block pointers. */ #define FINFO_FULLSIZE(fs, fip) \ - (FINFOSIZE + (fip)->fi_nblocks * LFS_BLKPTRSIZE(fs)) + (FINFOSIZE(fs) + lfs_fi_getnblocks(fs, fip) * LFS_BLKPTRSIZE(fs)) #define NEXT_FINFO(fs, fip) \ ((FINFO *)((char *)(fip) + FINFO_FULLSIZE(fs, fip))) +#define LFS_DEF_FI_ACCESSOR(type, type32, field) \ + static __unused inline type \ + lfs_fi_get##field(STRUCT_LFS *fs, FINFO *fip) \ + { \ + if (fs->lfs_is64) { \ + return fip->u_64.fi_##field; \ + } else { \ + return fip->u_32.fi_##field; \ + } \ + } \ + static __unused inline void \ + lfs_fi_set##field(STRUCT_LFS *fs, FINFO *fip, type val) \ + { \ + if (fs->lfs_is64) { \ + type *p = &fip->u_64.fi_##field; \ + (void)p; \ + fip->u_64.fi_##field = val; \ + } else { \ + type32 *p = &fip->u_32.fi_##field; \ + (void)p; \ + fip->u_32.fi_##field = val; \ + } \ + } \ + +LFS_DEF_FI_ACCESSOR(uint32_t, uint32_t, nblocks); +LFS_DEF_FI_ACCESSOR(uint32_t, uint32_t, version); +LFS_DEF_FI_ACCESSOR(uint64_t, uint32_t, ino); +LFS_DEF_FI_ACCESSOR(uint32_t, uint32_t, lastlength); + +static __unused inline daddr_t +lfs_fi_getblock(STRUCT_LFS *fs, FINFO *fip, unsigned index) +{ + void *firstblock; + + firstblock = (char *)fip + FINFOSIZE(fs); + KASSERT(index < lfs_fi_getnblocks(fs, fip)); + if (fs->lfs_is64) { + return ((int64_t *)firstblock)[index]; + } else { + return ((int32_t *)firstblock)[index]; + } +} + +static __unused inline void +lfs_fi_setblock(STRUCT_LFS *fs, FINFO *fip, unsigned index, daddr_t blk) +{ + void *firstblock; + + firstblock = (char *)fip + FINFOSIZE(fs); + KASSERT(index < lfs_fi_getnblocks(fs, fip)); + if (fs->lfs_is64) { + ((int64_t *)firstblock)[index] = blk; + } else { + ((int32_t *)firstblock)[index] = blk; + } +} + /* * Index file inode entries. */ @@ -498,11 +562,11 @@ lfs_ci_shiftdirtytoclean(STRUCT_LFS *fs, static __unused inline FINFO * segsum_finfobase(STRUCT_LFS *fs, SEGSUM *ssp) { - return (FINFO *)((char *)ssp) + SEGSUM_SIZE(fs); + return (FINFO *)((char *)ssp + SEGSUM_SIZE(fs)); } #else #define SEGSUM_FINFOBASE(fs, ssp) \ - ((FINFO *)((char *)(ssp)) + SEGSUM_SIZE(fs)); + ((FINFO *)((char *)(ssp) + SEGSUM_SIZE(fs))); #endif #define LFS_DEF_SS_ACCESSOR(type, type32, field) \ @@ -858,6 +922,88 @@ lfs_blksize(STRUCT_LFS *fs, struct inode } #endif +/* + * union lfs_blocks + */ + +static __unused inline void +lfs_blocks_fromvoid(STRUCT_LFS *fs, union lfs_blocks *bp, void *p) +{ + if (fs->lfs_is64) { + bp->b64 = p; + } else { + bp->b32 = p; + } +} + +static __unused inline void +lfs_blocks_fromfinfo(STRUCT_LFS *fs, union lfs_blocks *bp, FINFO *fip) +{ + void *firstblock; + + firstblock = (char *)fip + FINFOSIZE(fs); + if (fs->lfs_is64) { + bp->b64 = (int64_t *)firstblock; + } else { + bp->b32 = (int32_t *)firstblock; + } +} + +static __unused inline daddr_t +lfs_blocks_get(STRUCT_LFS *fs, union lfs_blocks *bp, unsigned index) +{ + if (fs->lfs_is64) { + return bp->b64[index]; + } else { + return bp->b32[index]; + } +} + +static __unused inline void +lfs_blocks_set(STRUCT_LFS *fs, union lfs_blocks *bp, unsigned index, daddr_t val) +{ + if (fs->lfs_is64) { + bp->b64[index] = val; + } else { + bp->b32[index] = val; + } +} + +static __unused inline void +lfs_blocks_inc(STRUCT_LFS *fs, union lfs_blocks *bp) +{ + if (fs->lfs_is64) { + bp->b64++; + } else { + bp->b32++; + } +} + +static __unused inline int +lfs_blocks_eq(STRUCT_LFS *fs, union lfs_blocks *bp1, union lfs_blocks *bp2) +{ + if (fs->lfs_is64) { + return bp1->b64 == bp2->b64; + } else { + return bp1->b32 == bp2->b32; + } +} + +static __unused inline int +lfs_blocks_sub(STRUCT_LFS *fs, union lfs_blocks *bp1, union lfs_blocks *bp2) +{ + /* (remember that the pointers are typed) */ + if (fs->lfs_is64) { + return bp1->b64 - bp2->b64; + } else { + return bp1->b32 - bp2->b32; + } +} + +/* + * struct segment + */ + /* * Macros for determining free space on the disk, with the variable metadata Index: src/sys/ufs/lfs/lfs_debug.c diff -u src/sys/ufs/lfs/lfs_debug.c:1.50 src/sys/ufs/lfs/lfs_debug.c:1.51 --- src/sys/ufs/lfs/lfs_debug.c:1.50 Sun Aug 2 18:18:10 2015 +++ src/sys/ufs/lfs/lfs_debug.c Wed Aug 12 18:27:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_debug.c,v 1.50 2015/08/02 18:18:10 dholland Exp $ */ +/* $NetBSD: lfs_debug.c,v 1.51 2015/08/12 18:27:01 dholland Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc. @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: lfs_debug.c,v 1.50 2015/08/02 18:18:10 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lfs_debug.c,v 1.51 2015/08/12 18:27:01 dholland Exp $"); #ifdef DEBUG @@ -225,9 +225,10 @@ lfs_check_segsum(struct lfs *fs, struct if ((actual = 1) == 1) return; /* XXXX not checking this anymore, really */ - if (sp->sum_bytes_left >= FINFOSIZE - && sp->fip->fi_nblocks > 512) { - printf("%s:%d: fi_nblocks = %d\n",file,line,sp->fip->fi_nblocks); + if (sp->sum_bytes_left >= FINFOSIZE(fs) + && lfs_fi_getnblocks(fs, sp->fip) > 512) { + printf("%s:%d: fi_nblocks = %d\n", file, line, + lfs_fi_getnblocks(fs, sp->fip)); #ifdef DDB Debugger(); #endif @@ -241,9 +242,10 @@ lfs_check_segsum(struct lfs *fs, struct actual = lfs_sb_getsumsize(fs) /* amount taken up by FINFOs */ - - ((char *)&(sp->fip->fi_blocks[sp->fip->fi_nblocks]) - (char *)(sp->segsum)) + - ((char *)NEXT_FINFO(fs, sp->fip) - (char *)(sp->segsum)) /* amount taken up by inode blocks */ - - sizeof(int32_t)*((sp->ninodes+LFS_INOPB(fs)-1) / LFS_INOPB(fs)); + /* XXX should this be INUMSIZE or BLKPTRSIZE? */ + - LFS_INUMSIZE(fs)*((sp->ninodes+LFS_INOPB(fs)-1) / LFS_INOPB(fs)); #if 0 if (actual - sp->sum_bytes_left < offset) { Index: src/sys/ufs/lfs/lfs_rfw.c diff -u src/sys/ufs/lfs/lfs_rfw.c:1.27 src/sys/ufs/lfs/lfs_rfw.c:1.28 --- src/sys/ufs/lfs/lfs_rfw.c:1.27 Wed Aug 12 18:26:27 2015 +++ src/sys/ufs/lfs/lfs_rfw.c Wed Aug 12 18:27:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_rfw.c,v 1.27 2015/08/12 18:26:27 dholland Exp $ */ +/* $NetBSD: lfs_rfw.c,v 1.28 2015/08/12 18:27:01 dholland Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: lfs_rfw.c,v 1.27 2015/08/12 18:26:27 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lfs_rfw.c,v 1.28 2015/08/12 18:27:01 dholland Exp $"); #if defined(_KERNEL_OPT) #include "opt_quota.h" @@ -428,8 +428,8 @@ check_segsum(struct lfs *fs, daddr_t off nblocks = 0; fip = SEGSUM_FINFOBASE(fs, (SEGSUM *)bp->b_data); for (i = 0; i < lfs_ss_getnfinfo(fs, ssp); ++i) { - nblocks += fip->fi_nblocks; - if (fip->fi_nblocks <= 0) + nblocks += lfs_fi_getnblocks(fs, fip); + if (lfs_fi_getnblocks(fs, fip) <= 0) break; fip = NEXT_FINFO(fs, fip); } @@ -452,6 +452,7 @@ check_segsum(struct lfs *fs, daddr_t off offset = -1; goto err2; } + /* XXX this can't be right, on-disk u_long? */ (*dp++) = ((u_long *)(dbp->b_data))[0]; brelse(dbp, BC_AGE); } @@ -469,9 +470,9 @@ check_segsum(struct lfs *fs, daddr_t off continue; } size = lfs_sb_getbsize(fs); - for (j = 0; j < fip->fi_nblocks; ++j) { - if (j == fip->fi_nblocks - 1) - size = fip->fi_lastlength; + for (j = 0; j < lfs_fi_getnblocks(fs, fip); ++j) { + if (j == lfs_fi_getnblocks(fs, fip) - 1) + size = lfs_fi_getlastlength(fs, fip); if (flags & CHECK_CKSUM) { error = bread(devvp, LFS_FSBTODB(fs, offset), size, 0, &dbp); @@ -484,10 +485,12 @@ check_segsum(struct lfs *fs, daddr_t off } /* Account for and update any direct blocks */ if ((flags & CHECK_UPDATE) && - fip->fi_ino > LFS_IFILE_INUM && - fip->fi_blocks[j] >= 0) { - update_meta(fs, fip->fi_ino, fip->fi_version, - fip->fi_blocks[j], offset, size, l); + lfs_fi_getino(fs, fip) > LFS_IFILE_INUM && + lfs_fi_getblock(fs, fip, j) >= 0) { + update_meta(fs, lfs_fi_getino(fs, fip), + lfs_fi_getversion(fs, fip), + lfs_fi_getblock(fs, fip, j), + offset, size, l); } offset += lfs_btofsb(fs, size); } Index: src/sys/ufs/lfs/lfs_segment.c diff -u src/sys/ufs/lfs/lfs_segment.c:1.254 src/sys/ufs/lfs/lfs_segment.c:1.255 --- src/sys/ufs/lfs/lfs_segment.c:1.254 Wed Aug 12 18:26:27 2015 +++ src/sys/ufs/lfs/lfs_segment.c Wed Aug 12 18:27:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_segment.c,v 1.254 2015/08/12 18:26:27 dholland Exp $ */ +/* $NetBSD: lfs_segment.c,v 1.255 2015/08/12 18:27:01 dholland Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc. @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: lfs_segment.c,v 1.254 2015/08/12 18:26:27 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lfs_segment.c,v 1.255 2015/08/12 18:27:01 dholland Exp $"); #define _VFS_VNODE_PRIVATE /* XXX: check for VI_MARKER, this has to go */ @@ -138,14 +138,15 @@ static void lfs_cluster_callback(struct int lfs_match_fake(struct lfs *, struct buf *); void lfs_newseg(struct lfs *); -/* XXX ondisk32 */ -void lfs_shellsort(struct buf **, int32_t *, int, int); void lfs_supercallback(struct buf *); void lfs_updatemeta(struct segment *); void lfs_writesuper(struct lfs *, daddr_t); int lfs_writevnodes(struct lfs *fs, struct mount *mp, struct segment *sp, int dirops); +static void lfs_shellsort(struct lfs *, struct buf **, union lfs_blocks *, + int, int); + int lfs_allclean_wakeup; /* Cleaner wakeup address. */ int lfs_writeindir = 1; /* whether to flush indir on non-ckp */ int lfs_clean_vnhead = 0; /* Allow freeing to head of vn list */ @@ -1332,7 +1333,7 @@ lfs_gatherblock(struct segment *sp, stru mutex_exit(mptr); lfs_updatemeta(sp); - vers = sp->fip->fi_version; + vers = lfs_fi_getversion(fs, sp->fip); (void) lfs_writeseg(fs, sp); /* Add the current file to the segment summary. */ @@ -1344,9 +1345,9 @@ lfs_gatherblock(struct segment *sp, stru } if (bp->b_flags & B_GATHERED) { - DLOG((DLOG_SEG, "lfs_gatherblock: already gathered! Ino %d," + DLOG((DLOG_SEG, "lfs_gatherblock: already gathered! Ino %ju," " lbn %" PRId64 "\n", - sp->fip->fi_ino, bp->b_lblkno)); + (uintmax_t)lfs_fi_getino(fs, sp->fip), bp->b_lblkno)); return (0); } @@ -1355,7 +1356,11 @@ lfs_gatherblock(struct segment *sp, stru *sp->cbpp++ = bp; for (j = 0; j < blksinblk; j++) { - sp->fip->fi_blocks[sp->fip->fi_nblocks++] = bp->b_lblkno + j; + unsigned bn; + + bn = lfs_fi_getnblocks(fs, sp->fip); + lfs_fi_setnblocks(fs, sp->fip, bn+1); + lfs_fi_setblock(fs, sp->fip, bn, bp->b_lblkno + j); /* This block's accounting moves from lfs_favail to lfs_avail */ lfs_deregister_block(sp->vp, bp->b_lblkno + j); } @@ -1611,13 +1616,44 @@ lfs_updatemeta(struct segment *sp) struct lfs *fs; struct vnode *vp; daddr_t lbn; - int i, nblocks, num; + int i, nblocks, nblocks_orig, num; int bb; int bytesleft, size; + unsigned lastlength; + union lfs_blocks tmpptr; - ASSERT_SEGLOCK(sp->fs); + fs = sp->fs; vp = sp->vp; - nblocks = &sp->fip->fi_blocks[sp->fip->fi_nblocks] - sp->start_lbp; + ASSERT_SEGLOCK(fs); + + /* + * This used to be: + * + * nblocks = &sp->fip->fi_blocks[sp->fip->fi_nblocks] - sp->start_lbp; + * + * that is, it allowed for the possibility that start_lbp did + * not point to the beginning of the finfo block pointer area. + * This particular formulation is six kinds of painful in the + * lfs64 world where we have two sizes of block pointer, so + * unless/until everything can be cleaned up to not move + * start_lbp around but instead use an offset, we do the + * following: + * 1. Get NEXT_FINFO(sp->fip). This is the same pointer as + * &sp->fip->fi_blocks[sp->fip->fi_nblocks], just the wrong + * type. (Ugh.) + * 2. Cast it to void *, then assign it to a temporary + * union lfs_blocks. + * 3. Subtract start_lbp from that. + * 4. Save the value of nblocks in blocks_orig so we can + * assert below that it hasn't changed without repeating this + * rubbish. + * + * XXX. + */ + lfs_blocks_fromvoid(fs, &tmpptr, (void *)NEXT_FINFO(fs, sp->fip)); + nblocks = lfs_blocks_sub(fs, &tmpptr, &sp->start_lbp); + nblocks_orig = nblocks; + KASSERT(nblocks >= 0); KASSERT(vp != NULL); if (nblocks == 0) @@ -1627,7 +1663,6 @@ lfs_updatemeta(struct segment *sp) * This count may be high due to oversize blocks from lfs_gop_write. * Correct for this. (XXX we should be able to keep track of these.) */ - fs = sp->fs; for (i = 0; i < nblocks; i++) { if (sp->start_bpp[i] == NULL) { DLOG((DLOG_SEG, "lfs_updatemeta: nblocks = %d, not %d\n", i, nblocks)); @@ -1639,8 +1674,13 @@ lfs_updatemeta(struct segment *sp) nblocks -= num - 1; } +#if 0 + /* pre-lfs64 assertion */ KASSERT(vp->v_type == VREG || nblocks == &sp->fip->fi_blocks[sp->fip->fi_nblocks] - sp->start_lbp); +#else + KASSERT(vp->v_type == VREG || nblocks == nblocks_orig); +#endif KASSERT(nblocks == sp->cbpp - sp->start_bpp); /* @@ -1651,7 +1691,7 @@ lfs_updatemeta(struct segment *sp) * same inode...and if we don't sort, and there are fragments * present, blocks may be written in the wrong place. */ - lfs_shellsort(sp->start_bpp, sp->start_lbp, nblocks, lfs_sb_getbsize(fs)); + lfs_shellsort(fs, sp->start_bpp, &sp->start_lbp, nblocks, lfs_sb_getbsize(fs)); /* * Record the length of the last block in case it's a fragment. @@ -1664,8 +1704,9 @@ lfs_updatemeta(struct segment *sp) * XXX true until lfs_markv is fixed to do everything with * XXX fake blocks (including fake inodes and fake indirect blocks). */ - sp->fip->fi_lastlength = ((sp->start_bpp[nblocks - 1]->b_bcount - 1) & + lastlength = ((sp->start_bpp[nblocks - 1]->b_bcount - 1) & lfs_sb_getbmask(fs)) + 1; + lfs_fi_setlastlength(fs, sp->fip, lastlength); /* * Assign disk addresses, and update references to the logical @@ -1673,7 +1714,7 @@ lfs_updatemeta(struct segment *sp) */ for (i = nblocks; i--; ++sp->start_bpp) { sbp = *sp->start_bpp; - lbn = *sp->start_lbp; + lbn = lfs_blocks_get(fs, &sp->start_lbp, 0); KASSERT(sbp->b_lblkno == lbn); sbp->b_blkno = LFS_FSBTODB(fs, lfs_sb_getoffset(fs)); @@ -1698,7 +1739,8 @@ lfs_updatemeta(struct segment *sp) bytesleft -= lfs_sb_getbsize(fs)) { size = MIN(bytesleft, lfs_sb_getbsize(fs)); bb = lfs_numfrags(fs, size); - lbn = *sp->start_lbp++; + lbn = lfs_blocks_get(fs, &sp->start_lbp, 0); + lfs_blocks_inc(fs, &sp->start_lbp); lfs_update_single(fs, sp, sp->vp, lbn, lfs_sb_getoffset(fs), size); lfs_sb_addoffset(fs, bb); @@ -1850,9 +1892,9 @@ lfs_initseg(struct lfs *fs) /* Set pointer to first FINFO, initialize it. */ sp->fip = SEGSUM_FINFOBASE(fs, sp->segsum); - sp->fip->fi_nblocks = 0; - sp->start_lbp = &sp->fip->fi_blocks[0]; - sp->fip->fi_lastlength = 0; + lfs_fi_setnblocks(fs, sp->fip, 0); + lfs_fi_setlastlength(fs, sp->fip, 0); + lfs_blocks_fromfinfo(fs, &sp->start_lbp, sp->fip); sp->seg_bytes_left -= lfs_sb_getsumsize(fs); sp->sum_bytes_left = lfs_sb_getsumsize(fs) - SEGSUM_SIZE(fs); @@ -2061,8 +2103,8 @@ lfs_writeseg(struct lfs *fs, struct segm /* Check for zero-length and zero-version FINFO entries. */ fip = SEGSUM_FINFOBASE(fs, ssp); for (findex = 0; findex < lfs_ss_getnfinfo(fs, ssp); findex++) { - KDASSERT(fip->fi_nblocks > 0); - KDASSERT(fip->fi_version > 0); + KDASSERT(lfs_fi_getnblocks(fs, fip) > 0); + KDASSERT(lfs_fi_getversion(fs, fip) > 0); fip = NEXT_FINFO(fs, fip); } #endif /* DEBUG */ @@ -2716,8 +2758,10 @@ lfs_callback(struct buf *bp) * negative block numbers (meta data blocks) sort AFTER the data blocks. */ -void -lfs_shellsort(struct buf **bp_array, int32_t *lb_array, int nmemb, int size) +static void +lfs_shellsort(struct lfs *fs, + struct buf **bp_array, union lfs_blocks *lb_array, + int nmemb, int size) { static int __rsshell_increments[] = { 4, 1, 0 }; int incr, *incrp, t1, t2; @@ -2727,7 +2771,7 @@ lfs_shellsort(struct buf **bp_array, int incr = 0; for (t1 = 0; t1 < nmemb; t1++) { for (t2 = 0; t2 * size < bp_array[t1]->b_bcount; t2++) { - if (lb_array[incr++] != bp_array[t1]->b_lblkno + t2) { + if (lfs_blocks_get(fs, lb_array, incr++) != bp_array[t1]->b_lblkno + t2) { /* dump before panic */ printf("lfs_shellsort: nmemb=%d, size=%d\n", nmemb, size); @@ -2742,8 +2786,8 @@ lfs_shellsort(struct buf **bp_array, int printf("lbns:"); for (t2 = 0; t2 * size < bp->b_bcount; t2++) { - printf(" %" PRId32, - lb_array[incr++]); + printf(" %jd", + (intmax_t)lfs_blocks_get(fs, lb_array, incr++)); } printf("\n"); } @@ -2756,8 +2800,8 @@ lfs_shellsort(struct buf **bp_array, int for (incrp = __rsshell_increments; (incr = *incrp++) != 0;) for (t1 = incr; t1 < nmemb; ++t1) for (t2 = t1 - incr; t2 >= 0;) - if ((u_int32_t)bp_array[t2]->b_lblkno > - (u_int32_t)bp_array[t2 + incr]->b_lblkno) { + if ((u_int64_t)bp_array[t2]->b_lblkno > + (u_int64_t)bp_array[t2 + incr]->b_lblkno) { bp_temp = bp_array[t2]; bp_array[t2] = bp_array[t2 + incr]; bp_array[t2 + incr] = bp_temp; @@ -2769,7 +2813,8 @@ lfs_shellsort(struct buf **bp_array, int incr = 0; for (t1 = 0; t1 < nmemb; t1++) { for (t2 = 0; t2 * size < bp_array[t1]->b_bcount; t2++) { - lb_array[incr++] = bp_array[t1]->b_lblkno + t2; + lfs_blocks_set(fs, lb_array, incr++, + bp_array[t1]->b_lblkno + t2); } } } @@ -2787,15 +2832,15 @@ lfs_acquire_finfo(struct lfs *fs, ino_t KASSERT(vers > 0); if (sp->seg_bytes_left < lfs_sb_getbsize(fs) || - sp->sum_bytes_left < sizeof(struct finfo)) + sp->sum_bytes_left < FINFOSIZE(fs) + LFS_BLKPTRSIZE(fs)) (void) lfs_writeseg(fs, fs->lfs_sp); - sp->sum_bytes_left -= FINFOSIZE; + sp->sum_bytes_left -= FINFOSIZE(fs); ssp = (SEGSUM *)sp->segsum; lfs_ss_setnfinfo(fs, ssp, lfs_ss_getnfinfo(fs, ssp) + 1); - sp->fip->fi_nblocks = 0; - sp->fip->fi_ino = ino; - sp->fip->fi_version = vers; + lfs_fi_setnblocks(fs, sp->fip, 0); + lfs_fi_setino(fs, sp->fip, ino); + lfs_fi_setversion(fs, sp->fip, vers); } /* @@ -2808,11 +2853,12 @@ lfs_release_finfo(struct lfs *fs) struct segment *sp = fs->lfs_sp; SEGSUM *ssp; - if (sp->fip->fi_nblocks != 0) { + if (lfs_fi_getnblocks(fs, sp->fip) != 0) { sp->fip = NEXT_FINFO(fs, sp->fip); - sp->start_lbp = &sp->fip->fi_blocks[0]; + lfs_blocks_fromfinfo(fs, &sp->start_lbp, sp->fip); } else { - sp->sum_bytes_left += FINFOSIZE; + /* XXX shouldn't this update sp->fip? */ + sp->sum_bytes_left += FINFOSIZE(fs); ssp = (SEGSUM *)sp->segsum; lfs_ss_setnfinfo(fs, ssp, lfs_ss_getnfinfo(fs, ssp) - 1); } Index: src/sys/ufs/lfs/lfs_vfsops.c diff -u src/sys/ufs/lfs/lfs_vfsops.c:1.338 src/sys/ufs/lfs/lfs_vfsops.c:1.339 --- src/sys/ufs/lfs/lfs_vfsops.c:1.338 Wed Aug 12 18:26:27 2015 +++ src/sys/ufs/lfs/lfs_vfsops.c Wed Aug 12 18:27:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_vfsops.c,v 1.338 2015/08/12 18:26:27 dholland Exp $ */ +/* $NetBSD: lfs_vfsops.c,v 1.339 2015/08/12 18:27:01 dholland Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2007, 2007 @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.338 2015/08/12 18:26:27 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.339 2015/08/12 18:27:01 dholland Exp $"); #if defined(_KERNEL_OPT) #include "opt_lfs.h" @@ -2057,7 +2057,7 @@ lfs_gop_write(struct vnode *vp, struct v int vers; lfs_updatemeta(sp); - vers = sp->fip->fi_version; + vers = lfs_fi_getversion(fs, sp->fip); lfs_release_finfo(fs); (void) lfs_writeseg(fs, sp); Index: src/usr.sbin/dumplfs/dumplfs.c diff -u src/usr.sbin/dumplfs/dumplfs.c:1.52 src/usr.sbin/dumplfs/dumplfs.c:1.53 --- src/usr.sbin/dumplfs/dumplfs.c:1.52 Wed Aug 12 18:26:27 2015 +++ src/usr.sbin/dumplfs/dumplfs.c Wed Aug 12 18:27:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: dumplfs.c,v 1.52 2015/08/12 18:26:27 dholland Exp $ */ +/* $NetBSD: dumplfs.c,v 1.53 2015/08/12 18:27:01 dholland Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -40,7 +40,7 @@ __COPYRIGHT("@(#) Copyright (c) 1991, 19 #if 0 static char sccsid[] = "@(#)dumplfs.c 8.5 (Berkeley) 5/24/95"; #else -__RCSID("$NetBSD: dumplfs.c,v 1.52 2015/08/12 18:26:27 dholland Exp $"); +__RCSID("$NetBSD: dumplfs.c,v 1.53 2015/08/12 18:27:01 dholland Exp $"); #endif #endif /* not lint */ @@ -498,6 +498,7 @@ dump_sum(int fd, struct lfs *lfsp, SEGSU { FINFO *fp; int32_t *dp, *idp; + union lfs_blocks fipblocks; int i, j, acc; int ck; int numbytes, numblocks; @@ -580,23 +581,26 @@ dump_sum(int fd, struct lfs *lfsp, SEGSU fp = SEGSUM_FINFOBASE(lfsp, sp); for (i = 0; i < lfs_ss_getnfinfo(lfsp, sp); i++) { - (void)printf(" FINFO for inode: %d version %d nblocks %d lastlength %d\n", - fp->fi_ino, fp->fi_version, fp->fi_nblocks, - fp->fi_lastlength); - dp = &(fp->fi_blocks[0]); - numblocks += fp->fi_nblocks; - for (j = 0; j < fp->fi_nblocks; j++, dp++) { - (void)printf("\t%d", *dp); + (void)printf(" FINFO for inode: %ju version %u nblocks %u lastlength %u\n", + (uintmax_t)lfs_fi_getino(lfsp, fp), + lfs_fi_getversion(lfsp, fp), + lfs_fi_getnblocks(lfsp, fp), + lfs_fi_getlastlength(lfsp, fp)); + lfs_blocks_fromfinfo(lfsp, &fipblocks, fp); + numblocks += lfs_fi_getnblocks(lfsp, fp); + for (j = 0; j < lfs_fi_getnblocks(lfsp, fp); j++) { + (void)printf("\t%jd", + (intmax_t)lfs_blocks_get(lfsp, &fipblocks, j)); if ((j % 8) == 7) (void)printf("\n"); - if (j == fp->fi_nblocks - 1) - numbytes += fp->fi_lastlength; + if (j == lfs_fi_getnblocks(lfsp, fp) - 1) + numbytes += lfs_fi_getlastlength(lfsp, fp); else numbytes += lfs_sb_getbsize(lfsp); } if ((j % 8) != 0) (void)printf("\n"); - fp = (FINFO *)dp; + fp = NEXT_FINFO(lfsp, fp); } if (datasum_check == 0) @@ -630,16 +634,16 @@ dump_sum(int fd, struct lfs *lfsp, SEGSU --idp; ++acc; } - for (j = 0; j < fp->fi_nblocks; j++) { + for (j = 0; j < lfs_fi_getnblocks(lfsp, fp); j++) { get(fd, fsbtobyte(lfsp, addr), buf, lfs_sb_getfsize(lfsp)); memcpy(datap + acc * el_size, buf, el_size); - if (j == fp->fi_nblocks - 1) - addr += lfs_btofsb(lfsp, fp->fi_lastlength); + if (j == lfs_fi_getnblocks(lfsp, fp) - 1) + addr += lfs_btofsb(lfsp, lfs_fi_getlastlength(lfsp, fp)); else addr += lfs_btofsb(lfsp, lfs_sb_getbsize(lfsp)); ++acc; } - fp = (FINFO *)&(fp->fi_blocks[fp->fi_nblocks]); + fp = NEXT_FINFO(lfsp, fp); } while (addr == *idp) { get(fd, fsbtobyte(lfsp, addr), buf, lfs_sb_getibsize(lfsp));