Note each type of failure in clean_inode and provide statistics on
failures as well as successes when a run of clean_all_inodes completes. Explicitly cast to off_t in get_dinode and get_rawblock, to make sure we read the right block.
This commit is contained in:
parent
1f5cf5c78c
commit
f4fea25c9f
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: coalesce.c,v 1.2 2002/06/14 00:58:40 perseant Exp $ */
|
||||
/* $NetBSD: coalesce.c,v 1.3 2002/06/14 05:21:21 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
|
@ -83,6 +83,36 @@ static int log2int(int n)
|
|||
return log - 1;
|
||||
}
|
||||
|
||||
enum coalesce_returncodes {
|
||||
COALESCE_OK = 0,
|
||||
COALESCE_NOINODE,
|
||||
COALESCE_TOOSMALL,
|
||||
COALESCE_BADSIZE,
|
||||
COALESCE_BADBLOCKSIZE,
|
||||
COALESCE_NOMEM,
|
||||
COALESCE_BADBMAPV,
|
||||
COALESCE_NOTWORTHIT,
|
||||
COALESCE_NOTHINGLEFT,
|
||||
COALESCE_NOTHINGLEFT2,
|
||||
|
||||
COALESCE_MAXERROR
|
||||
};
|
||||
|
||||
char *coalesce_return[] = {
|
||||
"Successfully coalesced",
|
||||
"File not in use or inode not found",
|
||||
"Not large enough to coalesce",
|
||||
"Negative size",
|
||||
"Not enough blocks to account for size",
|
||||
"Malloc failed",
|
||||
"lfs_bmapv failed",
|
||||
"Not broken enough to fix",
|
||||
"Too many blocks not found",
|
||||
"Too many blocks found in active segments",
|
||||
|
||||
"No such error"
|
||||
};
|
||||
|
||||
/*
|
||||
* Find out if this inode's data blocks are discontinuous; if they are,
|
||||
* rewrite them using lfs_markv. Return the number of inodes rewritten.
|
||||
|
@ -102,31 +132,33 @@ int clean_inode(struct fs_info *fsp, ino_t ino)
|
|||
|
||||
dip = get_dinode(fsp, ino);
|
||||
if (dip == NULL)
|
||||
return 0;
|
||||
return COALESCE_NOINODE;
|
||||
|
||||
/* Compute file block size, set up for lfs_bmapv */
|
||||
onb = nb = btofsb(lfsp, dip->di_size);
|
||||
|
||||
/* XXX for now, don't do any file small enough to have fragments */
|
||||
if (nb < NDADDR)
|
||||
return 0;
|
||||
return COALESCE_TOOSMALL;
|
||||
|
||||
/* Sanity checks */
|
||||
if (dip->di_size < 0) {
|
||||
syslog(LOG_WARNING, "ino %d, negative size (%lld)",
|
||||
ino, (long long)dip->di_size);
|
||||
return -1;
|
||||
if (debug)
|
||||
syslog(LOG_DEBUG, "ino %d, negative size (%lld)",
|
||||
ino, (long long)dip->di_size);
|
||||
return COALESCE_BADSIZE;
|
||||
}
|
||||
if (nb > dip->di_blocks) {
|
||||
syslog(LOG_WARNING, "ino %d, computed blocks %d > held blocks %d",
|
||||
ino, nb, dip->di_blocks);
|
||||
return -1;
|
||||
if (debug)
|
||||
syslog(LOG_DEBUG, "ino %d, computed blocks %d > held blocks %d",
|
||||
ino, nb, dip->di_blocks);
|
||||
return COALESCE_BADBLOCKSIZE;
|
||||
}
|
||||
|
||||
bip = (BLOCK_INFO_15 *)malloc(sizeof(BLOCK_INFO_15) * nb);
|
||||
if (bip == NULL) {
|
||||
syslog(LOG_WARNING, "ino %d, %d blocks: %m", ino, nb);
|
||||
return -1;
|
||||
return COALESCE_NOMEM;
|
||||
}
|
||||
for (i = 0; i < nb; i++) {
|
||||
memset(bip + i, 0, sizeof(BLOCK_INFO_15));
|
||||
|
@ -138,7 +170,7 @@ int clean_inode(struct fs_info *fsp, ino_t ino)
|
|||
if ((error = lfs_bmapv(&fsp->fi_statfsp->f_fsid, bip, nb)) < 0) {
|
||||
syslog(LOG_WARNING, "lfs_bmapv: %m");
|
||||
free(bip);
|
||||
return -1;
|
||||
return COALESCE_BADBMAPV;
|
||||
}
|
||||
noff = toff = 0;
|
||||
for (i = 1; i < nb; i++) {
|
||||
|
@ -157,7 +189,7 @@ int clean_inode(struct fs_info *fsp, ino_t ino)
|
|||
if (nb <= 1 || noff == 0 || noff < log2int(nb) ||
|
||||
segtod(lfsp, noff) * 2 < nb) {
|
||||
free(bip);
|
||||
return 0;
|
||||
return COALESCE_NOTWORTHIT;
|
||||
} else if (debug)
|
||||
syslog(LOG_DEBUG, "ino %d total discontinuity "
|
||||
"%d (%d) for %d blocks", ino, noff, toff, nb);
|
||||
|
@ -181,29 +213,17 @@ int clean_inode(struct fs_info *fsp, ino_t ino)
|
|||
--nb;
|
||||
if (nb == 0) {
|
||||
free(bip);
|
||||
return 0;
|
||||
return COALESCE_NOTHINGLEFT;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Double-check that we've tossed everything invalid. (wtf?!)
|
||||
*/
|
||||
for (i = 0; i < nb; i++) {
|
||||
if (bip[i].bi_daddr <= 0) {
|
||||
syslog(LOG_ERR, "negative daddr not tossed, bombing");
|
||||
free(bip);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We may have tossed enough blocks that it is no longer worthwhile
|
||||
* to rewrite this inode.
|
||||
*/
|
||||
if ((1 << (onb - nb)) > onb) {
|
||||
syslog(LOG_DEBUG, "too many blocks tossed, not rewriting");
|
||||
return 0;
|
||||
if (onb - nb > log2int(onb)) {
|
||||
if (debug)
|
||||
syslog(LOG_DEBUG, "too many blocks tossed, not rewriting");
|
||||
return COALESCE_NOTHINGLEFT2;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -237,7 +257,7 @@ int clean_inode(struct fs_info *fsp, ino_t ino)
|
|||
if (bip[i].bi_bp)
|
||||
free(bip[i].bi_bp);
|
||||
free(bip);
|
||||
return 1;
|
||||
return COALESCE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -246,16 +266,21 @@ int clean_inode(struct fs_info *fsp, ino_t ino)
|
|||
*/
|
||||
int clean_all_inodes(struct fs_info *fsp)
|
||||
{
|
||||
int i;
|
||||
int r, tot;
|
||||
int i, r;
|
||||
int totals[COALESCE_MAXERROR];
|
||||
|
||||
tot = 0;
|
||||
memset(totals, 0, sizeof(totals));
|
||||
for (i = 0; i < fsp->fi_ifile_count; i++) {
|
||||
r = clean_inode(fsp, i);
|
||||
if (r > 0)
|
||||
tot += r;
|
||||
++totals[r];
|
||||
}
|
||||
return tot;
|
||||
|
||||
for (i = 0; i < COALESCE_MAXERROR; i++)
|
||||
if (totals[i])
|
||||
syslog(LOG_DEBUG, "%s: %d", coalesce_return[i],
|
||||
totals[i]);
|
||||
|
||||
return totals[COALESCE_OK];
|
||||
}
|
||||
|
||||
int fork_coalesce(struct fs_info *fsp)
|
||||
|
@ -280,7 +305,7 @@ int fork_coalesce(struct fs_info *fsp)
|
|||
syslog(LOG_ERR, "fork: %m");
|
||||
return 0;
|
||||
} else if (childpid == 0) {
|
||||
syslog(LOG_NOTICE, "new coalescing process (%d)", childpid);
|
||||
syslog(LOG_NOTICE, "new coalescing process, pid %d", getpid());
|
||||
num = clean_all_inodes(fsp);
|
||||
syslog(LOG_NOTICE, "coalesced %d discontiguous inodes", num);
|
||||
exit(0);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: library.c,v 1.28 2002/06/14 00:58:40 perseant Exp $ */
|
||||
/* $NetBSD: library.c,v 1.29 2002/06/14 05:21:21 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.28 2002/06/14 00:58:40 perseant Exp $");
|
||||
__RCSID("$NetBSD: library.c,v 1.29 2002/06/14 05:21:21 perseant Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -175,7 +175,7 @@ get_rawblock(FS_INFO *fsp, char *buf, size_t size, ufs_daddr_t daddr)
|
|||
syslog(LOG_ERR, "%s", rdev);
|
||||
exit(1);
|
||||
}
|
||||
return pread(dev_fd, buf, size, fsbtob(&fsp->fi_lfs, daddr));
|
||||
return pread(dev_fd, buf, size, fsbtob(&fsp->fi_lfs, (off_t)daddr));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -199,8 +199,10 @@ get_dinode (FS_INFO *fsp, ino_t ino)
|
|||
memset(&bi, 0, sizeof(bi));
|
||||
bi.bi_inode = ino;
|
||||
bi.bi_lbn = LFS_UNUSED_LBN; /* We want the inode */
|
||||
if (lfs_bmapv(&fsp->fi_statfsp->f_fsid, &bi, 1) < 0)
|
||||
if (lfs_bmapv(&fsp->fi_statfsp->f_fsid, &bi, 1) < 0) {
|
||||
syslog(LOG_WARNING, "lfs_bmapv: %m");
|
||||
return NULL;
|
||||
}
|
||||
if (bi.bi_daddr <= 0)
|
||||
return NULL;
|
||||
|
||||
|
@ -214,12 +216,13 @@ get_dinode (FS_INFO *fsp, ino_t ino)
|
|||
exit(1);
|
||||
}
|
||||
dib = (struct dinode *)malloc(lfsp->lfs_ibsize);
|
||||
pread(dev_fd, dib, lfsp->lfs_ibsize, fsbtob(lfsp, bi.bi_daddr));
|
||||
pread(dev_fd, dib, lfsp->lfs_ibsize, fsbtob(lfsp, (off_t)bi.bi_daddr));
|
||||
for (dip = dib; dip != dib + lfsp->lfs_inopb; ++dip)
|
||||
if (dip->di_u.inumber == ino)
|
||||
break;
|
||||
if (dip == dib + lfsp->lfs_inopb) {
|
||||
free(dib);
|
||||
syslog(LOG_WARNING, "dinode %d not found at fsb 0x%x", ino, bi.bi_daddr);
|
||||
return NULL;
|
||||
}
|
||||
dino = *dip; /* structure copy */
|
||||
|
|
Loading…
Reference in New Issue