Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/libexec/lfs_cleanerd Handle segment 0 properly, if its offse...
details: https://anonhg.NetBSD.org/src/rev/1d503a17dbe0
branches: trunk
changeset: 512839:1d503a17dbe0
user: perseant <perseant%NetBSD.org@localhost>
date: Wed Jul 18 05:46:43 2001 +0000
description:
Handle segment 0 properly, if its offset is different from other segments
because of the disklabel.
Fix a problem with inode block handling that sometimes caused the wrong
blocks to be read, causing either cleaning failures or panics with v2 file
systems.
diffstat:
libexec/lfs_cleanerd/clean.h | 4 +-
libexec/lfs_cleanerd/cleanerd.c | 49 +++++++++++++++-----------
libexec/lfs_cleanerd/library.c | 74 ++++++++++++++++++++++++----------------
3 files changed, 75 insertions(+), 52 deletions(-)
diffs (truncated from 357 to 300 lines):
diff -r ebb900c13537 -r 1d503a17dbe0 libexec/lfs_cleanerd/clean.h
--- a/libexec/lfs_cleanerd/clean.h Wed Jul 18 05:37:55 2001 +0000
+++ b/libexec/lfs_cleanerd/clean.h Wed Jul 18 05:46:43 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: clean.h,v 1.11 2001/07/13 20:30:21 perseant Exp $ */
+/* $NetBSD: clean.h,v 1.12 2001/07/18 05:46:43 perseant Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -151,7 +151,7 @@
int fs_getmntinfo(struct statfs **, char *, const char *);
void get(int, off_t, void *, size_t);
FS_INFO *get_fs_info(struct statfs *, int);
-int lfs_segmapv(FS_INFO *, int, caddr_t, BLOCK_INFO **, int *);
+int lfs_segmapv(FS_INFO *, int, caddr_t, BLOCK_INFO_15 **, int *);
int mmap_segment(FS_INFO *, int, caddr_t *, int);
void munmap_segment(FS_INFO *, caddr_t, int);
void reread_fs_info(FS_INFO *, int);
diff -r ebb900c13537 -r 1d503a17dbe0 libexec/lfs_cleanerd/cleanerd.c
--- a/libexec/lfs_cleanerd/cleanerd.c Wed Jul 18 05:37:55 2001 +0000
+++ b/libexec/lfs_cleanerd/cleanerd.c Wed Jul 18 05:46:43 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cleanerd.c,v 1.31 2001/07/13 20:30:21 perseant Exp $ */
+/* $NetBSD: cleanerd.c,v 1.32 2001/07/18 05:46:43 perseant Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -40,7 +40,7 @@
#if 0
static char sccsid[] = "@(#)cleanerd.c 8.5 (Berkeley) 6/10/95";
#else
-__RCSID("$NetBSD: cleanerd.c,v 1.31 2001/07/13 20:30:21 perseant Exp $");
+__RCSID("$NetBSD: cleanerd.c,v 1.32 2001/07/18 05:46:43 perseant Exp $");
#endif
#endif /* not lint */
@@ -102,7 +102,7 @@
int nsegs; /* number of segments */
struct seglist **segs; /* segment numbers, costs, etc */
int nb; /* total number of blocks */
- BLOCK_INFO *ba; /* accumulated block_infos */
+ BLOCK_INFO_15 *ba; /* accumulated block_infos */
caddr_t *buf; /* segment buffers */
} SEGS_AND_BLOCKS;
@@ -111,8 +111,8 @@
/* function prototypes for system calls; not sure where they should go */
int lfs_segwait(fsid_t *, struct timeval *);
int lfs_segclean(fsid_t *, u_long);
-int lfs_bmapv(fsid_t *, BLOCK_INFO *, int);
-int lfs_markv(fsid_t *, BLOCK_INFO *, int);
+int lfs_bmapv(fsid_t *, BLOCK_INFO_15 *, int);
+int lfs_markv(fsid_t *, BLOCK_INFO_15 *, int);
/* function prototypes */
int bi_tossold(const void *, const void *, const void *);
@@ -650,7 +650,7 @@
add_segment(FS_INFO *fsp, struct seglist *slp, SEGS_AND_BLOCKS *sbp)
{
int id = slp->sl_id;
- BLOCK_INFO *tba, *_bip;
+ BLOCK_INFO_15 *tba, *_bip;
SEGUSE *sp;
struct lfs *lfsp;
struct tossstruct t;
@@ -714,7 +714,7 @@
/* Now toss any blocks not in the current segment */
t.lfs = lfsp;
t.seg = id;
- toss(tba, &num_blocks, sizeof(BLOCK_INFO), bi_tossold, &t);
+ toss(tba, &num_blocks, sizeof(BLOCK_INFO_15), bi_tossold, &t);
/* Check if last element should be tossed */
if (num_blocks && bi_tossold(&t, tba + num_blocks - 1, NULL))
--num_blocks;
@@ -728,17 +728,24 @@
/* XXX KS - check for misplaced blocks */
for(i=0; i<num_blocks; i++) {
if(tba[i].bi_daddr
- && ((char *)(tba[i].bi_bp) - seg_buf) != fsbtob(lfsp, tba[i].bi_daddr - seg_addr)
+ && tba[i].bi_daddr != (long)seg_addr +
+ btofsb(lfsp, (char *)(tba[i].bi_bp) - seg_buf)
&& dtosn(&(fsp->fi_lfs), tba[i].bi_daddr) == id)
{
- if(debug > 1) {
- syslog(LOG_DEBUG, "seg %d, ino %d lbn %d, 0x%x != 0x%lx (fixed)",
- id,
- tba[i].bi_inode,
- tba[i].bi_lbn,
- tba[i].bi_daddr,
- (long)seg_addr + btofsb(lfsp, (char *)(tba[i].bi_bp) - seg_buf));
- }
+ syslog(LOG_ERR, "bi_daddr = 0x%x = %db; %p - %p = %d",
+ tba[i].bi_daddr,
+ fsbtob(lfsp, tba[i].bi_daddr - seg_addr),
+ tba[i].bi_bp, seg_buf,
+ ((char *)(tba[i].bi_bp) - seg_buf));
+ syslog(LOG_ERR, "seg %d (0x%x), ino %d lbn %d, 0x%x != 0x%lx",
+ id, seg_addr,
+ tba[i].bi_inode,
+ tba[i].bi_lbn,
+ tba[i].bi_daddr,
+ (long)seg_addr + btofsb(lfsp, (char *)(tba[i].bi_bp) - seg_buf));
+ error = EFAULT;
+ goto out;
+
/*
* XXX KS - have to be careful here about Inodes;
* if lfs_bmapv shows them somewhere else in the
@@ -822,8 +829,8 @@
}
/* Add these blocks to the accumulated list */
- sbp->ba = realloc(sbp->ba, (sbp->nb + num_blocks) * sizeof(BLOCK_INFO));
- memcpy(sbp->ba + sbp->nb, tba, num_blocks * sizeof(BLOCK_INFO));
+ sbp->ba = realloc(sbp->ba, (sbp->nb + num_blocks) * sizeof(BLOCK_INFO_15));
+ memcpy(sbp->ba + sbp->nb, tba, num_blocks * sizeof(BLOCK_INFO_15));
sbp->nb += num_blocks;
free(tba);
@@ -848,7 +855,7 @@
clean_segments(FS_INFO *fsp, SEGS_AND_BLOCKS *sbp)
{
int maxblocks, clean_blocks;
- BLOCK_INFO *bp;
+ BLOCK_INFO_15 *bp;
int i, error;
double util;
@@ -895,8 +902,8 @@
t = (struct tossstruct *)client;
- return (((BLOCK_INFO *)a)->bi_daddr == LFS_UNUSED_DADDR ||
- dtosn(t->lfs, ((BLOCK_INFO *)a)->bi_daddr) != t->seg);
+ return (((BLOCK_INFO_15 *)a)->bi_daddr == LFS_UNUSED_DADDR ||
+ dtosn(t->lfs, ((BLOCK_INFO_15 *)a)->bi_daddr) != t->seg);
}
void
diff -r ebb900c13537 -r 1d503a17dbe0 libexec/lfs_cleanerd/library.c
--- a/libexec/lfs_cleanerd/library.c Wed Jul 18 05:37:55 2001 +0000
+++ b/libexec/lfs_cleanerd/library.c Wed Jul 18 05:46:43 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: library.c,v 1.22 2001/07/13 20:30:22 perseant Exp $ */
+/* $NetBSD: library.c,v 1.23 2001/07/18 05:46:44 perseant Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)library.c 8.3 (Berkeley) 5/24/95";
#else
-__RCSID("$NetBSD: library.c,v 1.22 2001/07/13 20:30:22 perseant Exp $");
+__RCSID("$NetBSD: library.c,v 1.23 2001/07/18 05:46:44 perseant Exp $");
#endif
#endif /* not lint */
@@ -62,9 +62,9 @@
#include "clean.h"
-void add_blocks(FS_INFO *, BLOCK_INFO *, int *, SEGSUM *, caddr_t,
+void add_blocks(FS_INFO *, BLOCK_INFO_15 *, int *, SEGSUM *, caddr_t,
daddr_t, daddr_t);
-void add_inodes(FS_INFO *, BLOCK_INFO *, int *, SEGSUM *, caddr_t,
+void add_inodes(FS_INFO *, BLOCK_INFO_15 *, int *, SEGSUM *, caddr_t,
daddr_t);
int bi_compare(const void *, const void *);
int bi_toss(const void *, const void *, const void *);
@@ -340,9 +340,9 @@
* pair will be listed at most once.
*/
int
-lfs_segmapv(FS_INFO *fsp, int seg, caddr_t seg_buf, BLOCK_INFO **blocks, int *bcount)
+lfs_segmapv(FS_INFO *fsp, int seg, caddr_t seg_buf, BLOCK_INFO_15 **blocks, int *bcount)
{
- BLOCK_INFO *bip, *_bip;
+ BLOCK_INFO_15 *bip, *_bip;
SEGSUM *sp;
SEGUSE *sup;
FINFO *fip;
@@ -355,7 +355,7 @@
bip = NULL;
lfsp = &fsp->fi_lfs;
nelem = 2 * lfsp->lfs_ssize;
- if (!(bip = malloc(nelem * sizeof(BLOCK_INFO))))
+ if (!(bip = malloc(nelem * sizeof(BLOCK_INFO_15))))
goto err0;
sup = SEGUSE_ENTRY(lfsp, fsp->fi_segusep, seg);
@@ -363,6 +363,14 @@
seg_addr = sntod(lfsp, seg);
pseg_addr = seg_addr + (sup->su_flags & SEGUSE_SUPERBLOCK ?
btofsb(lfsp, LFS_SBPAD) : 0);
+ if (seg == 0 && lfsp->lfs_version > 1) {
+ if (fsbtob(lfsp, pseg_addr) < LFS_LABELPAD + LFS_SBPAD) {
+ pseg_addr = btofsb(lfsp, LFS_LABELPAD + LFS_SBPAD);
+ s = seg_buf + LFS_LABELPAD + LFS_SBPAD;
+ syslog(LOG_DEBUG, "adj segment 0 offset to 0x%x\n",
+ pseg_addr);
+ }
+ }
if(debug > 1)
syslog(LOG_DEBUG, "\tsegment buffer at: %p\tseg_addr 0x%x", s, seg_addr);
@@ -403,7 +411,7 @@
if (*bcount + nblocks + sp->ss_ninos > nelem) {
nelem = *bcount + nblocks + sp->ss_ninos;
- bip = realloc (bip, nelem * sizeof(BLOCK_INFO));
+ bip = realloc (bip, nelem * sizeof(BLOCK_INFO_15));
if (!bip)
goto err0;
}
@@ -419,8 +427,8 @@
nsegs, seg, sup->su_nsums);
goto err0;
}
- qsort(bip, *bcount, sizeof(BLOCK_INFO), bi_compare);
- toss(bip, bcount, sizeof(BLOCK_INFO), bi_toss, NULL);
+ qsort(bip, *bcount, sizeof(BLOCK_INFO_15), bi_compare);
+ toss(bip, bcount, sizeof(BLOCK_INFO_15), bi_toss, NULL);
if(debug > 1) {
syslog(LOG_DEBUG, "BLOCK INFOS");
@@ -440,21 +448,21 @@
}
/*
- * This will parse a partial segment and fill in BLOCK_INFO structures
+ * This will parse a partial segment and fill in BLOCK_INFO_15 structures
* for each block described in the segment summary. It will not include
* blocks or inodes from files with new version numbers.
*/
void
-add_blocks (FS_INFO *fsp, BLOCK_INFO *bip, int *countp, SEGSUM *sp,
+add_blocks (FS_INFO *fsp, BLOCK_INFO_15 *bip, int *countp, SEGSUM *sp,
caddr_t seg_buf, daddr_t segaddr, daddr_t psegaddr)
{
IFILE *ifp;
FINFO *fip;
caddr_t bp;
daddr_t *dp, *iaddrp;
- int fsb_per_block, i, j;
- int fsb_frag;
- u_long page_size;
+ int fsb_per_block, fsb_per_iblock, i, j;
+ int fsb_frag, iblks_seen;
+ u_long iblk_size, blk_size;
struct lfs *lfsp;
if(debug > 1)
@@ -462,7 +470,9 @@
lfsp = &fsp->fi_lfs;
fsb_per_block = fragstofsb(lfsp, lfsp->lfs_frag);
- page_size = fsp->fi_lfs.lfs_bsize;
+ fsb_per_iblock = btofsb(lfsp, lfsp->lfs_ibsize);
+ blk_size = fsp->fi_lfs.lfs_bsize;
+ iblk_size = fsp->fi_lfs.lfs_ibsize;
bp = seg_buf + fsbtob(lfsp, psegaddr - segaddr) + lfsp->lfs_sumsize;
bip += *countp;
psegaddr += btofsb(lfsp, lfsp->lfs_sumsize);
@@ -472,19 +482,20 @@
fip = (FINFO *)(((char *)sp) + sizeof(SEGSUM_V1));
else
fip = (FINFO *)(sp + 1);
+ iblks_seen = 0;
for (i = 0; i < sp->ss_nfinfo;
++i, fip = (FINFO *)(&fip->fi_blocks[fip->fi_nblocks])) {
ifp = IFILE_ENTRY(&fsp->fi_lfs, fsp->fi_ifilep, fip->fi_ino);
PRINT_FINFO(fip, ifp);
- if (ifp->if_version > fip->fi_version)
- continue;
dp = &(fip->fi_blocks[0]);
for (j = 0; j < fip->fi_nblocks; j++, dp++) {
/* Skip over intervening inode blocks */
while (psegaddr == *iaddrp) {
- psegaddr += fsb_per_block;
- bp += page_size;
+ /* syslog(LOG_DEBUG, "skipping ino block at 0x%x",
+ psegaddr); */
+ psegaddr += fsb_per_iblock;
+ bp += iblk_size;
--iaddrp;
}
bip->bi_inode = fip->fi_ino;
@@ -494,15 +505,18 @@
bip->bi_segcreate = (time_t)(sp->ss_ident);
else
bip->bi_segcreate = (time_t)(sp->ss_create);
+ /* syslog(LOG_DEBUG, "ino %d lbn %d 0x%x %p",
+ bip->bi_inode, bip->bi_lbn, bip->bi_daddr,
+ bp); */
bip->bi_bp = bp;
bip->bi_version = ifp->if_version;
if (j < fip->fi_nblocks-1
- || fip->fi_lastlength == page_size)
Home |
Main Index |
Thread Index |
Old Index