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.
This commit is contained in:
dholland 2015-08-12 18:27:01 +00:00
parent 2e090556c4
commit e54b457c15
14 changed files with 405 additions and 156 deletions

View File

@ -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 daddr, BLOCK_INFO **bipp, int *bic)
* 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 daddr, BLOCK_INFO **bipp, int *bic)
#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 daddr, BLOCK_INFO **bipp, int *bic)
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 daddr, BLOCK_INFO **bipp, int *bic)
check_test_pattern(bip + *bic + i); /* XXXDEBUG */
#endif
}
*bic += fip->fi_nblocks;
*bic += lfs_fi_getnblocks(fs, fip);
fip = NEXT_FINFO(fs, fip);
}

View File

@ -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, ulfs_daddr_t pseg_addr, int debug,
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, ulfs_daddr_t pseg_addr, int debug,
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);

View File

@ -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_t, daddr_t *);
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 *, ...);

View File

@ -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 *fip)
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);
}
}

View File

@ -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 segment * sp, struct uvnode * vp)
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 segment * sp, struct uvnode * vp)
}
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 segment * sp, struct uvnode * vp)
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, struct ubuf * bp)
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, struct ubuf * bp)
/* 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 segment * sp)
/*
* 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, ulfs_daddr_t * lb_array, int nmemb, int s
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);
}
}
}

View File

@ -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 ubuf *);
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 *);

View File

@ -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);
}

View File

@ -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 */

View File

@ -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, CLEANERINFO *cip, unsigned num)
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 *ip, uint64_t lbn)
}
#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

View File

@ -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 segment *sp, char *file, int line)
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 segment *sp, char *file, int line)
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)
{

View File

@ -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 offset, u_int64_t nextserial,
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 offset, u_int64_t nextserial,
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 offset, u_int64_t nextserial,
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 offset, u_int64_t nextserial,
}
/* 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);
}

View File

@ -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 buf *);
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, struct buf *bp, kmutex_t *mptr)
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, struct buf *bp, kmutex_t *mptr)
}
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, struct buf *bp, kmutex_t *mptr)
*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 segment *sp)
/* 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, int32_t *lb_array, int nmemb, int size)
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, int32_t *lb_array, int nmemb, int size)
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, int32_t *lb_array, int nmemb, int size)
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, int32_t *lb_array, int nmemb, int size)
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 ino, int vers)
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);
}

View File

@ -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 vm_page **pgs, int npages,
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);

View File

@ -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, 1993\
#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, SEGSUM *sp, int segnum, daddr_t addr)
{
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, SEGSUM *sp, int segnum, daddr_t addr)
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, SEGSUM *sp, int segnum, daddr_t addr)
--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));