Merge the short-lived perseant-lfsv2 branch into the trunk.
Kernels and tools understand both v1 and v2 filesystems; newfs_lfs generates v2 by default. Changes for the v2 layout include: - Segments of non-PO2 size and arbitrary block offset, so these can be matched to convenient physical characteristics of the partition (e.g., stripe or track size and offset). - Address by fragment instead of by disk sector, paving the way for non-512-byte-sector devices. In theory fragments can be as large as you like, though in reality they must be smaller than MAXBSIZE in size. - Use serial number and filesystem identifier to ensure that roll-forward doesn't get old data and think it's new. Roll-forward is enabled for v2 filesystems, though not for v1 filesystems by default. - The inode free list is now a tailq, paving the way for undelete (undelete is not yet implemented, but can be without further non-backwards-compatible changes to disk structures). - Inode atime information is kept in the Ifile, instead of on the inode; that is, the inode is never written *just* because atime was changed. Because of this the inodes remain near the file data on the disk, rather than wandering all over as the disk is read repeatedly. This speeds up repeated reads by a small but noticeable amount. Other changes of note include: - The ifile written by newfs_lfs can now be of arbitrary length, it is no longer restricted to a single indirect block. - Fixed an old bug where ctime was changed every time a vnode was created. I need to look more closely to make sure that the times are only updated during write(2) and friends, not after-the-fact during a segment write, and certainly not by the cleaner.
This commit is contained in:
parent
c399f05222
commit
4e3fced95b
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: clean.h,v 1.10 2001/02/04 22:12:47 christos Exp $ */
|
||||
/* $NetBSD: clean.h,v 1.11 2001/07/13 20:30:21 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -84,7 +84,6 @@ typedef struct fs_info {
|
||||
CLEANERINFO *fi_cip; /* Cleaner info from ifile */
|
||||
SEGUSE *fi_segusep; /* segment usage table (from ifile) */
|
||||
IFILE *fi_ifilep; /* ifile table (from ifile) */
|
||||
u_long fi_daddr_shift; /* shift to get byte offset of daddr */
|
||||
u_long fi_ifile_count; /* # entries in the ifile table */
|
||||
off_t fi_ifile_length; /* length of the ifile */
|
||||
time_t fi_fs_tstamp; /* last fs activity, per ifile */
|
||||
@ -94,34 +93,26 @@ typedef struct fs_info {
|
||||
* XXX: size (in bytes) of a segment
|
||||
* should lfs_bsize be fsbtodb(fs,1), blksize(fs), or lfs_dsize?
|
||||
*/
|
||||
#define seg_size(fs) ((fs)->lfs_ssize << (fs)->lfs_bshift)
|
||||
|
||||
/* daddr -> byte offset */
|
||||
#define datobyte(fs, da) (((off_t)(da)) << (fs)->fi_daddr_shift)
|
||||
#define bytetoda(fs, byte) ((byte) >> (fs)->fi_daddr_shift)
|
||||
#define seg_size(fs) fsbtob((fs), segtod((fs), 1))
|
||||
|
||||
#define CLEANSIZE(fsp) (fsp->fi_lfs.lfs_cleansz << fsp->fi_lfs.lfs_bshift)
|
||||
#define SEGTABSIZE(fsp) (fsp->fi_lfs.lfs_segtabsz << fsp->fi_lfs.lfs_bshift)
|
||||
|
||||
#define IFILE_ENTRY(fs, if, i) \
|
||||
((IFILE *)((caddr_t)(if) + ((i) / (fs)->lfs_ifpb << (fs)->lfs_bshift)) \
|
||||
+ (i) % (fs)->lfs_ifpb)
|
||||
#define IFILE_ENTRY(fs, ife, i) \
|
||||
((fs)->lfs_version == 1 ? \
|
||||
(IFILE *)((IFILE_V1 *)((caddr_t)(ife) + ((i) / (fs)->lfs_ifpb <<\
|
||||
(fs)->lfs_bshift)) + (i) % (fs)->lfs_ifpb) : \
|
||||
((IFILE *)((caddr_t)(ife) + ((i) / (fs)->lfs_ifpb << \
|
||||
(fs)->lfs_bshift)) + (i) % (fs)->lfs_ifpb))
|
||||
|
||||
#define SEGUSE_ENTRY(fs, su, i) \
|
||||
((SEGUSE *)((caddr_t)(su) + (fs)->lfs_bsize * ((i) / (fs)->lfs_sepb)) +\
|
||||
(i) % (fs)->lfs_sepb)
|
||||
|
||||
__BEGIN_DECLS
|
||||
int dump_summary __P((struct lfs *, SEGSUM *, u_long, daddr_t **, daddr_t));
|
||||
int fs_getmntinfo __P((struct statfs **, char *, const char *));
|
||||
void get __P((int, off_t, void *, size_t));
|
||||
FS_INFO *get_fs_info __P((struct statfs *, int));
|
||||
int lfs_segmapv __P((FS_INFO *, int, caddr_t, BLOCK_INFO **, int *));
|
||||
int mmap_segment __P((FS_INFO *, int, caddr_t *, int));
|
||||
void munmap_segment __P((FS_INFO *, caddr_t, int));
|
||||
void reread_fs_info __P((FS_INFO *, int));
|
||||
void toss __P((void *, int *, size_t,
|
||||
int (*)(const void *, const void *, const void *), void *));
|
||||
#define SEGUSE_ENTRY(fs, su, i) \
|
||||
((fs)->lfs_version == 1 ? \
|
||||
(SEGUSE *)((SEGUSE_V1 *)((caddr_t)(su) + (fs)->lfs_bsize * \
|
||||
((i) / (fs)->lfs_sepb)) + \
|
||||
(i) % (fs)->lfs_sepb) : \
|
||||
((SEGUSE *)((caddr_t)(su) + (fs)->lfs_bsize * \
|
||||
((i) / (fs)->lfs_sepb)) + \
|
||||
(i) % (fs)->lfs_sepb))
|
||||
|
||||
/*
|
||||
* USEFUL DEBUGGING FUNCTIONS:
|
||||
@ -155,8 +146,20 @@ void toss __P((void *, int *, size_t,
|
||||
ctime((time_t *)&(sup)->su_lastmod)); \
|
||||
}
|
||||
|
||||
void dump_super __P((struct lfs *));
|
||||
void dump_cleaner_info __P((void *));
|
||||
void print_SEGSUM __P(( struct lfs *, SEGSUM *, daddr_t));
|
||||
void print_CLEANERINFO __P((CLEANERINFO *));
|
||||
__BEGIN_DECLS
|
||||
int dump_summary(struct lfs *, SEGSUM *, u_long, daddr_t **, daddr_t);
|
||||
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 mmap_segment(FS_INFO *, int, caddr_t *, int);
|
||||
void munmap_segment(FS_INFO *, caddr_t, int);
|
||||
void reread_fs_info(FS_INFO *, int);
|
||||
void toss __P((void *, int *, size_t,
|
||||
int (*)(const void *, const void *, const void *), void *));
|
||||
|
||||
void dump_super(struct lfs *);
|
||||
void dump_cleaner_info(void *);
|
||||
void print_SEGSUM(struct lfs *, SEGSUM *, daddr_t);
|
||||
void print_CLEANERINFO(CLEANERINFO *);
|
||||
__END_DECLS
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cleanerd.c,v 1.30 2001/02/04 22:12:47 christos Exp $ */
|
||||
/* $NetBSD: cleanerd.c,v 1.31 2001/07/13 20:30:21 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -40,7 +40,7 @@ __COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)cleanerd.c 8.5 (Berkeley) 6/10/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: cleanerd.c,v 1.30 2001/02/04 22:12:47 christos Exp $");
|
||||
__RCSID("$NetBSD: cleanerd.c,v 1.31 2001/07/13 20:30:21 perseant Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -109,24 +109,24 @@ typedef struct {
|
||||
#define CLEAN_BYTES 0x1
|
||||
|
||||
/* function prototypes for system calls; not sure where they should go */
|
||||
int lfs_segwait __P((fsid_t *, struct timeval *));
|
||||
int lfs_segclean __P((fsid_t *, u_long));
|
||||
int lfs_bmapv __P((fsid_t *, BLOCK_INFO *, int));
|
||||
int lfs_markv __P((fsid_t *, BLOCK_INFO *, int));
|
||||
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);
|
||||
|
||||
/* function prototypes */
|
||||
int bi_tossold __P((const void *, const void *, const void *));
|
||||
int choose_segments __P((FS_INFO *, struct seglist *,
|
||||
unsigned long (*)(FS_INFO *, SEGUSE *)));
|
||||
void clean_fs __P((FS_INFO *, unsigned long (*)(FS_INFO *, SEGUSE *), int, long));
|
||||
int clean_loop __P((FS_INFO *, int, long));
|
||||
int add_segment __P((FS_INFO *, struct seglist *, SEGS_AND_BLOCKS *));
|
||||
int clean_segments __P((FS_INFO *, SEGS_AND_BLOCKS *));
|
||||
unsigned long cost_benefit __P((FS_INFO *, SEGUSE *));
|
||||
int cost_compare __P((const void *, const void *));
|
||||
void sig_report __P((int));
|
||||
void just_exit __P((int));
|
||||
int main __P((int, char *[]));
|
||||
int bi_tossold(const void *, const void *, const void *);
|
||||
int choose_segments(FS_INFO *, struct seglist *,
|
||||
unsigned long (*)(FS_INFO *, SEGUSE *));
|
||||
void clean_fs(FS_INFO *, unsigned long (*)(FS_INFO *, SEGUSE *), int, long);
|
||||
int clean_loop(FS_INFO *, int, long);
|
||||
int add_segment(FS_INFO *, struct seglist *, SEGS_AND_BLOCKS *);
|
||||
int clean_segments(FS_INFO *, SEGS_AND_BLOCKS *);
|
||||
unsigned long cost_benefit(FS_INFO *, SEGUSE *);
|
||||
int cost_compare(const void *, const void *);
|
||||
void sig_report(int);
|
||||
void just_exit(int);
|
||||
int main(int, char *[]);
|
||||
|
||||
/*
|
||||
* Cleaning Cost Functions:
|
||||
@ -141,9 +141,7 @@ int main __P((int, char *[]));
|
||||
*/
|
||||
|
||||
unsigned long
|
||||
cost_benefit(fsp, su)
|
||||
FS_INFO *fsp; /* file system information */
|
||||
SEGUSE *su;
|
||||
cost_benefit(FS_INFO *fsp, SEGUSE *su)
|
||||
{
|
||||
struct lfs *lfsp;
|
||||
struct timeval t;
|
||||
@ -180,9 +178,7 @@ cost_benefit(fsp, su)
|
||||
}
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
FS_INFO *fsp;
|
||||
struct statfs *lstatfsp; /* file system stats */
|
||||
@ -340,24 +336,21 @@ main(argc, argv)
|
||||
|
||||
/* return the number of segments cleaned */
|
||||
int
|
||||
clean_loop(fsp, nsegs, options)
|
||||
FS_INFO *fsp; /* file system information */
|
||||
int nsegs;
|
||||
long options;
|
||||
clean_loop(FS_INFO *fsp, int nsegs, long options)
|
||||
{
|
||||
struct lfs *lfsp;
|
||||
double loadavg[MAXLOADS];
|
||||
time_t now;
|
||||
u_long max_free_segs;
|
||||
u_long db_per_seg;
|
||||
u_long fsb_per_seg;
|
||||
|
||||
lfsp = &fsp->fi_lfs;
|
||||
/*
|
||||
* Compute the maximum possible number of free segments, given the
|
||||
* number of free blocks.
|
||||
*/
|
||||
db_per_seg = fsbtodb(lfsp, lfsp->lfs_ssize);
|
||||
max_free_segs = fsp->fi_cip->bfree / db_per_seg + lfsp->lfs_minfreeseg;
|
||||
fsb_per_seg = segtod(lfsp, 1);
|
||||
max_free_segs = fsp->fi_cip->bfree / fsb_per_seg + lfsp->lfs_minfreeseg;
|
||||
|
||||
/*
|
||||
* We will clean if there are not enough free blocks or total clean
|
||||
@ -366,16 +359,16 @@ clean_loop(fsp, nsegs, options)
|
||||
now = time((time_t *)NULL);
|
||||
|
||||
if(debug > 1) {
|
||||
syslog(LOG_DEBUG, "db_per_seg = %lu bfree = %u avail = %d,"
|
||||
" bfree = %u, ", db_per_seg, fsp->fi_cip->bfree,
|
||||
syslog(LOG_DEBUG, "fsb_per_seg = %lu bfree = %u avail = %d,"
|
||||
" bfree = %u, ", fsb_per_seg, fsp->fi_cip->bfree,
|
||||
fsp->fi_cip->avail, fsp->fi_cip->bfree);
|
||||
syslog(LOG_DEBUG, "clean segs = %d, max_free_segs = %ld",
|
||||
fsp->fi_cip->clean, max_free_segs);
|
||||
}
|
||||
|
||||
if ((fsp->fi_cip->bfree - fsp->fi_cip->avail > db_per_seg &&
|
||||
fsp->fi_cip->avail < (long)db_per_seg &&
|
||||
fsp->fi_cip->bfree > (long)db_per_seg) ||
|
||||
if ((fsp->fi_cip->bfree - fsp->fi_cip->avail > fsb_per_seg &&
|
||||
fsp->fi_cip->avail < (long)fsb_per_seg &&
|
||||
fsp->fi_cip->bfree > (long)fsb_per_seg) ||
|
||||
(fsp->fi_cip->clean < max_free_segs &&
|
||||
(fsp->fi_cip->clean <= lfsp->lfs_minfreeseg ||
|
||||
fsp->fi_cip->clean < max_free_segs * BUSY_LIM)))
|
||||
@ -444,9 +437,9 @@ clean_loop(fsp, nsegs, options)
|
||||
}
|
||||
}
|
||||
if (debug > 1) {
|
||||
if (fsp->fi_cip->bfree - fsp->fi_cip->avail <= db_per_seg)
|
||||
if (fsp->fi_cip->bfree - fsp->fi_cip->avail <= fsb_per_seg)
|
||||
syslog(LOG_DEBUG, "condition 1 false");
|
||||
if (fsp->fi_cip->avail >= (long)db_per_seg)
|
||||
if (fsp->fi_cip->avail >= (long)fsb_per_seg)
|
||||
syslog(LOG_DEBUG, "condition 2 false");
|
||||
if (fsp->fi_cip->clean >= max_free_segs)
|
||||
syslog(LOG_DEBUG, "condition 3 false");
|
||||
@ -462,14 +455,11 @@ clean_loop(fsp, nsegs, options)
|
||||
|
||||
|
||||
void
|
||||
clean_fs(fsp, cost_func, nsegs, options)
|
||||
FS_INFO *fsp; /* file system information */
|
||||
unsigned long (*cost_func) __P((FS_INFO *, SEGUSE *));
|
||||
int nsegs;
|
||||
long options;
|
||||
clean_fs(FS_INFO *fsp, unsigned long (*cost_func)(FS_INFO *, SEGUSE *),
|
||||
int nsegs, long options)
|
||||
{
|
||||
struct seglist *segs, *sp;
|
||||
long int to_clean, cleaned_bytes, seg_size;
|
||||
long int to_clean, cleaned_bytes;
|
||||
unsigned long i, j, total;
|
||||
struct rusage ru;
|
||||
fsid_t *fsidp;
|
||||
@ -477,7 +467,6 @@ clean_fs(fsp, cost_func, nsegs, options)
|
||||
SEGS_AND_BLOCKS *sbp;
|
||||
|
||||
fsidp = &fsp->fi_statfsp->f_fsid;
|
||||
seg_size = (1 << fsp->fi_lfs.lfs_segshift);
|
||||
|
||||
if ((segs =
|
||||
malloc(fsp->fi_lfs.lfs_nseg * sizeof(struct seglist))) == NULL) {
|
||||
@ -589,9 +578,7 @@ clean_fs(fsp, cost_func, nsegs, options)
|
||||
* cost/benefit than any utilized segment.
|
||||
*/
|
||||
int
|
||||
cost_compare(a, b)
|
||||
const void *a;
|
||||
const void *b;
|
||||
cost_compare(const void *a, const void *b)
|
||||
{
|
||||
return ((struct seglist *)b)->sl_cost < ((struct seglist *)a)->sl_cost ? -1 : 1;
|
||||
}
|
||||
@ -602,10 +589,7 @@ cost_compare(a, b)
|
||||
* filled in.
|
||||
*/
|
||||
int
|
||||
choose_segments(fsp, seglist, cost_func)
|
||||
FS_INFO *fsp;
|
||||
struct seglist *seglist;
|
||||
unsigned long (*cost_func) __P((FS_INFO *, SEGUSE *));
|
||||
choose_segments(FS_INFO *fsp, struct seglist *seglist, unsigned long (*cost_func)(FS_INFO *, SEGUSE *))
|
||||
{
|
||||
struct lfs *lfsp;
|
||||
struct seglist *sp;
|
||||
@ -663,10 +647,7 @@ choose_segments(fsp, seglist, cost_func)
|
||||
* in preparation for sending through lfs_markv.
|
||||
*/
|
||||
int
|
||||
add_segment(fsp, slp, sbp)
|
||||
FS_INFO *fsp;
|
||||
struct seglist *slp;
|
||||
SEGS_AND_BLOCKS *sbp;
|
||||
add_segment(FS_INFO *fsp, struct seglist *slp, SEGS_AND_BLOCKS *sbp)
|
||||
{
|
||||
int id = slp->sl_id;
|
||||
BLOCK_INFO *tba, *_bip;
|
||||
@ -684,7 +665,7 @@ add_segment(fsp, slp, sbp)
|
||||
|
||||
lfsp = &fsp->fi_lfs;
|
||||
sp = SEGUSE_ENTRY(lfsp, fsp->fi_segusep, id);
|
||||
seg_addr = sntoda(lfsp,id);
|
||||
seg_addr = sntod(lfsp,id);
|
||||
error = 0;
|
||||
tba = NULL;
|
||||
|
||||
@ -718,7 +699,7 @@ add_segment(fsp, slp, sbp)
|
||||
"add_segment: lfs_segmapv failed for segment %d", id);
|
||||
goto out;
|
||||
}
|
||||
cleaner_stats.blocks_read += fsp->fi_lfs.lfs_ssize;
|
||||
cleaner_stats.blocks_read += segtod(lfsp, 1);
|
||||
|
||||
if (debug > 1)
|
||||
syslog(LOG_DEBUG, "lfs_segmapv returned %d blocks", num_blocks);
|
||||
@ -747,8 +728,8 @@ add_segment(fsp, slp, sbp)
|
||||
/* 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) != (tba[i].bi_daddr - seg_addr) * DEV_BSIZE
|
||||
&& datosn(&(fsp->fi_lfs), tba[i].bi_daddr) == id)
|
||||
&& ((char *)(tba[i].bi_bp) - seg_buf) != fsbtob(lfsp, tba[i].bi_daddr - seg_addr)
|
||||
&& 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)",
|
||||
@ -756,7 +737,7 @@ add_segment(fsp, slp, sbp)
|
||||
tba[i].bi_inode,
|
||||
tba[i].bi_lbn,
|
||||
tba[i].bi_daddr,
|
||||
(long)seg_addr + ((char *)(tba[i].bi_bp) - seg_buf)/DEV_BSIZE);
|
||||
(long)seg_addr + btofsb(lfsp, (char *)(tba[i].bi_bp) - seg_buf));
|
||||
}
|
||||
/*
|
||||
* XXX KS - have to be careful here about Inodes;
|
||||
@ -765,7 +746,7 @@ add_segment(fsp, slp, sbp)
|
||||
* the *right* inode, not the first one in the block.
|
||||
*/
|
||||
if(tba[i].bi_lbn == LFS_UNUSED_LBN) {
|
||||
dip = (struct dinode *)(seg_buf + (tba[i].bi_daddr - seg_addr) * DEV_BSIZE);
|
||||
dip = (struct dinode *)(seg_buf + fsbtob(lfsp, tba[i].bi_daddr - seg_addr));
|
||||
for(j=INOPB(lfsp)-1;j>=0;j--) {
|
||||
if(dip[j].di_u.inumber == tba[i].bi_inode) {
|
||||
tba[i].bi_bp = (char *)(dip+j);
|
||||
@ -785,13 +766,12 @@ add_segment(fsp, slp, sbp)
|
||||
}
|
||||
err(1,"lost inode");
|
||||
} else if (debug > 1) {
|
||||
syslog(LOG_DEBUG,"Ino %d corrected to 0x%x+%d",
|
||||
syslog(LOG_DEBUG,"Ino %d corrected to 0x%x",
|
||||
tba[i].bi_inode,
|
||||
tba[i].bi_daddr,
|
||||
(int)((caddr_t)(tba[i].bi_bp) - (caddr_t)(long)seg_addr) % DEV_BSIZE);
|
||||
tba[i].bi_daddr);
|
||||
}
|
||||
} else {
|
||||
tba[i].bi_bp = seg_buf + (tba[i].bi_daddr - seg_addr) * DEV_BSIZE;
|
||||
tba[i].bi_bp = seg_buf + fsbtob(lfsp, tba[i].bi_daddr - seg_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -865,9 +845,7 @@ add_segment(fsp, slp, sbp)
|
||||
|
||||
/* Call markv and clean up */
|
||||
int
|
||||
clean_segments(fsp, sbp)
|
||||
FS_INFO *fsp;
|
||||
SEGS_AND_BLOCKS *sbp;
|
||||
clean_segments(FS_INFO *fsp, SEGS_AND_BLOCKS *sbp)
|
||||
{
|
||||
int maxblocks, clean_blocks;
|
||||
BLOCK_INFO *bp;
|
||||
@ -878,7 +856,7 @@ clean_segments(fsp, sbp)
|
||||
|
||||
cleaner_stats.segs_cleaned += sbp->nsegs;
|
||||
cleaner_stats.blocks_written += sbp->nb;
|
||||
util = ((double)sbp->nb / fsp->fi_lfs.lfs_ssize);
|
||||
util = ((double)sbp->nb / segtod(&fsp->fi_lfs, 1));
|
||||
cleaner_stats.util_tot += util;
|
||||
cleaner_stats.util_sos += util * util;
|
||||
if (do_small)
|
||||
@ -911,22 +889,18 @@ clean_segments(fsp, sbp)
|
||||
|
||||
|
||||
int
|
||||
bi_tossold(client, a, b)
|
||||
const void *client;
|
||||
const void *a;
|
||||
const void *b;
|
||||
bi_tossold(const void *client, const void *a, const void *b)
|
||||
{
|
||||
const struct tossstruct *t;
|
||||
|
||||
t = (struct tossstruct *)client;
|
||||
|
||||
return (((BLOCK_INFO *)a)->bi_daddr == LFS_UNUSED_DADDR ||
|
||||
datosn(t->lfs, ((BLOCK_INFO *)a)->bi_daddr) != t->seg);
|
||||
dtosn(t->lfs, ((BLOCK_INFO *)a)->bi_daddr) != t->seg);
|
||||
}
|
||||
|
||||
void
|
||||
sig_report(sig)
|
||||
int sig;
|
||||
sig_report(int sig)
|
||||
{
|
||||
double avg = 0.0;
|
||||
|
||||
@ -958,8 +932,7 @@ sig_report(sig)
|
||||
}
|
||||
|
||||
void
|
||||
just_exit(sig)
|
||||
int sig;
|
||||
just_exit(int sig)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: lfs_cleanerd.8,v 1.8 2000/11/08 19:45:08 hubertf Exp $
|
||||
.\" $NetBSD: lfs_cleanerd.8,v 1.9 2001/07/13 20:30:22 perseant Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
@ -113,11 +113,10 @@ not usually necessary to set
|
||||
to a low value.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr lfs_bmapv 2 ,
|
||||
.Xr lfs_markv 2 ,
|
||||
.Xr lfs_segwait 2 ,
|
||||
.Xr mount_lfs 8 ,
|
||||
.Xr newfs_lfs 8
|
||||
.Xr mount_lfs 8
|
||||
.Xr lfs_bmapv 2
|
||||
.Xr lfs_markv 2
|
||||
.Xr lfs_segwait 2
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: library.c,v 1.21 2001/02/04 22:12:47 christos Exp $ */
|
||||
/* $NetBSD: library.c,v 1.22 2001/07/13 20:30:22 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.21 2001/02/04 22:12:47 christos Exp $");
|
||||
__RCSID("$NetBSD: library.c,v 1.22 2001/07/13 20:30:22 perseant Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -62,19 +62,19 @@ __RCSID("$NetBSD: library.c,v 1.21 2001/02/04 22:12:47 christos Exp $");
|
||||
|
||||
#include "clean.h"
|
||||
|
||||
void add_blocks __P((FS_INFO *, BLOCK_INFO *, int *, SEGSUM *, caddr_t,
|
||||
daddr_t, daddr_t));
|
||||
void add_inodes __P((FS_INFO *, BLOCK_INFO *, int *, SEGSUM *, caddr_t,
|
||||
daddr_t));
|
||||
int bi_compare __P((const void *, const void *));
|
||||
int bi_toss __P((const void *, const void *, const void *));
|
||||
void get_ifile __P((FS_INFO *, int));
|
||||
int get_superblock __P((FS_INFO *, struct lfs *));
|
||||
int pseg_valid __P((FS_INFO *, SEGSUM *, daddr_t));
|
||||
int pseg_size __P((daddr_t, FS_INFO *, SEGSUM *));
|
||||
void add_blocks(FS_INFO *, BLOCK_INFO *, int *, SEGSUM *, caddr_t,
|
||||
daddr_t, daddr_t);
|
||||
void add_inodes(FS_INFO *, BLOCK_INFO *, int *, SEGSUM *, caddr_t,
|
||||
daddr_t);
|
||||
int bi_compare(const void *, const void *);
|
||||
int bi_toss(const void *, const void *, const void *);
|
||||
void get_ifile(FS_INFO *, int);
|
||||
int get_superblock(FS_INFO *, struct lfs *);
|
||||
int pseg_valid(FS_INFO *, SEGSUM *, daddr_t);
|
||||
int pseg_size(daddr_t, FS_INFO *, SEGSUM *);
|
||||
|
||||
extern int debug;
|
||||
extern u_long cksum __P((void *, size_t)); /* XXX */
|
||||
extern u_long cksum(void *, size_t); /* XXX */
|
||||
|
||||
static int ifile_fd;
|
||||
static int dev_fd;
|
||||
@ -86,10 +86,7 @@ static int dev_fd;
|
||||
* a non-zero value is returned.
|
||||
*/
|
||||
int
|
||||
fs_getmntinfo(buf, name, type)
|
||||
struct statfs **buf;
|
||||
char *name;
|
||||
const char *type;
|
||||
fs_getmntinfo(struct statfs **buf, char *name, const char *type)
|
||||
{
|
||||
/* allocate space for the filesystem info */
|
||||
*buf = (struct statfs *)malloc(sizeof(struct statfs));
|
||||
@ -123,9 +120,7 @@ fs_getmntinfo(buf, name, type)
|
||||
* Returns an pointer to an FS_INFO structure, NULL on error.
|
||||
*/
|
||||
FS_INFO *
|
||||
get_fs_info (lstatfsp, use_mmap)
|
||||
struct statfs *lstatfsp; /* IN: pointer to statfs struct */
|
||||
int use_mmap; /* IN: mmap or read */
|
||||
get_fs_info (struct statfs *lstatfsp, int use_mmap)
|
||||
{
|
||||
FS_INFO *fsp;
|
||||
|
||||
@ -139,8 +134,6 @@ get_fs_info (lstatfsp, use_mmap)
|
||||
syslog(LOG_ERR, "Exiting: get_fs_info: get_superblock failed: %m");
|
||||
exit(1);
|
||||
}
|
||||
fsp->fi_daddr_shift =
|
||||
fsp->fi_lfs.lfs_bshift - fsp->fi_lfs.lfs_fsbtodb;
|
||||
get_ifile (fsp, use_mmap);
|
||||
return (fsp);
|
||||
}
|
||||
@ -151,9 +144,7 @@ get_fs_info (lstatfsp, use_mmap)
|
||||
* refresh the file system information (statfs) info.
|
||||
*/
|
||||
void
|
||||
reread_fs_info(fsp, use_mmap)
|
||||
FS_INFO *fsp; /* IN: prointer fs_infos to reread */
|
||||
int use_mmap;
|
||||
reread_fs_info(FS_INFO *fsp, int use_mmap)
|
||||
{
|
||||
if (ifile_fd <= 0) {
|
||||
if (fstatfs(ifile_fd, fsp->fi_statfsp)) {
|
||||
@ -171,12 +162,11 @@ reread_fs_info(fsp, use_mmap)
|
||||
* Gets the superblock from disk (possibly in face of errors)
|
||||
*/
|
||||
int
|
||||
get_superblock (fsp, sbp)
|
||||
FS_INFO *fsp; /* local file system info structure */
|
||||
struct lfs *sbp;
|
||||
get_superblock (FS_INFO *fsp, struct lfs *sbp)
|
||||
{
|
||||
char mntfromname[MNAMELEN+1];
|
||||
char buf[LFS_SBPAD];
|
||||
static off_t sboff = LFS_LABELPAD;
|
||||
|
||||
strcpy(mntfromname, "/dev/r");
|
||||
strcat(mntfromname, fsp->fi_statfsp->f_mntfromname+5);
|
||||
@ -189,10 +179,26 @@ get_superblock (fsp, sbp)
|
||||
} else
|
||||
lseek(dev_fd, 0, SEEK_SET);
|
||||
|
||||
get(dev_fd, LFS_LABELPAD, buf, LFS_SBPAD);
|
||||
memcpy(&(sbp->lfs_dlfs), buf, sizeof(struct dlfs));
|
||||
do {
|
||||
get(dev_fd, sboff, buf, LFS_SBPAD);
|
||||
memcpy(&(sbp->lfs_dlfs), buf, sizeof(struct dlfs));
|
||||
if (sboff == LFS_LABELPAD && fsbtob(sbp, 1) > LFS_LABELPAD)
|
||||
sboff = fsbtob(sbp, (off_t)sbp->lfs_sboffs[0]);
|
||||
else
|
||||
break;
|
||||
} while (1);
|
||||
|
||||
/* close (fid); */
|
||||
|
||||
/* Compatibility */
|
||||
if (sbp->lfs_version < 2) {
|
||||
sbp->lfs_sumsize = LFS_V1_SUMMARY_SIZE;
|
||||
sbp->lfs_ibsize = sbp->lfs_bsize;
|
||||
sbp->lfs_start = sbp->lfs_sboffs[0];
|
||||
sbp->lfs_tstamp = sbp->lfs_otstamp;
|
||||
sbp->lfs_fsbtodb = 0;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -201,10 +207,7 @@ get_superblock (fsp, sbp)
|
||||
* fatal error on failure.
|
||||
*/
|
||||
void
|
||||
get_ifile (fsp, use_mmap)
|
||||
FS_INFO *fsp;
|
||||
int use_mmap;
|
||||
|
||||
get_ifile (FS_INFO *fsp, int use_mmap)
|
||||
{
|
||||
struct stat file_stat;
|
||||
struct statfs statfsbuf;
|
||||
@ -306,19 +309,21 @@ redo_read:
|
||||
* Return the size of the partial segment, in bytes.
|
||||
*/
|
||||
int
|
||||
pseg_size(pseg_addr, fsp, sp)
|
||||
daddr_t pseg_addr; /* base address of the segsum */
|
||||
FS_INFO *fsp; /* Filesystem info */
|
||||
SEGSUM *sp; /* the segsum */
|
||||
pseg_size(daddr_t pseg_addr, FS_INFO *fsp, SEGSUM *sp)
|
||||
{
|
||||
int i, ssize = 0;
|
||||
struct lfs *lfsp;
|
||||
FINFO *fp;
|
||||
|
||||
lfsp = &fsp->fi_lfs;
|
||||
ssize = LFS_SUMMARY_SIZE
|
||||
+ howmany(sp->ss_ninos, INOPB(lfsp)) * lfsp->lfs_bsize;
|
||||
for (fp = (FINFO *)(sp + 1), i = 0; i < sp->ss_nfinfo; ++i) {
|
||||
ssize = lfsp->lfs_sumsize
|
||||
+ howmany(sp->ss_ninos, INOPB(lfsp)) * lfsp->lfs_ibsize;
|
||||
|
||||
if (lfsp->lfs_version == 1)
|
||||
fp = (FINFO *)(((char *)sp) + sizeof(SEGSUM_V1));
|
||||
else
|
||||
fp = (FINFO *)(sp + 1);
|
||||
for (i = 0; i < sp->ss_nfinfo; ++i) {
|
||||
ssize += (fp->fi_nblocks-1) * lfsp->lfs_bsize
|
||||
+ fp->fi_lastlength;
|
||||
fp = (FINFO *)(&fp->fi_blocks[fp->fi_nblocks]);
|
||||
@ -335,12 +340,7 @@ pseg_size(pseg_addr, fsp, sp)
|
||||
* pair will be listed at most once.
|
||||
*/
|
||||
int
|
||||
lfs_segmapv(fsp, seg, seg_buf, blocks, bcount)
|
||||
FS_INFO *fsp; /* pointer to local file system information */
|
||||
int seg; /* the segment number */
|
||||
caddr_t seg_buf; /* the buffer containing the segment's data */
|
||||
BLOCK_INFO **blocks; /* OUT: array of block_info for live blocks */
|
||||
int *bcount; /* OUT: number of active blocks in segment */
|
||||
lfs_segmapv(FS_INFO *fsp, int seg, caddr_t seg_buf, BLOCK_INFO **blocks, int *bcount)
|
||||
{
|
||||
BLOCK_INFO *bip, *_bip;
|
||||
SEGSUM *sp;
|
||||
@ -360,8 +360,9 @@ lfs_segmapv(fsp, seg, seg_buf, blocks, bcount)
|
||||
|
||||
sup = SEGUSE_ENTRY(lfsp, fsp->fi_segusep, seg);
|
||||
s = seg_buf + (sup->su_flags & SEGUSE_SUPERBLOCK ? LFS_SBPAD : 0);
|
||||
seg_addr = sntoda(lfsp, seg);
|
||||
pseg_addr = seg_addr + (sup->su_flags & SEGUSE_SUPERBLOCK ? btodb(LFS_SBPAD) : 0);
|
||||
seg_addr = sntod(lfsp, seg);
|
||||
pseg_addr = seg_addr + (sup->su_flags & SEGUSE_SUPERBLOCK ?
|
||||
btofsb(lfsp, LFS_SBPAD) : 0);
|
||||
|
||||
if(debug > 1)
|
||||
syslog(LOG_DEBUG, "\tsegment buffer at: %p\tseg_addr 0x%x", s, seg_addr);
|
||||
@ -380,14 +381,19 @@ lfs_segmapv(fsp, seg, seg_buf, blocks, bcount)
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
/* Verify size of summary block */
|
||||
sumsize = sizeof(SEGSUM) +
|
||||
sumsize = (lfsp->lfs_version == 1 ? sizeof(SEGSUM_V1) :
|
||||
sizeof(SEGSUM)) +
|
||||
(sp->ss_ninos + INOPB(lfsp) - 1) / INOPB(lfsp);
|
||||
for (i = 0, fip = (FINFO *)(sp + 1); i < sp->ss_nfinfo; ++i) {
|
||||
if (lfsp->lfs_version == 1)
|
||||
fip = (FINFO *)(((char *)sp) + sizeof(SEGSUM_V1));
|
||||
else
|
||||
fip = (FINFO *)(sp + 1);
|
||||
for (i = 0; i < sp->ss_nfinfo; ++i) {
|
||||
sumsize += sizeof(FINFO) +
|
||||
(fip->fi_nblocks - 1) * sizeof(daddr_t);
|
||||
fip = (FINFO *)(&fip->fi_blocks[fip->fi_nblocks]);
|
||||
}
|
||||
if (sumsize > LFS_SUMMARY_SIZE) {
|
||||
if (sumsize > lfsp->lfs_sumsize) {
|
||||
syslog(LOG_ERR,
|
||||
"Exiting: Segment %d summary block too big: %d\n",
|
||||
seg, sumsize);
|
||||
@ -406,7 +412,7 @@ lfs_segmapv(fsp, seg, seg_buf, blocks, bcount)
|
||||
|
||||
ssize = pseg_size(pseg_addr, fsp, sp);
|
||||
s += ssize;
|
||||
pseg_addr += btodb(ssize); /* XXX was bytetoda(fsp,ssize) */
|
||||
pseg_addr += btofsb(lfsp, ssize);
|
||||
}
|
||||
if(nsegs < sup->su_nsums) {
|
||||
syslog(LOG_WARNING,"only %d segment summaries in seg %d (expected %d)",
|
||||
@ -439,34 +445,34 @@ lfs_segmapv(fsp, seg, seg_buf, blocks, bcount)
|
||||
* blocks or inodes from files with new version numbers.
|
||||
*/
|
||||
void
|
||||
add_blocks (fsp, bip, countp, sp, seg_buf, segaddr, psegaddr)
|
||||
FS_INFO *fsp; /* pointer to super block */
|
||||
BLOCK_INFO *bip; /* Block info array */
|
||||
int *countp; /* IN/OUT: number of blocks in array */
|
||||
SEGSUM *sp; /* segment summmary pointer */
|
||||
caddr_t seg_buf; /* buffer containing segment */
|
||||
daddr_t segaddr; /* address of this segment */
|
||||
daddr_t psegaddr; /* address of this partial segment */
|
||||
add_blocks (FS_INFO *fsp, BLOCK_INFO *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 db_per_block, i, j;
|
||||
int db_frag;
|
||||
int fsb_per_block, i, j;
|
||||
int fsb_frag;
|
||||
u_long page_size;
|
||||
struct lfs *lfsp;
|
||||
|
||||
if(debug > 1)
|
||||
syslog(LOG_DEBUG, "FILE INFOS");
|
||||
|
||||
db_per_block = fsbtodb(&fsp->fi_lfs, 1);
|
||||
lfsp = &fsp->fi_lfs;
|
||||
fsb_per_block = fragstofsb(lfsp, lfsp->lfs_frag);
|
||||
page_size = fsp->fi_lfs.lfs_bsize;
|
||||
bp = seg_buf + datobyte(fsp, psegaddr - segaddr) + LFS_SUMMARY_SIZE;
|
||||
bp = seg_buf + fsbtob(lfsp, psegaddr - segaddr) + lfsp->lfs_sumsize;
|
||||
bip += *countp;
|
||||
psegaddr += bytetoda(fsp, LFS_SUMMARY_SIZE);
|
||||
iaddrp = (daddr_t *)((caddr_t)sp + LFS_SUMMARY_SIZE);
|
||||
psegaddr += btofsb(lfsp, lfsp->lfs_sumsize);
|
||||
iaddrp = (daddr_t *)((caddr_t)sp + lfsp->lfs_sumsize);
|
||||
--iaddrp;
|
||||
for (fip = (FINFO *)(sp + 1), i = 0; i < sp->ss_nfinfo;
|
||||
if (lfsp->lfs_version == 1)
|
||||
fip = (FINFO *)(((char *)sp) + sizeof(SEGSUM_V1));
|
||||
else
|
||||
fip = (FINFO *)(sp + 1);
|
||||
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);
|
||||
@ -477,14 +483,17 @@ add_blocks (fsp, bip, countp, sp, seg_buf, segaddr, psegaddr)
|
||||
for (j = 0; j < fip->fi_nblocks; j++, dp++) {
|
||||
/* Skip over intervening inode blocks */
|
||||
while (psegaddr == *iaddrp) {
|
||||
psegaddr += db_per_block;
|
||||
psegaddr += fsb_per_block;
|
||||
bp += page_size;
|
||||
--iaddrp;
|
||||
}
|
||||
bip->bi_inode = fip->fi_ino;
|
||||
bip->bi_lbn = *dp;
|
||||
bip->bi_daddr = psegaddr;
|
||||
bip->bi_segcreate = (time_t)(sp->ss_create);
|
||||
if (lfsp->lfs_version == 1)
|
||||
bip->bi_segcreate = (time_t)(sp->ss_ident);
|
||||
else
|
||||
bip->bi_segcreate = (time_t)(sp->ss_create);
|
||||
bip->bi_bp = bp;
|
||||
bip->bi_version = ifp->if_version;
|
||||
|
||||
@ -492,21 +501,21 @@ add_blocks (fsp, bip, countp, sp, seg_buf, segaddr, psegaddr)
|
||||
|| fip->fi_lastlength == page_size)
|
||||
{
|
||||
bip->bi_size = page_size;
|
||||
psegaddr += db_per_block;
|
||||
psegaddr += fsb_per_block;
|
||||
bp += page_size;
|
||||
} else {
|
||||
db_frag = fragstodb(&(fsp->fi_lfs),
|
||||
fsb_frag = fragstofsb(&(fsp->fi_lfs),
|
||||
numfrags(&(fsp->fi_lfs),
|
||||
fip->fi_lastlength));
|
||||
|
||||
if(debug > 1) {
|
||||
syslog(LOG_DEBUG, "lastlength, frags: %d, %d",
|
||||
fip->fi_lastlength, db_frag);
|
||||
fip->fi_lastlength, fsb_frag);
|
||||
}
|
||||
|
||||
bip->bi_size = fip->fi_lastlength;
|
||||
bp += fip->fi_lastlength;
|
||||
psegaddr += db_frag;
|
||||
psegaddr += fsb_frag;
|
||||
}
|
||||
++bip;
|
||||
++(*countp);
|
||||
@ -520,13 +529,8 @@ add_blocks (fsp, bip, countp, sp, seg_buf, segaddr, psegaddr)
|
||||
* actually added.
|
||||
*/
|
||||
void
|
||||
add_inodes (fsp, bip, countp, sp, seg_buf, seg_addr)
|
||||
FS_INFO *fsp; /* pointer to super block */
|
||||
BLOCK_INFO *bip; /* block info array */
|
||||
int *countp; /* pointer to current number of inodes */
|
||||
SEGSUM *sp; /* segsum pointer */
|
||||
caddr_t seg_buf; /* the buffer containing the segment's data */
|
||||
daddr_t seg_addr; /* disk address of seg_buf */
|
||||
add_inodes (FS_INFO *fsp, BLOCK_INFO *bip, int *countp, SEGSUM *sp,
|
||||
caddr_t seg_buf, daddr_t seg_addr)
|
||||
{
|
||||
struct dinode *di = NULL; /* XXX gcc */
|
||||
struct lfs *lfsp;
|
||||
@ -545,12 +549,12 @@ add_inodes (fsp, bip, countp, sp, seg_buf, seg_addr)
|
||||
if(debug > 1)
|
||||
syslog(LOG_DEBUG, "INODES:");
|
||||
|
||||
daddrp = (daddr_t *)((caddr_t)sp + LFS_SUMMARY_SIZE);
|
||||
daddrp = (daddr_t *)((caddr_t)sp + lfsp->lfs_sumsize);
|
||||
for (i = 0; i < sp->ss_ninos; ++i) {
|
||||
if (i % INOPB(lfsp) == 0) {
|
||||
--daddrp;
|
||||
di = (struct dinode *)(seg_buf +
|
||||
((*daddrp - seg_addr) << fsp->fi_daddr_shift));
|
||||
di = (struct dinode *)(seg_buf + fsbtob(lfsp,
|
||||
*daddrp - seg_addr));
|
||||
} else
|
||||
++di;
|
||||
|
||||
@ -559,7 +563,10 @@ add_inodes (fsp, bip, countp, sp, seg_buf, seg_addr)
|
||||
bp->bi_inode = inum;
|
||||
bp->bi_daddr = *daddrp;
|
||||
bp->bi_bp = di;
|
||||
bp->bi_segcreate = sp->ss_create;
|
||||
if (lfsp->lfs_version == 1)
|
||||
bp->bi_segcreate = sp->ss_ident;
|
||||
else
|
||||
bp->bi_segcreate = sp->ss_create;
|
||||
bp->bi_size = i; /* XXX KS - kludge */
|
||||
|
||||
if (inum == LFS_IFILE_INUM) {
|
||||
@ -586,10 +593,7 @@ add_inodes (fsp, bip, countp, sp, seg_buf, seg_addr)
|
||||
* the partial as well as whether or not the checksum is valid.
|
||||
*/
|
||||
int
|
||||
pseg_valid (fsp, ssp, addr)
|
||||
FS_INFO *fsp; /* pointer to file system info */
|
||||
SEGSUM *ssp; /* pointer to segment summary block */
|
||||
daddr_t addr; /* address of the summary block on disk */
|
||||
pseg_valid (FS_INFO *fsp, SEGSUM *ssp, daddr_t addr)
|
||||
{
|
||||
int nblocks;
|
||||
#if 0
|
||||
@ -610,7 +614,7 @@ pseg_valid (fsp, ssp, addr)
|
||||
#if 0
|
||||
/* check data/inode block(s) checksum too */
|
||||
datap = (u_long *)malloc(nblocks * sizeof(u_long));
|
||||
p = (caddr_t)ssp + LFS_SUMMARY_SIZE;
|
||||
p = (caddr_t)ssp + lfsp->lfs_sumsize;
|
||||
for (i = 0; i < nblocks; ++i) {
|
||||
datap[i] = *((u_long *)p);
|
||||
p += fsp->fi_lfs.lfs_bsize;
|
||||
@ -630,11 +634,7 @@ pseg_valid (fsp, ssp, addr)
|
||||
* read a segment into a memory buffer
|
||||
*/
|
||||
int
|
||||
mmap_segment (fsp, segment, segbuf, use_mmap)
|
||||
FS_INFO *fsp; /* file system information */
|
||||
int segment; /* segment number */
|
||||
caddr_t *segbuf; /* pointer to buffer area */
|
||||
int use_mmap; /* mmap instead of read */
|
||||
mmap_segment (FS_INFO *fsp, int segment, caddr_t *segbuf, int use_mmap)
|
||||
{
|
||||
struct lfs *lfsp;
|
||||
daddr_t seg_daddr; /* base disk address of segment */
|
||||
@ -645,8 +645,8 @@ mmap_segment (fsp, segment, segbuf, use_mmap)
|
||||
lfsp = &fsp->fi_lfs;
|
||||
|
||||
/* get the disk address of the beginning of the segment */
|
||||
seg_daddr = sntoda(lfsp, segment);
|
||||
seg_byte = datobyte(fsp, seg_daddr);
|
||||
seg_daddr = sntod(lfsp, segment);
|
||||
seg_byte = fsbtob(lfsp, (off_t)seg_daddr);
|
||||
ssize = seg_size(lfsp);
|
||||
|
||||
strcpy(mntfromname, "/dev/r");
|
||||
@ -697,10 +697,7 @@ mmap_segment (fsp, segment, segbuf, use_mmap)
|
||||
}
|
||||
|
||||
void
|
||||
munmap_segment (fsp, seg_buf, use_mmap)
|
||||
FS_INFO *fsp; /* file system information */
|
||||
caddr_t seg_buf; /* pointer to buffer area */
|
||||
int use_mmap; /* mmap instead of read/write */
|
||||
munmap_segment (FS_INFO *fsp, caddr_t seg_buf, int use_mmap)
|
||||
{
|
||||
if (use_mmap)
|
||||
munmap (seg_buf, seg_size(&fsp->fi_lfs));
|
||||
@ -712,10 +709,7 @@ munmap_segment (fsp, seg_buf, use_mmap)
|
||||
* USEFUL DEBUGGING TOOLS:
|
||||
*/
|
||||
void
|
||||
print_SEGSUM (lfsp, p, addr)
|
||||
struct lfs *lfsp;
|
||||
SEGSUM *p;
|
||||
daddr_t addr;
|
||||
print_SEGSUM (struct lfs *lfsp, SEGSUM *p, daddr_t addr)
|
||||
{
|
||||
if (p)
|
||||
(void) dump_summary(lfsp, p, DUMP_ALL, NULL, addr);
|
||||
@ -724,9 +718,7 @@ print_SEGSUM (lfsp, p, addr)
|
||||
}
|
||||
|
||||
int
|
||||
bi_compare(a, b)
|
||||
const void *a;
|
||||
const void *b;
|
||||
bi_compare(const void *a, const void *b)
|
||||
{
|
||||
const BLOCK_INFO *ba, *bb;
|
||||
int diff;
|
||||
@ -757,10 +749,7 @@ bi_compare(a, b)
|
||||
}
|
||||
|
||||
int
|
||||
bi_toss(dummy, a, b)
|
||||
const void *dummy;
|
||||
const void *a;
|
||||
const void *b;
|
||||
bi_toss(const void *dummy, const void *a, const void *b)
|
||||
{
|
||||
const BLOCK_INFO *ba, *bb;
|
||||
|
||||
@ -771,12 +760,7 @@ bi_toss(dummy, a, b)
|
||||
}
|
||||
|
||||
void
|
||||
toss(p, nump, size, dotoss, client)
|
||||
void *p;
|
||||
int *nump;
|
||||
size_t size;
|
||||
int (*dotoss) __P((const void *, const void *, const void *));
|
||||
void *client;
|
||||
toss(void *p, int *nump, size_t size, int (*dotoss)(const void *, const void *, const void *), void *client)
|
||||
{
|
||||
int i;
|
||||
char *p0, *p1;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: misc.c,v 1.6 1999/03/14 11:39:28 drochner Exp $ */
|
||||
/* $NetBSD: misc.c,v 1.7 2001/07/13 20:30:22 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -38,7 +38,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "from: @(#)misc.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: misc.c,v 1.6 1999/03/14 11:39:28 drochner Exp $");
|
||||
__RCSID("$NetBSD: misc.c,v 1.7 2001/07/13 20:30:22 perseant Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -60,11 +60,7 @@ __RCSID("$NetBSD: misc.c,v 1.6 1999/03/14 11:39:28 drochner Exp $");
|
||||
extern char *special;
|
||||
|
||||
void
|
||||
get(fd, off, p, len)
|
||||
int fd;
|
||||
off_t off;
|
||||
void *p;
|
||||
size_t len;
|
||||
get(int fd, off_t off, void *p, size_t len)
|
||||
{
|
||||
int rbytes;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: print.c,v 1.9 2001/01/04 17:29:04 lukem Exp $ */
|
||||
/* $NetBSD: print.c,v 1.10 2001/07/13 20:30:22 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -38,7 +38,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "from: @(#)print.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: print.c,v 1.9 2001/01/04 17:29:04 lukem Exp $");
|
||||
__RCSID("$NetBSD: print.c,v 1.10 2001/07/13 20:30:22 perseant Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -58,7 +58,7 @@ __RCSID("$NetBSD: print.c,v 1.9 2001/01/04 17:29:04 lukem Exp $");
|
||||
#include "clean.h"
|
||||
|
||||
extern int debug;
|
||||
extern u_long cksum __P((void *, size_t)); /* XXX */
|
||||
extern u_long cksum(void *, size_t); /* XXX */
|
||||
|
||||
/*
|
||||
* Print out a summary block; return number of blocks in segment; 0
|
||||
@ -67,12 +67,7 @@ extern u_long cksum __P((void *, size_t)); /* XXX */
|
||||
*/
|
||||
|
||||
int
|
||||
dump_summary(lfsp, sp, flags, iaddrp, addr)
|
||||
struct lfs *lfsp;
|
||||
SEGSUM *sp;
|
||||
u_long flags;
|
||||
daddr_t **iaddrp;
|
||||
daddr_t addr;
|
||||
dump_summary(struct lfs *lfsp, SEGSUM *sp, u_long flags, daddr_t **iaddrp, daddr_t addr)
|
||||
{
|
||||
int i, j, blk, numblocks, accino=0;
|
||||
daddr_t *dp, ddp, *idp;
|
||||
@ -87,7 +82,7 @@ dump_summary(lfsp, sp, flags, iaddrp, addr)
|
||||
return(-1);
|
||||
|
||||
if (sp->ss_sumsum != (ck = cksum(&sp->ss_datasum,
|
||||
LFS_SUMMARY_SIZE - sizeof(sp->ss_sumsum)))) {
|
||||
lfsp->lfs_sumsize - sizeof(sp->ss_sumsum)))) {
|
||||
free(datap);
|
||||
return(-1);
|
||||
}
|
||||
@ -99,7 +94,9 @@ dump_summary(lfsp, sp, flags, iaddrp, addr)
|
||||
"ninos ", sp->ss_ninos,
|
||||
"sumsum ", sp->ss_sumsum,
|
||||
"datasum ", sp->ss_datasum );
|
||||
syslog(LOG_DEBUG, "\tcreate %s", ctime((time_t *)&sp->ss_create));
|
||||
syslog(LOG_DEBUG, "\tcreate %s", ctime(
|
||||
(lfsp->lfs_version == 1 ? (time_t *)&sp->ss_ident :
|
||||
(time_t *)&sp->ss_create)));
|
||||
}
|
||||
|
||||
numblocks = (sp->ss_ninos + INOPB(lfsp) - 1) / INOPB(lfsp);
|
||||
@ -108,7 +105,7 @@ dump_summary(lfsp, sp, flags, iaddrp, addr)
|
||||
if (flags & DUMP_INODE_ADDRS)
|
||||
syslog(LOG_DEBUG, " Inode addresses:");
|
||||
|
||||
idp = dp = (daddr_t *)((caddr_t)sp + LFS_SUMMARY_SIZE);
|
||||
idp = dp = (daddr_t *)((caddr_t)sp + lfsp->lfs_sumsize);
|
||||
--idp;
|
||||
for (--dp, i = 0; i < howmany(sp->ss_ninos,INOPB(lfsp)); --dp) {
|
||||
if (flags & DUMP_INODE_ADDRS)
|
||||
@ -119,26 +116,30 @@ dump_summary(lfsp, sp, flags, iaddrp, addr)
|
||||
*iaddrp = dp;
|
||||
}
|
||||
|
||||
ddp = addr + LFS_SUMMARY_SIZE/DEV_BSIZE;
|
||||
for (fp = (FINFO *)(sp + 1), i = 0; i < sp->ss_nfinfo; ++i) {
|
||||
ddp = addr + btofsb(lfsp, lfsp->lfs_sumsize);
|
||||
if (lfsp->lfs_version == 1)
|
||||
fp = (FINFO *)(((char *)sp) + sizeof(SEGSUM_V1));
|
||||
else
|
||||
fp = (FINFO *)(sp + 1);
|
||||
for (i = 0; i < sp->ss_nfinfo; ++i) {
|
||||
/* Add any intervening Inode blocks to our checksum array */
|
||||
/* printf("finfo %d: ddp=%lx, *idp=%lx\n",i,ddp,*idp); */
|
||||
while(ddp == *idp) {
|
||||
/* printf(" [ino %lx]",ddp); */
|
||||
datap[blk++] = *(u_long*)((caddr_t)sp + (ddp-addr)*DEV_BSIZE);
|
||||
datap[blk++] = *(u_long*)((caddr_t)sp + fsbtob(lfsp, ddp-addr));
|
||||
--idp;
|
||||
ddp += lfsp->lfs_bsize/DEV_BSIZE;
|
||||
ddp += btofsb(lfsp, lfsp->lfs_ibsize);
|
||||
accino++;
|
||||
}
|
||||
for(j=0;j<fp->fi_nblocks;j++) {
|
||||
if(j==fp->fi_nblocks-1) {
|
||||
size = fp->fi_lastlength/DEV_BSIZE;
|
||||
size = btofsb(lfsp, fp->fi_lastlength);
|
||||
/* printf(" %lx:%d",ddp,size); */
|
||||
} else {
|
||||
size = lfsp->lfs_bsize/DEV_BSIZE;
|
||||
size = btofsb(lfsp, lfsp->lfs_bsize);
|
||||
/* printf(" %lx/%d",ddp,size); */
|
||||
}
|
||||
datap[blk++] = *(u_long*)((caddr_t)sp + (ddp-addr)*DEV_BSIZE);
|
||||
datap[blk++] = *(u_long*)((caddr_t)sp + fsbtob(lfsp, ddp-addr));
|
||||
ddp += size;
|
||||
}
|
||||
numblocks += fp->fi_nblocks;
|
||||
@ -160,7 +161,7 @@ dump_summary(lfsp, sp, flags, iaddrp, addr)
|
||||
while(*idp >= ddp && accino < howmany(sp->ss_ninos,INOPB(lfsp))) {
|
||||
ddp = *idp;
|
||||
/* printf(" [ino %lx]",ddp); */
|
||||
datap[blk++] = *(u_long*)((caddr_t)sp + (ddp-addr)*DEV_BSIZE);
|
||||
datap[blk++] = *(u_long*)((caddr_t)sp + fsbtob(lfsp, ddp-addr));
|
||||
--idp;
|
||||
accino++;
|
||||
}
|
||||
@ -185,8 +186,7 @@ dump_summary(lfsp, sp, flags, iaddrp, addr)
|
||||
}
|
||||
|
||||
void
|
||||
dump_cleaner_info(ipage)
|
||||
void *ipage;
|
||||
dump_cleaner_info(void *ipage)
|
||||
{
|
||||
CLEANERINFO *cip;
|
||||
|
||||
@ -199,8 +199,7 @@ dump_cleaner_info(ipage)
|
||||
}
|
||||
|
||||
void
|
||||
dump_super(lfsp)
|
||||
struct lfs *lfsp;
|
||||
dump_super(struct lfs *lfsp)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -278,6 +277,6 @@ dump_super(lfsp)
|
||||
syslog(LOG_DEBUG, "%s%d\t%s%d\t%s0x%X\t%s%d\n",
|
||||
"nactive ", lfsp->lfs_nactive,
|
||||
"fmod ", lfsp->lfs_fmod,
|
||||
"clean ", lfsp->lfs_clean,
|
||||
"pflags ", lfsp->lfs_pflags,
|
||||
"ronly ", lfsp->lfs_ronly);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.1 1999/09/29 04:57:49 perseant Exp $
|
||||
# $NetBSD: Makefile,v 1.2 2001/07/13 20:30:18 perseant Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/5/93
|
||||
|
||||
# lfs_inode.c LFS filestore-specific routines
|
||||
@ -9,6 +9,7 @@
|
||||
PROG= dump_lfs
|
||||
LINKS= ${BINDIR}/dump_lfs ${BINDIR}/rdump_lfs
|
||||
CPPFLAGS+=-DRDUMP -I${.CURDIR} -I${.CURDIR}/../dump
|
||||
CPPFLAGS+=-DDUMP_LFS
|
||||
# CPPFLAGS+= -DDEBUG -DTDEBUG -DFDEBUG -DWRITEDEBUG -DSTATS -DDIAGNOSTICS
|
||||
SRCS= itime.c main.c optr.c dumprmt.c rcache.c tape.c traverse.c unctime.c \
|
||||
ffs_bswap.c lfs_inode.c
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs_inode.c,v 1.2 1999/10/01 04:35:23 perseant Exp $ */
|
||||
/* $NetBSD: lfs_inode.c,v 1.3 2001/07/13 20:30:18 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993, 1994
|
||||
@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1991, 1993, 1994\n\
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/1/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: lfs_inode.c,v 1.2 1999/10/01 04:35:23 perseant Exp $");
|
||||
__RCSID("$NetBSD: lfs_inode.c,v 1.3 2001/07/13 20:30:18 perseant Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -82,19 +82,58 @@ struct lfs *sblock;
|
||||
int
|
||||
fs_read_sblock(char *sblock_buf)
|
||||
{
|
||||
char tbuf[LFS_SBPAD];
|
||||
int needswap = 0;
|
||||
off_t sboff = LFS_LABELPAD;
|
||||
|
||||
sblock = (struct lfs *)sblock_buf;
|
||||
rawread(LFS_LABELPAD, (char *) sblock, LFS_SBPAD);
|
||||
if (sblock->lfs_magic != LFS_MAGIC) {
|
||||
while(1) {
|
||||
rawread(sboff, (char *) sblock, LFS_SBPAD);
|
||||
if (sblock->lfs_magic != LFS_MAGIC) {
|
||||
#ifdef notyet
|
||||
if (sblock->lfs_magic == bswap32(LFS_MAGIC)) {
|
||||
lfs_sb_swap(sblock, sblock, 0);
|
||||
needswap = 1;
|
||||
} else
|
||||
if (sblock->lfs_magic == bswap32(LFS_MAGIC)) {
|
||||
lfs_sb_swap(sblock, sblock, 0);
|
||||
needswap = 1;
|
||||
} else
|
||||
#endif
|
||||
quit("bad sblock magic number\n");
|
||||
quit("bad sblock magic number\n");
|
||||
}
|
||||
if (fsbtob(sblock, sblock->lfs_sboffs[0]) != sboff) {
|
||||
sboff = fsbtob(sblock, sblock->lfs_sboffs[0]);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the secondary and take the older of the two
|
||||
*/
|
||||
rawread(fsbtob(sblock, sblock->lfs_sboffs[1]), tbuf, LFS_SBPAD);
|
||||
#ifdef notyet
|
||||
if (needswap)
|
||||
lfs_sb_swap(tbuf, tbuf, 0);
|
||||
#endif
|
||||
if (((struct lfs *)tbuf)->lfs_magic != LFS_MAGIC) {
|
||||
msg("Warning: secondary superblock at 0x%x bad magic\n",
|
||||
fsbtodb(sblock, sblock->lfs_sboffs[1]));
|
||||
} else {
|
||||
if (sblock->lfs_version > 1) {
|
||||
if (((struct lfs *)tbuf)->lfs_serial < sblock->lfs_serial) {
|
||||
memcpy(sblock, tbuf, LFS_SBPAD);
|
||||
sboff = fsbtob(sblock, sblock->lfs_sboffs[1]);
|
||||
}
|
||||
} else {
|
||||
if (((struct lfs *)tbuf)->lfs_otstamp < sblock->lfs_otstamp) {
|
||||
memcpy(sblock, tbuf, LFS_SBPAD);
|
||||
sboff = fsbtob(sblock, sblock->lfs_sboffs[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sboff != LFS_SBPAD) {
|
||||
msg("Using superblock at alternate location 0x%lx\n",
|
||||
(unsigned long)(btodb(sboff)));
|
||||
}
|
||||
|
||||
return needswap;
|
||||
}
|
||||
|
||||
@ -110,11 +149,15 @@ fs_parametrize(void)
|
||||
spcl.c_flags = iswap32(iswap32(spcl.c_flags) | DR_NEWINODEFMT);
|
||||
|
||||
ufsi.ufs_dsize = fsbtodb(sblock,sblock->lfs_size);
|
||||
if (sblock->lfs_version == 1)
|
||||
ufsi.ufs_dsize = sblock->lfs_size >> sblock->lfs_blktodb;
|
||||
ufsi.ufs_bsize = sblock->lfs_bsize;
|
||||
ufsi.ufs_bshift = sblock->lfs_bshift;
|
||||
ufsi.ufs_fsize = sblock->lfs_fsize;
|
||||
ufsi.ufs_frag = sblock->lfs_frag;
|
||||
ufsi.ufs_fsatoda = 0;
|
||||
ufsi.ufs_fsatoda = sblock->lfs_fsbtodb;
|
||||
if (sblock->lfs_version == 1)
|
||||
ufsi.ufs_fsatoda = 0;
|
||||
ufsi.ufs_nindir = sblock->lfs_nindir;
|
||||
ufsi.ufs_inopb = sblock->lfs_inopb;
|
||||
ufsi.ufs_maxsymlinklen = sblock->lfs_maxsymlinklen;
|
||||
@ -123,7 +166,7 @@ fs_parametrize(void)
|
||||
ufsi.ufs_fmask = ~(sblock->lfs_ffmask);
|
||||
ufsi.ufs_qfmask = sblock->lfs_ffmask;
|
||||
|
||||
dev_bsize = sblock->lfs_bsize >> sblock->lfs_fsbtodb;
|
||||
dev_bsize = sblock->lfs_bsize >> sblock->lfs_blktodb;
|
||||
|
||||
return &ufsi;
|
||||
}
|
||||
@ -154,7 +197,7 @@ lfs_bmap(struct lfs *fs, struct dinode *idinode, ufs_daddr_t lbn)
|
||||
int off=0;
|
||||
char bp[MAXBSIZE];
|
||||
|
||||
if(lbn > 0 && lbn > (idinode->di_size-1)/dev_bsize) {
|
||||
if(lbn > 0 && lbn > lblkno(fs, idinode->di_size)) {
|
||||
return UNASSIGNED;
|
||||
}
|
||||
/*
|
||||
@ -188,7 +231,7 @@ lfs_bmap(struct lfs *fs, struct dinode *idinode, ufs_daddr_t lbn)
|
||||
if(up == UNASSIGNED || up == LFS_UNUSED_DADDR)
|
||||
return UNASSIGNED;
|
||||
/* printf("lbn %d: parent is the triple\n", -lbn); */
|
||||
bread(up, bp, sblock->lfs_bsize);
|
||||
bread(fsbtodb(sblock, up), bp, sblock->lfs_bsize);
|
||||
return ((daddr_t *)bp)[off];
|
||||
} else /* residue == 0 */ {
|
||||
/* Single indirect. Two cases. */
|
||||
@ -220,7 +263,7 @@ lfs_bmap(struct lfs *fs, struct dinode *idinode, ufs_daddr_t lbn)
|
||||
up = lfs_bmap(fs,idinode,up);
|
||||
if(up == UNASSIGNED || up == LFS_UNUSED_DADDR)
|
||||
return UNASSIGNED;
|
||||
bread(up, bp, sblock->lfs_bsize);
|
||||
bread(fsbtodb(sblock, up), bp, sblock->lfs_bsize);
|
||||
return ((daddr_t *)bp)[off];
|
||||
}
|
||||
|
||||
@ -235,7 +278,8 @@ lfs_ientry(ino_t ino)
|
||||
lbn = ino/sblock->lfs_ifpb + sblock->lfs_cleansz + sblock->lfs_segtabsz;
|
||||
blkno = lfs_bmap(sblock,getino(sblock->lfs_ifile),lbn);
|
||||
if(blkno != ifblkno)
|
||||
bread(blkno, (char *)ifileblock, sblock->lfs_bsize);
|
||||
bread(fsbtodb(sblock, blkno), (char *)ifileblock,
|
||||
sblock->lfs_bsize);
|
||||
return ifileblock + (ino%sblock->lfs_ifpb);
|
||||
}
|
||||
|
||||
@ -266,7 +310,8 @@ getino(inum)
|
||||
/* Load the ifile inode if not already */
|
||||
if(ifile_dinode.di_u.inumber == 0) {
|
||||
blkno = sblock->lfs_idaddr;
|
||||
bread(blkno, (char *)inoblock, (int)sblock->lfs_bsize);
|
||||
bread(fsbtodb(sblock, blkno), (char *)inoblock,
|
||||
(int)sblock->lfs_bsize);
|
||||
dp = lfs_ifind(sblock, inum, inoblock);
|
||||
ifile_dinode = *dp; /* Structure copy */
|
||||
}
|
||||
@ -279,7 +324,8 @@ getino(inum)
|
||||
return &empty_dinode;
|
||||
|
||||
if(blkno != inoblkno) {
|
||||
bread(blkno, (char *)inoblock, (int)sblock->lfs_bsize);
|
||||
bread(fsbtodb(sblock, blkno), (char *)inoblock,
|
||||
(int)sblock->lfs_bsize);
|
||||
#ifdef notyet
|
||||
if (needswap)
|
||||
for (i = 0; i < MAXINOPB; i++)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dir.c,v 1.4 2000/06/14 18:43:57 perseant Exp $ */
|
||||
/* $NetBSD: dir.c,v 1.5 2001/07/13 20:30:18 perseant Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
@ -122,7 +122,7 @@ dirscan(struct inodesc * idesc)
|
||||
(idesc->id_filesize & (DIRBLKSIZ - 1)) != 0)
|
||||
idesc->id_filesize = roundup(idesc->id_filesize, DIRBLKSIZ);
|
||||
blksiz = idesc->id_numfrags * sblock.lfs_fsize;
|
||||
if (chkrange(idesc->id_blkno, idesc->id_numfrags)) {
|
||||
if (chkrange(idesc->id_blkno, fragstofsb(&sblock, idesc->id_numfrags))) {
|
||||
idesc->id_filesize -= blksiz;
|
||||
return (SKIP);
|
||||
}
|
||||
@ -574,9 +574,9 @@ expanddir(struct dinode * dp, char *name)
|
||||
dp->di_db[lastbn + 1] = dp->di_db[lastbn];
|
||||
dp->di_db[lastbn] = newblk;
|
||||
dp->di_size += sblock.lfs_bsize;
|
||||
dp->di_blocks += btodb(sblock.lfs_bsize);
|
||||
bp = getdirblk(dp->di_db[lastbn + 1],
|
||||
(long)dblksize(&sblock, dp, lastbn + 1));
|
||||
dp->di_blocks += btofsb(&sblock, sblock.lfs_bsize);
|
||||
bp = getdirblk(dp->di_db[lastbn + 1],
|
||||
(long)dblksize(&sblock, dp, lastbn + 1));
|
||||
if (bp->b_errs)
|
||||
goto bad;
|
||||
memcpy(firstblk, bp->b_un.b_buf, DIRBLKSIZ);
|
||||
@ -606,7 +606,7 @@ bad:
|
||||
dp->di_db[lastbn] = dp->di_db[lastbn + 1];
|
||||
dp->di_db[lastbn + 1] = 0;
|
||||
dp->di_size -= sblock.lfs_bsize;
|
||||
dp->di_blocks -= btodb(sblock.lfs_bsize);
|
||||
dp->di_blocks -= btofsb(&sblock, sblock.lfs_bsize);
|
||||
freeblk(newblk, sblock.lfs_frag);
|
||||
return (0);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: inode.c,v 1.10 2001/02/04 21:52:02 christos Exp $ */
|
||||
/* $NetBSD: inode.c,v 1.11 2001/07/13 20:30:18 perseant Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997, 1998
|
||||
@ -65,11 +65,21 @@ int lfs_maxino(void);
|
||||
struct dinode *
|
||||
lfs_difind(struct lfs * fs, ino_t ino, struct dinode * dip)
|
||||
{
|
||||
register int cnt;
|
||||
struct dinode *ldip, *fin;
|
||||
|
||||
for (cnt = 0; cnt < INOPB(fs); cnt++)
|
||||
if (dip[cnt].di_inumber == ino)
|
||||
return &(dip[cnt]);
|
||||
#ifdef LFS_IFILE_FRAG_ADDRESSING
|
||||
if (fs->lfs_version == 1)
|
||||
fin = dip + INOPB(fs);
|
||||
else
|
||||
fin = dip + INOPF(fs);
|
||||
#else
|
||||
fin = dip + INOPB(fs);
|
||||
#endif
|
||||
|
||||
for (ldip = dip; ldip < fin; ++ldip) {
|
||||
if (ldip->di_inumber == ino)
|
||||
return ldip;
|
||||
}
|
||||
/* printf("lfs_difind: dinode %u not found\n", ino); */
|
||||
return NULL;
|
||||
}
|
||||
@ -228,7 +238,7 @@ gidinode(void)
|
||||
struct ifile *
|
||||
lfs_ientry(ino_t ino, struct bufarea ** bpp)
|
||||
{
|
||||
struct ifile *ifp;
|
||||
IFILE *ifp;
|
||||
|
||||
*bpp = getfileblk(&sblock, lfs_ginode(LFS_IFILE_INUM),
|
||||
ino / sblock.lfs_ifpb + sblock.lfs_cleansz +
|
||||
@ -237,8 +247,14 @@ lfs_ientry(ino_t ino, struct bufarea ** bpp)
|
||||
printf("Warning: ino %d ientry in unassigned block\n", ino);
|
||||
}
|
||||
if (*bpp) {
|
||||
ifp = (((struct ifile *)((*bpp)->b_un.b_buf)) +
|
||||
(ino % sblock.lfs_ifpb));
|
||||
if (sblock.lfs_version > 1) {
|
||||
ifp = (((IFILE *)((*bpp)->b_un.b_buf)) +
|
||||
(ino % sblock.lfs_ifpb));
|
||||
} else {
|
||||
ifp = (IFILE *)(((IFILE_V1 *)
|
||||
((*bpp)->b_un.b_buf)) +
|
||||
(ino % sblock.lfs_ifpb));
|
||||
}
|
||||
return ifp;
|
||||
} else
|
||||
return NULL;
|
||||
@ -248,10 +264,15 @@ SEGUSE *
|
||||
lfs_gseguse(int segnum, struct bufarea ** bpp)
|
||||
{
|
||||
int blkno;
|
||||
struct bufarea *bp;
|
||||
|
||||
blkno = segnum / (sblock.lfs_bsize / sizeof(SEGUSE)) + sblock.lfs_cleansz;
|
||||
(*bpp) = getfileblk(&sblock, lfs_ginode(LFS_IFILE_INUM), blkno);
|
||||
return ((SEGUSE *)(*bpp)->b_un.b_buf) + segnum % (sblock.lfs_bsize / sizeof(SEGUSE));
|
||||
blkno = segnum / sblock.lfs_sepb + sblock.lfs_cleansz;
|
||||
(*bpp) = bp = getfileblk(&sblock, lfs_ginode(LFS_IFILE_INUM), blkno);
|
||||
if (sblock.lfs_version == 1)
|
||||
return (SEGUSE *)((SEGUSE_V1 *)(bp->b_un.b_buf) +
|
||||
segnum % sblock.lfs_sepb);
|
||||
else
|
||||
return (SEGUSE *)(bp->b_un.b_buf) + segnum % sblock.lfs_sepb;
|
||||
}
|
||||
|
||||
daddr_t
|
||||
@ -280,7 +301,7 @@ lfs_ino_daddr(ino_t inumber)
|
||||
}
|
||||
|
||||
din_table[inumber] = daddr;
|
||||
seg_table[datosn(&sblock, daddr)].su_nbytes += DINODE_SIZE;
|
||||
seg_table[dtosn(&sblock, daddr)].su_nbytes += DINODE_SIZE;
|
||||
}
|
||||
return daddr;
|
||||
}
|
||||
@ -301,7 +322,7 @@ lfs_ginode(ino_t inumber)
|
||||
daddr = idaddr;
|
||||
if (din_table[LFS_IFILE_INUM] == 0) {
|
||||
din_table[LFS_IFILE_INUM] = daddr;
|
||||
seg_table[datosn(&sblock, daddr)].su_nbytes += DINODE_SIZE;
|
||||
seg_table[dtosn(&sblock, daddr)].su_nbytes += DINODE_SIZE;
|
||||
}
|
||||
return gidinode();
|
||||
}
|
||||
@ -314,7 +335,10 @@ lfs_ginode(ino_t inumber)
|
||||
if (pbp)
|
||||
pbp->b_flags &= ~B_INUSE;
|
||||
|
||||
pbp = getddblk(daddr, sblock.lfs_bsize);
|
||||
if (sblock.lfs_version == 1)
|
||||
pbp = getddblk(daddr, sblock.lfs_bsize);
|
||||
else
|
||||
pbp = getddblk(daddr, sblock.lfs_fsize);
|
||||
din = lfs_difind(&sblock, inumber, pbp->b_un.b_dinode);
|
||||
|
||||
if (din == NULL) {
|
||||
@ -467,7 +491,7 @@ iblock(struct inodesc * idesc, long ilevel, u_int64_t isize)
|
||||
return (n);
|
||||
} else
|
||||
func = dirscan;
|
||||
if (chkrange(idesc->id_blkno, fragstodb(&sblock, idesc->id_numfrags)))
|
||||
if (chkrange(idesc->id_blkno, fragstofsb(&sblock, idesc->id_numfrags)))
|
||||
return (SKIP);
|
||||
bp = getddblk(idesc->id_blkno, sblock.lfs_bsize);
|
||||
ilevel--;
|
||||
@ -536,10 +560,16 @@ iblock(struct inodesc * idesc, long ilevel, u_int64_t isize)
|
||||
int
|
||||
chkrange(daddr_t blk, int cnt)
|
||||
{
|
||||
if (blk < btodb(LFS_LABELPAD+LFS_SBPAD)) {
|
||||
if (blk < sntod(&sblock, 0)) {
|
||||
return (1);
|
||||
}
|
||||
if (blk > fsbtodb(&sblock, maxfsblock)) {
|
||||
if (blk > maxfsblock) {
|
||||
return (1);
|
||||
}
|
||||
if (blk + cnt < sntod(&sblock, 0)) {
|
||||
return (1);
|
||||
}
|
||||
if (blk + cnt > maxfsblock) {
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
@ -797,7 +827,7 @@ allocino(ino_t request, int type)
|
||||
dp->di_atime = t;
|
||||
dp->di_mtime = dp->di_ctime = dp->di_atime;
|
||||
dp->di_size = sblock.lfs_fsize;
|
||||
dp->di_blocks = btodb(sblock.lfs_fsize);
|
||||
dp->di_blocks = btofsb(&sblock, sblock.lfs_fsize);
|
||||
n_files++;
|
||||
inodirty();
|
||||
if (newinofmt)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pass0.c,v 1.8 2001/01/05 02:02:58 lukem Exp $ */
|
||||
/* $NetBSD: pass0.c,v 1.9 2001/07/13 20:30:19 perseant Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Konrad E. Schroder.
|
||||
@ -68,7 +68,7 @@ check_segment(int, int, daddr_t, struct lfs *, int,
|
||||
* finfo blocks, for one thing.
|
||||
*/
|
||||
|
||||
#define dbshift (sblock.lfs_bshift - sblock.lfs_fsbtodb)
|
||||
#define dbshift (sblock.lfs_bshift - sblock.lfs_blktodb)
|
||||
|
||||
void
|
||||
pass0()
|
||||
@ -161,7 +161,8 @@ dump_segsum(SEGSUM * sump, daddr_t addr)
|
||||
printf("\tsumsum: %x (%d)\n", sump->ss_sumsum, sump->ss_sumsum);
|
||||
printf("\tdatasum: %x (%d)\n", sump->ss_datasum, sump->ss_datasum);
|
||||
printf("\tnext: %x (%d)\n", sump->ss_next, sump->ss_next);
|
||||
printf("\tcreate: %x (%d)\n", sump->ss_create, sump->ss_create);
|
||||
printf("\tcreate: %llx (%lld)\n", (long long)sump->ss_create,
|
||||
(long long)sump->ss_create);
|
||||
printf("\tnfinfo: %x (%d)\n", sump->ss_nfinfo, sump->ss_nfinfo);
|
||||
printf("\tninos: %x (%d)\n", sump->ss_ninos, sump->ss_ninos);
|
||||
printf("\tflags: %c%c\n",
|
||||
@ -169,6 +170,7 @@ dump_segsum(SEGSUM * sump, daddr_t addr)
|
||||
sump->ss_flags & SS_CONT ? 'c' : '-');
|
||||
}
|
||||
|
||||
/* XXX Don't use... broken. -JO */
|
||||
void
|
||||
check_segment(int fd, int segnum, daddr_t addr, struct lfs * fs, int flags, int (*func)(struct lfs *, SEGSUM *, daddr_t))
|
||||
{
|
||||
@ -180,7 +182,7 @@ check_segment(int fd, int segnum, daddr_t addr, struct lfs * fs, int flags, int
|
||||
off_t sum_offset, db_ssize;
|
||||
int bc, su_flags, su_nsums, su_ninos;
|
||||
|
||||
db_ssize = sblock.lfs_ssize << sblock.lfs_fsbtodb;
|
||||
db_ssize = segtod(&sblock, 1);
|
||||
|
||||
su = lfs_gseguse(segnum, &bp);
|
||||
su_flags = su->su_flags;
|
||||
@ -223,7 +225,7 @@ check_segment(int fd, int segnum, daddr_t addr, struct lfs * fs, int flags, int
|
||||
while (1) {
|
||||
if (su_nsums <= psegnum)
|
||||
break;
|
||||
bp = getddblk(sum_offset >> dbshift, LFS_SUMMARY_SIZE);
|
||||
bp = getddblk(sum_offset >> dbshift, sblock.lfs_sumsize);
|
||||
sump = (SEGSUM *)(bp->b_un.b_buf);
|
||||
if (sump->ss_magic != SS_MAGIC) {
|
||||
if (flags & CKSEG_VERBOSE)
|
||||
@ -232,7 +234,7 @@ check_segment(int fd, int segnum, daddr_t addr, struct lfs * fs, int flags, int
|
||||
bp->b_flags &= ~B_INUSE;
|
||||
break;
|
||||
}
|
||||
if (sump->ss_sumsum != cksum(&sump->ss_datasum, LFS_SUMMARY_SIZE - sizeof(sump->ss_sumsum))) {
|
||||
if (sump->ss_sumsum != cksum(&sump->ss_datasum, sblock.lfs_sumsize - sizeof(sump->ss_sumsum))) {
|
||||
if (flags & CKSEG_VERBOSE) {
|
||||
/* Corrupt partial segment */
|
||||
pwarn("CORRUPT PARTIAL SEGMENT %d/%d OF SEGMENT %d AT BLK 0x%llx",
|
||||
@ -262,8 +264,9 @@ check_segment(int fd, int segnum, daddr_t addr, struct lfs * fs, int flags, int
|
||||
*/
|
||||
bc = (*func)(&sblock, sump, (daddr_t)(sum_offset >> dbshift));
|
||||
if (bc) {
|
||||
sum_offset += LFS_SUMMARY_SIZE + bc;
|
||||
ninos += (sump->ss_ninos + INOPB(&sblock) - 1) / INOPB(&sblock);
|
||||
sum_offset += sblock.lfs_sumsize + bc;
|
||||
ninos += (sump->ss_ninos + INOPB(&sblock) - 1)
|
||||
/ INOPB(&sblock);
|
||||
psegnum++;
|
||||
} else {
|
||||
bp->b_flags &= ~B_INUSE;
|
||||
@ -295,8 +298,8 @@ check_summary(struct lfs * fs, SEGSUM * sp, daddr_t pseg_addr)
|
||||
u_long *datap;
|
||||
u_int32_t ccksum;
|
||||
|
||||
sn = datosn(fs, pseg_addr);
|
||||
seg_addr = sntoda(fs, sn);
|
||||
sn = dtosn(fs, pseg_addr);
|
||||
seg_addr = sntod(fs, sn);
|
||||
|
||||
/*
|
||||
* printf("Pseg at 0x%x, %d inos, %d
|
||||
@ -318,11 +321,11 @@ check_summary(struct lfs * fs, SEGSUM * sp, daddr_t pseg_addr)
|
||||
datac = 0;
|
||||
|
||||
dp = (daddr_t *)sp;
|
||||
dp += LFS_SUMMARY_SIZE / sizeof(daddr_t);
|
||||
dp += sblock.lfs_sumsize / sizeof(daddr_t);
|
||||
dp--;
|
||||
|
||||
idp = dp;
|
||||
daddr = pseg_addr + (LFS_SUMMARY_SIZE / dev_bsize);
|
||||
daddr = pseg_addr + btofsb(&sblock, sblock.lfs_sumsize);
|
||||
fp = (FINFO *)(sp + 1);
|
||||
for (i = 0, j = 0; i < sp->ss_nfinfo || j < howmany(sp->ss_ninos, INOPB(fs)); i++) {
|
||||
/* printf("*idp=%x, daddr=%x\n", *idp, daddr); */
|
||||
@ -333,22 +336,22 @@ check_summary(struct lfs * fs, SEGSUM * sp, daddr_t pseg_addr)
|
||||
break;
|
||||
}
|
||||
while (j < howmany(sp->ss_ninos, INOPB(fs)) && *idp == daddr) {
|
||||
bp = getddblk(daddr, (1 << fs->lfs_bshift));
|
||||
bp = getddblk(daddr, fs->lfs_bsize);
|
||||
datap[datac++] = ((u_long *)(bp->b_un.b_buf))[0];
|
||||
bp->b_flags &= ~B_INUSE;
|
||||
|
||||
++j;
|
||||
daddr += (1 << fs->lfs_bshift) / dev_bsize;
|
||||
daddr += btofsb(&sblock, fs->lfs_bsize);
|
||||
--idp;
|
||||
}
|
||||
if (i < sp->ss_nfinfo) {
|
||||
for (k = 0; k < fp->fi_nblocks; k++) {
|
||||
len = (k == fp->fi_nblocks - 1 ? fp->fi_lastlength
|
||||
: (1 << fs->lfs_bshift));
|
||||
: fs->lfs_bsize);
|
||||
bp = getddblk(daddr, len);
|
||||
datap[datac++] = ((u_long *)(bp->b_un.b_buf))[0];
|
||||
bp->b_flags &= ~B_INUSE;
|
||||
daddr += len / dev_bsize;
|
||||
daddr += btofsb(&sblock, len);
|
||||
}
|
||||
fp = (FINFO *)(fp->fi_blocks + fp->fi_nblocks);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pass1.c,v 1.10 2001/01/06 23:08:26 joff Exp $ */
|
||||
/* $NetBSD: pass1.c,v 1.11 2001/07/13 20:30:19 perseant Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
@ -84,7 +84,7 @@ void
|
||||
pass1()
|
||||
{
|
||||
ino_t inumber;
|
||||
int i, total_segments;
|
||||
int i;
|
||||
struct inodesc idesc;
|
||||
struct dinode *idinode, *tinode;
|
||||
struct ifile *ifp;
|
||||
@ -105,7 +105,6 @@ pass1()
|
||||
|
||||
cp = (CLEANERINFO *)(pbp->b_un.b_buf);
|
||||
#endif
|
||||
total_segments = sblock.lfs_size / sblock.lfs_bsize;
|
||||
|
||||
/*
|
||||
* Find all allocated blocks, initialize numdirs.
|
||||
@ -362,7 +361,7 @@ pass1check(struct inodesc * idesc)
|
||||
register struct dups *dlp;
|
||||
struct dups *new;
|
||||
|
||||
if ((anyout = chkrange(blkno, fragstodb(&sblock, idesc->id_numfrags))) != 0) {
|
||||
if ((anyout = chkrange(blkno, fragstofsb(&sblock, idesc->id_numfrags))) != 0) {
|
||||
blkerror(idesc->id_number, "BAD", blkno);
|
||||
if (badblk++ >= MAXBAD) {
|
||||
pwarn("EXCESSIVE BAD BLKS I=%u",
|
||||
@ -374,9 +373,9 @@ pass1check(struct inodesc * idesc)
|
||||
return (STOP);
|
||||
}
|
||||
} else if (!testbmap(blkno)) {
|
||||
seg_table[datosn(&sblock, blkno)].su_nbytes += idesc->id_numfrags * sblock.lfs_fsize;
|
||||
seg_table[dtosn(&sblock, blkno)].su_nbytes += idesc->id_numfrags * sblock.lfs_fsize;
|
||||
}
|
||||
for (ndblks = fragstodb(&sblock, idesc->id_numfrags); ndblks > 0; blkno++, ndblks--) {
|
||||
for (ndblks = fragstofsb(&sblock, idesc->id_numfrags); ndblks > 0; blkno++, ndblks--) {
|
||||
if (anyout && chkrange(blkno, 1)) {
|
||||
res = SKIP;
|
||||
} else if (!testbmap(blkno)) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pass5.c,v 1.8 2000/11/21 06:24:26 perseant Exp $ */
|
||||
/* $NetBSD: pass5.c,v 1.9 2001/07/13 20:30:19 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
@ -61,6 +61,7 @@ pass5()
|
||||
unsigned long avail; /* blocks available for writing */
|
||||
unsigned long dmeta; /* blocks in segsums and inodes */
|
||||
int nclean; /* clean segments */
|
||||
size_t labelskew;
|
||||
|
||||
/*
|
||||
* Check segment holdings against actual holdings. Check for
|
||||
@ -97,24 +98,33 @@ pass5()
|
||||
}
|
||||
}
|
||||
if (su->su_flags & SEGUSE_DIRTY) {
|
||||
bb += btodb(su->su_nbytes) + su->su_nsums;
|
||||
ubb += btodb(su->su_nbytes) + su->su_nsums + fsbtodb(&sblock, su->su_ninos);
|
||||
dmeta += btodb(LFS_SUMMARY_SIZE * su->su_nsums);
|
||||
dmeta += fsbtodb(&sblock, su->su_ninos);
|
||||
bb += btofsb(&sblock, su->su_nbytes +
|
||||
su->su_nsums * sblock.lfs_sumsize);
|
||||
ubb += btofsb(&sblock, su->su_nbytes +
|
||||
su->su_nsums * sblock.lfs_sumsize +
|
||||
su->su_ninos * sblock.lfs_ibsize);
|
||||
dmeta += btofsb(&sblock,
|
||||
sblock.lfs_sumsize * su->su_nsums);
|
||||
dmeta += btofsb(&sblock,
|
||||
sblock.lfs_ibsize * su->su_ninos);
|
||||
} else {
|
||||
nclean++;
|
||||
avail += fsbtodb(&sblock, sblock.lfs_ssize);
|
||||
avail += segtod(&sblock, 1);
|
||||
if (su->su_flags & SEGUSE_SUPERBLOCK)
|
||||
avail -= btodb(LFS_SBPAD);
|
||||
avail -= btofsb(&sblock, LFS_SBPAD);
|
||||
if (i == 0 && sblock.lfs_version > 1 &&
|
||||
sblock.lfs_start < btofsb(&sblock, LFS_LABELPAD))
|
||||
avail -= btofsb(&sblock, LFS_LABELPAD) -
|
||||
sblock.lfs_start;
|
||||
}
|
||||
bp->b_flags &= ~B_INUSE;
|
||||
}
|
||||
/* Also may be available bytes in current seg */
|
||||
i = datosn(&sblock, sblock.lfs_offset);
|
||||
avail += sntoda(&sblock, i + 1) - sblock.lfs_offset;
|
||||
i = dtosn(&sblock, sblock.lfs_offset);
|
||||
avail += sntod(&sblock, i + 1) - sblock.lfs_offset;
|
||||
/* But do not count minfreesegs */
|
||||
avail -= fsbtodb(&sblock, sblock.lfs_ssize) *
|
||||
(sblock.lfs_minfreeseg - (sblock.lfs_minfreeseg / 2));
|
||||
avail -= segtod(&sblock, (sblock.lfs_minfreeseg -
|
||||
(sblock.lfs_minfreeseg / 2)));
|
||||
|
||||
if (dmeta != sblock.lfs_dmeta) {
|
||||
pwarn("dmeta given as %d, should be %ld\n", sblock.lfs_dmeta,
|
||||
@ -140,13 +150,16 @@ pass5()
|
||||
sbdirty();
|
||||
}
|
||||
}
|
||||
if (sblock.lfs_bfree > sblock.lfs_dsize - bb ||
|
||||
sblock.lfs_bfree < sblock.lfs_dsize - ubb) {
|
||||
labelskew = (sblock.lfs_version == 1 ? 0 :
|
||||
btofsb(&sblock, LFS_LABELPAD));
|
||||
if (sblock.lfs_bfree > sblock.lfs_dsize - bb - labelskew ||
|
||||
sblock.lfs_bfree < sblock.lfs_dsize - ubb - labelskew) {
|
||||
pwarn("bfree given as %d, should be between %ld and %ld\n",
|
||||
sblock.lfs_bfree, sblock.lfs_dsize - ubb,
|
||||
sblock.lfs_dsize - bb);
|
||||
sblock.lfs_bfree, sblock.lfs_dsize - ubb - labelskew,
|
||||
sblock.lfs_dsize - bb - labelskew);
|
||||
if (preen || reply("fix")) {
|
||||
sblock.lfs_bfree = sblock.lfs_dsize - (ubb + bb) / 2;
|
||||
sblock.lfs_bfree = sblock.lfs_dsize - labelskew -
|
||||
(ubb + bb) / 2;
|
||||
sbdirty();
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: setup.c,v 1.8 2001/01/05 02:02:58 lukem Exp $ */
|
||||
/* $NetBSD: setup.c,v 1.9 2001/07/13 20:30:19 perseant Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
@ -91,15 +91,16 @@ try_verify(struct lfs * osb, struct lfs * nsb)
|
||||
{
|
||||
daddr_t daddr;
|
||||
SEGSUM *sp;
|
||||
char summary[LFS_SUMMARY_SIZE];
|
||||
char *summary;
|
||||
int bc, flag;
|
||||
|
||||
daddr = osb->lfs_offset;
|
||||
summary = malloc(osb->lfs_sumsize);
|
||||
while (daddr != nsb->lfs_offset) {
|
||||
flag = 0;
|
||||
oncemore:
|
||||
/* Read in summary block */
|
||||
bread(fsreadfd, summary, daddr, LFS_SUMMARY_SIZE);
|
||||
bread(fsreadfd, summary, fsbtodb(osb, daddr), osb->lfs_sumsize);
|
||||
sp = (SEGSUM *)summary;
|
||||
|
||||
/*
|
||||
@ -108,10 +109,10 @@ oncemore:
|
||||
* setup before we can...fix this
|
||||
*/
|
||||
if (sp->ss_magic != SS_MAGIC ||
|
||||
sp->ss_sumsum != cksum(&sp->ss_datasum, LFS_SUMMARY_SIZE -
|
||||
sp->ss_sumsum != cksum(&sp->ss_datasum, osb->lfs_sumsize -
|
||||
sizeof(sp->ss_sumsum))) {
|
||||
if (flag == 0) {
|
||||
daddr += LFS_SBPAD / dev_bsize;
|
||||
daddr += btofsb(osb, LFS_SBPAD);
|
||||
goto oncemore;
|
||||
}
|
||||
return 0x0;
|
||||
@ -119,14 +120,33 @@ oncemore:
|
||||
bc = check_summary(osb, sp, daddr);
|
||||
if (bc == 0)
|
||||
break;
|
||||
daddr += (LFS_SUMMARY_SIZE + bc) / dev_bsize;
|
||||
if (datosn(osb, daddr) != datosn(osb, daddr + (LFS_SUMMARY_SIZE + (1 << osb->lfs_bshift)) / dev_bsize)) {
|
||||
daddr += btofsb(osb, osb->lfs_sumsize + bc);
|
||||
if (dtosn(osb, daddr) != dtosn(osb, daddr +
|
||||
btofsb(osb, osb->lfs_sumsize + osb->lfs_bsize)))
|
||||
daddr = ((SEGSUM *)summary)->ss_next;
|
||||
}
|
||||
}
|
||||
return daddr;
|
||||
}
|
||||
|
||||
u_quad_t maxtable[] = {
|
||||
/* 1 */ -1,
|
||||
/* 2 */ -1,
|
||||
/* 4 */ -1,
|
||||
/* 8 */ -1,
|
||||
/* 16 */ -1,
|
||||
/* 32 */ -1,
|
||||
/* 64 */ -1,
|
||||
/* 128 */ -1,
|
||||
/* 256 */ -1,
|
||||
/* 512 */ NDADDR + 128 + 128 * 128 + 128 * 128 * 128,
|
||||
/* 1024 */ NDADDR + 256 + 256 * 256 + 256 * 256 * 256,
|
||||
/* 2048 */ NDADDR + 512 + 512 * 512 + 512 * 512 * 512,
|
||||
/* 4096 */ NDADDR + 1024 + 1024 * 1024 + 1024 * 1024 * 1024,
|
||||
/* 8192 */ 1 << 31,
|
||||
/* 16 K */ 1 << 31,
|
||||
/* 32 K */ 1 << 31,
|
||||
};
|
||||
|
||||
int
|
||||
setup(const char *dev)
|
||||
{
|
||||
@ -217,6 +237,22 @@ setup(const char *dev)
|
||||
bufinit();
|
||||
|
||||
if (bflag == 0x0 && idaddr == 0x0) {
|
||||
/*
|
||||
* If we read a proper superblock, but its address was not
|
||||
* lfs_sboffs[0], we're holding a fake primary superblock,
|
||||
* and need to read the real one.
|
||||
*/
|
||||
if (sblock.lfs_sboffs[0] != dbtofsb(&sblock,
|
||||
LFS_LABELPAD / dev_bsize))
|
||||
{
|
||||
if (debug)
|
||||
pwarn("Getting 'real' prinary superblock from 0x%x\n",
|
||||
fsbtodb(&sblock, sblock.lfs_sboffs[0]));
|
||||
bflag = fsbtodb(&sblock, sblock.lfs_sboffs[0]);
|
||||
readsb(1);
|
||||
bflag = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Even if that superblock read in properly, it may not
|
||||
* be guaranteed to point to a complete checkpoint.
|
||||
@ -226,7 +262,7 @@ setup(const char *dev)
|
||||
sb0 = malloc(sizeof(*sb0));
|
||||
sb1 = malloc(sizeof(*sb1));
|
||||
memcpy(sb0, &sblock, sizeof(*sb0));
|
||||
bflag = sblock.lfs_sboffs[1];
|
||||
bflag = fsbtodb(&sblock, sblock.lfs_sboffs[1]);
|
||||
if (readsb(1) == 0) {
|
||||
pwarn("COULDN'T READ ALT SUPERBLOCK AT BLK %d", bflag);
|
||||
if (reply("ASSUME PRIMARY SUPERBLOCK IS GOOD") == 0) {
|
||||
@ -236,32 +272,55 @@ setup(const char *dev)
|
||||
}
|
||||
} else {
|
||||
memcpy(sb1, &sblock, sizeof(*sb1));
|
||||
if (debug)
|
||||
pwarn("sb0 %d, sb1 %d\n", sb0->lfs_tstamp, sblock.lfs_tstamp);
|
||||
if (debug) {
|
||||
if (sb0->lfs_version > 1) {
|
||||
pwarn("sb0 sn=%lld, sb1 sn=%lld\n",
|
||||
(long long)sb0->lfs_serial,
|
||||
(long long)sblock.lfs_serial);
|
||||
} else {
|
||||
pwarn("sb0 %lld, sb1 %lld\n",
|
||||
(long long)sb0->lfs_otstamp,
|
||||
(long long)sblock.lfs_otstamp);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Verify the checkpoint of the newer superblock,
|
||||
* if the timestamp of the two superblocks is
|
||||
* different. XXX use lfs_offset instead, discover
|
||||
* how to quickly discover "newness" based on that.
|
||||
*/
|
||||
if (sb0->lfs_tstamp != sb1->lfs_tstamp) {
|
||||
if (sb0->lfs_tstamp > sb1->lfs_tstamp) {
|
||||
osb = sb1;
|
||||
nsb = sb0;
|
||||
if ((sb0->lfs_version == 1 &&
|
||||
sb0->lfs_otstamp != sb1->lfs_otstamp) ||
|
||||
(sb0->lfs_version > 1 &&
|
||||
sb0->lfs_serial != sb1->lfs_serial)) {
|
||||
if (sb0->lfs_version == 1) {
|
||||
if (sb0->lfs_otstamp > sb1->lfs_otstamp) {
|
||||
osb = sb1;
|
||||
nsb = sb0;
|
||||
} else {
|
||||
osb = sb0;
|
||||
nsb = sb1;
|
||||
}
|
||||
} else {
|
||||
osb = sb0;
|
||||
nsb = sb1;
|
||||
if (sb0->lfs_serial > sb1->lfs_serial) {
|
||||
osb = sb1;
|
||||
nsb = sb0;
|
||||
} else {
|
||||
osb = sb0;
|
||||
nsb = sb1;
|
||||
}
|
||||
}
|
||||
daddr = try_verify(osb, nsb);
|
||||
|
||||
if (debug)
|
||||
printf("done.\n");
|
||||
if (daddr == nsb->lfs_offset) {
|
||||
pwarn("Checkpoint verified, recovered %d seconds of data\n", nsb->lfs_tstamp - osb->lfs_tstamp);
|
||||
pwarn("Checkpoint verified, recovered %lld seconds of data\n",
|
||||
(long long)nsb->lfs_tstamp - (long long)osb->lfs_tstamp);
|
||||
memcpy(&sblock, nsb, sizeof(*nsb));
|
||||
sbdirty();
|
||||
} else {
|
||||
pwarn("Checkpoint invalid, lost %d seconds of data\n", nsb->lfs_tstamp - osb->lfs_tstamp);
|
||||
pwarn("Checkpoint invalid, lost %lld seconds of data\n", (long long)nsb->lfs_tstamp - (long long)osb->lfs_tstamp);
|
||||
memcpy(&sblock, osb, sizeof(*osb));
|
||||
}
|
||||
}
|
||||
@ -276,73 +335,47 @@ setup(const char *dev)
|
||||
printf("lfs_bsize = %lu\n", (unsigned long)sblock.lfs_bsize);
|
||||
printf("lfs_fsize = %lu\n", (unsigned long)sblock.lfs_fsize);
|
||||
printf("lfs_frag = %lu\n", (unsigned long)sblock.lfs_frag);
|
||||
printf("INOPB(fs) = %lu\n", (unsigned long) INOPB(&sblock));
|
||||
printf("INOPB(fs) = %lu\n", (unsigned long)INOPB(&sblock));
|
||||
if (sblock.lfs_version > 1)
|
||||
printf("INOPF(fs) = %lu\n",
|
||||
(unsigned long)INOPF(&sblock));
|
||||
/* printf("fsbtodb(fs,1) = %lu\n",fsbtodb(&sblock,1)); */
|
||||
}
|
||||
#if 0 /* FFS-specific fs-clean check */
|
||||
if (debug)
|
||||
printf("clean = %d\n", sblock.lfs_clean);
|
||||
if (sblock.lfs_clean & FS_ISCLEAN) {
|
||||
if (doskipclean) {
|
||||
pwarn("%sile system is clean; not checking\n",
|
||||
preen ? "f" : "** F");
|
||||
return (-1);
|
||||
}
|
||||
if (!preen)
|
||||
pwarn("** File system is already clean\n");
|
||||
/* Compatibility */
|
||||
if (sblock.lfs_version == 1) {
|
||||
sblock.lfs_sumsize = LFS_V1_SUMMARY_SIZE;
|
||||
sblock.lfs_ibsize = sblock.lfs_bsize;
|
||||
sblock.lfs_start = sblock.lfs_sboffs[0];
|
||||
sblock.lfs_fsbtodb = 0;
|
||||
}
|
||||
maxino = sblock.lfs_ncg * sblock.lfs_ipg;
|
||||
#else
|
||||
initbarea(&iblk);
|
||||
iblk.b_un.b_buf = malloc(sblock.lfs_bsize);
|
||||
if (bread(fsreadfd, (char *)iblk.b_un.b_buf, idaddr,
|
||||
(long)sblock.lfs_bsize) != 0) {
|
||||
iblk.b_un.b_buf = malloc(sblock.lfs_ibsize);
|
||||
if (bread(fsreadfd, (char *)iblk.b_un.b_buf, fsbtodb(&sblock, idaddr),
|
||||
(long)sblock.lfs_ibsize) != 0) {
|
||||
printf("Couldn't read disk block %d\n", idaddr);
|
||||
exit(1);
|
||||
}
|
||||
idinode = lfs_difind(&sblock, sblock.lfs_ifile, &ifblock);
|
||||
if (idinode == NULL) {
|
||||
printf("Ifile inode not found at daddr 0x%x\n", idaddr);
|
||||
exit(1);
|
||||
/* XXX find it in the segment summaries */
|
||||
}
|
||||
|
||||
maxino = ((idinode->di_size
|
||||
- (sblock.lfs_cleansz + sblock.lfs_segtabsz) * sblock.lfs_bsize)
|
||||
/ sblock.lfs_bsize) * sblock.lfs_ifpb;
|
||||
if (debug)
|
||||
printf("maxino=%d\n", maxino);
|
||||
printf("maxino = %d\n", maxino);
|
||||
din_table = (daddr_t *)malloc(maxino * sizeof(*din_table));
|
||||
memset(din_table, 0, maxino * sizeof(*din_table));
|
||||
seg_table = (SEGUSE *)malloc(sblock.lfs_nseg * sizeof(SEGUSE));
|
||||
memset(seg_table, 0, sblock.lfs_nseg * sizeof(SEGUSE));
|
||||
#endif
|
||||
maxfsblock = sblock.lfs_size * (sblock.lfs_bsize / dev_bsize);
|
||||
#if 0
|
||||
sizepb = sblock.lfs_bsize;
|
||||
maxfilesize = sblock.lfs_bsize * NDADDR - 1;
|
||||
for (i = 0; i < NIADDR; i++) {
|
||||
sizepb *= NINDIR(&sblock);
|
||||
maxfilesize += sizepb;
|
||||
}
|
||||
maxfilesize++; /* XXX */
|
||||
#else /* LFS way */
|
||||
{
|
||||
u_quad_t maxtable[] = {
|
||||
/* 1 */ -1,
|
||||
/* 2 */ -1,
|
||||
/* 4 */ -1,
|
||||
/* 8 */ -1,
|
||||
/* 16 */ -1,
|
||||
/* 32 */ -1,
|
||||
/* 64 */ -1,
|
||||
/* 128 */ -1,
|
||||
/* 256 */ -1,
|
||||
/* 512 */ NDADDR + 128 + 128 * 128 + 128 * 128 * 128,
|
||||
/* 1024 */ NDADDR + 256 + 256 * 256 + 256 * 256 * 256,
|
||||
/* 2048 */ NDADDR + 512 + 512 * 512 + 512 * 512 * 512,
|
||||
/* 4096 */ NDADDR + 1024 + 1024 * 1024 + 1024 * 1024 * 1024,
|
||||
/* 8192 */ 1 << 31,
|
||||
/* 16 K */ 1 << 31,
|
||||
/* 32 K */ 1 << 31,
|
||||
};
|
||||
maxfilesize = maxtable[sblock.lfs_bshift] << sblock.lfs_bshift;
|
||||
}
|
||||
#endif
|
||||
if (sblock.lfs_version == 1)
|
||||
maxfsblock = sblock.lfs_size * (sblock.lfs_bsize / dev_bsize);
|
||||
else
|
||||
maxfsblock = sblock.lfs_size;
|
||||
maxfilesize = maxtable[sblock.lfs_bshift] << sblock.lfs_bshift;
|
||||
if ((sblock.lfs_minfree < 0 || sblock.lfs_minfree > 99)) {
|
||||
pfatal("IMPOSSIBLE MINFREE=%d IN SUPERBLOCK",
|
||||
sblock.lfs_minfree);
|
||||
@ -351,7 +384,6 @@ setup(const char *dev)
|
||||
sbdirty();
|
||||
}
|
||||
}
|
||||
/* XXX used to be ~(sblock.lfs_bsize - 1) */
|
||||
if (sblock.lfs_bmask != sblock.lfs_bsize - 1) {
|
||||
pwarn("INCORRECT BMASK=%x IN SUPERBLOCK (should be %x)",
|
||||
(unsigned int)sblock.lfs_bmask,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: utilities.c,v 1.7 2001/02/04 21:52:04 christos Exp $ */
|
||||
/* $NetBSD: utilities.c,v 1.8 2001/07/13 20:30:19 perseant Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
@ -184,7 +184,7 @@ foundit:
|
||||
struct bufarea *
|
||||
getdatablk(daddr_t blkno, long size)
|
||||
{
|
||||
return getddblk(fsbtodb(&sblock, blkno), size);
|
||||
return getddblk(blkno, size);
|
||||
}
|
||||
|
||||
void
|
||||
@ -193,16 +193,18 @@ getdblk(struct bufarea * bp, daddr_t blk, long size)
|
||||
if (bp->b_bno != blk) {
|
||||
flush(fswritefd, bp);
|
||||
diskreads++;
|
||||
bp->b_errs = bread(fsreadfd, bp->b_un.b_buf, blk, size);
|
||||
bp->b_errs = bread(fsreadfd, bp->b_un.b_buf,
|
||||
fsbtodb(&sblock, blk), size);
|
||||
bp->b_bno = blk;
|
||||
bp->b_size = size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
getblk(struct bufarea * bp, daddr_t blk, long size)
|
||||
{
|
||||
getdblk(bp, fsbtodb(&sblock, blk), size);
|
||||
getdblk(bp, blk, size);
|
||||
}
|
||||
|
||||
void
|
||||
@ -251,20 +253,21 @@ ckfini(int markclean)
|
||||
return;
|
||||
}
|
||||
flush(fswritefd, &sblk);
|
||||
if (havesb && sblk.b_bno != LFS_LABELPAD / dev_bsize &&
|
||||
sblk.b_bno != sblock.lfs_sboffs[0] &&
|
||||
if (havesb && sblk.b_bno != sblock.lfs_sboffs[0] &&
|
||||
sblk.b_bno != sblock.lfs_sboffs[1] &&
|
||||
!preen && reply("UPDATE STANDARD SUPERBLOCKS")) {
|
||||
sblk.b_bno = LFS_LABELPAD / dev_bsize;
|
||||
sblk.b_bno = fsbtodb(&sblock, sblock.lfs_sboffs[0]);
|
||||
sbdirty();
|
||||
flush(fswritefd, &sblk);
|
||||
}
|
||||
if (havesb) {
|
||||
if (sblk.b_bno == LFS_LABELPAD / dev_bsize) {
|
||||
if (sblk.b_bno == fsbtodb(&sblock, sblock.lfs_sboffs[0])) {
|
||||
/* Do the first alternate */
|
||||
sblk.b_bno = sblock.lfs_sboffs[1];
|
||||
sblk.b_bno = fsbtodb(&sblock, sblock.lfs_sboffs[1]);
|
||||
sbdirty();
|
||||
flush(fswritefd, &sblk);
|
||||
} else if (sblk.b_bno == sblock.lfs_sboffs[1]) {
|
||||
} else if (sblk.b_bno ==
|
||||
fsbtodb(&sblock, sblock.lfs_sboffs[1])) {
|
||||
/* Do the primary */
|
||||
sblk.b_bno = LFS_LABELPAD / dev_bsize;
|
||||
sbdirty();
|
||||
@ -283,7 +286,7 @@ ckfini(int markclean)
|
||||
if (bufhead.b_size != cnt)
|
||||
errexit("Panic: lost %d buffers\n", bufhead.b_size - cnt);
|
||||
pbp = pdirbp = (struct bufarea *)0;
|
||||
if (markclean && sblock.lfs_clean == 0) {
|
||||
if (markclean && !(sblock.lfs_pflags & LFS_PF_CLEAN)) {
|
||||
/*
|
||||
* Mark the file system as clean, and sync the superblock.
|
||||
*/
|
||||
@ -292,14 +295,16 @@ ckfini(int markclean)
|
||||
else if (!reply("MARK FILE SYSTEM CLEAN"))
|
||||
markclean = 0;
|
||||
if (markclean) {
|
||||
sblock.lfs_clean = 1;
|
||||
sblock.lfs_pflags |= LFS_PF_CLEAN;
|
||||
sbdirty();
|
||||
flush(fswritefd, &sblk);
|
||||
if (sblk.b_bno == LFS_LABELPAD / dev_bsize) {
|
||||
/* Do the first alternate */
|
||||
sblk.b_bno = sblock.lfs_sboffs[0];
|
||||
sblk.b_bno = fsbtodb(&sblock,
|
||||
sblock.lfs_sboffs[0]);
|
||||
flush(fswritefd, &sblk);
|
||||
} else if (sblk.b_bno == sblock.lfs_sboffs[0]) {
|
||||
} else if (sblk.b_bno == fsbtodb(&sblock,
|
||||
sblock.lfs_sboffs[0])) {
|
||||
/* Do the primary */
|
||||
sblk.b_bno = LFS_LABELPAD / dev_bsize;
|
||||
flush(fswritefd, &sblk);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: config.h,v 1.5 2000/09/09 04:49:56 perseant Exp $ */
|
||||
/* $NetBSD: config.h,v 1.6 2001/07/13 20:30:19 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
@ -36,11 +36,9 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* The first boot and super blocks are given in absolute disk addresses.
|
||||
* The byte-offset forms are preferred, as they don't imply a sector size.
|
||||
* Version of the LFS to make. Default to the newest one.
|
||||
*/
|
||||
#define BBSIZE 8192
|
||||
#define SBSIZE 8192
|
||||
#define DFL_VERSION LFS_VERSION
|
||||
|
||||
/*
|
||||
* The following two constants set the default block and fragment sizes.
|
||||
@ -49,7 +47,7 @@
|
||||
* sectorsize <= DESFRAGSIZE <= DESBLKSIZE
|
||||
* DESBLKSIZE / DESFRAGSIZE <= 8
|
||||
*/
|
||||
#define DFL_FRAGSIZE 1024
|
||||
#define DFL_FRAGSIZE 512
|
||||
#define DFL_BLKSIZE 8192
|
||||
|
||||
/*
|
||||
@ -67,11 +65,10 @@
|
||||
|
||||
/*
|
||||
* The following constants set the default block and segment size for a log
|
||||
* structured file system. Both must be powers of two and the segment size
|
||||
* must be a multiple of the block size. We also set minimum block and segment
|
||||
* sizes.
|
||||
* structured file system. The block size must be a power of two and less
|
||||
* than the segment size.
|
||||
*/
|
||||
#define LFS_MINSEGSIZE (64*1024)
|
||||
#define LFS_MINSEGSIZE (64 * 1024)
|
||||
#define DFL_LFSSEG (1024 * 1024)
|
||||
#define DFL_LFSSEG_SHIFT 20
|
||||
#define DFL_LFSSEG_MASK 0xFFFFF
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: extern.h,v 1.4 2000/12/05 19:51:14 perseant Exp $ */
|
||||
/* $NetBSD: extern.h,v 1.5 2001/07/13 20:30:20 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
@ -37,15 +37,14 @@
|
||||
|
||||
struct dlfs;
|
||||
|
||||
u_long lfs_sb_cksum __P((struct dlfs *));
|
||||
u_long cksum __P((void *, size_t));
|
||||
u_short dkcksum __P((struct disklabel *));
|
||||
void fatal __P((const char *fmt, ...))
|
||||
u_long lfs_sb_cksum(struct dlfs *);
|
||||
u_long cksum(void *, size_t);
|
||||
u_short dkcksum(struct disklabel *);
|
||||
void fatal(const char *fmt, ...)
|
||||
__attribute__((__format__(__printf__,1,2)));
|
||||
u_int log2 __P((u_int));
|
||||
int make_lfs
|
||||
__P((int, struct disklabel *, struct partition *, int,
|
||||
int, int, int, int));
|
||||
u_int log2(u_int);
|
||||
int make_lfs(int, struct disklabel *, struct partition *, int,
|
||||
int, int, int, int, int, int, int, int, u_int32_t);
|
||||
|
||||
extern char *progname;
|
||||
extern char *special;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs.c,v 1.21 2000/11/23 23:09:57 perseant Exp $ */
|
||||
/* $NetBSD: lfs.c,v 1.22 2001/07/13 20:30:20 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
@ -38,7 +38,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)lfs.c 8.5 (Berkeley) 5/24/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: lfs.c,v 1.21 2000/11/23 23:09:57 perseant Exp $");
|
||||
__RCSID("$NetBSD: lfs.c,v 1.22 2001/07/13 20:30:20 perseant Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -66,13 +66,14 @@ __RCSID("$NetBSD: lfs.c,v 1.21 2000/11/23 23:09:57 perseant Exp $");
|
||||
#include "extern.h"
|
||||
|
||||
extern int Nflag; /* Don't write anything */
|
||||
daddr_t *ifib = NULL; /* Ifile single indirect block (lbn -NDADDR) */
|
||||
daddr_t **ifibp = NULL; /* Ifile single indirect blocks */
|
||||
int ifibc; /* Number of indirect blocks */
|
||||
|
||||
/*
|
||||
* This table is indexed by the log base 2 of the block size.
|
||||
* It returns the maximum file size allowed in a file system
|
||||
* with the specified block size. For block sizes smaller than
|
||||
* 8K, the size is limited by tha maximum number of blocks that
|
||||
* 8K, the size is limited by the maximum number of blocks that
|
||||
* can be reached by triply indirect blocks:
|
||||
* NDADDR + INOPB(bsize) + INOPB(bsize)^2 + INOPB(bsize)^3
|
||||
* For block size of 8K or larger, the file size is limited by the
|
||||
@ -105,7 +106,7 @@ static struct lfs lfs_default = {
|
||||
/* dlfs_magic */ LFS_MAGIC,
|
||||
/* dlfs_version */ LFS_VERSION,
|
||||
/* dlfs_size */ 0,
|
||||
/* dlfs_ssize */ DFL_LFSSEG/DFL_LFSBLOCK,
|
||||
/* dlfs_ssize */ DFL_LFSSEG,
|
||||
/* dlfs_dsize */ 0,
|
||||
/* dlfs_bsize */ DFL_LFSBLOCK,
|
||||
/* dlfs_fsize */ DFL_LFSFRAG,
|
||||
@ -122,10 +123,10 @@ static struct lfs lfs_default = {
|
||||
/* dlfs_curseg */ 0,
|
||||
/* dlfs_offset */ 0,
|
||||
/* dlfs_lastpseg */ 0,
|
||||
/* dlfs_tstamp */ 0,
|
||||
/* dlfs_inopf */ 0,
|
||||
/* dlfs_minfree */ MINFREE,
|
||||
/* dlfs_maxfilesize */ 0,
|
||||
/* dlfs_dbpseg */ DFL_LFSSEG/DEV_BSIZE,
|
||||
/* dlfs_fsbpseg */ 0,
|
||||
/* dlfs_inopb */ DFL_LFSBLOCK/sizeof(struct dinode),
|
||||
/* dlfs_ifpb */ DFL_LFSBLOCK/sizeof(IFILE),
|
||||
/* dlfs_sepb */ DFL_LFSBLOCK/sizeof(SEGUSE),
|
||||
@ -142,15 +143,24 @@ static struct lfs lfs_default = {
|
||||
/* dlfs_bmask */ DFL_LFSBLOCK_MASK,
|
||||
/* dlfs_ffmask */ DFL_LFS_FFMASK,
|
||||
/* dlfs_fbmask */ DFL_LFS_FBMASK,
|
||||
/* dlfs_fsbtodb */ 0,
|
||||
/* dlfs_blktodb */ 0,
|
||||
/* dlfs_sushift */ 0,
|
||||
/* dlfs_maxsymlinklen */ MAXSYMLINKLEN,
|
||||
/* dlfs_sboffs */ { 0 },
|
||||
/* dlfs_nclean */ 0,
|
||||
/* dlfs_fsmnt */ { 0 },
|
||||
/* dlfs_clean */ 0,
|
||||
/* dlfs_pflags */ 0,
|
||||
/* dlfs_dmeta */ 0,
|
||||
/* dlfs_minfreeseg */ 0,
|
||||
/* dlfs_sumsize */ 0,
|
||||
/* dlfs_serial */ 0,
|
||||
/* dlfs_ibsize */ DFL_LFSFRAG,
|
||||
/* dlfs_start */ 0,
|
||||
/* dlfs_inodefmt */ LFS_44INODEFMT,
|
||||
/* dlfs_tstamp */ 0,
|
||||
/* dlfs_interleave */ 0,
|
||||
/* dlfs_ident */ 0,
|
||||
/* dlfs_fsbtodb */ 0,
|
||||
|
||||
/* dlfs_pad */ { 0 },
|
||||
/* dlfs_cksum */ 0
|
||||
@ -183,21 +193,15 @@ struct direct lfs_lf_dir[] = {
|
||||
{ ROOTINO, sizeof(struct direct), DT_DIR, 2, ".." },
|
||||
};
|
||||
|
||||
static daddr_t make_dinode
|
||||
__P((ino_t, struct dinode *, int, daddr_t, struct lfs *));
|
||||
static void make_dir __P(( void *, struct direct *, int));
|
||||
static void put __P((int, off_t, void *, size_t));
|
||||
static daddr_t make_dinode(ino_t, struct dinode *, int, daddr_t, struct lfs *);
|
||||
static void make_dir( void *, struct direct *, int);
|
||||
static void put(int, off_t, void *, size_t);
|
||||
|
||||
int
|
||||
make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
int fd;
|
||||
struct disklabel *lp;
|
||||
struct partition *partp;
|
||||
int minfree;
|
||||
int block_size;
|
||||
int frag_size;
|
||||
int seg_size;
|
||||
int minfreeseg;
|
||||
make_lfs(int fd, struct disklabel *lp, struct partition *partp, int minfree,
|
||||
int block_size, int frag_size, int seg_size, int minfreeseg,
|
||||
int version, daddr_t start, int ibsize, int interleave,
|
||||
u_int32_t roll_id)
|
||||
{
|
||||
struct dinode *dip; /* Pointer to a disk inode */
|
||||
struct dinode *dpagep; /* Pointer to page of disk inodes */
|
||||
@ -205,6 +209,7 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
FINFO file_info; /* File info structure in summary blocks */
|
||||
IFILE *ifile; /* Pointer to array of ifile structures */
|
||||
IFILE *ip; /* Pointer to array of ifile structures */
|
||||
IFILE_V1 *ifile_v1, *ip_v1;
|
||||
struct lfs *lfsp; /* Superblock */
|
||||
SEGUSE *segp; /* Segment usage table */
|
||||
SEGUSE *segtable; /* Segment usage table */
|
||||
@ -222,17 +227,23 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
int block_array_size; /* How many entries in block array */
|
||||
int bsize; /* Block size */
|
||||
int fsize; /* Fragment size */
|
||||
int db_per_fb; /* Disk blocks per file block */
|
||||
int db_per_blk; /* Disk blocks per file block */
|
||||
int i, j;
|
||||
off_t off; /* Offset at which to write */
|
||||
off_t off, startoff; /* Offset at which to write */
|
||||
int sb_interval; /* number of segs between super blocks */
|
||||
off_t seg_seek; /* Seek offset for a segment */
|
||||
int ssize; /* Segment size */
|
||||
int sum_size; /* Size of the summary block */
|
||||
int warned_segtoobig=0;
|
||||
double fssize;
|
||||
int label_fsb, sb_fsb;
|
||||
int curw, ww;
|
||||
char tbuf[BUFSIZ];
|
||||
|
||||
lfsp = &lfs_default;
|
||||
|
||||
lfsp->lfs_version = version;
|
||||
|
||||
/* If partition is not an LFS partition, warn that that is the case */
|
||||
if(partp->p_fstype != FS_BSDLFS) {
|
||||
fatal("partition label indicated fs type \"%s\", expected \"%s\"",
|
||||
@ -245,12 +256,21 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
if (!(fsize = frag_size))
|
||||
if (!(fsize = partp->p_fsize))
|
||||
fsize = DFL_LFSFRAG;
|
||||
if (!(ssize = seg_size))
|
||||
if (!(ssize = seg_size)) {
|
||||
ssize = DFL_LFSSEG;
|
||||
if (partp->p_sgs == 0 ||
|
||||
!(ssize = (partp->p_fsize * partp->p_frag) << partp->p_sgs))
|
||||
{
|
||||
ssize = DFL_LFSSEG;
|
||||
}
|
||||
}
|
||||
if (version > 1) {
|
||||
if (ibsize == 0)
|
||||
ibsize = fsize;
|
||||
if (ibsize <= 0 || ibsize % fsize)
|
||||
fatal("illegal inode block size: %d\n", ibsize);
|
||||
} else if (ibsize && ibsize != bsize)
|
||||
fatal("cannot specify inode block size when version == 1\n");
|
||||
|
||||
/* Sanity check: fsize<=bsize<ssize */
|
||||
if (fsize > bsize) {
|
||||
@ -267,6 +287,13 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
progname, ssize, DFL_LFSSEG);
|
||||
ssize = DFL_LFSSEG;
|
||||
}
|
||||
if (start < 0 || start >= partp->p_size)
|
||||
fatal("filesystem offset %ld out of range", (long)start);
|
||||
if (version == 1) {
|
||||
if (start)
|
||||
warnx("filesystem offset ignored for version 1 filesystem");
|
||||
start = LFS_LABELPAD / lp->d_secsize;
|
||||
}
|
||||
|
||||
tryagain:
|
||||
/* Modify parts of superblock overridden by command line arguments */
|
||||
@ -277,7 +304,6 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
lfsp->lfs_bsize = bsize;
|
||||
lfsp->lfs_fsize = fsize;
|
||||
lfsp->lfs_bmask = bsize - 1;
|
||||
lfsp->lfs_inopb = bsize / sizeof(struct dinode);
|
||||
lfsp->lfs_ffmask = fsize - 1;
|
||||
lfsp->lfs_ffshift = log2(fsize);
|
||||
if (1 << lfsp->lfs_ffshift != fsize)
|
||||
@ -285,33 +311,69 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
lfsp->lfs_frag = numfrags(lfsp, bsize);
|
||||
lfsp->lfs_fbmask = lfsp->lfs_frag - 1;
|
||||
lfsp->lfs_fbshift = log2(lfsp->lfs_frag);
|
||||
/* MIS -- should I round to power of 2 */
|
||||
lfsp->lfs_ifpb = bsize / sizeof(IFILE);
|
||||
lfsp->lfs_sepb = bsize / sizeof(SEGUSE);
|
||||
lfsp->lfs_nindir = bsize / sizeof(daddr_t);
|
||||
}
|
||||
|
||||
if (ssize != DFL_LFSSEG) {
|
||||
if (lfsp->lfs_version == 1) {
|
||||
lfsp->lfs_sumsize = LFS_V1_SUMMARY_SIZE;
|
||||
lfsp->lfs_segshift = log2(ssize);
|
||||
if (1 << lfsp->lfs_segshift != ssize)
|
||||
fatal("%d: segment size not power of 2", ssize);
|
||||
lfsp->lfs_ssize = ssize;
|
||||
lfsp->lfs_segmask = ssize - 1;
|
||||
lfsp->lfs_dbpseg = ssize / DEV_BSIZE;
|
||||
lfsp->lfs_ifpb = lfsp->lfs_bsize / sizeof(IFILE_V1);
|
||||
lfsp->lfs_ibsize = lfsp->lfs_bsize;
|
||||
lfsp->lfs_sepb = bsize / sizeof(SEGUSE_V1);
|
||||
lfsp->lfs_ssize = ssize >> lfsp->lfs_bshift;
|
||||
} else {
|
||||
if (ssize % fsize) {
|
||||
fprintf(stderr,
|
||||
"Segment size %d is not a multiple of frag size; ",
|
||||
ssize);
|
||||
ssize = roundup(ssize, fsize);
|
||||
fprintf(stderr, "trying size %d.\n", ssize);
|
||||
goto tryagain;
|
||||
}
|
||||
lfsp->lfs_sumsize = fsize;
|
||||
lfsp->lfs_segshift = 0;
|
||||
lfsp->lfs_segmask = 0;
|
||||
lfsp->lfs_sepb = bsize / sizeof(SEGUSE);
|
||||
lfsp->lfs_ssize = ssize;
|
||||
lfsp->lfs_ibsize = ibsize;
|
||||
}
|
||||
lfsp->lfs_ssize = ssize >> lfsp->lfs_bshift;
|
||||
lfsp->lfs_inopb = lfsp->lfs_ibsize / sizeof(struct dinode);
|
||||
lfsp->lfs_minfree = minfree;
|
||||
|
||||
if (version > 1) {
|
||||
lfsp->lfs_inopf = lp->d_secsize/DINODE_SIZE;
|
||||
lfsp->lfs_interleave = interleave;
|
||||
if (roll_id == 0) {
|
||||
/* Pick one; even time(NULL) would almost do */
|
||||
srandom(time(NULL));
|
||||
roll_id = random();
|
||||
}
|
||||
lfsp->lfs_ident = roll_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in parts of superblock that can be computed from file system
|
||||
* size, disk geometry and current time.
|
||||
*/
|
||||
db_per_fb = bsize/lp->d_secsize;
|
||||
lfsp->lfs_fsbtodb = log2(db_per_fb);
|
||||
lfsp->lfs_sushift = log2(lfsp->lfs_sepb);
|
||||
db_per_blk = bsize/lp->d_secsize;
|
||||
lfsp->lfs_blktodb = log2(db_per_blk);
|
||||
lfsp->lfs_fsbtodb = log2(fsize / lp->d_secsize);
|
||||
if (version == 1) {
|
||||
lfsp->lfs_sushift = log2(lfsp->lfs_sepb);
|
||||
lfsp->lfs_fsbtodb = 0;
|
||||
lfsp->lfs_size = partp->p_size >> lfsp->lfs_blktodb;
|
||||
}
|
||||
label_fsb = btofsb(lfsp, roundup(LFS_LABELPAD, fsize));
|
||||
sb_fsb = btofsb(lfsp, roundup(LFS_SBPAD, fsize));
|
||||
lfsp->lfs_fsbpseg = dbtofsb(lfsp, ssize / lp->d_secsize);
|
||||
lfsp->lfs_size = partp->p_size >> lfsp->lfs_fsbtodb;
|
||||
lfsp->lfs_dsize = lfsp->lfs_size - (LFS_LABELPAD >> lfsp->lfs_bshift);
|
||||
lfsp->lfs_nseg = lfsp->lfs_dsize / lfsp->lfs_ssize;
|
||||
lfsp->lfs_dsize = dbtofsb(lfsp, partp->p_size) -
|
||||
MAX(label_fsb, dbtofsb(lfsp, start));
|
||||
lfsp->lfs_nseg = lfsp->lfs_dsize / segtod(lfsp, 1);
|
||||
|
||||
lfsp->lfs_nclean = lfsp->lfs_nseg - 1;
|
||||
lfsp->lfs_maxfilesize = maxtable[lfsp->lfs_bshift] << lfsp->lfs_bshift;
|
||||
@ -327,23 +389,24 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
{
|
||||
if(seg_size == 0 && ssize > (bsize<<1)) {
|
||||
if(!warned_segtoobig) {
|
||||
fprintf(stderr,"Segment size %d is too large; trying smaller sizes.\n", ssize);
|
||||
fprintf(stderr,"Segment size %d is too large; "
|
||||
"trying smaller sizes.\n", ssize);
|
||||
if (ssize == (bsize << 16)) {
|
||||
fprintf(stderr, "(Did you perhaps accidentally leave \"16\" in the disklabel's sgs field?)\n");
|
||||
fprintf(stderr, "(Did you perhaps "
|
||||
"accidentally leave \"16\" "
|
||||
"in the disklabel's sgs "
|
||||
"field?)\n");
|
||||
}
|
||||
}
|
||||
++warned_segtoobig;
|
||||
ssize >>= 1;
|
||||
goto tryagain;
|
||||
}
|
||||
fatal("Could not allocate enough segments with segment size %d and block size %d;\nplease decrease the segment size.\n",
|
||||
ssize, lfsp->lfs_bsize);
|
||||
fatal("Could not allocate enough segments with segment "
|
||||
"size %d and block size %d;\nplease decrease the "
|
||||
"segment size.\n", ssize, lfsp->lfs_bsize);
|
||||
}
|
||||
|
||||
printf("%.1fMB in %d segments of size %d\n",
|
||||
(lfsp->lfs_nseg * (double)ssize) / 1048576.0,
|
||||
lfsp->lfs_nseg, ssize);
|
||||
|
||||
/*
|
||||
* The number of free blocks is set from the number of segments
|
||||
* times the segment size - lfs_minfreesegs (that we never write
|
||||
@ -353,19 +416,24 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
* be written due to fragmentation.
|
||||
*/
|
||||
lfsp->lfs_dsize = (lfsp->lfs_nseg - lfsp->lfs_minfreeseg) *
|
||||
fsbtodb(lfsp, lfsp->lfs_ssize);
|
||||
|
||||
segtod(lfsp, 1);
|
||||
lfsp->lfs_bfree = lfsp->lfs_dsize;
|
||||
lfsp->lfs_bfree -= fsbtodb(lfsp, lfsp->lfs_nseg / 2);
|
||||
lfsp->lfs_bfree -= dbtofsb(lfsp, ((lfsp->lfs_nseg / 2) <<
|
||||
lfsp->lfs_blktodb));
|
||||
|
||||
lfsp->lfs_segtabsz = SEGTABSIZE_SU(lfsp);
|
||||
lfsp->lfs_cleansz = CLEANSIZE_SU(lfsp);
|
||||
if ((lfsp->lfs_tstamp = time(NULL)) == -1)
|
||||
fatal("time: %s", strerror(errno));
|
||||
if (version == 1)
|
||||
lfsp->lfs_otstamp = lfsp->lfs_tstamp;
|
||||
|
||||
if ((sb_interval = lfsp->lfs_nseg / LFS_MAXNUMSB) < LFS_MIN_SBINTERVAL)
|
||||
sb_interval = LFS_MIN_SBINTERVAL;
|
||||
|
||||
/* To start, one inode block and one segsum are dirty metadata */
|
||||
lfsp->lfs_dmeta = 1 + fsbtodb(lfsp, 1);
|
||||
lfsp->lfs_dmeta = btofsb(lfsp, lfsp->lfs_sumsize + lfsp->lfs_ibsize);
|
||||
|
||||
/*
|
||||
* Now, lay out the file system. We need to figure out where
|
||||
* the superblocks go, initialize the checkpoint information
|
||||
@ -376,27 +444,33 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
*/
|
||||
|
||||
/* Figure out where the superblocks are going to live */
|
||||
lfsp->lfs_sboffs[0] = btodb(LFS_LABELPAD);
|
||||
lfsp->lfs_dsize -= btodb(LFS_SBPAD);
|
||||
lfsp->lfs_sboffs[0] = label_fsb;
|
||||
if (version == 1)
|
||||
lfsp->lfs_start = lfsp->lfs_sboffs[0];
|
||||
else
|
||||
lfsp->lfs_start = dbtofsb(lfsp, start);
|
||||
lfsp->lfs_dsize -= sb_fsb;
|
||||
for (i = 1; i < LFS_MAXNUMSB; i++) {
|
||||
sb_addr = ((i * sb_interval) <<
|
||||
(lfsp->lfs_segshift - lfsp->lfs_bshift + lfsp->lfs_fsbtodb))
|
||||
sb_addr = ((i * sb_interval) * segtod(lfsp, 1))
|
||||
+ lfsp->lfs_sboffs[0];
|
||||
if (sb_addr > partp->p_size)
|
||||
/* Segment 0 eats the label, except for version 1 */
|
||||
if (lfsp->lfs_version > 1 && lfsp->lfs_start < label_fsb)
|
||||
sb_addr -= label_fsb - start;
|
||||
if (sb_addr > dbtofsb(lfsp, partp->p_size))
|
||||
break;
|
||||
lfsp->lfs_sboffs[i] = sb_addr;
|
||||
lfsp->lfs_dsize -= btodb(LFS_SBPAD);
|
||||
lfsp->lfs_dsize -= sb_fsb;
|
||||
}
|
||||
|
||||
/* We need >= 2 superblocks */
|
||||
if(lfsp->lfs_sboffs[1] == 0x0) {
|
||||
fatal("Could not assign a disk adress for the second superblock.\nPlease decrease the segment size.\n");
|
||||
fatal("Could not assign a disk adress for the second "
|
||||
"superblock.\nPlease decrease the segment size.\n");
|
||||
}
|
||||
|
||||
last_sb_addr = lfsp->lfs_sboffs[i - 1];
|
||||
lfsp->lfs_lastseg = lfsp->lfs_sboffs[0];
|
||||
lfsp->lfs_nextseg =
|
||||
lfsp->lfs_sboffs[1] ? lfsp->lfs_sboffs[1] : lfsp->lfs_sboffs[0];
|
||||
lfsp->lfs_lastseg = sntod(lfsp, 0);
|
||||
lfsp->lfs_nextseg = sntod(lfsp, 1);
|
||||
lfsp->lfs_curseg = lfsp->lfs_lastseg;
|
||||
|
||||
/*
|
||||
@ -410,36 +484,48 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
fatal("%s", strerror(errno));
|
||||
cleaninfo->clean = lfsp->lfs_nseg - 1;
|
||||
cleaninfo->dirty = 1;
|
||||
if (version > 1) {
|
||||
cleaninfo->free_head = LFS_FIRST_INUM;
|
||||
cleaninfo->free_tail = lfsp->lfs_ifpb - 1;
|
||||
}
|
||||
|
||||
if (!(segtable = malloc(lfsp->lfs_segtabsz << lfsp->lfs_bshift)))
|
||||
fatal("%s", strerror(errno));
|
||||
memset(segtable, 0, lfsp->lfs_segtabsz << lfsp->lfs_bshift);
|
||||
segp = segtable;
|
||||
blocks_used = lfsp->lfs_segtabsz + lfsp->lfs_cleansz + 4;
|
||||
segp->su_nbytes = ((lfsp->lfs_segtabsz + lfsp->lfs_cleansz + 1) <<
|
||||
lfsp->lfs_bshift) +
|
||||
2 * roundup(DIRBLKSIZ,lfsp->lfs_fsize) +
|
||||
2 * roundup(DIRBLKSIZ, lfsp->lfs_fsize) +
|
||||
3 * DINODE_SIZE;
|
||||
segp->su_lastmod = lfsp->lfs_tstamp;
|
||||
if (version == 1)
|
||||
segp->su_olastmod = lfsp->lfs_tstamp;
|
||||
else
|
||||
segp->su_lastmod = lfsp->lfs_tstamp;
|
||||
segp->su_nsums = 1; /* 1 summary blocks */
|
||||
segp->su_ninos = 1; /* 1 inode block */
|
||||
segp->su_flags = SEGUSE_SUPERBLOCK | SEGUSE_DIRTY;
|
||||
|
||||
lfsp->lfs_bfree -= btodb(LFS_SUMMARY_SIZE);
|
||||
lfsp->lfs_bfree -=
|
||||
fsbtodb(lfsp, lfsp->lfs_cleansz + lfsp->lfs_segtabsz + 4);
|
||||
lfsp->lfs_bfree -= btofsb(lfsp, lfsp->lfs_sumsize);
|
||||
lfsp->lfs_bfree -= fragstofsb(lfsp, blkstofrags(lfsp,
|
||||
(lfsp->lfs_cleansz + lfsp->lfs_segtabsz + 4)));
|
||||
|
||||
/*
|
||||
* Now figure out the address of the ifile inode. The inode block
|
||||
* appears immediately after the segment summary.
|
||||
*/
|
||||
lfsp->lfs_idaddr = (LFS_LABELPAD + LFS_SBPAD + LFS_SUMMARY_SIZE) /
|
||||
lp->d_secsize;
|
||||
lfsp->lfs_idaddr = label_fsb + sb_fsb +
|
||||
btofsb(lfsp, lfsp->lfs_sumsize);
|
||||
|
||||
j = 1;
|
||||
for (segp = segtable + 1, i = 1; i < lfsp->lfs_nseg; i++, segp++) {
|
||||
for (i = 1, j = 1; i < lfsp->lfs_nseg; i++) {
|
||||
segp = (SEGUSE *)(((char *)segtable) +
|
||||
((i / lfsp->lfs_sepb) << lfsp->lfs_bshift) +
|
||||
(i % lfsp->lfs_sepb) * (version == 1 ?
|
||||
sizeof(SEGUSE_V1) :
|
||||
sizeof(SEGUSE)));
|
||||
if ((i % sb_interval) == 0 && j < LFS_MAXNUMSB) {
|
||||
segp->su_flags = SEGUSE_SUPERBLOCK;
|
||||
lfsp->lfs_bfree -= (LFS_SBPAD / lp->d_secsize);
|
||||
lfsp->lfs_bfree -= sb_fsb;
|
||||
++j;
|
||||
} else
|
||||
segp->su_flags = 0;
|
||||
@ -466,50 +552,72 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
lfsp->lfs_nfiles = LFS_FIRST_INUM - 1;
|
||||
|
||||
/* Now create a block of disk inodes */
|
||||
if (!(dpagep = malloc(lfsp->lfs_bsize)))
|
||||
if (!(dpagep = malloc(lfsp->lfs_ibsize)))
|
||||
fatal("%s", strerror(errno));
|
||||
dip = (struct dinode *)dpagep;
|
||||
memset(dip, 0, lfsp->lfs_bsize);
|
||||
memset(dip, 0, lfsp->lfs_ibsize);
|
||||
|
||||
/* Create a block of IFILE structures. */
|
||||
if (!(ipagep = (char *)malloc(lfsp->lfs_bsize)))
|
||||
fatal("%s", strerror(errno));
|
||||
ifile = (IFILE *)ipagep;
|
||||
if (version == 1)
|
||||
ifile_v1 = (IFILE_V1 *)ipagep;
|
||||
else
|
||||
ifile = (IFILE *)ipagep;
|
||||
|
||||
/*
|
||||
* Initialize IFILE. It is the next block following the
|
||||
* block of inodes (whose address has been calculated in
|
||||
* lfsp->lfs_idaddr;
|
||||
*/
|
||||
sb_addr = lfsp->lfs_idaddr + lfsp->lfs_bsize / lp->d_secsize;
|
||||
ifibc = 0;
|
||||
sb_addr = lfsp->lfs_idaddr + btofsb(lfsp, lfsp->lfs_ibsize);
|
||||
sb_addr = make_dinode(LFS_IFILE_INUM, dip,
|
||||
(lfsp->lfs_cleansz + lfsp->lfs_segtabsz+1)<<lfsp->lfs_fbshift,
|
||||
blkstofrags(lfsp, lfsp->lfs_cleansz + lfsp->lfs_segtabsz+1),
|
||||
sb_addr, lfsp);
|
||||
dip->di_mode = IFREG|IREAD|IWRITE;
|
||||
dip->di_flags = SF_IMMUTABLE; /* XXX KS */
|
||||
ip = &ifile[LFS_IFILE_INUM];
|
||||
ip->if_version = 1;
|
||||
ip->if_daddr = lfsp->lfs_idaddr;
|
||||
if (version == 1) {
|
||||
ip_v1 = &ifile_v1[LFS_IFILE_INUM];
|
||||
ip_v1->if_version = 1;
|
||||
ip_v1->if_daddr = lfsp->lfs_idaddr;
|
||||
} else {
|
||||
ip = &ifile[LFS_IFILE_INUM];
|
||||
ip->if_version = 1;
|
||||
ip->if_daddr = lfsp->lfs_idaddr;
|
||||
}
|
||||
|
||||
/* Initialize the ROOT Directory */
|
||||
sb_addr = make_dinode(ROOTINO, ++dip, howmany(DIRBLKSIZ,lfsp->lfs_fsize), sb_addr, lfsp);
|
||||
dip->di_mode = IFDIR | UMASK;
|
||||
dip->di_size = DIRBLKSIZ;
|
||||
dip->di_blocks = howmany(roundup(DIRBLKSIZ,lfsp->lfs_fsize),DEV_BSIZE);
|
||||
dip->di_blocks = btofsb(lfsp, roundup(DIRBLKSIZ,lfsp->lfs_fsize));
|
||||
dip->di_nlink = 3;
|
||||
ip = &ifile[ROOTINO];
|
||||
ip->if_version = 1;
|
||||
ip->if_daddr = lfsp->lfs_idaddr;
|
||||
if (version == 1) {
|
||||
ip_v1 = &ifile_v1[ROOTINO];
|
||||
ip_v1->if_version = 1;
|
||||
ip_v1->if_daddr = lfsp->lfs_idaddr;
|
||||
} else {
|
||||
ip = &ifile[ROOTINO];
|
||||
ip->if_version = 1;
|
||||
ip->if_daddr = lfsp->lfs_idaddr;
|
||||
}
|
||||
|
||||
/* Initialize the lost+found Directory */
|
||||
sb_addr = make_dinode(LOSTFOUNDINO, ++dip, howmany(DIRBLKSIZ,lfsp->lfs_fsize), sb_addr, lfsp);
|
||||
dip->di_mode = IFDIR | UMASK;
|
||||
dip->di_size = DIRBLKSIZ;
|
||||
dip->di_blocks = howmany(roundup(DIRBLKSIZ,lfsp->lfs_fsize),DEV_BSIZE);
|
||||
dip->di_blocks = btofsb(lfsp, roundup(DIRBLKSIZ,lfsp->lfs_fsize));
|
||||
dip->di_nlink = 2;
|
||||
ip = &ifile[LOSTFOUNDINO];
|
||||
ip->if_version = 1;
|
||||
ip->if_daddr = lfsp->lfs_idaddr;
|
||||
if (version == 1) {
|
||||
ip_v1 = &ifile_v1[LOSTFOUNDINO];
|
||||
ip_v1->if_version = 1;
|
||||
ip_v1->if_daddr = lfsp->lfs_idaddr;
|
||||
} else {
|
||||
ip = &ifile[LOSTFOUNDINO];
|
||||
ip->if_version = 1;
|
||||
ip->if_daddr = lfsp->lfs_idaddr;
|
||||
}
|
||||
|
||||
/* Make all the other dinodes invalid */
|
||||
for (i = INOPB(lfsp)-3, dip++; i; i--, dip++)
|
||||
@ -517,21 +625,57 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
|
||||
|
||||
/* Link remaining IFILE entries in free list */
|
||||
for (ip = &ifile[LFS_FIRST_INUM], i = LFS_FIRST_INUM;
|
||||
i < lfsp->lfs_ifpb; ++ip) {
|
||||
ip->if_version = 1;
|
||||
ip->if_daddr = LFS_UNUSED_DADDR;
|
||||
ip->if_nextfree = ++i;
|
||||
if (version == 1) {
|
||||
for (ip_v1 = &ifile_v1[LFS_FIRST_INUM], i = LFS_FIRST_INUM;
|
||||
i < lfsp->lfs_ifpb; ++ip_v1) {
|
||||
ip_v1->if_version = 1;
|
||||
ip_v1->if_daddr = LFS_UNUSED_DADDR;
|
||||
ip_v1->if_nextfree = ++i;
|
||||
}
|
||||
ifile_v1[lfsp->lfs_ifpb - 1].if_nextfree = LFS_UNUSED_INUM;
|
||||
} else {
|
||||
for (ip = &ifile[LFS_FIRST_INUM], i = LFS_FIRST_INUM;
|
||||
i < lfsp->lfs_ifpb; ++ip) {
|
||||
ip->if_version = 1;
|
||||
ip->if_daddr = LFS_UNUSED_DADDR;
|
||||
ip->if_nextfree = ++i;
|
||||
}
|
||||
ifile[lfsp->lfs_ifpb - 1].if_nextfree = LFS_UNUSED_INUM;
|
||||
}
|
||||
|
||||
/* XXX Check to make sure it will all fit in one segment. */
|
||||
/* XXX When we have a partial-segment writer this can go away. */
|
||||
if (dtosn(lfsp, sb_addr - 1) != 0) {
|
||||
if (!warned_segtoobig) {
|
||||
fprintf(stderr, "Segment size %d is too small; ",
|
||||
ssize);
|
||||
if (version == 1)
|
||||
while(ssize < fsbtob(lfsp, sb_addr))
|
||||
ssize <<= 1;
|
||||
else
|
||||
ssize = fsbtob(lfsp, sb_addr);
|
||||
fprintf(stderr, "trying size %d.\n", ssize);
|
||||
goto tryagain;
|
||||
}
|
||||
fatal("Can't fit %d bytes into one segment sized %d",
|
||||
fsbtob(lfsp, sb_addr), ssize);
|
||||
}
|
||||
ifile[lfsp->lfs_ifpb - 1].if_nextfree = LFS_UNUSED_INUM;
|
||||
|
||||
/* Now, write the segment */
|
||||
|
||||
printf("Creating a version %d LFS", lfsp->lfs_version);
|
||||
if (lfsp->lfs_version > 1)
|
||||
printf(" with roll-forward ident 0x%x", lfsp->lfs_ident);
|
||||
printf("\n");
|
||||
fssize = (double)lfsp->lfs_nseg;
|
||||
fssize *= (double)ssize;
|
||||
fssize /= 1048576.0;
|
||||
printf("%.1fMB in %d segments of size %d\n", fssize,
|
||||
lfsp->lfs_nseg, ssize);
|
||||
|
||||
/* Adjust blocks_used to take indirect block into account */
|
||||
if(ifib) {
|
||||
++blocks_used;
|
||||
segtable[0].su_nbytes += lfsp->lfs_bsize;
|
||||
}
|
||||
blocks_used += ifibc;
|
||||
segtable[0].su_nbytes += ifibc * lfsp->lfs_bsize;
|
||||
|
||||
/* Compute a checksum across all the data you're writing */
|
||||
dp = datasump = malloc (blocks_used * sizeof(u_long));
|
||||
@ -542,14 +686,17 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
for (i = 0; i < lfsp->lfs_segtabsz; i++)
|
||||
*dp++ = ((u_long *)segtable)[(i << lfsp->lfs_bshift) /
|
||||
sizeof(u_long)]; /* Segusage table */
|
||||
*dp++ = ((u_long *)ifile)[0]; /* Ifile */
|
||||
*dp++ = ((u_long *)ipagep)[0]; /* Ifile */
|
||||
|
||||
/* Still need the root and l+f bytes; get them later */
|
||||
|
||||
/* Write out the inode block */
|
||||
off = LFS_LABELPAD + LFS_SBPAD + LFS_SUMMARY_SIZE;
|
||||
put(fd, off, dpagep, lfsp->lfs_bsize);
|
||||
off += lfsp->lfs_bsize;
|
||||
startoff = fsbtob(lfsp, label_fsb + sb_fsb);
|
||||
if (startoff < fsbtob(lfsp, lfsp->lfs_start))
|
||||
startoff = fsbtob(lfsp, lfsp->lfs_start);
|
||||
off = startoff + lfsp->lfs_sumsize;
|
||||
put(fd, off, dpagep, lfsp->lfs_ibsize);
|
||||
off += lfsp->lfs_ibsize;
|
||||
|
||||
/* Write out the ifile */
|
||||
|
||||
@ -561,13 +708,13 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
off += (lfsp->lfs_segtabsz << lfsp->lfs_bshift);
|
||||
(void)free(segtable);
|
||||
|
||||
put(fd, off, ifile, lfsp->lfs_bsize);
|
||||
put(fd, off, ipagep, lfsp->lfs_bsize);
|
||||
off += lfsp->lfs_bsize;
|
||||
|
||||
/* XXX KS - write the single indirect block */
|
||||
if(ifib) {
|
||||
*dp++ = ((u_long *)ifib)[0];
|
||||
put(fd, off, ifib, lfsp->lfs_bsize);
|
||||
/* Write the indirect blocks */
|
||||
for (i = 0; i < ifibc; i++) {
|
||||
*dp++ = ((u_long *)(ifibp[i]))[0];
|
||||
put(fd, off, ifibp[i], lfsp->lfs_bsize);
|
||||
off += lfsp->lfs_bsize;
|
||||
}
|
||||
|
||||
@ -583,7 +730,7 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
*dp++ = ((u_long *)ipagep)[0];
|
||||
dip = ((struct dinode *)dpagep) + 1;
|
||||
put(fd, off, ipagep, dblksize(lfsp,dip,0));
|
||||
off += dblksize(lfsp,dip,0);
|
||||
off += dblksize(lfsp, dip, 0);
|
||||
|
||||
memset(ipagep, 0, lfsp->lfs_bsize);
|
||||
make_dir(ipagep, lfs_lf_dir,
|
||||
@ -591,22 +738,27 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
*dp++ = ((u_long *)ipagep)[0];
|
||||
dip = ((struct dinode *)dpagep) + 2;
|
||||
put(fd, off, ipagep, dblksize(lfsp,dip,0));
|
||||
off += dblksize(lfsp,dip,0);
|
||||
off += dblksize(lfsp, dip, 0);
|
||||
|
||||
/* Write Superblock */
|
||||
lfsp->lfs_offset = off / lp->d_secsize;
|
||||
lfsp->lfs_avail = lfsp->lfs_dsize -
|
||||
(fsbtodb(lfsp, lfsp->lfs_ssize) - btodb(LFS_SBPAD) -
|
||||
(sntoda(lfsp, 1) - lfsp->lfs_offset));
|
||||
|
||||
lfsp->lfs_offset = btofsb(lfsp, off);
|
||||
lfsp->lfs_avail = lfsp->lfs_dsize - btofsb(lfsp, (off - startoff));
|
||||
if (lfsp->lfs_start < label_fsb)
|
||||
lfsp->lfs_avail -= label_fsb - lfsp->lfs_start;
|
||||
lfsp->lfs_bfree = lfsp->lfs_avail; /* XXX */
|
||||
/* Slop for an imperfect cleaner */
|
||||
lfsp->lfs_avail += (lfsp->lfs_minfreeseg / 2) *
|
||||
fsbtodb(lfsp, lfsp->lfs_ssize);
|
||||
|
||||
lfsp->lfs_avail += segtod(lfsp, lfsp->lfs_minfreeseg / 2);
|
||||
lfsp->lfs_cksum = lfs_sb_cksum(&(lfsp->lfs_dlfs));
|
||||
|
||||
put(fd, (off_t)LFS_LABELPAD, &(lfsp->lfs_dlfs), sizeof(struct dlfs));
|
||||
/* If that was different from lfs_sboffs[0], write the latter too */
|
||||
if (LFS_LABELPAD < fsbtob(lfsp, (off_t)lfsp->lfs_sboffs[0])) {
|
||||
printf("Writing 1st superblock at both %lld and %lld bytes\n",
|
||||
(long long)LFS_LABELPAD,
|
||||
fsbtob(lfsp, (long long)lfsp->lfs_sboffs[0]));
|
||||
put(fd, (off_t)lfsp->lfs_sboffs[0], &(lfsp->lfs_dlfs),
|
||||
sizeof(struct dlfs));
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally, calculate all the fields for the summary structure
|
||||
@ -615,7 +767,13 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
|
||||
memset(&summary,0,sizeof(summary));
|
||||
summary.ss_next = lfsp->lfs_nextseg;
|
||||
summary.ss_create = lfsp->lfs_tstamp;
|
||||
if (version == 1)
|
||||
/* ident is where create was in v1 */
|
||||
summary.ss_ident = lfsp->lfs_tstamp;
|
||||
else {
|
||||
summary.ss_create = lfsp->lfs_tstamp;
|
||||
summary.ss_ident = lfsp->lfs_ident;
|
||||
}
|
||||
summary.ss_nfinfo = 3;
|
||||
summary.ss_ninos = 3;
|
||||
summary.ss_magic = SS_MAGIC;
|
||||
@ -631,12 +789,14 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
* is already counted. Finally, we leave room for 1 inode block
|
||||
* address.
|
||||
*/
|
||||
sum_size = 3*sizeof(FINFO) + sizeof(SEGSUM) + 2*sizeof(daddr_t) +
|
||||
sum_size = (version == 1 ? sizeof(SEGSUM_V1) : sizeof(SEGSUM));
|
||||
sum_size += 3 * sizeof(FINFO) + 2 * sizeof(daddr_t) +
|
||||
(lfsp->lfs_cleansz + lfsp->lfs_segtabsz) * sizeof(ufs_daddr_t);
|
||||
#define SUMERR \
|
||||
"Multiple summary blocks in segment 1 not yet implemented\nsummary is %d bytes."
|
||||
if (sum_size > LFS_SUMMARY_SIZE)
|
||||
fatal(SUMERR, sum_size);
|
||||
|
||||
if (sum_size > lfsp->lfs_sumsize)
|
||||
fatal("Multiple summary blocks in segment 0 "
|
||||
"not yet implemented\n"
|
||||
"summary is %d bytes.", sum_size);
|
||||
|
||||
block_array_size = lfsp->lfs_cleansz + lfsp->lfs_segtabsz + 1;
|
||||
if (block_array_size > NDADDR)
|
||||
@ -654,7 +814,10 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
/* copy into segment */
|
||||
sump = ipagep;
|
||||
memcpy(sump, &summary, sizeof(SEGSUM));
|
||||
sump += sizeof(SEGSUM);
|
||||
if (version == 1)
|
||||
sump += sizeof(SEGSUM_V1);
|
||||
else
|
||||
sump += sizeof(SEGSUM);
|
||||
|
||||
/* Now, add the ifile */
|
||||
file_info.fi_nblocks = block_array_size;
|
||||
@ -683,14 +846,15 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
file_info.fi_lastlength = dblksize(lfsp, dip, 0);
|
||||
memmove(sump, &file_info, sizeof(FINFO));
|
||||
|
||||
((daddr_t *)ipagep)[LFS_SUMMARY_SIZE / sizeof(daddr_t) - 1] =
|
||||
((daddr_t *)ipagep)[lfsp->lfs_sumsize / sizeof(daddr_t) - 1] =
|
||||
lfsp->lfs_idaddr;
|
||||
((SEGSUM *)ipagep)->ss_sumsum = cksum(ipagep+sizeof(summary.ss_sumsum),
|
||||
LFS_SUMMARY_SIZE - sizeof(summary.ss_sumsum));
|
||||
put(fd, (off_t)LFS_LABELPAD + LFS_SBPAD, ipagep, LFS_SUMMARY_SIZE);
|
||||
lfsp->lfs_sumsize - sizeof(summary.ss_sumsum));
|
||||
put(fd, (off_t)startoff, ipagep, lfsp->lfs_sumsize);
|
||||
|
||||
sp = (SEGSUM *)ipagep;
|
||||
sp->ss_create = 0;
|
||||
sp->ss_ident = 0;
|
||||
sp->ss_nfinfo = 0;
|
||||
sp->ss_ninos = 0;
|
||||
sp->ss_datasum = 0;
|
||||
@ -700,23 +864,33 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
|
||||
/* Now write the summary block for the next partial so it's invalid */
|
||||
sp->ss_sumsum =
|
||||
cksum(&sp->ss_datasum, LFS_SUMMARY_SIZE - sizeof(sp->ss_sumsum));
|
||||
put(fd, off, sp, LFS_SUMMARY_SIZE);
|
||||
cksum(&sp->ss_datasum, lfsp->lfs_sumsize - sizeof(sp->ss_sumsum));
|
||||
put(fd, off, sp, lfsp->lfs_sumsize);
|
||||
|
||||
/* Now, write the rest of the superblocks */
|
||||
lfsp->lfs_cksum = lfs_sb_cksum(&(lfsp->lfs_dlfs));
|
||||
printf("super-block backups (for fsck -b #) at:\n");
|
||||
curw = 0;
|
||||
ww = 0;
|
||||
for (i = 0; i < LFS_MAXNUMSB; i++) {
|
||||
seg_addr = lfsp->lfs_sboffs[i];
|
||||
|
||||
printf("%d%s ", seg_addr, (i == LFS_MAXNUMSB - 1 ? "" : ","));
|
||||
sprintf(tbuf, "%d%s ", fsbtodb(lfsp, seg_addr),
|
||||
(i == LFS_MAXNUMSB - 1 ? "" : ","));
|
||||
ww = strlen(tbuf);
|
||||
curw += ww;
|
||||
if (curw + ww > 78) {
|
||||
printf("%s\n", tbuf);
|
||||
curw = 0;
|
||||
} else
|
||||
printf("%s", tbuf);
|
||||
|
||||
/* Leave the time stamp on the alt sb, zero the rest */
|
||||
if(i == 2) {
|
||||
lfsp->lfs_tstamp = 0;
|
||||
lfsp->lfs_cksum = lfs_sb_cksum(&(lfsp->lfs_dlfs));
|
||||
}
|
||||
seg_seek = (off_t)seg_addr * lp->d_secsize;
|
||||
seg_seek = fsbtob(lfsp, (off_t)seg_addr);
|
||||
put(fd, seg_seek, &(lfsp->lfs_dlfs), sizeof(struct dlfs));
|
||||
}
|
||||
printf("\n");
|
||||
@ -726,11 +900,7 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size, minfreeseg)
|
||||
}
|
||||
|
||||
static void
|
||||
put(fd, off, p, len)
|
||||
int fd;
|
||||
off_t off;
|
||||
void *p;
|
||||
size_t len;
|
||||
put(int fd, off_t off, void *p, size_t len)
|
||||
{
|
||||
int wbytes;
|
||||
|
||||
@ -738,9 +908,11 @@ put(fd, off, p, len)
|
||||
return;
|
||||
|
||||
if (lseek(fd, off, SEEK_SET) < 0)
|
||||
fatal("%s: seek: %s", special, strerror(errno));
|
||||
fatal("%s: seek %lld: %s", special, (long long)off,
|
||||
strerror(errno));
|
||||
if ((wbytes = write(fd, p, len)) < 0)
|
||||
fatal("%s: write: %s", special, strerror(errno));
|
||||
fatal("%s: write: %d at %lld: %s", special, len,
|
||||
(long long)off, strerror(errno));
|
||||
if (wbytes != len)
|
||||
fatal("%s: short write (%d, not %ld)",
|
||||
special, wbytes, (u_long) len);
|
||||
@ -752,22 +924,17 @@ put(fd, off, p, len)
|
||||
*/
|
||||
|
||||
static daddr_t
|
||||
make_dinode(ino, dip, nfrags, saddr, lfsp)
|
||||
ino_t ino; /* inode we're creating */
|
||||
struct dinode *dip; /* disk inode */
|
||||
int nfrags; /* number of frags in file */
|
||||
daddr_t saddr; /* starting block address */
|
||||
struct lfs *lfsp; /* superblock */
|
||||
make_dinode(ino_t ino, struct dinode *dip, int nfrags, daddr_t saddr, struct lfs *lfsp)
|
||||
{
|
||||
int db_per_fb, i;
|
||||
int nblocks;
|
||||
int fsb_per_blk, i;
|
||||
int nblocks, bb, ibi, base, factor, lvl;
|
||||
|
||||
nblocks = howmany(nfrags, lfsp->lfs_frag);
|
||||
if(nblocks >= NDADDR)
|
||||
nfrags = roundup(nfrags, lfsp->lfs_frag);
|
||||
|
||||
dip->di_nlink = 1;
|
||||
dip->di_blocks = fragstodb(lfsp, nfrags);
|
||||
dip->di_blocks = fragstofsb(lfsp, nfrags);
|
||||
|
||||
dip->di_size = (nfrags << lfsp->lfs_ffshift);
|
||||
dip->di_atime = dip->di_mtime = dip->di_ctime = lfsp->lfs_tstamp;
|
||||
@ -775,35 +942,64 @@ make_dinode(ino, dip, nfrags, saddr, lfsp)
|
||||
dip->di_inumber = ino;
|
||||
dip->di_gen = 1;
|
||||
|
||||
db_per_fb = 1 << lfsp->lfs_fsbtodb;
|
||||
#if 0
|
||||
if (NDADDR < nblocks)
|
||||
fatal("File ino=%d requires more than the number of direct blocks; please increase block or segment size.",ino);
|
||||
#else
|
||||
if (NDADDR+NINDIR(lfsp) < nblocks) {
|
||||
fatal("File ino=%d requires more blocks than can be accommodated with a single indirect block; please increase segment or block size.",ino);
|
||||
} else if (NDADDR < nblocks) {
|
||||
fprintf(stderr,"Using %d single indirect block(s) for inode %d\n",
|
||||
(nblocks-NDADDR)/NINDIR(lfsp) + 1, ino);
|
||||
dip->di_blocks += db_per_fb;
|
||||
fsb_per_blk = fragstofsb(lfsp, blkstofrags(lfsp, 1));
|
||||
|
||||
if (NDADDR < nblocks) {
|
||||
/* Count up how many indirect blocks we need, recursively */
|
||||
/* XXX We are only called with nblocks > 1 for Ifile */
|
||||
bb = nblocks - NDADDR;
|
||||
while (bb > 0) {
|
||||
bb = howmany(bb, NINDIR(lfsp));
|
||||
ifibc += bb;
|
||||
--bb;
|
||||
}
|
||||
/* printf("using %d indirect blocks for inode %d\n", ifibc, ino); */
|
||||
ifibp = (daddr_t **)malloc(ifibc * sizeof(daddr_t *));
|
||||
for (i = 0; i < ifibc ; i++) {
|
||||
ifibp[i] = (daddr_t *)malloc(lfsp->lfs_bsize);
|
||||
memset(ifibp[i], 0, lfsp->lfs_bsize);
|
||||
}
|
||||
dip->di_blocks += fragstofsb(lfsp, blkstofrags(lfsp, ifibc));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Assign the block addresses for the ifile */
|
||||
for (i = 0; i < MIN(nblocks,NDADDR); i++, saddr += db_per_fb) {
|
||||
for (i = 0; i < MIN(nblocks,NDADDR); i++, saddr += fsb_per_blk) {
|
||||
dip->di_db[i] = saddr;
|
||||
/* printf("direct block %d at 0x%x\n", i, saddr); */
|
||||
}
|
||||
if (nfrags & lfsp->lfs_fbmask) {
|
||||
/* Last block is a fragment */
|
||||
saddr -= db_per_fb - fragstodb(lfsp, nfrags & lfsp->lfs_fbmask);
|
||||
saddr -= fsb_per_blk - fragstofsb(lfsp, nfrags & lfsp->lfs_fbmask);
|
||||
}
|
||||
/* XXX We are only called with nblocks > 1 for Ifile */
|
||||
if(ino == LFS_IFILE_INUM && nblocks > NDADDR) {
|
||||
ifib = (daddr_t *)malloc(lfsp->lfs_bsize);
|
||||
memset(ifib,0,lfsp->lfs_bsize);
|
||||
for (i = 0; i < nblocks-NDADDR; i++, saddr += db_per_fb)
|
||||
ifib[i] = saddr;
|
||||
if(nblocks > NDADDR) {
|
||||
for (i = 0; i < nblocks - NDADDR; i++, saddr += fsb_per_blk) {
|
||||
ifibp[i / NINDIR(lfsp)][i % NINDIR(lfsp)] = saddr;
|
||||
/* printf("direct block %d at 0x%x\n", i + NDADDR, saddr); */
|
||||
}
|
||||
/* printf("indir block ib[0] (%d) at 0x%x\n", -NDADDR, saddr);*/
|
||||
dip->di_ib[0] = saddr;
|
||||
saddr += db_per_fb;
|
||||
saddr += fsb_per_blk;
|
||||
bb = howmany(nblocks - NDADDR, NINDIR(lfsp)) - 1;
|
||||
factor = NINDIR(lfsp);
|
||||
base = -NDADDR - factor;
|
||||
lvl = 1;
|
||||
while (bb > 0) {
|
||||
for (ibi = 0; ibi < bb; i++, ibi++, saddr += fsb_per_blk) {
|
||||
ifibp[i / NINDIR(lfsp)][i % NINDIR(lfsp)] =
|
||||
saddr;
|
||||
/* printf("indir block %d at 0x%x\n",
|
||||
base - ibi * factor - lvl + 1, saddr); */
|
||||
}
|
||||
/* printf("indir block ib[%d] (%d) at 0x%x\n", lvl,
|
||||
base - lvl, saddr); */
|
||||
dip->di_ib[lvl] = saddr;
|
||||
saddr += fsb_per_blk;
|
||||
bb = howmany(bb, NINDIR(lfsp));
|
||||
--bb;
|
||||
factor *= NINDIR(lfsp);
|
||||
base -= factor;
|
||||
++lvl;
|
||||
}
|
||||
}
|
||||
|
||||
return (saddr);
|
||||
@ -815,10 +1011,7 @@ make_dinode(ino, dip, nfrags, saddr, lfsp)
|
||||
* entries in protodir fir in the first DIRBLKSIZ.
|
||||
*/
|
||||
static void
|
||||
make_dir(bufp, protodir, entries)
|
||||
void *bufp;
|
||||
struct direct *protodir;
|
||||
int entries;
|
||||
make_dir(void *bufp, struct direct *protodir, int entries)
|
||||
{
|
||||
char *cp;
|
||||
int i, spcleft;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: misc.c,v 1.1 1999/03/18 17:18:05 perseant Exp $ */
|
||||
/* $NetBSD: misc.c,v 1.2 2001/07/13 20:30:20 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
@ -38,7 +38,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 6/5/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: misc.c,v 1.1 1999/03/18 17:18:05 perseant Exp $");
|
||||
__RCSID("$NetBSD: misc.c,v 1.2 2001/07/13 20:30:20 perseant Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -50,8 +50,7 @@ __RCSID("$NetBSD: misc.c,v 1.1 1999/03/18 17:18:05 perseant Exp $");
|
||||
#include "extern.h"
|
||||
|
||||
u_int
|
||||
log2(num)
|
||||
u_int num;
|
||||
log2(u_int num)
|
||||
{
|
||||
u_int i, limit;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: newfs.c,v 1.6 2000/12/05 19:51:15 perseant Exp $ */
|
||||
/* $NetBSD: newfs.c,v 1.7 2001/07/13 20:30:20 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1989, 1992, 1993
|
||||
@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1989, 1992, 1993\n\
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)newfs.c 8.5 (Berkeley) 5/24/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: newfs.c,v 1.6 2000/12/05 19:51:15 perseant Exp $");
|
||||
__RCSID("$NetBSD: newfs.c,v 1.7 2001/07/13 20:30:20 perseant Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -78,15 +78,17 @@ __RCSID("$NetBSD: newfs.c,v 1.6 2000/12/05 19:51:15 perseant Exp $");
|
||||
|
||||
#define COMPAT /* allow non-labeled disks */
|
||||
|
||||
int Nflag; /* run without writing file system */
|
||||
int version = DFL_VERSION; /* what version of lfs to make */
|
||||
int Nflag = 0; /* run without writing file system */
|
||||
int fssize; /* file system size */
|
||||
int sectorsize; /* bytes/sector */
|
||||
int fsize = 0; /* fragment size */
|
||||
int bsize = 0; /* block size */
|
||||
int ibsize = 0; /* inode block size */
|
||||
int interleave = 0; /* segment interleave */
|
||||
int minfree = MINFREE; /* free space threshold */
|
||||
int minfreeseg = 0; /* free segments reserved for the cleaner */
|
||||
int bbsize = BBSIZE; /* boot block size */
|
||||
int sbsize = SBSIZE; /* superblock size */
|
||||
u_int32_t roll_id = 0; /* roll-forward id */
|
||||
u_long memleft; /* virtual memory available */
|
||||
caddr_t membase; /* start address of memory based filesystem */
|
||||
#ifdef COMPAT
|
||||
@ -97,15 +99,15 @@ int unlabeled;
|
||||
char device[MAXPATHLEN];
|
||||
char *progname, *special;
|
||||
|
||||
int main __P((int, char **));
|
||||
static struct disklabel *getdisklabel __P((char *, int));
|
||||
static struct disklabel *debug_readlabel __P((int));
|
||||
static struct disklabel *getdisklabel(char *, int);
|
||||
static struct disklabel *debug_readlabel(int);
|
||||
#ifdef notdef
|
||||
static void rewritelabel __P((char *, int, struct disklabel *));
|
||||
static void rewritelabel(char *, int, struct disklabel *);
|
||||
#endif
|
||||
static void usage __P((void));
|
||||
static void usage(void);
|
||||
|
||||
#define CHUNKSIZE 65536
|
||||
/* CHUNKSIZE should be larger than MAXPHYS */
|
||||
#define CHUNKSIZE (1024 * 1024)
|
||||
|
||||
static size_t
|
||||
auto_segsize(int fd, off_t len, int version)
|
||||
@ -145,31 +147,27 @@ auto_segsize(int fd, off_t len, int version)
|
||||
if (seeks == 0)
|
||||
seeks = 1;
|
||||
|
||||
printf("bandwidth %ld B/s, seek time %ld ms (%ld seeks/s)\n",
|
||||
printf("bw = %ld B/s, seek time %ld ms (%ld seeks/s)\n",
|
||||
(long)bw, 1000/seeks, seeks);
|
||||
final = dbtob(btodb(4 * bw / seeks));
|
||||
|
||||
/* Version 1 filesystems have po2 segment sizes */
|
||||
if (version == 1) {
|
||||
for (i = 0; final; final >>= 1, i++)
|
||||
;
|
||||
final = 1 << i;
|
||||
}
|
||||
|
||||
printf("using initial segment size %ld\n", (long)final);
|
||||
return final;
|
||||
}
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ch;
|
||||
struct partition *pp;
|
||||
struct disklabel *lp;
|
||||
struct stat st;
|
||||
int debug, force, fsi, fso, segsize, maxpartitions;
|
||||
daddr_t start;
|
||||
char *cp, *opstring;
|
||||
|
||||
if ((progname = strrchr(*argv, '/')) != NULL)
|
||||
@ -181,9 +179,9 @@ main(argc, argv)
|
||||
if (maxpartitions > 26)
|
||||
fatal("insane maxpartitions value %d", maxpartitions);
|
||||
|
||||
opstring = "AB:DFLNb:f:M:m:s:";
|
||||
opstring = "AB:b:DFf:I:i:LM:m:NO:r:s:v:";
|
||||
|
||||
debug = force = segsize = 0;
|
||||
debug = force = segsize = start = 0;
|
||||
while ((ch = getopt(argc, argv, opstring)) != -1)
|
||||
switch(ch) {
|
||||
case 'A': /* Adaptively configure segment size */
|
||||
@ -199,6 +197,9 @@ main(argc, argv)
|
||||
case 'F':
|
||||
force = 1;
|
||||
break;
|
||||
case 'I':
|
||||
interleave = atoi(optarg);
|
||||
break;
|
||||
case 'L': /* Compatibility only */
|
||||
break;
|
||||
case 'M':
|
||||
@ -207,6 +208,9 @@ main(argc, argv)
|
||||
case 'N':
|
||||
Nflag++;
|
||||
break;
|
||||
case 'O':
|
||||
start = atoi(optarg);
|
||||
break;
|
||||
#ifdef COMPAT
|
||||
case 'T':
|
||||
disktype = optarg;
|
||||
@ -220,14 +224,27 @@ main(argc, argv)
|
||||
if ((fsize = atoi(optarg)) <= 0)
|
||||
fatal("%s: bad frag size", optarg);
|
||||
break;
|
||||
case 'i':
|
||||
if ((ibsize = atoi(optarg)) <= 0)
|
||||
fatal("%s: bad inode block size", optarg);
|
||||
break;
|
||||
case 'm':
|
||||
if ((minfree = atoi(optarg)) < 0 || minfree > 99)
|
||||
fatal("%s: bad free space %%\n", optarg);
|
||||
break;
|
||||
case 'r':
|
||||
if ((roll_id = strtoul(optarg, NULL, 0)) == 0)
|
||||
fatal("%s: bad roll-forward id\n", optarg);
|
||||
break;
|
||||
case 's':
|
||||
if ((fssize = atoi(optarg)) <= 0)
|
||||
fatal("%s: bad file system size", optarg);
|
||||
break;
|
||||
case 'v':
|
||||
version = atoi(optarg);
|
||||
if (version <= 0 || version > LFS_VERSION)
|
||||
fatal("%s: bad version", optarg);
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
@ -303,11 +320,12 @@ main(argc, argv)
|
||||
|
||||
/* Try autoconfiguring segment size, if asked to */
|
||||
if (segsize == -1)
|
||||
segsize = auto_segsize(fsi, dbtob(pp->p_size), 1);
|
||||
segsize = auto_segsize(fsi, dbtob(pp->p_size), version);
|
||||
|
||||
/* If we're making a LFS, we break out here */
|
||||
exit(make_lfs(fso, lp, pp, minfree, bsize, fsize, segsize,
|
||||
minfreeseg));
|
||||
minfreeseg, version, start, ibsize, interleave,
|
||||
roll_id));
|
||||
}
|
||||
|
||||
#ifdef COMPAT
|
||||
@ -317,9 +335,7 @@ char lmsg[] = "%s: can't read disk label";
|
||||
#endif
|
||||
|
||||
static struct disklabel *
|
||||
getdisklabel(s, fd)
|
||||
char *s;
|
||||
int fd;
|
||||
getdisklabel(char *s, int fd)
|
||||
{
|
||||
static struct disklabel lab;
|
||||
|
||||
@ -344,8 +360,7 @@ getdisklabel(s, fd)
|
||||
|
||||
|
||||
static struct disklabel *
|
||||
debug_readlabel(fd)
|
||||
int fd;
|
||||
debug_readlabel(int fd)
|
||||
{
|
||||
static struct disklabel lab;
|
||||
int n;
|
||||
@ -360,10 +375,7 @@ debug_readlabel(fd)
|
||||
|
||||
#ifdef notdef
|
||||
static void
|
||||
rewritelabel(s, fd, lp)
|
||||
char *s;
|
||||
int fd;
|
||||
struct disklabel *lp;
|
||||
rewritelabel(char *s, int fd, struct disklabel *lp)
|
||||
{
|
||||
#ifdef COMPAT
|
||||
if (unlabeled)
|
||||
@ -421,12 +433,14 @@ usage()
|
||||
fprintf(stderr, "where fsoptions are:\n");
|
||||
fprintf(stderr, "\t-A (autoconfigure segment size)\n");
|
||||
fprintf(stderr, "\t-B segment size in bytes\n");
|
||||
fprintf(stderr, "\t-D debug\n");
|
||||
fprintf(stderr, "\t-D (debug)\n");
|
||||
fprintf(stderr,
|
||||
"\t-N (do not create file system, just print out parameters)\n");
|
||||
fprintf(stderr, "\t-O first segment offset in sectors\n");
|
||||
fprintf(stderr, "\t-b block size in bytes\n");
|
||||
fprintf(stderr, "\t-f frag size in bytes\n");
|
||||
fprintf(stderr, "\t-m minimum free space %%\n");
|
||||
fprintf(stderr, "\t-s file system size in sectors\n");
|
||||
fprintf(stderr, "\t-v version\n");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: newfs_lfs.8,v 1.12 2001/06/05 11:22:51 wiz Exp $
|
||||
.\" $NetBSD: newfs_lfs.8,v 1.13 2001/07/13 20:30:20 perseant Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
@ -33,7 +33,7 @@
|
||||
.\"
|
||||
.\" @(#)newlfs.8 8.1 (Berkeley) 6/19/93
|
||||
.\"
|
||||
.Dd July 15, 1999
|
||||
.Dd July 12, 2001
|
||||
.Dt NEWFS_LFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -83,21 +83,38 @@ shift, unless these are overridden by command-line flags.
|
||||
The fragment size of the file system in bytes. If not specified,
|
||||
the fragment size is taken from the partition label, or if the partition
|
||||
label indicates 0, a compile-time default of 1K is used.
|
||||
.It Fl I Ar interleave
|
||||
Specify the interleave between segments. The default is zero.
|
||||
.It Fl i
|
||||
The size of an inode block, in bytes. The default is to use the same
|
||||
size as a fragment, or in a v1 filesystem, the same size as a data block.
|
||||
.It Fl L
|
||||
Create a log-structured file system (LFS). This is the default, and this
|
||||
option is provided for compatibility only.
|
||||
.It Fl m Ar free space \&%
|
||||
The percentage of space reserved from normal users; the minimum
|
||||
free space threshold. The default value used is 10%.
|
||||
.It Fl M Ar nsegs
|
||||
Reserve this many segments for use exclusively by the cleaner, instead
|
||||
of letting
|
||||
.Nm
|
||||
do the computation. Do not use this option.
|
||||
.It Fl m Ar free space \&%
|
||||
The percentage of space reserved from normal users; the minimum
|
||||
free space threshold. The default value used is 10%.
|
||||
.It Fl N
|
||||
Do not actually create the filesystem.
|
||||
.It Fl O Ar offset
|
||||
Start the first segment this many sectors from the beginning of the
|
||||
partition. The default is zero.
|
||||
.It Fl r Ar ident
|
||||
For a v2 filesystem, specify the roll-forward identifier for the
|
||||
filesystem. This identifier, a 32-bit numeric quantity,
|
||||
should be different from that of any LFS that may previously
|
||||
have existed on the same disk. By default the
|
||||
identifier is chosen at random.
|
||||
.It Fl s Ar size
|
||||
The size of the file system in sectors.
|
||||
.It Fl v Ar version
|
||||
Make a filesystem with the specified disk layout version. Valid options
|
||||
are 1 (the default) or 2.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr disktab 5 ,
|
||||
|
@ -1,23 +1,20 @@
|
||||
# $NetBSD: TODO,v 1.4 2000/11/17 19:14:41 perseant Exp $
|
||||
# $NetBSD: TODO,v 1.5 2001/07/13 20:30:22 perseant Exp $
|
||||
|
||||
- If we put an LFS onto a striped disk, we want to be able to specify
|
||||
the segment size to be equal to the stripe size, regardless of whether
|
||||
this is a power of two; also, the first segment should just eat the
|
||||
label pad, like the segments eat the superblocks. Then, we could
|
||||
neatly lay out the segments along stripe boundaries. [v2]
|
||||
- Investigate alternate inode locking strategy: Inode locks are useful
|
||||
for locking against simultaneous changes to inode size (balloc,
|
||||
truncate, write) but because the assignment of disk blocks is also
|
||||
covered by the segment lock, we don't really need to pay attention to
|
||||
the inode lock when writing a segment, right? If this is true, the
|
||||
locking problem in lfs_{bmapv,markv} goes away and lfs_reserve can go,
|
||||
too.
|
||||
|
||||
- Working fsck_lfs. (Have something that will verify, need something
|
||||
that will fix too. Really, need a general-purpose external
|
||||
- Fully working fsck_lfs. (Really, need a general-purpose external
|
||||
partial-segment writer.)
|
||||
|
||||
- Roll-forward agent, *at least* to verify the newer superblock's
|
||||
checkpoint (easy) but also to create a valid checkpoint for
|
||||
post-checkpoint writes (requires an external partial-segment writer).
|
||||
|
||||
- Inode blocks are currently the same size as the fs block size; but all
|
||||
the ones I've seen are mostly empty, and this will be especially true
|
||||
if atime information is kept in the ifile instead of the inode. Could
|
||||
we shrink the inode block size to 512? Or parametrize it at fs
|
||||
we shrink the inode block size to DEV_BSIZE? Or parametrize it at fs
|
||||
creation time?
|
||||
|
||||
- Get rid of DEV_BSIZE, pay attention to the media block size at mount time.
|
||||
@ -28,12 +25,6 @@
|
||||
be put back on the *head* of the vnode free list. Make sure we
|
||||
actually do this, since we now take IN_CLEANING off during segment write.
|
||||
|
||||
- Investigate the "unlocked access" in lfs_bmapv, see if we could wait
|
||||
there most of the time? Are we getting inconsistent data?
|
||||
|
||||
- Change the free_lock to be fs-specific, and change the dirvcount to be
|
||||
subsystem-wide.
|
||||
|
||||
- The cleaner could be enhanced to be controlled from other processes,
|
||||
and possibly perform additional tasks:
|
||||
|
||||
@ -82,14 +73,6 @@
|
||||
avoid the problem, and one that reads/writes from the raw disk could
|
||||
fix it.
|
||||
|
||||
- Overlap the version and nextfree fields in the IFILE
|
||||
|
||||
- Change so that only search one sector of inode block file for the
|
||||
inode by using sector addresses in the ifile instead of
|
||||
logical disk addresses.
|
||||
|
||||
- Fix the use of the ifile version field to use the generation number instead.
|
||||
|
||||
- Need to keep vnode v_numoutput up to date for pending writes?
|
||||
|
||||
- If delete a file that's being executed, the version number isn't
|
||||
@ -97,11 +80,6 @@
|
||||
have an inode that no directory references, so the file should be
|
||||
reattached into lost+found.
|
||||
|
||||
- Investigate: should the access time be part of the IFILE:
|
||||
pro: theoretically, saves disk writes
|
||||
con: cacheing inodes should obviate this advantage
|
||||
the IFILE is already humongous
|
||||
|
||||
- Currently there's no notion of write error checking.
|
||||
+ Failed data/inode writes should be rescheduled (kernel level bad blocking).
|
||||
+ Failed superblock writes should cause selection of new superblock
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs.h,v 1.36 2000/12/20 00:24:23 cgd Exp $ */
|
||||
/* $NetBSD: lfs.h,v 1.37 2001/07/13 20:30:22 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
@ -75,12 +75,10 @@
|
||||
*/
|
||||
#define LFS_EAGAIN_FAIL /* markv fail with EAGAIN if ino is locked */
|
||||
#define LFS_TRACK_IOS /* attempt to avoid cleaning segments not yet fully written to disk */
|
||||
#define LFS_CANNOT_ROLLFW /* No roll-forward agent exists */
|
||||
#define LFS_DEBUG_RFW /* print roll-forward debugging info */
|
||||
|
||||
/* #define DEBUG_LFS */ /* Intensive debugging of LFS subsystem */
|
||||
|
||||
/* #define LFS_ATIME_IFILE */ /* Store atime in Ifile, don't push */
|
||||
|
||||
/*
|
||||
* Parameters and generic definitions
|
||||
*/
|
||||
@ -88,6 +86,9 @@
|
||||
#define MIN_FREE_SEGS 2
|
||||
#define LFS_MAX_ACTIVE 10
|
||||
#define LFS_MAXDIROP (desiredvnodes>>2)
|
||||
#ifndef LFS_ATIME_IFILE
|
||||
# define LFS_ATIME_IFILE 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* #define WRITE_THRESHHOLD ((nbuf >> 1) - 10)
|
||||
@ -121,6 +122,7 @@
|
||||
|
||||
/* For convenience */
|
||||
#define IN_ALLMOD (IN_MODIFIED|IN_ACCESS|IN_CHANGE|IN_UPDATE|IN_ACCESSED|IN_CLEANING)
|
||||
|
||||
#define LFS_SET_UINO(ip, flags) do { \
|
||||
if (((flags) & IN_ACCESSED) && !((ip)->i_flag & IN_ACCESSED)) \
|
||||
++(ip)->i_lfs->lfs_uinodes; \
|
||||
@ -144,13 +146,21 @@
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
#ifndef LFS_ATIME_IFILE
|
||||
#define LFS_ITIMES(ip, acc, mod, cre) { \
|
||||
if ((ip)->i_flag & IN_ACCESS) { \
|
||||
#define LFS_ITIMES(ip, acc, mod, cre) do { \
|
||||
if ((ip)->i_flag & IN_ACCESS) { \
|
||||
(ip)->i_ffs_atime = (acc)->tv_sec; \
|
||||
(ip)->i_ffs_atimensec = (acc)->tv_nsec; \
|
||||
LFS_SET_UINO(ip, IN_ACCESSED); \
|
||||
if ((ip)->i_lfs->lfs_version > 1) { \
|
||||
struct buf *ibp; \
|
||||
IFILE *ifp; \
|
||||
\
|
||||
LFS_IENTRY(ifp, ip->i_lfs, ip->i_number, ibp); \
|
||||
ifp->if_atime_sec = (acc)->tv_sec; \
|
||||
ifp->if_atime_nsec = (acc)->tv_nsec; \
|
||||
VOP_BWRITE(ibp); \
|
||||
} else { \
|
||||
LFS_SET_UINO(ip, IN_ACCESSED); \
|
||||
} \
|
||||
} \
|
||||
if ((ip)->i_flag & (IN_CHANGE | IN_UPDATE)) { \
|
||||
if ((ip)->i_flag & IN_UPDATE) { \
|
||||
@ -165,35 +175,10 @@
|
||||
LFS_SET_UINO(ip, IN_MODIFIED); \
|
||||
} \
|
||||
(ip)->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); \
|
||||
}
|
||||
#else
|
||||
# define LFS_ITIMES(ip, acc, mod, cre) { \
|
||||
struct buf *ibp; \
|
||||
IFILE *ifp; \
|
||||
\
|
||||
if ((ip)->i_flag & IN_ACCESS) { \
|
||||
LFS_IENTRY(ifp, ip->i_lfs, ip->i_number, ibp); \
|
||||
ifp->if_atime = (mod); \
|
||||
VOP_BWRITE(bp); \
|
||||
(ip)->i_flag &= ~IN_ACCESS; \
|
||||
} \
|
||||
if ((ip)->i_flag & (IN_CHANGE | IN_UPDATE)) { \
|
||||
LFS_SET_UINO(ip, IN_MODIFIED); \
|
||||
if ((ip)->i_flag & IN_UPDATE) { \
|
||||
(ip)->i_ffs_mtime = (mod)->tv_sec; \
|
||||
(ip)->i_ffs_mtimensec = (mod)->tv_nsec; \
|
||||
(ip)->i_modrev++; \
|
||||
} \
|
||||
if ((ip)->i_flag & IN_CHANGE) { \
|
||||
(ip)->i_ffs_ctime = (cre)->tv_sec; \
|
||||
(ip)->i_ffs_ctimensec = (cre)->tv_nsec; \
|
||||
} \
|
||||
(ip)->i_flag &= ~(IN_CHANGE | IN_UPDATE); \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
} while(0)
|
||||
|
||||
#define WRITEINPROG(vp) (vp->v_dirtyblkhd.lh_first && !(VTOI(vp)->i_flag & (IN_MODIFIED|IN_ACCESSED|IN_CLEANING)))
|
||||
#define WRITEINPROG(vp) (vp->v_dirtyblkhd.lh_first && !(VTOI(vp)->i_flag & \
|
||||
(IN_MODIFIED | IN_ACCESSED | IN_CLEANING)))
|
||||
|
||||
/* Here begins the berkeley code */
|
||||
|
||||
@ -203,21 +188,31 @@
|
||||
/* On-disk and in-memory checkpoint segment usage structure. */
|
||||
typedef struct segusage SEGUSE;
|
||||
struct segusage {
|
||||
u_int32_t su_nbytes; /* number of live bytes */
|
||||
u_int32_t su_lastmod; /* SEGUSE last modified timestamp */
|
||||
u_int16_t su_nsums; /* number of summaries in segment */
|
||||
u_int16_t su_ninos; /* number of inode blocks in seg */
|
||||
u_int32_t su_nbytes; /* 0: number of live bytes */
|
||||
u_int32_t su_olastmod; /* 4: SEGUSE last modified timestamp */
|
||||
u_int16_t su_nsums; /* 8: number of summaries in segment */
|
||||
u_int16_t su_ninos; /* 10: number of inode blocks in seg */
|
||||
|
||||
#define SEGUSE_ACTIVE 0x01 /* segment is currently being written */
|
||||
#define SEGUSE_DIRTY 0x02 /* segment has data in it */
|
||||
#define SEGUSE_SUPERBLOCK 0x04 /* segment contains a superblock */
|
||||
#define SEGUSE_ERROR 0x08 /* cleaner: do not clean segment */
|
||||
u_int32_t su_flags;
|
||||
#define SEGUSE_ACTIVE 0x01 /* segment currently being written */
|
||||
#define SEGUSE_DIRTY 0x02 /* segment has data in it */
|
||||
#define SEGUSE_SUPERBLOCK 0x04 /* segment contains a superblock */
|
||||
#define SEGUSE_ERROR 0x08 /* cleaner: do not clean segment */
|
||||
u_int32_t su_flags; /* 12: segment flags */
|
||||
u_int64_t su_lastmod; /* 16: last modified timestamp */
|
||||
};
|
||||
|
||||
#define SEGUPB(fs) (1 << (fs)->lfs_sushift)
|
||||
typedef struct segusage_v1 SEGUSE_V1;
|
||||
struct segusage_v1 {
|
||||
u_int32_t su_nbytes; /* 0: number of live bytes */
|
||||
u_int32_t su_lastmod; /* 4: SEGUSE last modified timestamp */
|
||||
u_int16_t su_nsums; /* 8: number of summaries in segment */
|
||||
u_int16_t su_ninos; /* 10: number of inode blocks in seg */
|
||||
u_int32_t su_flags; /* 12: segment flags */
|
||||
};
|
||||
|
||||
#define SEGUPB(fs) (fs->lfs_sepb)
|
||||
#define SEGTABSIZE_SU(fs) \
|
||||
(((fs)->lfs_nseg + SEGUPB(fs) - 1) >> (fs)->lfs_sushift)
|
||||
(((fs)->lfs_nseg + SEGUPB(fs) - 1) / (fs)->lfs_sepb)
|
||||
|
||||
/* On-disk file information. One per file with data blocks in the segment. */
|
||||
typedef struct finfo FINFO;
|
||||
@ -226,18 +221,21 @@ struct finfo {
|
||||
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 */
|
||||
ufs_daddr_t fi_blocks[1]; /* array of logical block numbers */
|
||||
ufs_daddr_t fi_blocks[1]; /* array of logical block numbers */
|
||||
};
|
||||
|
||||
|
||||
/* On-disk super block. */
|
||||
struct dlfs {
|
||||
#define LFS_MAGIC 0x070162
|
||||
#define LFS_MAGIC 0x070162
|
||||
u_int32_t dlfs_magic; /* 0: magic number */
|
||||
#define LFS_VERSION 1
|
||||
#define LFS_VERSION 2
|
||||
u_int32_t dlfs_version; /* 4: version number */
|
||||
|
||||
u_int32_t dlfs_size; /* 8: number of blocks in fs */
|
||||
u_int32_t dlfs_ssize; /* 12: number of blocks per segment */
|
||||
u_int32_t dlfs_size; /* 8: number of blocks in fs (v1) */
|
||||
/* number of frags in fs (v2) */
|
||||
u_int32_t dlfs_ssize; /* 12: number of blocks per segment (v1) */
|
||||
/* number of bytes per segment (v2) */
|
||||
u_int32_t dlfs_dsize; /* 16: number of disk blocks in fs */
|
||||
u_int32_t dlfs_bsize; /* 20: file system block size */
|
||||
u_int32_t dlfs_fsize; /* 24: size of frag blocks in fs */
|
||||
@ -256,14 +254,15 @@ struct dlfs {
|
||||
ufs_daddr_t dlfs_curseg; /* 68: current segment being written */
|
||||
ufs_daddr_t dlfs_offset; /* 72: offset in curseg for next partial */
|
||||
ufs_daddr_t dlfs_lastpseg; /* 76: address of last partial written */
|
||||
u_int32_t dlfs_tstamp; /* 80: time stamp */
|
||||
u_int32_t dlfs_inopf; /* 80: v1: time stamp; v2: inodes per frag */
|
||||
#define dlfs_otstamp dlfs_inopf
|
||||
|
||||
/* These are configuration parameters. */
|
||||
u_int32_t dlfs_minfree; /* 84: minimum percentage of free blocks */
|
||||
|
||||
/* These fields can be computed from the others. */
|
||||
u_int64_t dlfs_maxfilesize; /* 88: maximum representable file size */
|
||||
u_int32_t dlfs_dbpseg; /* 96: disk blocks per segment */
|
||||
u_int32_t dlfs_fsbpseg; /* 96: fsb per segment */
|
||||
u_int32_t dlfs_inopb; /* 100: inodes per block */
|
||||
u_int32_t dlfs_ifpb; /* 104: IFILE entries per block */
|
||||
u_int32_t dlfs_sepb; /* 108: SEGUSE entries per block */
|
||||
@ -280,24 +279,34 @@ struct dlfs {
|
||||
u_int64_t dlfs_bmask; /* 152: calc block offset from file offset */
|
||||
u_int64_t dlfs_ffmask; /* 160: calc frag offset from file offset */
|
||||
u_int64_t dlfs_fbmask; /* 168: calc frag offset from block offset */
|
||||
u_int32_t dlfs_fsbtodb; /* 176: fsbtodb and dbtofsb shift constant */
|
||||
u_int32_t dlfs_blktodb; /* 176: blktodb and dbtoblk shift constant */
|
||||
u_int32_t dlfs_sushift; /* 180: fast mult/div for segusage table */
|
||||
|
||||
int32_t dlfs_maxsymlinklen; /* 184: max length of an internal symlink */
|
||||
|
||||
#define LFS_MIN_SBINTERVAL 5 /* minimum superblock segment spacing */
|
||||
#define LFS_MIN_SBINTERVAL 5 /* minimum superblock segment spacing */
|
||||
#define LFS_MAXNUMSB 10 /* 188: superblock disk offsets */
|
||||
ufs_daddr_t dlfs_sboffs[LFS_MAXNUMSB];
|
||||
|
||||
u_int32_t dlfs_nclean; /* 228: Number of clean segments */
|
||||
u_char dlfs_fsmnt[MNAMELEN]; /* 232: name mounted on */
|
||||
/* XXX this is 2 bytes only to pad to a quad boundary */
|
||||
u_int16_t dlfs_clean; /* 322: file system is clean flag */
|
||||
#define LFS_PF_CLEAN 0x1
|
||||
u_int16_t dlfs_pflags; /* 322: file system persistent flags */
|
||||
int32_t dlfs_dmeta; /* 324: total number of dirty summaries */
|
||||
u_int32_t dlfs_minfreeseg; /* 328: segs reserved for cleaner */
|
||||
int8_t dlfs_pad[176]; /* 332: round to 512 bytes */
|
||||
u_int32_t dlfs_sumsize; /* 332: size of summary blocks */
|
||||
u_int64_t dlfs_serial; /* 336: serial number */
|
||||
u_int32_t dlfs_ibsize; /* 344: size of inode blocks */
|
||||
ufs_daddr_t dlfs_start; /* 348: start of segment 0 */
|
||||
u_int64_t dlfs_tstamp; /* 352: time stamp */
|
||||
#define LFS_44INODEFMT 0
|
||||
#define LFS_MAXINODEFMT 0
|
||||
u_int32_t dlfs_inodefmt; /* 360: inode format version */
|
||||
u_int32_t dlfs_interleave; /* 364: segment interleave */
|
||||
u_int32_t dlfs_ident; /* 368: per-fs identifier */
|
||||
u_int32_t dlfs_fsbtodb; /* 372: fsbtodb abd dbtodsb shift constant */
|
||||
int8_t dlfs_pad[132]; /* 376: round to 512 bytes */
|
||||
/* Checksum -- last valid disk field. */
|
||||
u_int32_t dlfs_cksum; /* 508: checksum for superblock checking */
|
||||
u_int32_t dlfs_cksum; /* 508: checksum for superblock checking */
|
||||
};
|
||||
|
||||
/* Maximum number of io's we can have pending at once */
|
||||
@ -326,10 +335,11 @@ struct lfs {
|
||||
#define lfs_curseg lfs_dlfs.dlfs_curseg
|
||||
#define lfs_offset lfs_dlfs.dlfs_offset
|
||||
#define lfs_lastpseg lfs_dlfs.dlfs_lastpseg
|
||||
#define lfs_tstamp lfs_dlfs.dlfs_tstamp
|
||||
#define lfs_otstamp lfs_dlfs.dlfs_inopf
|
||||
#define lfs_inopf lfs_dlfs.dlfs_inopf
|
||||
#define lfs_minfree lfs_dlfs.dlfs_minfree
|
||||
#define lfs_maxfilesize lfs_dlfs.dlfs_maxfilesize
|
||||
#define lfs_dbpseg lfs_dlfs.dlfs_dbpseg
|
||||
#define lfs_fsbpseg lfs_dlfs.dlfs_fsbpseg
|
||||
#define lfs_inopb lfs_dlfs.dlfs_inopb
|
||||
#define lfs_ifpb lfs_dlfs.dlfs_ifpb
|
||||
#define lfs_sepb lfs_dlfs.dlfs_sepb
|
||||
@ -346,16 +356,25 @@ struct lfs {
|
||||
#define lfs_ffshift lfs_dlfs.dlfs_ffshift
|
||||
#define lfs_fbmask lfs_dlfs.dlfs_fbmask
|
||||
#define lfs_fbshift lfs_dlfs.dlfs_fbshift
|
||||
#define lfs_blktodb lfs_dlfs.dlfs_blktodb
|
||||
#define lfs_fsbtodb lfs_dlfs.dlfs_fsbtodb
|
||||
#define lfs_sushift lfs_dlfs.dlfs_sushift
|
||||
#define lfs_maxsymlinklen lfs_dlfs.dlfs_maxsymlinklen
|
||||
#define lfs_sboffs lfs_dlfs.dlfs_sboffs
|
||||
#define lfs_cksum lfs_dlfs.dlfs_cksum
|
||||
#define lfs_clean lfs_dlfs.dlfs_clean
|
||||
#define lfs_pflags lfs_dlfs.dlfs_pflags
|
||||
#define lfs_fsmnt lfs_dlfs.dlfs_fsmnt
|
||||
#define lfs_nclean lfs_dlfs.dlfs_nclean
|
||||
#define lfs_dmeta lfs_dlfs.dlfs_dmeta
|
||||
#define lfs_minfreeseg lfs_dlfs.dlfs_minfreeseg
|
||||
#define lfs_sumsize lfs_dlfs.dlfs_sumsize
|
||||
#define lfs_serial lfs_dlfs.dlfs_serial
|
||||
#define lfs_ibsize lfs_dlfs.dlfs_ibsize
|
||||
#define lfs_start lfs_dlfs.dlfs_start
|
||||
#define lfs_tstamp lfs_dlfs.dlfs_tstamp
|
||||
#define lfs_inodefmt lfs_dlfs.dlfs_inodefmt
|
||||
#define lfs_interleave lfs_dlfs.dlfs_interleave
|
||||
#define lfs_ident lfs_dlfs.dlfs_ident
|
||||
|
||||
/* These fields are set at mount time and are meaningless on disk. */
|
||||
struct segment *lfs_sp; /* current segment being written */
|
||||
@ -375,12 +394,12 @@ struct lfs {
|
||||
#ifdef LFS_TRACK_IOS
|
||||
daddr_t lfs_pending[LFS_THROTTLE]; /* daddrs of pending writes */
|
||||
#endif /* LFS_TRACK_IOS */
|
||||
#ifdef LFS_CANNOT_ROLLFW
|
||||
daddr_t lfs_sbactive; /* disk address of in-progress sb write */
|
||||
#endif
|
||||
struct vnode *lfs_flushvp; /* vnode being flushed */
|
||||
struct vnode *lfs_unlockvp; /* being inactivated in lfs_segunlock */
|
||||
u_int32_t lfs_diropwait; /* # procs waiting on dirop flush */
|
||||
size_t lfs_devbsize; /* Device block size */
|
||||
size_t lfs_devbshift; /* Device block shift */
|
||||
struct lock lfs_freelock;
|
||||
pid_t lfs_rfpid; /* Process ID of roll-forward agent */
|
||||
int lfs_nadirop; /* number of active dirop nodes */
|
||||
@ -416,7 +435,17 @@ struct ifile {
|
||||
#define LFS_UNUSED_DADDR 0 /* out-of-band daddr */
|
||||
ufs_daddr_t if_daddr; /* inode disk address */
|
||||
ino_t if_nextfree; /* next-unallocated inode */
|
||||
#ifdef LFS_ATIME_IFILE
|
||||
/* XXX - when inode format changes, this changes too */
|
||||
u_int32_t if_atime_sec; /* Last access time, seconds */
|
||||
u_int32_t if_atime_nsec; /* and nanoseconds */
|
||||
};
|
||||
|
||||
typedef struct ifile_v1 IFILE_V1;
|
||||
struct ifile_v1 {
|
||||
u_int32_t if_version; /* inode version number */
|
||||
ufs_daddr_t if_daddr; /* inode disk address */
|
||||
ino_t if_nextfree; /* next-unallocated inode */
|
||||
#if LFS_ATIME_IFILE
|
||||
struct timespec if_atime; /* Last access time */
|
||||
#endif
|
||||
};
|
||||
@ -430,6 +459,8 @@ typedef struct _cleanerinfo {
|
||||
u_int32_t dirty; /* number of dirty segments */
|
||||
u_int32_t bfree; /* disk blocks free */
|
||||
int32_t avail; /* disk blocks available */
|
||||
u_int32_t free_head; /* head of the inode free list */
|
||||
u_int32_t free_tail; /* tail of the inode free list */
|
||||
} CLEANERINFO;
|
||||
|
||||
#define CLEANSIZE_SU(fs) \
|
||||
@ -439,32 +470,54 @@ typedef struct _cleanerinfo {
|
||||
* All summary blocks are the same size, so we can always read a summary
|
||||
* block easily from a segment.
|
||||
*/
|
||||
#define LFS_SUMMARY_SIZE 512
|
||||
#define LFS_V1_SUMMARY_SIZE 512
|
||||
#define LFS_DFL_SUMMARY_SIZE 512
|
||||
|
||||
/* On-disk segment summary information */
|
||||
typedef struct segsum SEGSUM;
|
||||
struct segsum {
|
||||
u_int32_t ss_sumsum; /* check sum of summary block */
|
||||
u_int32_t ss_datasum; /* check sum of data */
|
||||
u_int32_t ss_magic; /* segment summary magic number */
|
||||
typedef struct segsum_v1 SEGSUM_V1;
|
||||
struct segsum_v1 {
|
||||
u_int32_t ss_sumsum; /* 0: check sum of summary block */
|
||||
u_int32_t ss_datasum; /* 4: check sum of data */
|
||||
u_int32_t ss_magic; /* 8: segment summary magic number */
|
||||
#define SS_MAGIC 0x061561
|
||||
ufs_daddr_t ss_next; /* next segment */
|
||||
u_int32_t ss_create; /* creation time stamp */
|
||||
u_int16_t ss_nfinfo; /* number of file info structures */
|
||||
u_int16_t ss_ninos; /* number of inodes in summary */
|
||||
ufs_daddr_t ss_next; /* 12: next segment */
|
||||
u_int32_t ss_create; /* 16: creation time stamp */
|
||||
u_int16_t ss_nfinfo; /* 20: number of file info structures */
|
||||
u_int16_t ss_ninos; /* 22: number of inodes in summary */
|
||||
|
||||
#define SS_DIROP 0x01 /* segment begins a dirop */
|
||||
#define SS_CONT 0x02 /* more partials to finish this write*/
|
||||
u_int16_t ss_flags; /* used for directory operations */
|
||||
u_int16_t ss_pad; /* extra space */
|
||||
u_int16_t ss_flags; /* 24: used for directory operations */
|
||||
u_int16_t ss_pad; /* 26: extra space */
|
||||
/* FINFO's and inode daddr's... */
|
||||
};
|
||||
|
||||
typedef struct segsum SEGSUM;
|
||||
struct segsum {
|
||||
u_int32_t ss_sumsum; /* 0: check sum of summary block */
|
||||
u_int32_t ss_datasum; /* 4: check sum of data */
|
||||
u_int32_t ss_magic; /* 8: segment summary magic number */
|
||||
ufs_daddr_t ss_next; /* 12: next segment */
|
||||
u_int32_t ss_ident; /* 16: roll-forward fsid */
|
||||
#define ss_ocreate ss_ident /* ident is where create was in v1 */
|
||||
u_int16_t ss_nfinfo; /* 20: number of file info structures */
|
||||
u_int16_t ss_ninos; /* 22: number of inodes in summary */
|
||||
u_int16_t ss_flags; /* 24: used for directory operations */
|
||||
u_int8_t ss_pad[6]; /* 26: extra space */
|
||||
u_int64_t ss_serial; /* 32: serial number */
|
||||
u_int64_t ss_create; /* 40: time stamp */
|
||||
/* FINFO's and inode daddr's... */
|
||||
};
|
||||
|
||||
#define SEGSUM_SIZE(fs) ((fs)->lfs_version == 1 ? sizeof(SEGSUM_V1) : sizeof(SEGSUM))
|
||||
|
||||
/* NINDIR is the number of indirects in a file system block. */
|
||||
#define NINDIR(fs) ((fs)->lfs_nindir)
|
||||
|
||||
/* INOPB is the number of inodes in a secondary storage block. */
|
||||
#define INOPB(fs) ((fs)->lfs_inopb)
|
||||
/* INOPF is the number of inodes in a fragment. */
|
||||
#define INOPF(fs) ((fs)->lfs_inopf)
|
||||
|
||||
#define blksize(fs, ip, lbn) \
|
||||
(((lbn) >= NDADDR || (ip)->i_ffs_size >= ((lbn) + 1) << (fs)->lfs_bshift) \
|
||||
@ -475,10 +528,20 @@ struct segsum {
|
||||
((int)((loc) & (fs)->lfs_ffmask))
|
||||
#define fsbtodb(fs, b) ((b) << (fs)->lfs_fsbtodb)
|
||||
#define dbtofsb(fs, b) ((b) >> (fs)->lfs_fsbtodb)
|
||||
#define fragstodb(fs, b) ((b) << ((fs)->lfs_fsbtodb - (fs)->lfs_fbshift))
|
||||
#define dbtofrags(fs, b) ((b) >> ((fs)->lfs_fsbtodb - (fs)->lfs_fbshift))
|
||||
#define fragstodb(fs, b) ((b) << ((fs)->lfs_blktodb - (fs)->lfs_fbshift))
|
||||
#define dbtofrags(fs, b) ((b) >> ((fs)->lfs_blktodb - (fs)->lfs_fbshift))
|
||||
#define lblkno(fs, loc) ((loc) >> (fs)->lfs_bshift)
|
||||
#define lblktosize(fs, blk) ((blk) << (fs)->lfs_bshift)
|
||||
/* Same as above, but named like dbtob(), btodb() */
|
||||
#define fsbtob(fs, b) ((b) << ((fs)->lfs_bshift - \
|
||||
(fs)->lfs_blktodb + (fs)->lfs_fsbtodb))
|
||||
#define btofsb(fs, b) ((b) >> ((fs)->lfs_bshift - \
|
||||
(fs)->lfs_blktodb + (fs)->lfs_fsbtodb))
|
||||
#define fsbtofrags(fs, b) ((b) >> ((fs)->lfs_blktodb - (fs)->lfs_fbshift - \
|
||||
(fs)->lfs_fsbtodb))
|
||||
#define fragstofsb(fs, b) ((b) << ((fs)->lfs_blktodb - (fs)->lfs_fbshift - \
|
||||
(fs)->lfs_fsbtodb))
|
||||
#define btofrags(fs, b) ((b) >> (fs)->lfs_ffshift)
|
||||
#define numfrags(fs, loc) /* calculates (loc / fs->lfs_fsize) */ \
|
||||
((loc) >> (fs)->lfs_ffshift)
|
||||
#define blkroundup(fs, size) /* calculates roundup(size, fs->lfs_bsize) */ \
|
||||
@ -497,11 +560,14 @@ struct segsum {
|
||||
(((lbn) >= NDADDR || (dip)->di_size >= ((lbn) + 1) << (fs)->lfs_bshift)\
|
||||
? (fs)->lfs_bsize \
|
||||
: (fragroundup(fs, blkoff(fs, (dip)->di_size))))
|
||||
#define datosn(fs, daddr) /* disk address to segment number */ \
|
||||
(((daddr) - (fs)->lfs_sboffs[0]) / fsbtodb((fs), (fs)->lfs_ssize))
|
||||
#define sntoda(fs, sn) /* segment number to disk address */ \
|
||||
((ufs_daddr_t)((sn) * ((fs)->lfs_ssize << (fs)->lfs_fsbtodb) + \
|
||||
(fs)->lfs_sboffs[0]))
|
||||
|
||||
#define segtod(fs, seg) (((fs)->lfs_version == 1 ? \
|
||||
(fs)->lfs_ssize << (fs)->lfs_blktodb : \
|
||||
btofsb((fs), (fs)->lfs_ssize)) * (seg))
|
||||
#define dtosn(fs, daddr) /* block address to segment number */ \
|
||||
(((daddr) - (fs)->lfs_start) / segtod((fs), 1))
|
||||
#define sntod(fs, sn) /* segment number to disk address */ \
|
||||
((ufs_daddr_t)(segtod((fs), (sn)) + (fs)->lfs_start))
|
||||
|
||||
/* Read in the block with the cleaner info from the ifile. */
|
||||
#define LFS_CLEANERINFO(CP, F, BP) { \
|
||||
@ -523,15 +589,52 @@ struct segsum {
|
||||
brelse(bp); \
|
||||
} while(0)
|
||||
|
||||
#define LFS_GET_HEADFREE(FS, CIP, BP, FREEP) do { \
|
||||
if ((FS)->lfs_version > 1) { \
|
||||
LFS_CLEANERINFO((CIP), (FS), (BP)); \
|
||||
(FS)->lfs_free = (CIP)->free_head; \
|
||||
brelse(BP); \
|
||||
} \
|
||||
*(FREEP) = (FS)->lfs_free; \
|
||||
} while (0)
|
||||
|
||||
#define LFS_PUT_HEADFREE(FS, CIP, BP, VAL) do { \
|
||||
(FS)->lfs_free = (VAL); \
|
||||
if ((FS)->lfs_version > 1) { \
|
||||
LFS_CLEANERINFO((CIP), (FS), (BP)); \
|
||||
(CIP)->free_head = (VAL); \
|
||||
VOP_BWRITE(BP); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LFS_GET_TAILFREE(FS, CIP, BP, FREEP) do { \
|
||||
LFS_CLEANERINFO((CIP), (FS), (BP)); \
|
||||
*(FREEP) = (CIP)->free_tail; \
|
||||
brelse(BP); \
|
||||
} while (0)
|
||||
|
||||
#define LFS_PUT_TAILFREE(FS, CIP, BP, VAL) do { \
|
||||
LFS_CLEANERINFO((CIP), (FS), (BP)); \
|
||||
(CIP)->free_tail = (VAL); \
|
||||
VOP_BWRITE(BP); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* XXX - v1 compatibility code is not allowed to touch if_atime, since it
|
||||
* may not be mapped!
|
||||
*/
|
||||
/* Read in the block with a specific inode from the ifile. */
|
||||
#define LFS_IENTRY(IP, F, IN, BP) { \
|
||||
int _e; \
|
||||
VTOI((F)->lfs_ivnode)->i_flag |= IN_ACCESS; \
|
||||
if ((_e = bread((F)->lfs_ivnode, \
|
||||
(IN) / (F)->lfs_ifpb + (F)->lfs_cleansz + (F)->lfs_segtabsz,\
|
||||
(F)->lfs_bsize, NOCRED, &(BP))) != 0) \
|
||||
(IN) / (F)->lfs_ifpb + (F)->lfs_cleansz + (F)->lfs_segtabsz, \
|
||||
(F)->lfs_bsize, NOCRED, &(BP))) != 0) \
|
||||
panic("lfs: ifile read %d", _e); \
|
||||
(IP) = (IFILE *)(BP)->b_data + (IN) % (F)->lfs_ifpb; \
|
||||
if((F)->lfs_version == 1) \
|
||||
(IP) = (IFILE *)((IFILE_V1 *)(BP)->b_data + (IN) % (F)->lfs_ifpb); \
|
||||
else \
|
||||
(IP) = (IFILE *)(BP)->b_data + (IN) % (F)->lfs_ifpb; \
|
||||
}
|
||||
|
||||
/* Read in the block with a specific segment usage entry from the ifile. */
|
||||
@ -539,10 +642,14 @@ struct segsum {
|
||||
int _e; \
|
||||
VTOI((F)->lfs_ivnode)->i_flag |= IN_ACCESS; \
|
||||
if ((_e = bread((F)->lfs_ivnode, \
|
||||
((IN) >> (F)->lfs_sushift) + (F)->lfs_cleansz, \
|
||||
((IN) / (F)->lfs_sepb) + (F)->lfs_cleansz, \
|
||||
(F)->lfs_bsize, NOCRED, &(BP))) != 0) \
|
||||
panic("lfs: ifile read: %d", _e); \
|
||||
(SP) = (SEGUSE *)(BP)->b_data + ((IN) & ((F)->lfs_sepb - 1)); \
|
||||
if ((F)->lfs_version == 1) \
|
||||
(SP) = (SEGUSE *)((SEGUSE_V1 *)(BP)->b_data + \
|
||||
((IN) & ((F)->lfs_sepb - 1))); \
|
||||
else \
|
||||
(SP) = (SEGUSE *)(BP)->b_data + ((IN) % (F)->lfs_sepb); \
|
||||
}
|
||||
|
||||
/* Determine if a buffer belongs to the ifile */
|
||||
@ -556,12 +663,23 @@ typedef struct block_info {
|
||||
ino_t bi_inode; /* inode # */
|
||||
ufs_daddr_t bi_lbn; /* logical block w/in file */
|
||||
ufs_daddr_t bi_daddr; /* disk address of block */
|
||||
time_t bi_segcreate; /* origin segment create time */
|
||||
u_int64_t bi_segcreate; /* origin segment create time */
|
||||
int bi_version; /* file version number */
|
||||
void *bi_bp; /* data buffer */
|
||||
int bi_size; /* size of the block (if fragment) */
|
||||
} BLOCK_INFO;
|
||||
|
||||
/* Compatibility for 1.5 binaries */
|
||||
typedef struct block_info_15 {
|
||||
ino_t bi_inode; /* inode # */
|
||||
ufs_daddr_t bi_lbn; /* logical block w/in file */
|
||||
ufs_daddr_t bi_daddr; /* disk address of block */
|
||||
u_int32_t bi_segcreate; /* origin segment create time */
|
||||
int bi_version; /* file version number */
|
||||
void *bi_bp; /* data buffer */
|
||||
int bi_size; /* size of the block (if fragment) */
|
||||
} BLOCK_INFO_15;
|
||||
|
||||
/* In-memory description of a segment about to be written. */
|
||||
struct segment {
|
||||
struct lfs *fs; /* file system pointer */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs_alloc.c,v 1.47 2001/05/30 11:57:18 mrg Exp $ */
|
||||
/* $NetBSD: lfs_alloc.c,v 1.48 2001/07/13 20:30:23 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
@ -111,11 +111,12 @@ lfs_rf_valloc(struct lfs *fs, ino_t ino, int version, struct proc *p,
|
||||
struct vnode **vpp)
|
||||
{
|
||||
IFILE *ifp;
|
||||
struct buf *bp;
|
||||
struct buf *bp, *cbp;
|
||||
struct vnode *vp;
|
||||
struct inode *ip;
|
||||
ino_t tino, oldnext;
|
||||
int error;
|
||||
CLEANERINFO *cip;
|
||||
|
||||
/*
|
||||
* First, just try a vget. If the version number is the one we want,
|
||||
@ -148,9 +149,9 @@ lfs_rf_valloc(struct lfs *fs, ino_t ino, int version, struct proc *p,
|
||||
* The inode is not in use. Find it on the free list.
|
||||
*/
|
||||
/* If the Ifile is too short to contain this inum, extend it */
|
||||
while (VTOI(fs->lfs_ivnode)->i_ffs_size <=
|
||||
dbtob(fsbtodb(fs, ino / fs->lfs_ifpb + fs->lfs_cleansz +
|
||||
fs->lfs_segtabsz))) {
|
||||
while (VTOI(fs->lfs_ivnode)->i_ffs_size <= (ino /
|
||||
fs->lfs_ifpb + fs->lfs_cleansz + fs->lfs_segtabsz)
|
||||
<< fs->lfs_bshift) {
|
||||
extend_ifile(fs, NOCRED);
|
||||
}
|
||||
|
||||
@ -159,10 +160,11 @@ lfs_rf_valloc(struct lfs *fs, ino_t ino, int version, struct proc *p,
|
||||
ifp->if_version = version;
|
||||
brelse(bp);
|
||||
|
||||
if (ino == fs->lfs_free) {
|
||||
fs->lfs_free = oldnext;
|
||||
LFS_GET_HEADFREE(fs, cip, cbp, &ino);
|
||||
if (ino) {
|
||||
LFS_PUT_HEADFREE(fs, cip, cbp, oldnext);
|
||||
} else {
|
||||
tino = fs->lfs_free;
|
||||
tino = ino;
|
||||
while(1) {
|
||||
LFS_IENTRY(ifp, fs, tino, bp);
|
||||
if (ifp->if_nextfree == ino ||
|
||||
@ -211,10 +213,12 @@ extend_ifile(struct lfs *fs, struct ucred *cred)
|
||||
struct vnode *vp;
|
||||
struct inode *ip;
|
||||
IFILE *ifp;
|
||||
struct buf *bp;
|
||||
IFILE_V1 *ifp_v1;
|
||||
struct buf *bp, *cbp;
|
||||
int error;
|
||||
ufs_daddr_t i, blkno, max;
|
||||
ino_t oldlast;
|
||||
CLEANERINFO *cip;
|
||||
|
||||
vp = fs->lfs_ivnode;
|
||||
(void)lfs_vref(vp);
|
||||
@ -233,21 +237,33 @@ extend_ifile(struct lfs *fs, struct ucred *cred)
|
||||
|
||||
i = (blkno - fs->lfs_segtabsz - fs->lfs_cleansz) *
|
||||
fs->lfs_ifpb;
|
||||
oldlast = fs->lfs_free;
|
||||
fs->lfs_free = i;
|
||||
LFS_GET_HEADFREE(fs, cip, cbp, &oldlast);
|
||||
LFS_PUT_HEADFREE(fs, cip, cbp, i);
|
||||
#ifdef DIAGNOSTIC
|
||||
if(fs->lfs_free == LFS_UNUSED_INUM)
|
||||
panic("inode 0 allocated [2]");
|
||||
#endif /* DIAGNOSTIC */
|
||||
max = i + fs->lfs_ifpb;
|
||||
/* printf("extend ifile for ino %d--%d\n", i, max); */
|
||||
for (ifp = (struct ifile *)bp->b_data; i < max; ++ifp) {
|
||||
ifp->if_version = 1;
|
||||
ifp->if_daddr = LFS_UNUSED_DADDR;
|
||||
ifp->if_nextfree = ++i;
|
||||
|
||||
if(fs->lfs_version == 1) {
|
||||
for (ifp_v1 = (IFILE_V1 *)bp->b_data; i < max; ++ifp_v1) {
|
||||
ifp_v1->if_version = 1;
|
||||
ifp_v1->if_daddr = LFS_UNUSED_DADDR;
|
||||
ifp_v1->if_nextfree = ++i;
|
||||
}
|
||||
ifp_v1--;
|
||||
ifp_v1->if_nextfree = oldlast;
|
||||
} else {
|
||||
for (ifp = (IFILE *)bp->b_data; i < max; ++ifp) {
|
||||
ifp->if_version = 1;
|
||||
ifp->if_daddr = LFS_UNUSED_DADDR;
|
||||
ifp->if_nextfree = ++i;
|
||||
}
|
||||
ifp--;
|
||||
ifp->if_nextfree = oldlast;
|
||||
}
|
||||
ifp--;
|
||||
ifp->if_nextfree = oldlast;
|
||||
|
||||
(void) VOP_BWRITE(bp); /* Ifile */
|
||||
lfs_vunref(vp);
|
||||
|
||||
@ -258,8 +274,7 @@ extend_ifile(struct lfs *fs, struct ucred *cred)
|
||||
/* ARGSUSED */
|
||||
/* VOP_BWRITE 2i times */
|
||||
int
|
||||
lfs_valloc(v)
|
||||
void *v;
|
||||
lfs_valloc(void *v)
|
||||
{
|
||||
struct vop_valloc_args /* {
|
||||
struct vnode *a_pvp;
|
||||
@ -268,30 +283,33 @@ lfs_valloc(v)
|
||||
struct vnode **a_vpp;
|
||||
} */ *ap = v;
|
||||
struct lfs *fs;
|
||||
struct buf *bp;
|
||||
struct buf *bp, *cbp;
|
||||
struct ifile *ifp;
|
||||
ino_t new_ino;
|
||||
int error;
|
||||
int new_gen;
|
||||
CLEANERINFO *cip;
|
||||
|
||||
fs = VTOI(ap->a_pvp)->i_lfs;
|
||||
if (fs->lfs_ronly)
|
||||
return EROFS;
|
||||
*ap->a_vpp = NULL;
|
||||
|
||||
/*
|
||||
* Use lfs_seglock here, instead of fs->lfs_freelock, to ensure that
|
||||
* the free list is not changed in between the time that the ifile
|
||||
* blocks are written to disk and the time that the superblock is
|
||||
* written to disk.
|
||||
*
|
||||
* XXX this sucks. We should instead encode the head of the free
|
||||
* list into the CLEANERINFO block of the Ifile. [XXX v2]
|
||||
*/
|
||||
lfs_seglock(fs, SEGM_PROT);
|
||||
if (fs->lfs_version == 1) {
|
||||
/*
|
||||
* Use lfs_seglock here, instead of fs->lfs_freelock, to
|
||||
* ensure that the free list is not changed in between
|
||||
* the time that the ifile blocks are written to disk
|
||||
* and the time that the superblock is written to disk.
|
||||
*/
|
||||
lfs_seglock(fs, SEGM_PROT);
|
||||
} else {
|
||||
lockmgr(&fs->lfs_freelock, LK_EXCLUSIVE, 0);
|
||||
}
|
||||
|
||||
/* Get the head of the freelist. */
|
||||
new_ino = fs->lfs_free;
|
||||
LFS_GET_HEADFREE(fs, cip, cbp, &new_ino);
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if(new_ino == LFS_UNUSED_INUM) {
|
||||
#ifdef DEBUG
|
||||
@ -311,15 +329,19 @@ lfs_valloc(v)
|
||||
LFS_IENTRY(ifp, fs, new_ino, bp);
|
||||
if (ifp->if_daddr != LFS_UNUSED_DADDR)
|
||||
panic("lfs_valloc: inuse inode %d on the free list", new_ino);
|
||||
fs->lfs_free = ifp->if_nextfree;
|
||||
LFS_PUT_HEADFREE(fs, cip, cbp, ifp->if_nextfree);
|
||||
|
||||
new_gen = ifp->if_version; /* version was updated by vfree */
|
||||
brelse(bp);
|
||||
|
||||
/* Extend IFILE so that the next lfs_valloc will succeed. */
|
||||
if (fs->lfs_free == LFS_UNUSED_INUM) {
|
||||
if ((error = extend_ifile(fs, ap->a_cred)) != 0) {
|
||||
fs->lfs_free = new_ino;
|
||||
lfs_segunlock(fs);
|
||||
LFS_PUT_HEADFREE(fs, cip, cbp, new_ino);
|
||||
if (fs->lfs_version == 1)
|
||||
lfs_segunlock(fs);
|
||||
else
|
||||
lockmgr(&fs->lfs_freelock, LK_RELEASE, 0);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
@ -327,8 +349,11 @@ lfs_valloc(v)
|
||||
if(fs->lfs_free == LFS_UNUSED_INUM)
|
||||
panic("inode 0 allocated [3]");
|
||||
#endif /* DIAGNOSTIC */
|
||||
|
||||
lfs_segunlock(fs);
|
||||
|
||||
if (fs->lfs_version == 1)
|
||||
lfs_segunlock(fs);
|
||||
else
|
||||
lockmgr(&fs->lfs_freelock, LK_RELEASE, 0);
|
||||
|
||||
return lfs_ialloc(fs, ap->a_pvp, new_ino, new_gen, ap->a_vpp);
|
||||
}
|
||||
@ -340,8 +365,9 @@ lfs_ialloc(struct lfs *fs, struct vnode *pvp, ino_t new_ino, int new_gen,
|
||||
struct inode *ip;
|
||||
struct vnode *vp;
|
||||
IFILE *ifp;
|
||||
struct buf *bp;
|
||||
struct buf *bp, *cbp;
|
||||
int error;
|
||||
CLEANERINFO *cip;
|
||||
|
||||
error = getnewvnode(VT_LFS, pvp->v_mount, lfs_vnodeop_p, &vp);
|
||||
/* printf("lfs_ialloc: ino %d vp %p error %d\n", new_ino, vp, error);*/
|
||||
@ -353,6 +379,7 @@ lfs_ialloc(struct lfs *fs, struct vnode *pvp, ino_t new_ino, int new_gen,
|
||||
lfs_vcreate(pvp->v_mount, new_ino, vp);
|
||||
|
||||
ip = VTOI(vp);
|
||||
LFS_SET_UINO(ip, IN_CHANGE | IN_MODIFIED);
|
||||
/* Zero out the direct and indirect block addresses. */
|
||||
bzero(&ip->i_din, sizeof(ip->i_din));
|
||||
ip->i_din.ffs_din.di_inumber = new_ino;
|
||||
@ -397,8 +424,8 @@ lfs_ialloc(struct lfs *fs, struct vnode *pvp, ino_t new_ino, int new_gen,
|
||||
*/
|
||||
LFS_IENTRY(ifp, fs, new_ino, bp);
|
||||
ifp->if_daddr = LFS_UNUSED_DADDR;
|
||||
ifp->if_nextfree = fs->lfs_free;
|
||||
fs->lfs_free = new_ino;
|
||||
LFS_GET_HEADFREE(fs, cip, cbp, &(ifp->if_nextfree));
|
||||
LFS_PUT_HEADFREE(fs, cip, cbp, new_ino);
|
||||
(void) VOP_BWRITE(bp); /* Ifile */
|
||||
|
||||
*vpp = NULLVP;
|
||||
@ -407,10 +434,7 @@ lfs_ialloc(struct lfs *fs, struct vnode *pvp, ino_t new_ino, int new_gen,
|
||||
|
||||
/* Create a new vnode/inode pair and initialize what fields we can. */
|
||||
void
|
||||
lfs_vcreate(mp, ino, vp)
|
||||
struct mount *mp;
|
||||
ino_t ino;
|
||||
struct vnode *vp;
|
||||
lfs_vcreate(struct mount *mp, ino_t ino, struct vnode *vp)
|
||||
{
|
||||
struct inode *ip;
|
||||
struct ufsmount *ump;
|
||||
@ -440,15 +464,15 @@ lfs_vcreate(mp, ino, vp)
|
||||
ip->i_ffs_blocks = 0;
|
||||
ip->i_lfs_effnblks = 0;
|
||||
ip->i_flag = 0;
|
||||
LFS_SET_UINO(ip, IN_CHANGE | IN_MODIFIED);
|
||||
/* Why was IN_MODIFIED ever set here? */
|
||||
/* LFS_SET_UINO(ip, IN_CHANGE | IN_MODIFIED); */
|
||||
}
|
||||
|
||||
/* Free an inode. */
|
||||
/* ARGUSED */
|
||||
/* VOP_BWRITE 2i times */
|
||||
int
|
||||
lfs_vfree(v)
|
||||
void *v;
|
||||
lfs_vfree(void *v)
|
||||
{
|
||||
struct vop_vfree_args /* {
|
||||
struct vnode *a_pvp;
|
||||
@ -456,13 +480,14 @@ lfs_vfree(v)
|
||||
int a_mode;
|
||||
} */ *ap = v;
|
||||
SEGUSE *sup;
|
||||
struct buf *bp;
|
||||
CLEANERINFO *cip;
|
||||
struct buf *cbp, *bp;
|
||||
struct ifile *ifp;
|
||||
struct inode *ip;
|
||||
struct vnode *vp;
|
||||
struct lfs *fs;
|
||||
ufs_daddr_t old_iaddr;
|
||||
ino_t ino;
|
||||
ino_t ino, otail;
|
||||
extern int lfs_dirvcount;
|
||||
|
||||
/* Get the inode number and file system. */
|
||||
@ -471,17 +496,14 @@ lfs_vfree(v)
|
||||
fs = ip->i_lfs;
|
||||
ino = ip->i_number;
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Right now this is unnecessary since we take the seglock.
|
||||
* But if the seglock is no longer necessary (e.g. we put the
|
||||
* head of the free list into the Ifile) we will need to drain
|
||||
* this vnode of any pending writes.
|
||||
*/
|
||||
if (WRITEINPROG(vp))
|
||||
/* Drain of pending writes */
|
||||
if (fs->lfs_version > 1 && WRITEINPROG(vp))
|
||||
tsleep(vp, (PRIBIO+1), "lfs_vfree", 0);
|
||||
#endif
|
||||
lfs_seglock(fs, SEGM_PROT);
|
||||
|
||||
if (fs->lfs_version == 1)
|
||||
lfs_seglock(fs, SEGM_PROT);
|
||||
else
|
||||
lockmgr(&fs->lfs_freelock, LK_EXCLUSIVE, 0);
|
||||
|
||||
if(vp->v_flag & VDIROP) {
|
||||
--lfs_dirvcount;
|
||||
@ -499,27 +521,43 @@ lfs_vfree(v)
|
||||
|
||||
/*
|
||||
* Set the ifile's inode entry to unused, increment its version number
|
||||
* and link it into the free chain.
|
||||
* and link it onto the free chain.
|
||||
*/
|
||||
LFS_IENTRY(ifp, fs, ino, bp);
|
||||
old_iaddr = ifp->if_daddr;
|
||||
ifp->if_daddr = LFS_UNUSED_DADDR;
|
||||
++ifp->if_version;
|
||||
ifp->if_nextfree = fs->lfs_free;
|
||||
fs->lfs_free = ino;
|
||||
(void) VOP_BWRITE(bp); /* Ifile */
|
||||
if (fs->lfs_version == 1) {
|
||||
LFS_GET_HEADFREE(fs, cip, cbp, &(ifp->if_nextfree));
|
||||
LFS_PUT_HEADFREE(fs, cip, cbp, ino);
|
||||
(void) VOP_BWRITE(bp); /* Ifile */
|
||||
} else {
|
||||
ifp->if_nextfree = LFS_UNUSED_INUM;
|
||||
/*
|
||||
* XXX Writing the freed node here means that it might not
|
||||
* XXX make it into the free list in the event of a crash
|
||||
* XXX (the ifile could be written before the rest of this
|
||||
* XXX completes).
|
||||
*/
|
||||
(void) VOP_BWRITE(bp); /* Ifile */
|
||||
LFS_GET_TAILFREE(fs, cip, cbp, &otail);
|
||||
LFS_IENTRY(ifp, fs, otail, bp);
|
||||
ifp->if_nextfree = ino;
|
||||
VOP_BWRITE(bp);
|
||||
LFS_PUT_TAILFREE(fs, cip, cbp, ino);
|
||||
}
|
||||
#ifdef DIAGNOSTIC
|
||||
if(fs->lfs_free == LFS_UNUSED_INUM) {
|
||||
if(ino == LFS_UNUSED_INUM) {
|
||||
panic("inode 0 freed");
|
||||
}
|
||||
#endif /* DIAGNOSTIC */
|
||||
if (old_iaddr != LFS_UNUSED_DADDR) {
|
||||
LFS_SEGENTRY(sup, fs, datosn(fs, old_iaddr), bp);
|
||||
LFS_SEGENTRY(sup, fs, dtosn(fs, old_iaddr), bp);
|
||||
#ifdef DIAGNOSTIC
|
||||
if (sup->su_nbytes < DINODE_SIZE) {
|
||||
printf("lfs_vfree: negative byte count"
|
||||
" (segment %d short by %d)\n",
|
||||
datosn(fs, old_iaddr),
|
||||
dtosn(fs, old_iaddr),
|
||||
(int)DINODE_SIZE - sup->su_nbytes);
|
||||
panic("lfs_vfree: negative byte count");
|
||||
sup->su_nbytes = DINODE_SIZE;
|
||||
@ -533,6 +571,9 @@ lfs_vfree(v)
|
||||
fs->lfs_fmod = 1;
|
||||
--fs->lfs_nfiles;
|
||||
|
||||
lfs_segunlock(fs);
|
||||
if (fs->lfs_version == 1)
|
||||
lfs_segunlock(fs);
|
||||
else
|
||||
lockmgr(&fs->lfs_freelock, LK_RELEASE, 0);
|
||||
return (0);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs_balloc.c,v 1.28 2001/05/30 11:57:18 mrg Exp $ */
|
||||
/* $NetBSD: lfs_balloc.c,v 1.29 2001/07/13 20:30:23 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
@ -93,7 +93,7 @@
|
||||
#include <ufs/lfs/lfs.h>
|
||||
#include <ufs/lfs/lfs_extern.h>
|
||||
|
||||
int lfs_fragextend __P((struct vnode *, int, int, ufs_daddr_t, struct buf **));
|
||||
int lfs_fragextend(struct vnode *, int, int, ufs_daddr_t, struct buf **, struct ucred *);
|
||||
|
||||
/*
|
||||
* Allocate a block, and to inode and filesystem block accounting for it
|
||||
@ -110,8 +110,7 @@ int lfs_fragextend __P((struct vnode *, int, int, ufs_daddr_t, struct buf **));
|
||||
*/
|
||||
/* VOP_BWRITE NIADDR+2 times */
|
||||
int
|
||||
lfs_balloc(v)
|
||||
void *v;
|
||||
lfs_balloc(void *v)
|
||||
{
|
||||
struct vop_balloc_args /* {
|
||||
struct vnode *a_vp;
|
||||
@ -165,7 +164,8 @@ lfs_balloc(v)
|
||||
osize = blksize(fs, ip, lastblock);
|
||||
if (osize < fs->lfs_bsize && osize > 0) {
|
||||
if ((error = lfs_fragextend(vp, osize, fs->lfs_bsize,
|
||||
lastblock, &bp)))
|
||||
lastblock, &bp,
|
||||
ap->a_cred)))
|
||||
return(error);
|
||||
ip->i_ffs_size = (lastblock + 1) * fs->lfs_bsize;
|
||||
uvm_vnp_setsize(vp, ip->i_ffs_size);
|
||||
@ -188,7 +188,7 @@ lfs_balloc(v)
|
||||
if (lblktosize(fs, lbn) >= ip->i_ffs_size) {
|
||||
/* Brand new block or fragment */
|
||||
frags = numfrags(fs, nsize);
|
||||
bb = fragstodb(fs, frags);
|
||||
bb = fragstofsb(fs, frags);
|
||||
*ap->a_bpp = bp = getblk(vp, lbn, nsize, 0, 0);
|
||||
ip->i_lfs_effnblks += bb;
|
||||
ip->i_lfs->lfs_bfree -= bb;
|
||||
@ -201,7 +201,8 @@ lfs_balloc(v)
|
||||
} else {
|
||||
/* Extend existing block */
|
||||
if ((error =
|
||||
lfs_fragextend(vp, osize, nsize, lbn, &bp)))
|
||||
lfs_fragextend(vp, osize, nsize, lbn, &bp,
|
||||
ap->a_cred)))
|
||||
return error;
|
||||
}
|
||||
*ap->a_bpp = bp;
|
||||
@ -249,7 +250,7 @@ lfs_balloc(v)
|
||||
clrbuf(ibp);
|
||||
ibp->b_blkno = UNWRITTEN;
|
||||
} else if (!(ibp->b_flags & (B_DELWRI | B_DONE))) {
|
||||
ibp->b_blkno = idaddr;
|
||||
ibp->b_blkno = fsbtodb(fs, idaddr);
|
||||
ibp->b_flags |= B_READ;
|
||||
VOP_STRATEGY(ibp);
|
||||
biowait(ibp);
|
||||
@ -273,7 +274,7 @@ lfs_balloc(v)
|
||||
/*
|
||||
* Get the existing block from the cache.
|
||||
*/
|
||||
frags = dbtofrags(fs, bb);
|
||||
frags = fsbtofrags(fs, bb);
|
||||
*ap->a_bpp = bp = getblk(vp, lbn, blksize(fs, ip, lbn), 0, 0);
|
||||
|
||||
/*
|
||||
@ -331,12 +332,7 @@ lfs_balloc(v)
|
||||
|
||||
/* VOP_BWRITE 1 time */
|
||||
int
|
||||
lfs_fragextend(vp, osize, nsize, lbn, bpp)
|
||||
struct vnode *vp;
|
||||
int osize;
|
||||
int nsize;
|
||||
ufs_daddr_t lbn;
|
||||
struct buf **bpp;
|
||||
lfs_fragextend(struct vnode *vp, int osize, int nsize, ufs_daddr_t lbn, struct buf **bpp, struct ucred *cred)
|
||||
{
|
||||
struct inode *ip;
|
||||
struct lfs *fs;
|
||||
@ -349,7 +345,7 @@ lfs_fragextend(vp, osize, nsize, lbn, bpp)
|
||||
|
||||
ip = VTOI(vp);
|
||||
fs = ip->i_lfs;
|
||||
bb = (long)fragstodb(fs, numfrags(fs, nsize - osize));
|
||||
bb = (long)fragstofsb(fs, numfrags(fs, nsize - osize));
|
||||
error = 0;
|
||||
|
||||
/*
|
||||
@ -359,7 +355,7 @@ lfs_fragextend(vp, osize, nsize, lbn, bpp)
|
||||
top:
|
||||
lfs_seglock(fs, SEGM_PROT);
|
||||
|
||||
if (!ISSPACE(fs, bb, curproc->p_ucred)) {
|
||||
if (!ISSPACE(fs, bb, cred)) {
|
||||
error = ENOSPC;
|
||||
goto out;
|
||||
}
|
||||
@ -368,7 +364,7 @@ lfs_fragextend(vp, osize, nsize, lbn, bpp)
|
||||
goto out;
|
||||
}
|
||||
#ifdef QUOTA
|
||||
if ((error = chkdq(ip, bb, curproc->p_ucred, 0))) {
|
||||
if ((error = chkdq(ip, bb, cred, 0))) {
|
||||
brelse(*bpp);
|
||||
goto out;
|
||||
}
|
||||
@ -383,7 +379,7 @@ lfs_fragextend(vp, osize, nsize, lbn, bpp)
|
||||
if (!lfs_fits(fs, bb)) {
|
||||
brelse(*bpp);
|
||||
#ifdef QUOTA
|
||||
chkdq(ip, -bb, curproc->p_ucred, 0);
|
||||
chkdq(ip, -bb, cred, 0);
|
||||
#endif
|
||||
lfs_segunlock(fs);
|
||||
lfs_availwait(fs, bb);
|
||||
@ -399,7 +395,7 @@ lfs_fragextend(vp, osize, nsize, lbn, bpp)
|
||||
* is written, so the on-disk live bytes count is always correct.
|
||||
*/
|
||||
if ((*bpp)->b_blkno > 0) {
|
||||
LFS_SEGENTRY(sup, fs, datosn(fs, (*bpp)->b_blkno), ibp);
|
||||
LFS_SEGENTRY(sup, fs, dtosn(fs, dbtofsb(fs, (*bpp)->b_blkno)), ibp);
|
||||
sup->su_nbytes += (nsize - osize);
|
||||
VOP_BWRITE(ibp);
|
||||
ip->i_ffs_blocks += bb;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs_bio.c,v 1.35 2000/12/03 06:43:36 perseant Exp $ */
|
||||
/* $NetBSD: lfs_bio.c,v 1.36 2001/07/13 20:30:23 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
@ -115,10 +115,7 @@ extern int lfs_dostats;
|
||||
* Called with vp locked. (Note nowever that if nb < 0, vp is ignored.)
|
||||
*/
|
||||
int
|
||||
lfs_reserve(fs, vp, nb)
|
||||
struct lfs *fs;
|
||||
struct vnode *vp;
|
||||
int nb;
|
||||
lfs_reserve(struct lfs *fs, struct vnode *vp, int nb)
|
||||
{
|
||||
CLEANERINFO *cip;
|
||||
struct buf *bp;
|
||||
@ -169,8 +166,7 @@ lfs_reserve(fs, vp, nb)
|
||||
#define CANT_WAIT(BP,F) (IS_IFILE((BP)) || (BP)->b_lblkno<0 || ((F) & BW_CLEAN))
|
||||
|
||||
int
|
||||
lfs_bwrite(v)
|
||||
void *v;
|
||||
lfs_bwrite(void *v)
|
||||
{
|
||||
struct vop_bwrite_args /* {
|
||||
struct buf *a_bp;
|
||||
@ -195,19 +191,19 @@ lfs_bwrite(v)
|
||||
* the segment usage table, plus an ifile page.
|
||||
*/
|
||||
int
|
||||
lfs_fits(struct lfs *fs, int db)
|
||||
lfs_fits(struct lfs *fs, int fsb)
|
||||
{
|
||||
int needed;
|
||||
|
||||
needed = db + btodb(LFS_SUMMARY_SIZE) +
|
||||
needed = fsb + btofsb(fs, fs->lfs_sumsize) +
|
||||
fsbtodb(fs, howmany(fs->lfs_uinodes + 1, INOPB(fs)) +
|
||||
fs->lfs_segtabsz + 1);
|
||||
fs->lfs_segtabsz + btofsb(fs, fs->lfs_sumsize));
|
||||
|
||||
if (needed >= fs->lfs_avail) {
|
||||
#ifdef DEBUG
|
||||
printf("lfs_fits: no fit: db = %d, uinodes = %d, "
|
||||
printf("lfs_fits: no fit: fsb = %d, uinodes = %d, "
|
||||
"needed = %d, avail = %d\n",
|
||||
db, fs->lfs_uinodes, needed, fs->lfs_avail);
|
||||
fsb, fs->lfs_uinodes, needed, fs->lfs_avail);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@ -215,9 +211,7 @@ lfs_fits(struct lfs *fs, int db)
|
||||
}
|
||||
|
||||
int
|
||||
lfs_availwait(fs, db)
|
||||
struct lfs *fs;
|
||||
int db;
|
||||
lfs_availwait(struct lfs *fs, int db)
|
||||
{
|
||||
int error;
|
||||
CLEANERINFO *cip;
|
||||
@ -250,13 +244,11 @@ lfs_availwait(fs, db)
|
||||
}
|
||||
|
||||
int
|
||||
lfs_bwrite_ext(bp, flags)
|
||||
struct buf *bp;
|
||||
int flags;
|
||||
lfs_bwrite_ext(struct buf *bp, int flags)
|
||||
{
|
||||
struct lfs *fs;
|
||||
struct inode *ip;
|
||||
int db, error, s;
|
||||
int fsb, error, s;
|
||||
|
||||
/*
|
||||
* Don't write *any* blocks if we're mounted read-only.
|
||||
@ -288,9 +280,9 @@ lfs_bwrite_ext(bp, flags)
|
||||
*/
|
||||
if (!(bp->b_flags & B_LOCKED)) {
|
||||
fs = VFSTOUFS(bp->b_vp->v_mount)->um_lfs;
|
||||
db = fragstodb(fs, numfrags(fs, bp->b_bcount));
|
||||
fsb = fragstofsb(fs, numfrags(fs, bp->b_bcount));
|
||||
if (!CANT_WAIT(bp, flags)) {
|
||||
if ((error = lfs_availwait(fs, db)) != 0) {
|
||||
if ((error = lfs_availwait(fs, fsb)) != 0) {
|
||||
brelse(bp);
|
||||
return error;
|
||||
}
|
||||
@ -300,9 +292,11 @@ lfs_bwrite_ext(bp, flags)
|
||||
if (bp->b_flags & B_CALL) {
|
||||
LFS_SET_UINO(ip, IN_CLEANING);
|
||||
} else {
|
||||
LFS_SET_UINO(ip, IN_CHANGE | IN_MODIFIED | IN_UPDATE);
|
||||
LFS_SET_UINO(ip, IN_MODIFIED);
|
||||
if (bp->b_lblkno >= 0)
|
||||
LFS_SET_UINO(ip, IN_UPDATE);
|
||||
}
|
||||
fs->lfs_avail -= db;
|
||||
fs->lfs_avail -= fsb;
|
||||
bp->b_flags |= B_DELWRI;
|
||||
|
||||
LFS_LOCK_BUF(bp);
|
||||
@ -322,9 +316,7 @@ lfs_bwrite_ext(bp, flags)
|
||||
}
|
||||
|
||||
void
|
||||
lfs_flush_fs(fs, flags)
|
||||
struct lfs *fs;
|
||||
int flags;
|
||||
lfs_flush_fs(struct lfs *fs, int flags)
|
||||
{
|
||||
if(fs->lfs_ronly == 0 && fs->lfs_dirops == 0)
|
||||
{
|
||||
@ -359,9 +351,7 @@ lfs_flush_fs(fs, flags)
|
||||
* work for multiple file systems, put the count into the mount structure.
|
||||
*/
|
||||
void
|
||||
lfs_flush(fs, flags)
|
||||
struct lfs *fs;
|
||||
int flags;
|
||||
lfs_flush(struct lfs *fs, int flags)
|
||||
{
|
||||
int s;
|
||||
struct mount *mp, *nmp;
|
||||
@ -401,10 +391,7 @@ lfs_flush(fs, flags)
|
||||
}
|
||||
|
||||
int
|
||||
lfs_check(vp, blkno, flags)
|
||||
struct vnode *vp;
|
||||
ufs_daddr_t blkno;
|
||||
int flags;
|
||||
lfs_check(struct vnode *vp, ufs_daddr_t blkno, int flags)
|
||||
{
|
||||
int error;
|
||||
struct lfs *fs;
|
||||
@ -453,7 +440,7 @@ lfs_check(vp, blkno, flags)
|
||||
{
|
||||
if(lfs_dostats)
|
||||
++lfs_stats.wait_exceeded;
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG_LFS
|
||||
printf("lfs_check: waiting: count=%d, bytes=%ld\n",
|
||||
locked_queue_count, locked_queue_bytes);
|
||||
#endif
|
||||
@ -485,26 +472,18 @@ lfs_check(vp, blkno, flags)
|
||||
#ifdef MALLOCLOG
|
||||
# define DOMALLOC(S, T, F) _malloc((S), (T), (F), file, line)
|
||||
struct buf *
|
||||
lfs_newbuf_malloclog(vp, daddr, size, file, line)
|
||||
struct vnode *vp;
|
||||
ufs_daddr_t daddr;
|
||||
size_t size;
|
||||
char *file;
|
||||
int line;
|
||||
lfs_newbuf_malloclog(struct lfs *fs, struct vnode *vp, ufs_daddr_t daddr, size_t size, char *file, int line)
|
||||
#else
|
||||
# define DOMALLOC(S, T, F) malloc((S), (T), (F))
|
||||
struct buf *
|
||||
lfs_newbuf(vp, daddr, size)
|
||||
struct vnode *vp;
|
||||
ufs_daddr_t daddr;
|
||||
size_t size;
|
||||
lfs_newbuf(struct lfs *fs, struct vnode *vp, ufs_daddr_t daddr, size_t size)
|
||||
#endif
|
||||
{
|
||||
struct buf *bp;
|
||||
size_t nbytes;
|
||||
int s;
|
||||
|
||||
nbytes = roundup(size, DEV_BSIZE);
|
||||
nbytes = roundup(size, fsbtob(fs, 1));
|
||||
|
||||
bp = DOMALLOC(sizeof(struct buf), M_SEGMENT, M_WAITOK);
|
||||
bzero(bp, sizeof(struct buf));
|
||||
@ -538,15 +517,11 @@ lfs_newbuf(vp, daddr, size)
|
||||
#ifdef MALLOCLOG
|
||||
# define DOFREE(A, T) _free((A), (T), file, line)
|
||||
void
|
||||
lfs_freebuf_malloclog(bp, file, line)
|
||||
struct buf *bp;
|
||||
char *file;
|
||||
int line;
|
||||
lfs_freebuf_malloclog(struct buf *bp, char *file, int line)
|
||||
#else
|
||||
# define DOFREE(A, T) free((A), (T))
|
||||
void
|
||||
lfs_freebuf(bp)
|
||||
struct buf *bp;
|
||||
lfs_freebuf(struct buf *bp)
|
||||
#endif
|
||||
{
|
||||
int s;
|
||||
@ -579,9 +554,7 @@ extern TAILQ_HEAD(bqueues, buf) bufqueues[BQUEUES];
|
||||
* Don't count malloced buffers, since they don't detract from the total.
|
||||
*/
|
||||
void
|
||||
lfs_countlocked(count, bytes)
|
||||
int *count;
|
||||
long *bytes;
|
||||
lfs_countlocked(int *count, long *bytes)
|
||||
{
|
||||
struct buf *bp;
|
||||
int n = 0;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs_cksum.c,v 1.15 2001/02/04 21:51:19 christos Exp $ */
|
||||
/* $NetBSD: lfs_cksum.c,v 1.16 2001/07/13 20:30:23 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
@ -91,9 +91,7 @@
|
||||
* Use the TCP/IP checksum instead.
|
||||
*/
|
||||
u_int32_t
|
||||
cksum(str, len)
|
||||
void *str;
|
||||
size_t len;
|
||||
cksum(void *str, size_t len)
|
||||
{
|
||||
u_int32_t sum;
|
||||
|
||||
@ -106,8 +104,7 @@ cksum(str, len)
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
lfs_sb_cksum(fs)
|
||||
struct dlfs *fs;
|
||||
lfs_sb_cksum(struct dlfs *fs)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs_debug.c,v 1.11 2000/09/09 04:49:54 perseant Exp $ */
|
||||
/* $NetBSD: lfs_debug.c,v 1.12 2001/07/13 20:30:23 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
@ -83,8 +83,7 @@
|
||||
#include <ufs/lfs/lfs_extern.h>
|
||||
|
||||
void
|
||||
lfs_dump_super(lfsp)
|
||||
struct lfs *lfsp;
|
||||
lfs_dump_super(struct lfs *lfsp)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -146,12 +145,11 @@ lfs_dump_super(lfsp)
|
||||
"nextseg ", lfsp->lfs_nextseg,
|
||||
"curseg ", lfsp->lfs_curseg,
|
||||
"offset ", lfsp->lfs_offset);
|
||||
printf("tstamp %x\n", lfsp->lfs_tstamp);
|
||||
printf("tstamp %llx\n", (long long)lfsp->lfs_tstamp);
|
||||
}
|
||||
|
||||
void
|
||||
lfs_dump_dinode(dip)
|
||||
struct dinode *dip;
|
||||
lfs_dump_dinode(struct dinode *dip)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -195,11 +193,11 @@ lfs_check_segsum(struct lfs *fs, struct segment *sp, char *file, int line)
|
||||
|
||||
if(sp->sum_bytes_left > 484) {
|
||||
printf("%s:%d: bad value (%d = -%d) for sum_bytes_left\n",
|
||||
file, line, sp->sum_bytes_left, LFS_SUMMARY_SIZE-sp->sum_bytes_left);
|
||||
file, line, sp->sum_bytes_left, fs->lfs_sumsize-sp->sum_bytes_left);
|
||||
panic("too many bytes");
|
||||
}
|
||||
|
||||
actual = LFS_SUMMARY_SIZE
|
||||
actual = fs->lfs_sumsize
|
||||
/* amount taken up by FINFOs */
|
||||
- ((char *)&(sp->fip->fi_blocks[sp->fip->fi_nblocks]) - (char *)(sp->segsum))
|
||||
/* amount taken up by inode blocks */
|
||||
@ -217,16 +215,16 @@ lfs_check_segsum(struct lfs *fs, struct segment *sp, char *file, int line)
|
||||
if(actual != sp->sum_bytes_left)
|
||||
printf("%s:%d: warning: segsum miscalc at %d (-%d => %d)\n",
|
||||
file, line, sp->sum_bytes_left,
|
||||
LFS_SUMMARY_SIZE-sp->sum_bytes_left,
|
||||
fs->lfs_sumsize-sp->sum_bytes_left,
|
||||
actual);
|
||||
#endif
|
||||
if(sp->sum_bytes_left > 0
|
||||
&& ((char *)(sp->segsum))[LFS_SUMMARY_SIZE
|
||||
&& ((char *)(sp->segsum))[fs->lfs_sumsize
|
||||
- sizeof(ufs_daddr_t) * ((sp->ninodes+INOPB(fs)-1) / INOPB(fs))
|
||||
- sp->sum_bytes_left] != '\0') {
|
||||
printf("%s:%d: warning: segsum overwrite at %d (-%d => %d)\n",
|
||||
file, line, sp->sum_bytes_left,
|
||||
LFS_SUMMARY_SIZE-sp->sum_bytes_left,
|
||||
fs->lfs_sumsize-sp->sum_bytes_left,
|
||||
actual);
|
||||
#ifdef DDB
|
||||
Debugger();
|
||||
@ -235,11 +233,7 @@ lfs_check_segsum(struct lfs *fs, struct segment *sp, char *file, int line)
|
||||
}
|
||||
|
||||
void
|
||||
lfs_check_bpp(fs, sp, file, line)
|
||||
struct lfs *fs;
|
||||
struct segment *sp;
|
||||
char *file;
|
||||
int line;
|
||||
lfs_check_bpp(struct lfs *fs, struct segment *sp, char *file, int line)
|
||||
{
|
||||
daddr_t blkno;
|
||||
struct buf **bpp;
|
||||
@ -263,7 +257,7 @@ lfs_check_bpp(fs, sp, file, line)
|
||||
(*bpp)->b_blkno);
|
||||
}
|
||||
}
|
||||
blkno += btodb((*bpp)->b_bcount);
|
||||
blkno += fsbtodb(fs, btofsb(fs, (*bpp)->b_bcount));
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs_extern.h,v 1.24 2000/12/03 05:56:27 perseant Exp $ */
|
||||
/* $NetBSD: lfs_extern.h,v 1.25 2001/07/13 20:30:23 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
@ -111,122 +111,121 @@ extern struct pool lfs_inode_pool; /* memory pool for inodes */
|
||||
|
||||
__BEGIN_DECLS
|
||||
/* lfs_alloc.c */
|
||||
int lfs_rf_valloc __P((struct lfs *, ino_t, int, struct proc *, struct vnode **));
|
||||
void lfs_vcreate __P((struct mount *, ino_t, struct vnode *));
|
||||
int lfs_rf_valloc(struct lfs *, ino_t, int, struct proc *, struct vnode **);
|
||||
void lfs_vcreate(struct mount *, ino_t, struct vnode *);
|
||||
/* lfs_bio.c */
|
||||
int lfs_availwait __P((struct lfs *, int));
|
||||
int lfs_bwrite_ext __P((struct buf *, int));
|
||||
int lfs_fits __P((struct lfs *, int));
|
||||
void lfs_flush_fs __P((struct lfs *, int));
|
||||
void lfs_flush __P((struct lfs *, int));
|
||||
int lfs_check __P((struct vnode *, ufs_daddr_t, int));
|
||||
int lfs_availwait(struct lfs *, int);
|
||||
int lfs_bwrite_ext(struct buf *, int);
|
||||
int lfs_fits(struct lfs *, int);
|
||||
void lfs_flush_fs(struct lfs *, int);
|
||||
void lfs_flush(struct lfs *, int);
|
||||
int lfs_check(struct vnode *, ufs_daddr_t, int);
|
||||
#ifdef MALLOCLOG
|
||||
void lfs_freebuf_malloclog __P((struct buf *, char *, int));
|
||||
struct buf *lfs_newbuf_malloclog __P((struct vnode *, ufs_daddr_t, size_t,
|
||||
char *, int));
|
||||
void lfs_freebuf_malloclog(struct buf *, char *, int);
|
||||
struct buf *lfs_newbuf_malloclog(struct lfs *, struct vnode *,
|
||||
ufs_daddr_t, size_t, char *, int);
|
||||
#define lfs_freebuf(BP) lfs_freebuf_malloclog((BP), __FILE__, __LINE__)
|
||||
#define lfs_newbuf(V, A, S) lfs_newbuf_malloclog((V),(A),(S),__FILE__,__LINE__)
|
||||
#define lfs_newbuf(F, V, A, S) lfs_newbuf_malloclog((F),(V),(A),(S),__FILE__,__LINE__)
|
||||
#else
|
||||
void lfs_freebuf __P((struct buf *));
|
||||
struct buf *lfs_newbuf __P((struct vnode *, ufs_daddr_t, size_t));
|
||||
void lfs_freebuf(struct buf *);
|
||||
struct buf *lfs_newbuf(struct lfs *, struct vnode *, ufs_daddr_t, size_t);
|
||||
#endif
|
||||
void lfs_countlocked __P((int *, long *));
|
||||
int lfs_reserve __P((struct lfs *, struct vnode *, int));
|
||||
void lfs_countlocked(int *, long *);
|
||||
int lfs_reserve(struct lfs *, struct vnode *, int);
|
||||
|
||||
/* lfs_cksum.c */
|
||||
u_int32_t cksum __P((void *, size_t));
|
||||
u_int32_t lfs_sb_cksum __P((struct dlfs *));
|
||||
u_int32_t cksum(void *, size_t);
|
||||
u_int32_t lfs_sb_cksum(struct dlfs *);
|
||||
|
||||
/* lfs_debug.c */
|
||||
#ifdef DEBUG
|
||||
void lfs_dump_super __P((struct lfs *));
|
||||
void lfs_dump_dinode __P((struct dinode *));
|
||||
void lfs_check_bpp __P((struct lfs *, struct segment *, char *, int));
|
||||
void lfs_check_segsum __P((struct lfs *, struct segment *, char *, int));
|
||||
void lfs_dump_super(struct lfs *);
|
||||
void lfs_dump_dinode(struct dinode *);
|
||||
void lfs_check_bpp(struct lfs *, struct segment *, char *, int);
|
||||
void lfs_check_segsum(struct lfs *, struct segment *, char *, int);
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* lfs_inode.c */
|
||||
struct dinode *lfs_ifind __P((struct lfs *, ino_t, struct buf *));
|
||||
struct dinode *lfs_ifind(struct lfs *, ino_t, struct buf *);
|
||||
|
||||
/* lfs_segment.c */
|
||||
void lfs_imtime __P((struct lfs *));
|
||||
int lfs_vflush __P((struct vnode *));
|
||||
int lfs_writevnodes __P((struct lfs *, struct mount *, struct segment *, int));
|
||||
int lfs_segwrite __P((struct mount *, int));
|
||||
void lfs_writefile __P((struct lfs *, struct segment *, struct vnode *));
|
||||
int lfs_writeinode __P((struct lfs *, struct segment *, struct inode *));
|
||||
int lfs_gatherblock __P((struct segment *, struct buf *, int *));
|
||||
int lfs_gather __P((struct lfs *, struct segment *, struct vnode *, int (*match )__P ((struct lfs *, struct buf *))));
|
||||
void lfs_updatemeta __P((struct segment *));
|
||||
int lfs_initseg __P((struct lfs *));
|
||||
void lfs_newseg __P((struct lfs *));
|
||||
int lfs_writeseg __P((struct lfs *, struct segment *));
|
||||
void lfs_writesuper __P((struct lfs *, daddr_t));
|
||||
int lfs_match_data __P((struct lfs *, struct buf *));
|
||||
int lfs_match_indir __P((struct lfs *, struct buf *));
|
||||
int lfs_match_dindir __P((struct lfs *, struct buf *));
|
||||
int lfs_match_tindir __P((struct lfs *, struct buf *));
|
||||
void lfs_callback __P((struct buf *));
|
||||
void lfs_supercallback __P((struct buf *));
|
||||
void lfs_shellsort __P((struct buf **, ufs_daddr_t *, int));
|
||||
int lfs_vref __P((struct vnode *));
|
||||
void lfs_vunref __P((struct vnode *));
|
||||
void lfs_vunref_head __P((struct vnode *));
|
||||
void lfs_imtime(struct lfs *);
|
||||
int lfs_vflush(struct vnode *);
|
||||
int lfs_writevnodes(struct lfs *, struct mount *, struct segment *, int);
|
||||
int lfs_segwrite(struct mount *, int);
|
||||
void lfs_writefile(struct lfs *, struct segment *, struct vnode *);
|
||||
int lfs_writeinode(struct lfs *, struct segment *, struct inode *);
|
||||
int lfs_gatherblock(struct segment *, struct buf *, int *);
|
||||
int lfs_gather(struct lfs *, struct segment *, struct vnode *, int (*match )(struct lfs *, struct buf *));
|
||||
void lfs_updatemeta(struct segment *);
|
||||
int lfs_initseg(struct lfs *);
|
||||
void lfs_newseg(struct lfs *);
|
||||
int lfs_writeseg(struct lfs *, struct segment *);
|
||||
void lfs_writesuper(struct lfs *, daddr_t);
|
||||
int lfs_match_data(struct lfs *, struct buf *);
|
||||
int lfs_match_indir(struct lfs *, struct buf *);
|
||||
int lfs_match_dindir(struct lfs *, struct buf *);
|
||||
int lfs_match_tindir(struct lfs *, struct buf *);
|
||||
void lfs_callback(struct buf *);
|
||||
void lfs_supercallback(struct buf *);
|
||||
void lfs_shellsort(struct buf **, ufs_daddr_t *, int);
|
||||
int lfs_vref(struct vnode *);
|
||||
void lfs_vunref(struct vnode *);
|
||||
void lfs_vunref_head(struct vnode *);
|
||||
|
||||
/* lfs_subr.c */
|
||||
void lfs_seglock __P((struct lfs *, unsigned long));
|
||||
void lfs_segunlock __P((struct lfs *));
|
||||
void lfs_seglock(struct lfs *, unsigned long);
|
||||
void lfs_segunlock(struct lfs *);
|
||||
|
||||
/* lfs_syscalls.c */
|
||||
int lfs_fastvget __P((struct mount *, ino_t, ufs_daddr_t, struct vnode **, struct dinode *, int *));
|
||||
struct buf *lfs_fakebuf __P((struct vnode *, int, size_t, caddr_t));
|
||||
int lfs_fastvget(struct mount *, ino_t, ufs_daddr_t, struct vnode **, struct dinode *, int *);
|
||||
struct buf *lfs_fakebuf(struct vnode *, int, size_t, caddr_t);
|
||||
|
||||
/* lfs_vfsops.c */
|
||||
void lfs_init __P((void));
|
||||
void lfs_done __P((void));
|
||||
int lfs_mountroot __P((void));
|
||||
int lfs_mount __P((struct mount *, const char *, void *, struct nameidata *, struct proc *));
|
||||
int lfs_mountfs __P((struct vnode *, struct mount *, struct proc *));
|
||||
int lfs_unmount __P((struct mount *, int, struct proc *));
|
||||
int lfs_statfs __P((struct mount *, struct statfs *, struct proc *));
|
||||
int lfs_sync __P((struct mount *, int, struct ucred *, struct proc *));
|
||||
int lfs_vget __P((struct mount *, ino_t, struct vnode **));
|
||||
int lfs_fhtovp __P((struct mount *, struct fid *, struct vnode **));
|
||||
int lfs_vptofh __P((struct vnode *, struct fid *));
|
||||
int lfs_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
|
||||
struct proc *));
|
||||
void lfs_init(void);
|
||||
void lfs_done(void);
|
||||
int lfs_mountroot(void);
|
||||
int lfs_mount(struct mount *, const char *, void *, struct nameidata *, struct proc *);
|
||||
int lfs_mountfs(struct vnode *, struct mount *, struct proc *);
|
||||
int lfs_unmount(struct mount *, int, struct proc *);
|
||||
int lfs_statfs(struct mount *, struct statfs *, struct proc *);
|
||||
int lfs_sync(struct mount *, int, struct ucred *, struct proc *);
|
||||
int lfs_vget(struct mount *, ino_t, struct vnode **);
|
||||
int lfs_fhtovp(struct mount *, struct fid *, struct vnode **);
|
||||
int lfs_vptofh(struct vnode *, struct fid *);
|
||||
int lfs_sysctl(int *, u_int, void *, size_t *, void *, size_t, struct proc *);
|
||||
|
||||
/* lfs_vnops.c */
|
||||
void lfs_unmark_vnode __P((struct vnode *));
|
||||
void lfs_itimes __P((struct inode *, struct timespec *, struct timespec *,
|
||||
struct timespec *));
|
||||
void lfs_unmark_vnode(struct vnode *);
|
||||
void lfs_itimes(struct inode *, struct timespec *, struct timespec *,
|
||||
struct timespec *);
|
||||
|
||||
int lfs_balloc __P((void *));
|
||||
int lfs_valloc __P((void *));
|
||||
int lfs_vfree __P((void *));
|
||||
int lfs_bwrite __P((void *));
|
||||
int lfs_update __P((void *));
|
||||
int lfs_truncate __P((void *));
|
||||
int lfs_blkatoff __P((void *));
|
||||
int lfs_fsync __P((void *));
|
||||
int lfs_symlink __P((void *));
|
||||
int lfs_mknod __P((void *));
|
||||
int lfs_create __P((void *));
|
||||
int lfs_mkdir __P((void *));
|
||||
int lfs_read __P((void *));
|
||||
int lfs_remove __P((void *));
|
||||
int lfs_rmdir __P((void *));
|
||||
int lfs_link __P((void *));
|
||||
int lfs_rename __P((void *));
|
||||
int lfs_getattr __P((void *));
|
||||
int lfs_close __P((void *));
|
||||
int lfs_inactive __P((void *));
|
||||
int lfs_reclaim __P((void *));
|
||||
int lfs_write __P((void *));
|
||||
int lfs_whiteout __P((void *));
|
||||
int lfs_balloc (void *);
|
||||
int lfs_valloc (void *);
|
||||
int lfs_vfree (void *);
|
||||
int lfs_bwrite (void *);
|
||||
int lfs_update (void *);
|
||||
int lfs_truncate(void *);
|
||||
int lfs_blkatoff(void *);
|
||||
int lfs_fsync (void *);
|
||||
int lfs_symlink (void *);
|
||||
int lfs_mknod (void *);
|
||||
int lfs_create (void *);
|
||||
int lfs_mkdir (void *);
|
||||
int lfs_read (void *);
|
||||
int lfs_remove (void *);
|
||||
int lfs_rmdir (void *);
|
||||
int lfs_link (void *);
|
||||
int lfs_rename (void *);
|
||||
int lfs_getattr (void *);
|
||||
int lfs_close (void *);
|
||||
int lfs_inactive(void *);
|
||||
int lfs_reclaim (void *);
|
||||
int lfs_write (void *);
|
||||
int lfs_whiteout(void *);
|
||||
|
||||
__END_DECLS
|
||||
extern int lfs_mount_type;
|
||||
extern int (**lfs_vnodeop_p) __P((void *));
|
||||
extern int (**lfs_specop_p) __P((void *));
|
||||
extern int (**lfs_fifoop_p) __P((void *));
|
||||
extern int (**lfs_vnodeop_p)(void *);
|
||||
extern int (**lfs_specop_p)(void *);
|
||||
extern int (**lfs_fifoop_p)(void *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs_inode.c,v 1.51 2001/05/30 11:57:18 mrg Exp $ */
|
||||
/* $NetBSD: lfs_inode.c,v 1.52 2001/07/13 20:30:24 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
@ -106,30 +106,40 @@ static int lfs_vtruncbuf(struct vnode *, daddr_t, int, int);
|
||||
|
||||
/* Search a block for a specific dinode. */
|
||||
struct dinode *
|
||||
lfs_ifind(fs, ino, bp)
|
||||
struct lfs *fs;
|
||||
ino_t ino;
|
||||
struct buf *bp;
|
||||
lfs_ifind(struct lfs *fs, ino_t ino, struct buf *bp)
|
||||
{
|
||||
int cnt;
|
||||
struct dinode *dip = (struct dinode *)bp->b_data;
|
||||
struct dinode *ldip;
|
||||
struct dinode *ldip, *fin;
|
||||
|
||||
for (cnt = INOPB(fs), ldip = dip + (cnt - 1); cnt--; --ldip)
|
||||
#ifdef LFS_IFILE_FRAG_ADDRESSING
|
||||
if (fs->lfs_version == 1)
|
||||
fin = dip + INOPB(fs);
|
||||
else
|
||||
fin = dip + INOPF(fs);
|
||||
#else
|
||||
fin = dip + INOPB(fs);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* XXX we used to go from the top down here, presumably with the
|
||||
* idea that the same inode could be written twice in the same
|
||||
* block (which is not supposed to be true).
|
||||
*/
|
||||
for (ldip = dip; ldip < fin; ++ldip)
|
||||
if (ldip->di_inumber == ino)
|
||||
return (ldip);
|
||||
|
||||
|
||||
printf("searched %d entries\n", (int)(fin - dip));
|
||||
printf("offset is 0x%x (seg %d)\n", fs->lfs_offset,
|
||||
datosn(fs,fs->lfs_offset));
|
||||
printf("block is 0x%x (seg %d)\n", bp->b_blkno,
|
||||
datosn(fs,bp->b_blkno));
|
||||
dtosn(fs, fs->lfs_offset));
|
||||
printf("block is 0x%x (seg %d)\n", dbtofsb(fs, bp->b_blkno),
|
||||
dtosn(fs, dbtofsb(fs, bp->b_blkno)));
|
||||
panic("lfs_ifind: dinode %u not found", ino);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
int
|
||||
lfs_update(v)
|
||||
void *v;
|
||||
lfs_update(void *v)
|
||||
{
|
||||
struct vop_update_args /* {
|
||||
struct vnode *a_vp;
|
||||
@ -205,8 +215,7 @@ lfs_update(v)
|
||||
*/
|
||||
/* VOP_BWRITE 1 + NIADDR + VOP_BALLOC == 2 + 2*NIADDR times */
|
||||
int
|
||||
lfs_truncate(v)
|
||||
void *v;
|
||||
lfs_truncate(void *v)
|
||||
{
|
||||
struct vop_truncate_args /* {
|
||||
struct vnode *a_vp;
|
||||
@ -279,11 +288,11 @@ lfs_truncate(v)
|
||||
aflags = B_CLRBUF;
|
||||
if (ap->a_flags & IO_SYNC)
|
||||
aflags |= B_SYNC;
|
||||
error = lfs_reserve(fs, ovp, fsbtodb(fs, NIADDR + 2));
|
||||
error = lfs_reserve(fs, ovp, btofsb(fs, (NIADDR + 2) << fs->lfs_bshift));
|
||||
if (error)
|
||||
return (error);
|
||||
error = VOP_BALLOC(ovp, length - 1, 1, ap->a_cred, aflags, &bp);
|
||||
lfs_reserve(fs, ovp, -fsbtodb(fs, NIADDR + 2));
|
||||
lfs_reserve(fs, ovp, -btofsb(fs, (NIADDR + 2) << fs->lfs_bshift));
|
||||
if (error)
|
||||
return (error);
|
||||
oip->i_ffs_size = length;
|
||||
@ -293,7 +302,7 @@ lfs_truncate(v)
|
||||
return (VOP_UPDATE(ovp, NULL, NULL, 0));
|
||||
}
|
||||
|
||||
if ((error = lfs_reserve(fs, ovp, fsbtodb(fs, 2 * NIADDR + 3))) != 0)
|
||||
if ((error = lfs_reserve(fs, ovp, btofsb(fs, (2 * NIADDR + 3) << fs->lfs_bshift))) != 0)
|
||||
return (error);
|
||||
/*
|
||||
* Make sure no writes to this inode can happen while we're
|
||||
@ -330,11 +339,11 @@ lfs_truncate(v)
|
||||
aflags |= B_SYNC;
|
||||
error = VOP_BALLOC(ovp, length - 1, 1, ap->a_cred, aflags, &bp);
|
||||
if (error) {
|
||||
lfs_reserve(fs, ovp, -fsbtodb(fs, 2 * NIADDR + 3));
|
||||
lfs_reserve(fs, ovp, -btofsb(fs, (2 * NIADDR + 3) << fs->lfs_bshift));
|
||||
return (error);
|
||||
}
|
||||
obufsize = bp->b_bufsize;
|
||||
odb = btodb(bp->b_bcount);
|
||||
odb = btofsb(fs, bp->b_bcount);
|
||||
oip->i_ffs_size = length;
|
||||
size = blksize(fs, oip, lbn);
|
||||
if (ovp->v_type != VDIR)
|
||||
@ -344,7 +353,7 @@ lfs_truncate(v)
|
||||
if (bp->b_flags & B_DELWRI) {
|
||||
if ((bp->b_flags & (B_LOCKED | B_CALL)) == B_LOCKED)
|
||||
locked_queue_bytes -= obufsize - bp->b_bufsize;
|
||||
fs->lfs_avail += odb - btodb(size);
|
||||
fs->lfs_avail += odb - btofsb(fs, size);
|
||||
}
|
||||
(void) VOP_BWRITE(bp);
|
||||
}
|
||||
@ -359,7 +368,7 @@ lfs_truncate(v)
|
||||
lastiblock[SINGLE] = lastblock - NDADDR;
|
||||
lastiblock[DOUBLE] = lastiblock[SINGLE] - NINDIR(fs);
|
||||
lastiblock[TRIPLE] = lastiblock[DOUBLE] - NINDIR(fs) * NINDIR(fs);
|
||||
nblocks = btodb(fs->lfs_bsize);
|
||||
nblocks = btofsb(fs, fs->lfs_bsize);
|
||||
/*
|
||||
* Record changed file and block pointers before we start
|
||||
* freeing blocks. lastiblock values are also normalized to -1
|
||||
@ -419,8 +428,8 @@ lfs_truncate(v)
|
||||
continue;
|
||||
bsize = blksize(fs, oip, i);
|
||||
if (oip->i_ffs_db[i] > 0)
|
||||
real_released += btodb(bsize);
|
||||
blocksreleased += btodb(bsize);
|
||||
real_released += btofsb(fs, bsize);
|
||||
blocksreleased += btofsb(fs, bsize);
|
||||
oip->i_ffs_db[i] = 0;
|
||||
lfs_blkfree(fs, bn, bsize, &lastseg, &bc);
|
||||
}
|
||||
@ -447,8 +456,8 @@ lfs_truncate(v)
|
||||
if (oldspace - newspace > 0) {
|
||||
lfs_blkfree(fs, bn, oldspace - newspace, &lastseg, &bc);
|
||||
if (bn > 0)
|
||||
real_released += btodb(oldspace - newspace);
|
||||
blocksreleased += btodb(oldspace - newspace);
|
||||
real_released += btofsb(fs, oldspace - newspace);
|
||||
blocksreleased += btofsb(fs, oldspace - newspace);
|
||||
}
|
||||
}
|
||||
|
||||
@ -484,7 +493,7 @@ done:
|
||||
#ifdef QUOTA
|
||||
(void) chkdq(oip, -blocksreleased, NOCRED, 0);
|
||||
#endif
|
||||
lfs_reserve(fs, ovp, -fsbtodb(fs, 2 * NIADDR + 3));
|
||||
lfs_reserve(fs, ovp, -btofsb(fs, (2 * NIADDR + 3) << fs->lfs_bshift));
|
||||
return (allerror);
|
||||
}
|
||||
|
||||
@ -498,7 +507,7 @@ lfs_blkfree(struct lfs *fs, daddr_t daddr, size_t bsize, long *lastseg,
|
||||
|
||||
bsize = fragroundup(fs, bsize);
|
||||
if (daddr > 0) {
|
||||
if (*lastseg != (seg = datosn(fs, daddr))) {
|
||||
if (*lastseg != (seg = dtosn(fs, daddr))) {
|
||||
error = lfs_update_seguse(fs, *lastseg, *num);
|
||||
*num = bsize;
|
||||
*lastseg = seg;
|
||||
@ -565,7 +574,7 @@ lfs_indirtrunc(struct inode *ip, ufs_daddr_t lbn, daddr_t dbn,
|
||||
last = lastbn;
|
||||
if (lastbn > 0)
|
||||
last /= factor;
|
||||
nblocks = btodb(fs->lfs_bsize);
|
||||
nblocks = btofsb(fs, fs->lfs_bsize);
|
||||
/*
|
||||
* Get buffer of block pointers, zero those entries corresponding
|
||||
* to blocks to be free'd, and update on disk copy first. Since
|
||||
@ -585,7 +594,7 @@ lfs_indirtrunc(struct inode *ip, ufs_daddr_t lbn, daddr_t dbn,
|
||||
bp->b_flags |= B_READ;
|
||||
if (bp->b_bcount > bp->b_bufsize)
|
||||
panic("lfs_indirtrunc: bad buffer size");
|
||||
bp->b_blkno = dbn;
|
||||
bp->b_blkno = fsbtodb(fs, dbn);
|
||||
VOP_STRATEGY(bp);
|
||||
error = biowait(bp);
|
||||
}
|
||||
@ -653,7 +662,7 @@ lfs_indirtrunc(struct inode *ip, ufs_daddr_t lbn, daddr_t dbn,
|
||||
} else {
|
||||
if (bp->b_flags & B_DELWRI) {
|
||||
LFS_UNLOCK_BUF(bp);
|
||||
fs->lfs_avail += btodb(bp->b_bcount);
|
||||
fs->lfs_avail += btofsb(fs, bp->b_bcount);
|
||||
wakeup(&fs->lfs_avail);
|
||||
}
|
||||
bp->b_flags |= B_INVAL;
|
||||
@ -670,10 +679,7 @@ lfs_indirtrunc(struct inode *ip, ufs_daddr_t lbn, daddr_t dbn,
|
||||
* Inlined from vtruncbuf, so that lfs_avail could be updated.
|
||||
*/
|
||||
static int
|
||||
lfs_vtruncbuf(vp, lbn, slpflag, slptimeo)
|
||||
struct vnode *vp;
|
||||
daddr_t lbn;
|
||||
int slpflag, slptimeo;
|
||||
lfs_vtruncbuf(struct vnode *vp, daddr_t lbn, int slpflag, int slptimeo)
|
||||
{
|
||||
struct buf *bp, *nbp;
|
||||
int s, error;
|
||||
@ -700,7 +706,7 @@ restart:
|
||||
bp->b_flags |= B_BUSY | B_INVAL | B_VFLUSH;
|
||||
if (bp->b_flags & B_DELWRI) {
|
||||
bp->b_flags &= ~B_DELWRI;
|
||||
fs->lfs_avail += btodb(bp->b_bcount);
|
||||
fs->lfs_avail += btofsb(fs, bp->b_bcount);
|
||||
wakeup(&fs->lfs_avail);
|
||||
}
|
||||
LFS_UNLOCK_BUF(bp);
|
||||
@ -724,7 +730,7 @@ restart:
|
||||
bp->b_flags |= B_BUSY | B_INVAL | B_VFLUSH;
|
||||
if (bp->b_flags & B_DELWRI) {
|
||||
bp->b_flags &= ~B_DELWRI;
|
||||
fs->lfs_avail += btodb(bp->b_bcount);
|
||||
fs->lfs_avail += btofsb(fs, bp->b_bcount);
|
||||
wakeup(&fs->lfs_avail);
|
||||
}
|
||||
LFS_UNLOCK_BUF(bp);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs_segment.c,v 1.68 2001/05/30 11:57:18 mrg Exp $ */
|
||||
/* $NetBSD: lfs_segment.c,v 1.69 2001/07/13 20:30:24 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
@ -102,7 +102,7 @@
|
||||
#include <ufs/lfs/lfs.h>
|
||||
#include <ufs/lfs/lfs_extern.h>
|
||||
|
||||
extern int count_lock_queue __P((void));
|
||||
extern int count_lock_queue(void);
|
||||
extern struct simplelock vnode_free_list_slock; /* XXX */
|
||||
|
||||
/*
|
||||
@ -110,31 +110,31 @@ extern struct simplelock vnode_free_list_slock; /* XXX */
|
||||
* to go on to a new segment.
|
||||
*/
|
||||
#define LFS_PARTIAL_FITS(fs) \
|
||||
((fs)->lfs_dbpseg - ((fs)->lfs_offset - (fs)->lfs_curseg) > \
|
||||
1 << (fs)->lfs_fsbtodb)
|
||||
((fs)->lfs_fsbpseg - ((fs)->lfs_offset - (fs)->lfs_curseg) > \
|
||||
fragstofsb((fs), (fs)->lfs_frag))
|
||||
|
||||
void lfs_callback __P((struct buf *));
|
||||
int lfs_gather __P((struct lfs *, struct segment *,
|
||||
struct vnode *, int (*) __P((struct lfs *, struct buf *))));
|
||||
int lfs_gatherblock __P((struct segment *, struct buf *, int *));
|
||||
void lfs_iset __P((struct inode *, ufs_daddr_t, time_t));
|
||||
int lfs_match_fake __P((struct lfs *, struct buf *));
|
||||
int lfs_match_data __P((struct lfs *, struct buf *));
|
||||
int lfs_match_dindir __P((struct lfs *, struct buf *));
|
||||
int lfs_match_indir __P((struct lfs *, struct buf *));
|
||||
int lfs_match_tindir __P((struct lfs *, struct buf *));
|
||||
void lfs_newseg __P((struct lfs *));
|
||||
void lfs_shellsort __P((struct buf **, ufs_daddr_t *, int));
|
||||
void lfs_supercallback __P((struct buf *));
|
||||
void lfs_updatemeta __P((struct segment *));
|
||||
int lfs_vref __P((struct vnode *));
|
||||
void lfs_vunref __P((struct vnode *));
|
||||
void lfs_writefile __P((struct lfs *, struct segment *, struct vnode *));
|
||||
int lfs_writeinode __P((struct lfs *, struct segment *, struct inode *));
|
||||
int lfs_writeseg __P((struct lfs *, struct segment *));
|
||||
void lfs_writesuper __P((struct lfs *, daddr_t));
|
||||
int lfs_writevnodes __P((struct lfs *fs, struct mount *mp,
|
||||
struct segment *sp, int dirops));
|
||||
void lfs_callback(struct buf *);
|
||||
int lfs_gather(struct lfs *, struct segment *,
|
||||
struct vnode *, int (*)(struct lfs *, struct buf *));
|
||||
int lfs_gatherblock(struct segment *, struct buf *, int *);
|
||||
void lfs_iset(struct inode *, ufs_daddr_t, time_t);
|
||||
int lfs_match_fake(struct lfs *, struct buf *);
|
||||
int lfs_match_data(struct lfs *, struct buf *);
|
||||
int lfs_match_dindir(struct lfs *, struct buf *);
|
||||
int lfs_match_indir(struct lfs *, struct buf *);
|
||||
int lfs_match_tindir(struct lfs *, struct buf *);
|
||||
void lfs_newseg(struct lfs *);
|
||||
void lfs_shellsort(struct buf **, ufs_daddr_t *, int);
|
||||
void lfs_supercallback(struct buf *);
|
||||
void lfs_updatemeta(struct segment *);
|
||||
int lfs_vref(struct vnode *);
|
||||
void lfs_vunref(struct vnode *);
|
||||
void lfs_writefile(struct lfs *, struct segment *, struct vnode *);
|
||||
int lfs_writeinode(struct lfs *, struct segment *, struct inode *);
|
||||
int lfs_writeseg(struct lfs *, struct segment *);
|
||||
void lfs_writesuper(struct lfs *, daddr_t);
|
||||
int lfs_writevnodes(struct lfs *fs, struct mount *mp,
|
||||
struct segment *sp, int dirops);
|
||||
|
||||
int lfs_allclean_wakeup; /* Cleaner wakeup address. */
|
||||
int lfs_writeindir = 1; /* whether to flush indir on non-ckp */
|
||||
@ -163,8 +163,7 @@ extern long locked_queue_bytes;
|
||||
* case that wouldn't happen to the Ifile until we checkpoint).
|
||||
*/
|
||||
void
|
||||
lfs_imtime(fs)
|
||||
struct lfs *fs;
|
||||
lfs_imtime(struct lfs *fs)
|
||||
{
|
||||
struct timespec ts;
|
||||
struct inode *ip;
|
||||
@ -187,8 +186,7 @@ lfs_imtime(fs)
|
||||
#define CLR_FLUSHING(fs,vp) (fs)->lfs_flushvp = NULL
|
||||
|
||||
int
|
||||
lfs_vflush(vp)
|
||||
struct vnode *vp;
|
||||
lfs_vflush(struct vnode *vp)
|
||||
{
|
||||
struct inode *ip;
|
||||
struct lfs *fs;
|
||||
@ -222,9 +220,11 @@ lfs_vflush(vp)
|
||||
&& tbp->b_lblkno == bp->b_lblkno
|
||||
&& tbp != bp)
|
||||
{
|
||||
fs->lfs_avail += btodb(bp->b_bcount);
|
||||
fs->lfs_avail += btofsb(fs, bp->b_bcount);
|
||||
wakeup(&fs->lfs_avail);
|
||||
lfs_freebuf(bp);
|
||||
bp = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -252,13 +252,14 @@ lfs_vflush(vp)
|
||||
for(bp=vp->v_dirtyblkhd.lh_first; bp; bp=nbp) {
|
||||
nbp = bp->b_vnbufs.le_next;
|
||||
if (bp->b_flags & B_DELWRI) { /* XXX always true? */
|
||||
fs->lfs_avail += btodb(bp->b_bcount);
|
||||
fs->lfs_avail += btofsb(fs, bp->b_bcount);
|
||||
wakeup(&fs->lfs_avail);
|
||||
}
|
||||
/* Copied from lfs_writeseg */
|
||||
if (bp->b_flags & B_CALL) {
|
||||
/* if B_CALL, it was created with newbuf */
|
||||
lfs_freebuf(bp);
|
||||
bp = NULL;
|
||||
} else {
|
||||
bremfree(bp);
|
||||
LFS_UNLOCK_BUF(bp);
|
||||
@ -312,7 +313,7 @@ lfs_vflush(vp)
|
||||
/* panic("VDIROP being flushed...this can\'t happen"); */
|
||||
}
|
||||
if(vp->v_usecount<0) {
|
||||
printf("usecount=%d\n",vp->v_usecount);
|
||||
printf("usecount=%ld\n", (long)vp->v_usecount);
|
||||
panic("lfs_vflush: usecount<0");
|
||||
}
|
||||
#endif
|
||||
@ -344,11 +345,7 @@ lfs_vflush(vp)
|
||||
#endif
|
||||
|
||||
int
|
||||
lfs_writevnodes(fs, mp, sp, op)
|
||||
struct lfs *fs;
|
||||
struct mount *mp;
|
||||
struct segment *sp;
|
||||
int op;
|
||||
lfs_writevnodes(struct lfs *fs, struct mount *mp, struct segment *sp, int op)
|
||||
{
|
||||
struct inode *ip;
|
||||
struct vnode *vp;
|
||||
@ -468,10 +465,11 @@ lfs_writevnodes(fs, mp, sp, op)
|
||||
return inodes_written;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do a checkpoint.
|
||||
*/
|
||||
int
|
||||
lfs_segwrite(mp, flags)
|
||||
struct mount *mp;
|
||||
int flags; /* Do a checkpoint. */
|
||||
lfs_segwrite(struct mount *mp, int flags)
|
||||
{
|
||||
struct buf *bp;
|
||||
struct inode *ip;
|
||||
@ -543,8 +541,11 @@ lfs_segwrite(mp, flags)
|
||||
if((error = tsleep(&fs->lfs_writer, PRIBIO + 1,
|
||||
"lfs writer", 0)))
|
||||
{
|
||||
/* XXX why not segunlock? */
|
||||
free(sp->bpp, M_SEGMENT);
|
||||
sp->bpp = NULL;
|
||||
free(sp, M_SEGMENT);
|
||||
fs->lfs_sp = NULL;
|
||||
return (error);
|
||||
}
|
||||
fs->lfs_writer++;
|
||||
@ -566,19 +567,32 @@ lfs_segwrite(mp, flags)
|
||||
|
||||
panic("lfs_segwrite: ifile read");
|
||||
segusep = (SEGUSE *)bp->b_data;
|
||||
for (i = fs->lfs_sepb; i--; segusep++) {
|
||||
for (i = fs->lfs_sepb; i--;) {
|
||||
if (segusep->su_flags & SEGUSE_ACTIVE) {
|
||||
segusep->su_flags &= ~SEGUSE_ACTIVE;
|
||||
++dirty;
|
||||
}
|
||||
if (fs->lfs_version > 1)
|
||||
++segusep;
|
||||
else
|
||||
segusep = (SEGUSE *)
|
||||
((SEGUSE_V1 *)segusep + 1);
|
||||
}
|
||||
|
||||
/* But the current segment is still ACTIVE */
|
||||
segusep = (SEGUSE *)bp->b_data;
|
||||
if (datosn(fs, fs->lfs_curseg) / fs->lfs_sepb ==
|
||||
if (dtosn(fs, fs->lfs_curseg) / fs->lfs_sepb ==
|
||||
(ibno-fs->lfs_cleansz)) {
|
||||
segusep[datosn(fs, fs->lfs_curseg) %
|
||||
fs->lfs_sepb].su_flags |= SEGUSE_ACTIVE;
|
||||
if (fs->lfs_version > 1)
|
||||
segusep[dtosn(fs, fs->lfs_curseg) %
|
||||
fs->lfs_sepb].su_flags |=
|
||||
SEGUSE_ACTIVE;
|
||||
else
|
||||
((SEGUSE *)
|
||||
((SEGUSE_V1 *)(bp->b_data) +
|
||||
(dtosn(fs, fs->lfs_curseg) %
|
||||
fs->lfs_sepb)))->su_flags
|
||||
|= SEGUSE_ACTIVE;
|
||||
--dirty;
|
||||
}
|
||||
if (dirty)
|
||||
@ -648,10 +662,7 @@ lfs_segwrite(mp, flags)
|
||||
* Write the dirty blocks associated with a vnode.
|
||||
*/
|
||||
void
|
||||
lfs_writefile(fs, sp, vp)
|
||||
struct lfs *fs;
|
||||
struct segment *sp;
|
||||
struct vnode *vp;
|
||||
lfs_writefile(struct lfs *fs, struct segment *sp, struct vnode *vp)
|
||||
{
|
||||
struct buf *bp;
|
||||
struct finfo *fip;
|
||||
@ -719,10 +730,7 @@ lfs_writefile(fs, sp, vp)
|
||||
}
|
||||
|
||||
int
|
||||
lfs_writeinode(fs, sp, ip)
|
||||
struct lfs *fs;
|
||||
struct segment *sp;
|
||||
struct inode *ip;
|
||||
lfs_writeinode(struct lfs *fs, struct segment *sp, struct inode *ip)
|
||||
{
|
||||
struct buf *bp, *ibp;
|
||||
struct dinode *cdp;
|
||||
@ -731,10 +739,10 @@ lfs_writeinode(fs, sp, ip)
|
||||
ufs_daddr_t daddr;
|
||||
daddr_t *daddrp;
|
||||
ino_t ino;
|
||||
int error, i, ndx;
|
||||
int error, i, ndx, fsb = 0;
|
||||
int redo_ifile = 0;
|
||||
struct timespec ts;
|
||||
int gotblk=0;
|
||||
int gotblk = 0;
|
||||
|
||||
if (!(ip->i_flag & IN_ALLMOD))
|
||||
return(0);
|
||||
@ -742,15 +750,16 @@ lfs_writeinode(fs, sp, ip)
|
||||
/* Allocate a new inode block if necessary. */
|
||||
if ((ip->i_number != LFS_IFILE_INUM || sp->idp==NULL) && sp->ibp == NULL) {
|
||||
/* Allocate a new segment if necessary. */
|
||||
if (sp->seg_bytes_left < fs->lfs_bsize ||
|
||||
if (sp->seg_bytes_left < fs->lfs_ibsize ||
|
||||
sp->sum_bytes_left < sizeof(ufs_daddr_t))
|
||||
(void) lfs_writeseg(fs, sp);
|
||||
|
||||
/* Get next inode block. */
|
||||
daddr = fs->lfs_offset;
|
||||
fs->lfs_offset += fsbtodb(fs, 1);
|
||||
fs->lfs_offset += btofsb(fs, fs->lfs_ibsize);
|
||||
sp->ibp = *sp->cbpp++ =
|
||||
getblk(VTOI(fs->lfs_ivnode)->i_devvp, daddr, fs->lfs_bsize, 0, 0);
|
||||
getblk(VTOI(fs->lfs_ivnode)->i_devvp, fsbtodb(fs, daddr),
|
||||
fs->lfs_ibsize, 0, 0);
|
||||
gotblk++;
|
||||
|
||||
/* Zero out inode numbers */
|
||||
@ -758,11 +767,11 @@ lfs_writeinode(fs, sp, ip)
|
||||
((struct dinode *)sp->ibp->b_data)[i].di_inumber = 0;
|
||||
|
||||
++sp->start_bpp;
|
||||
fs->lfs_avail -= fsbtodb(fs, 1);
|
||||
fs->lfs_avail -= btofsb(fs, fs->lfs_ibsize);
|
||||
/* Set remaining space counters. */
|
||||
sp->seg_bytes_left -= fs->lfs_bsize;
|
||||
sp->seg_bytes_left -= fs->lfs_ibsize;
|
||||
sp->sum_bytes_left -= sizeof(ufs_daddr_t);
|
||||
ndx = LFS_SUMMARY_SIZE / sizeof(ufs_daddr_t) -
|
||||
ndx = fs->lfs_sumsize / sizeof(ufs_daddr_t) -
|
||||
sp->ninodes / INOPB(fs) - 1;
|
||||
((ufs_daddr_t *)(sp->segsum))[ndx] = daddr;
|
||||
}
|
||||
@ -787,6 +796,10 @@ lfs_writeinode(fs, sp, ip)
|
||||
bp = sp->ibp;
|
||||
cdp = ((struct dinode *)bp->b_data) + (sp->ninodes % INOPB(fs));
|
||||
*cdp = ip->i_din.ffs_din;
|
||||
#ifdef LFS_IFILE_FRAG_ADDRESSING
|
||||
if (fs->lfs_version > 1)
|
||||
fsb = (sp->ninodes % INOPB(fs)) / INOPF(fs);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If we are cleaning, ensure that we don't write UNWRITTEN disk
|
||||
@ -846,11 +859,11 @@ lfs_writeinode(fs, sp, ip)
|
||||
ino = ip->i_number;
|
||||
if (ino == LFS_IFILE_INUM) {
|
||||
daddr = fs->lfs_idaddr;
|
||||
fs->lfs_idaddr = bp->b_blkno;
|
||||
fs->lfs_idaddr = dbtofsb(fs, bp->b_blkno);
|
||||
} else {
|
||||
LFS_IENTRY(ifp, fs, ino, ibp);
|
||||
daddr = ifp->if_daddr;
|
||||
ifp->if_daddr = bp->b_blkno;
|
||||
ifp->if_daddr = dbtofsb(fs, bp->b_blkno) + fsb;
|
||||
#ifdef LFS_DEBUG_NEXTFREE
|
||||
if(ino > 3 && ifp->if_nextfree) {
|
||||
vprint("lfs_writeinode",ITOV(ip));
|
||||
@ -875,21 +888,25 @@ lfs_writeinode(fs, sp, ip)
|
||||
* su_nbytes until lfs_writeseg, this shouldn't be a problem as we
|
||||
* have more data blocks in the current partial segment.
|
||||
*/
|
||||
if (daddr >= fs->lfs_lastpseg && daddr <= bp->b_blkno)
|
||||
if (daddr >= fs->lfs_lastpseg && daddr <= dbtofsb(fs, bp->b_blkno))
|
||||
printf("lfs_writeinode: last inode addr in current pseg "
|
||||
"(ino %d daddr 0x%x)\n", ino, daddr);
|
||||
#endif
|
||||
if (daddr != LFS_UNUSED_DADDR) {
|
||||
LFS_SEGENTRY(sup, fs, datosn(fs, daddr), bp);
|
||||
LFS_SEGENTRY(sup, fs, dtosn(fs, daddr), bp);
|
||||
#ifdef DIAGNOSTIC
|
||||
if (sup->su_nbytes < DINODE_SIZE) {
|
||||
printf("lfs_writeinode: negative bytes "
|
||||
"(segment %d short by %d)\n",
|
||||
datosn(fs, daddr),
|
||||
dtosn(fs, daddr),
|
||||
(int)DINODE_SIZE - sup->su_nbytes);
|
||||
panic("lfs_writeinode: negative bytes");
|
||||
sup->su_nbytes = DINODE_SIZE;
|
||||
}
|
||||
#endif
|
||||
#ifdef DEBUG_SU_NBYTES
|
||||
printf("seg %d -= %d for ino %d inode\n",
|
||||
dtosn(fs, daddr), DINODE_SIZE, ino);
|
||||
#endif
|
||||
sup->su_nbytes -= DINODE_SIZE;
|
||||
redo_ifile =
|
||||
@ -900,10 +917,7 @@ lfs_writeinode(fs, sp, ip)
|
||||
}
|
||||
|
||||
int
|
||||
lfs_gatherblock(sp, bp, sptr)
|
||||
struct segment *sp;
|
||||
struct buf *bp;
|
||||
int *sptr;
|
||||
lfs_gatherblock(struct segment *sp, struct buf *bp, int *sptr)
|
||||
{
|
||||
struct lfs *fs;
|
||||
int version;
|
||||
@ -956,11 +970,7 @@ lfs_gatherblock(sp, bp, sptr)
|
||||
}
|
||||
|
||||
int
|
||||
lfs_gather(fs, sp, vp, match)
|
||||
struct lfs *fs;
|
||||
struct segment *sp;
|
||||
struct vnode *vp;
|
||||
int (*match) __P((struct lfs *, struct buf *));
|
||||
lfs_gather(struct lfs *fs, struct segment *sp, struct vnode *vp, int (*match)(struct lfs *, struct buf *))
|
||||
{
|
||||
struct buf *bp;
|
||||
int s, count=0;
|
||||
@ -1006,7 +1016,7 @@ loop: for (bp = vp->v_dirtyblkhd.lh_first; bp && bp->b_vnbufs.le_next != NULL;
|
||||
if (!(bp->b_flags & B_LOCKED)) {
|
||||
printf("lfs_gather: lbn %d blk %d"
|
||||
" not B_LOCKED\n", bp->b_lblkno,
|
||||
bp->b_blkno);
|
||||
dbtofsb(fs, bp->b_blkno));
|
||||
VOP_PRINT(bp->b_vp);
|
||||
panic("lfs_gather: bp not B_LOCKED");
|
||||
}
|
||||
@ -1032,8 +1042,7 @@ loop: for (bp = vp->v_dirtyblkhd.lh_first; bp && bp->b_vnbufs.le_next != NULL;
|
||||
* array.
|
||||
*/
|
||||
void
|
||||
lfs_updatemeta(sp)
|
||||
struct segment *sp;
|
||||
lfs_updatemeta(struct segment *sp)
|
||||
{
|
||||
SEGUSE *sup;
|
||||
struct buf *bp;
|
||||
@ -1079,7 +1088,8 @@ lfs_updatemeta(sp)
|
||||
for (i = nblocks; i--; ++sp->start_bpp) {
|
||||
lbn = *sp->start_lbp++;
|
||||
|
||||
(*sp->start_bpp)->b_blkno = off = fs->lfs_offset;
|
||||
(*sp->start_bpp)->b_blkno = fsbtodb(fs, fs->lfs_offset);
|
||||
off = fs->lfs_offset;
|
||||
if((*sp->start_bpp)->b_blkno == (*sp->start_bpp)->b_lblkno) {
|
||||
printf("lfs_updatemeta: ino %d blk %d"
|
||||
" has same lbn and daddr\n",
|
||||
@ -1089,9 +1099,11 @@ lfs_updatemeta(sp)
|
||||
if((*sp->start_bpp)->b_bcount < fs->lfs_bsize && i != 0)
|
||||
panic("lfs_updatemeta: fragment is not last block\n");
|
||||
#endif
|
||||
bb = fragstodb(fs, numfrags(fs, (*sp->start_bpp)->b_bcount));
|
||||
bb = fragstofsb(fs, numfrags(fs, (*sp->start_bpp)->b_bcount));
|
||||
fs->lfs_offset += bb;
|
||||
error = ufs_bmaparray(vp, lbn, &daddr, a, &num, NULL);
|
||||
if (daddr > 0)
|
||||
daddr = dbtofsb(fs, daddr);
|
||||
if (error)
|
||||
panic("lfs_updatemeta: ufs_bmaparray %d", error);
|
||||
ip = VTOI(vp);
|
||||
@ -1150,21 +1162,27 @@ lfs_updatemeta(sp)
|
||||
#endif
|
||||
/* Update segment usage information. */
|
||||
if (daddr > 0) {
|
||||
LFS_SEGENTRY(sup, fs, datosn(fs, daddr), bp);
|
||||
LFS_SEGENTRY(sup, fs, dtosn(fs, daddr), bp);
|
||||
#ifdef DIAGNOSTIC
|
||||
if (sup->su_nbytes < (*sp->start_bpp)->b_bcount) {
|
||||
/* XXX -- Change to a panic. */
|
||||
printf("lfs_updatemeta: negative bytes "
|
||||
"(segment %d short by %ld)\n",
|
||||
datosn(fs, daddr),
|
||||
dtosn(fs, daddr),
|
||||
(*sp->start_bpp)->b_bcount -
|
||||
sup->su_nbytes);
|
||||
printf("lfs_updatemeta: ino %d, lbn %d, "
|
||||
"addr = %x\n", VTOI(sp->vp)->i_number,
|
||||
"addr = 0x%x\n", VTOI(sp->vp)->i_number,
|
||||
(*sp->start_bpp)->b_lblkno, daddr);
|
||||
panic("lfs_updatemeta: negative bytes");
|
||||
sup->su_nbytes = (*sp->start_bpp)->b_bcount;
|
||||
}
|
||||
#endif
|
||||
#ifdef DEBUG_SU_NBYTES
|
||||
printf("seg %d -= %ld for ino %d lbn %d db 0x%x\n",
|
||||
dtosn(fs, daddr), (*sp->start_bpp)->b_bcount,
|
||||
VTOI(sp->vp)->i_number,
|
||||
(*sp->start_bpp)->b_lblkno, daddr);
|
||||
#endif
|
||||
sup->su_nbytes -= (*sp->start_bpp)->b_bcount;
|
||||
error = VOP_BWRITE(bp); /* Ifile */
|
||||
@ -1176,8 +1194,7 @@ lfs_updatemeta(sp)
|
||||
* Start a new segment.
|
||||
*/
|
||||
int
|
||||
lfs_initseg(fs)
|
||||
struct lfs *fs;
|
||||
lfs_initseg(struct lfs *fs)
|
||||
{
|
||||
struct segment *sp;
|
||||
SEGUSE *sup;
|
||||
@ -1186,12 +1203,12 @@ lfs_initseg(fs)
|
||||
int repeat;
|
||||
|
||||
sp = fs->lfs_sp;
|
||||
|
||||
|
||||
repeat = 0;
|
||||
/* Advance to the next segment. */
|
||||
if (!LFS_PARTIAL_FITS(fs)) {
|
||||
/* lfs_avail eats the remaining space */
|
||||
fs->lfs_avail -= fs->lfs_dbpseg - (fs->lfs_offset -
|
||||
fs->lfs_avail -= fs->lfs_fsbpseg - (fs->lfs_offset -
|
||||
fs->lfs_curseg);
|
||||
/* Wake up any cleaning procs waiting on this file system. */
|
||||
wakeup(&lfs_allclean_wakeup);
|
||||
@ -1199,21 +1216,27 @@ lfs_initseg(fs)
|
||||
lfs_newseg(fs);
|
||||
repeat = 1;
|
||||
fs->lfs_offset = fs->lfs_curseg;
|
||||
sp->seg_number = datosn(fs, fs->lfs_curseg);
|
||||
sp->seg_bytes_left = dbtob(fs->lfs_dbpseg);
|
||||
sp->seg_number = dtosn(fs, fs->lfs_curseg);
|
||||
sp->seg_bytes_left = fsbtob(fs, fs->lfs_fsbpseg);
|
||||
/*
|
||||
* If the segment contains a superblock, update the offset
|
||||
* and summary address to skip over it.
|
||||
*/
|
||||
LFS_SEGENTRY(sup, fs, sp->seg_number, bp);
|
||||
if (sup->su_flags & SEGUSE_SUPERBLOCK) {
|
||||
fs->lfs_offset += btodb(LFS_SBPAD);
|
||||
fs->lfs_offset += btofsb(fs, LFS_SBPAD);
|
||||
sp->seg_bytes_left -= LFS_SBPAD;
|
||||
}
|
||||
brelse(bp);
|
||||
/* Segment zero could also contain the labelpad */
|
||||
if (fs->lfs_version > 1 && sp->seg_number == 0 &&
|
||||
fs->lfs_start < btofsb(fs, LFS_LABELPAD)) {
|
||||
fs->lfs_offset += btofsb(fs, LFS_LABELPAD) - fs->lfs_start;
|
||||
sp->seg_bytes_left -= LFS_LABELPAD - fsbtob(fs, fs->lfs_start);
|
||||
}
|
||||
} else {
|
||||
sp->seg_number = datosn(fs, fs->lfs_curseg);
|
||||
sp->seg_bytes_left = dbtob(fs->lfs_dbpseg -
|
||||
sp->seg_number = dtosn(fs, fs->lfs_curseg);
|
||||
sp->seg_bytes_left = fsbtob(fs, fs->lfs_fsbpseg -
|
||||
(fs->lfs_offset - fs->lfs_curseg));
|
||||
}
|
||||
fs->lfs_lastpseg = fs->lfs_offset;
|
||||
@ -1222,15 +1245,15 @@ lfs_initseg(fs)
|
||||
sp->ibp = NULL;
|
||||
sp->idp = NULL;
|
||||
sp->ninodes = 0;
|
||||
|
||||
|
||||
/* Get a new buffer for SEGSUM and enter it into the buffer list. */
|
||||
sp->cbpp = sp->bpp;
|
||||
*sp->cbpp = lfs_newbuf(VTOI(fs->lfs_ivnode)->i_devvp,
|
||||
fs->lfs_offset, LFS_SUMMARY_SIZE);
|
||||
*sp->cbpp = lfs_newbuf(fs, VTOI(fs->lfs_ivnode)->i_devvp,
|
||||
fsbtodb(fs, fs->lfs_offset), fs->lfs_sumsize);
|
||||
sp->segsum = (*sp->cbpp)->b_data;
|
||||
bzero(sp->segsum, LFS_SUMMARY_SIZE);
|
||||
bzero(sp->segsum, fs->lfs_sumsize);
|
||||
sp->start_bpp = ++sp->cbpp;
|
||||
fs->lfs_offset += btodb(LFS_SUMMARY_SIZE);
|
||||
fs->lfs_offset += btofsb(fs, fs->lfs_sumsize);
|
||||
|
||||
/* Set point to SEGSUM, initialize it. */
|
||||
ssp = sp->segsum;
|
||||
@ -1239,13 +1262,13 @@ lfs_initseg(fs)
|
||||
ssp->ss_magic = SS_MAGIC;
|
||||
|
||||
/* Set pointer to first FINFO, initialize it. */
|
||||
sp->fip = (struct finfo *)((caddr_t)sp->segsum + sizeof(SEGSUM));
|
||||
sp->fip = (struct finfo *)((caddr_t)sp->segsum + SEGSUM_SIZE(fs));
|
||||
sp->fip->fi_nblocks = 0;
|
||||
sp->start_lbp = &sp->fip->fi_blocks[0];
|
||||
sp->fip->fi_lastlength = 0;
|
||||
|
||||
sp->seg_bytes_left -= LFS_SUMMARY_SIZE;
|
||||
sp->sum_bytes_left = LFS_SUMMARY_SIZE - sizeof(SEGSUM);
|
||||
sp->seg_bytes_left -= fs->lfs_sumsize;
|
||||
sp->sum_bytes_left = fs->lfs_sumsize - SEGSUM_SIZE(fs);
|
||||
|
||||
return(repeat);
|
||||
}
|
||||
@ -1254,15 +1277,18 @@ lfs_initseg(fs)
|
||||
* Return the next segment to write.
|
||||
*/
|
||||
void
|
||||
lfs_newseg(fs)
|
||||
struct lfs *fs;
|
||||
lfs_newseg(struct lfs *fs)
|
||||
{
|
||||
CLEANERINFO *cip;
|
||||
SEGUSE *sup;
|
||||
struct buf *bp;
|
||||
int curseg, isdirty, sn;
|
||||
|
||||
LFS_SEGENTRY(sup, fs, datosn(fs, fs->lfs_nextseg), bp);
|
||||
LFS_SEGENTRY(sup, fs, dtosn(fs, fs->lfs_nextseg), bp);
|
||||
#ifdef DEBUG_SU_NBYTES
|
||||
printf("lfs_newseg: seg %d := 0 in newseg\n", /* XXXDEBUG */
|
||||
dtosn(fs, fs->lfs_nextseg)); /* XXXDEBUG */
|
||||
#endif
|
||||
sup->su_flags |= SEGUSE_DIRTY | SEGUSE_ACTIVE;
|
||||
sup->su_nbytes = 0;
|
||||
sup->su_nsums = 0;
|
||||
@ -1277,7 +1303,7 @@ lfs_newseg(fs)
|
||||
|
||||
fs->lfs_lastseg = fs->lfs_curseg;
|
||||
fs->lfs_curseg = fs->lfs_nextseg;
|
||||
for (sn = curseg = datosn(fs, fs->lfs_curseg);;) {
|
||||
for (sn = curseg = dtosn(fs, fs->lfs_curseg) + fs->lfs_interleave;;) {
|
||||
sn = (sn + 1) % fs->lfs_nseg;
|
||||
if (sn == curseg)
|
||||
panic("lfs_nextseg: no clean segments");
|
||||
@ -1289,32 +1315,30 @@ lfs_newseg(fs)
|
||||
}
|
||||
|
||||
++fs->lfs_nactive;
|
||||
fs->lfs_nextseg = sntoda(fs, sn);
|
||||
fs->lfs_nextseg = sntod(fs, sn);
|
||||
if(lfs_dostats) {
|
||||
++lfs_stats.segsused;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
lfs_writeseg(fs, sp)
|
||||
struct lfs *fs;
|
||||
struct segment *sp;
|
||||
lfs_writeseg(struct lfs *fs, struct segment *sp)
|
||||
{
|
||||
struct buf **bpp, *bp, *cbp, *newbp;
|
||||
SEGUSE *sup;
|
||||
SEGSUM *ssp;
|
||||
dev_t i_dev;
|
||||
u_long *datap, *dp;
|
||||
int do_again, i, nblocks, s;
|
||||
char *datap, *dp;
|
||||
int do_again, i, nblocks, s, el_size;
|
||||
#ifdef LFS_TRACK_IOS
|
||||
int j;
|
||||
#endif
|
||||
int (*strategy)__P((void *));
|
||||
int (*strategy)(void *);
|
||||
struct vop_strategy_args vop_strategy_a;
|
||||
u_short ninos;
|
||||
struct vnode *devvp;
|
||||
char *p;
|
||||
struct vnode *vn;
|
||||
struct vnode *vp;
|
||||
struct inode *ip;
|
||||
daddr_t *daddrp;
|
||||
int changed;
|
||||
@ -1343,20 +1367,36 @@ lfs_writeseg(fs, sp)
|
||||
|
||||
/* Loop through all blocks, except the segment summary. */
|
||||
for (bpp = sp->bpp; ++bpp < sp->cbpp; ) {
|
||||
if((*bpp)->b_vp != devvp)
|
||||
if((*bpp)->b_vp != devvp) {
|
||||
sup->su_nbytes += (*bpp)->b_bcount;
|
||||
#ifdef DEBUG_SU_NBYTES
|
||||
printf("seg %d += %ld for ino %d lbn %d db 0x%x\n",
|
||||
sp->seg_number, (*bpp)->b_bcount,
|
||||
VTOI((*bpp)->b_vp)->i_number,
|
||||
(*bpp)->b_lblkno, (*bpp)->b_blkno);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ssp = (SEGSUM *)sp->segsum;
|
||||
|
||||
ninos = (ssp->ss_ninos + INOPB(fs) - 1) / INOPB(fs);
|
||||
#ifdef DEBUG_SU_NBYTES
|
||||
printf("seg %d += %d for %d inodes\n", /* XXXDEBUG */
|
||||
sp->seg_number, ssp->ss_ninos * DINODE_SIZE,
|
||||
ssp->ss_ninos);
|
||||
#endif
|
||||
sup->su_nbytes += ssp->ss_ninos * DINODE_SIZE;
|
||||
/* sup->su_nbytes += LFS_SUMMARY_SIZE; */
|
||||
sup->su_lastmod = time.tv_sec;
|
||||
/* sup->su_nbytes += fs->lfs_sumsize; */
|
||||
if (fs->lfs_version == 1)
|
||||
sup->su_olastmod = time.tv_sec;
|
||||
else
|
||||
sup->su_lastmod = time.tv_sec;
|
||||
sup->su_ninos += ninos;
|
||||
++sup->su_nsums;
|
||||
fs->lfs_dmeta += (btodb(LFS_SUMMARY_SIZE) + fsbtodb(fs, ninos));
|
||||
fs->lfs_avail -= btodb(LFS_SUMMARY_SIZE);
|
||||
fs->lfs_dmeta += (btofsb(fs, fs->lfs_sumsize) + btofsb(fs, ninos *
|
||||
fs->lfs_ibsize));
|
||||
fs->lfs_avail -= btofsb(fs, fs->lfs_sumsize);
|
||||
|
||||
do_again = !(bp->b_flags & B_GATHERED);
|
||||
(void)VOP_BWRITE(bp); /* Ifile */
|
||||
@ -1399,7 +1439,7 @@ lfs_writeseg(fs, sp)
|
||||
VTOI(bp->b_vp)->i_ffs_blocks);
|
||||
#endif
|
||||
/* Make a copy we'll make changes to */
|
||||
newbp = lfs_newbuf(bp->b_vp, bp->b_lblkno,
|
||||
newbp = lfs_newbuf(fs, bp->b_vp, bp->b_lblkno,
|
||||
bp->b_bcount);
|
||||
newbp->b_blkno = bp->b_blkno;
|
||||
memcpy(newbp->b_data, bp->b_data,
|
||||
@ -1424,9 +1464,10 @@ lfs_writeseg(fs, sp)
|
||||
*/
|
||||
if (changed) {
|
||||
bp->b_flags &= ~(B_ERROR | B_GATHERED);
|
||||
if (bp->b_flags & B_CALL)
|
||||
if (bp->b_flags & B_CALL) {
|
||||
lfs_freebuf(bp);
|
||||
else {
|
||||
bp = NULL;
|
||||
} else {
|
||||
/* Still on free list, leave it there */
|
||||
s = splbio();
|
||||
bp->b_flags &= ~B_BUSY;
|
||||
@ -1439,22 +1480,23 @@ lfs_writeseg(fs, sp)
|
||||
* back around to us in the next
|
||||
* segment.
|
||||
*/
|
||||
fs->lfs_avail -= btodb(bp->b_bcount);
|
||||
fs->lfs_avail -= btofsb(fs, bp->b_bcount);
|
||||
}
|
||||
} else {
|
||||
bp->b_flags &= ~(B_ERROR | B_READ | B_DELWRI |
|
||||
B_GATHERED);
|
||||
LFS_UNLOCK_BUF(bp);
|
||||
if (bp->b_flags & B_CALL)
|
||||
if (bp->b_flags & B_CALL) {
|
||||
lfs_freebuf(bp);
|
||||
else {
|
||||
bp = NULL;
|
||||
} else {
|
||||
bremfree(bp);
|
||||
bp->b_flags |= B_DONE;
|
||||
reassignbuf(bp, bp->b_vp);
|
||||
brelse(bp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
@ -1465,24 +1507,40 @@ lfs_writeseg(fs, sp)
|
||||
* XXX
|
||||
* Fix this to do it inline, instead of malloc/copy.
|
||||
*/
|
||||
datap = dp = malloc(nblocks * sizeof(u_long), M_SEGMENT, M_WAITOK);
|
||||
if (fs->lfs_version == 1)
|
||||
el_size = sizeof(u_long);
|
||||
else
|
||||
el_size = sizeof(u_int32_t);
|
||||
datap = dp = malloc(nblocks * el_size, M_SEGMENT, M_WAITOK);
|
||||
for (bpp = sp->bpp, i = nblocks - 1; i--;) {
|
||||
if (((*++bpp)->b_flags & (B_CALL|B_INVAL)) == (B_CALL|B_INVAL)) {
|
||||
if (copyin((*bpp)->b_saveaddr, dp++, sizeof(u_long)))
|
||||
if (copyin((*bpp)->b_saveaddr, dp, el_size))
|
||||
panic("lfs_writeseg: copyin failed [1]: "
|
||||
"ino %d blk %d",
|
||||
VTOI((*bpp)->b_vp)->i_number,
|
||||
(*bpp)->b_lblkno);
|
||||
} else
|
||||
*dp++ = ((u_long *)(*bpp)->b_data)[0];
|
||||
memcpy(dp, (*bpp)->b_data, el_size);
|
||||
dp += el_size;
|
||||
}
|
||||
ssp->ss_create = time.tv_sec;
|
||||
ssp->ss_datasum = cksum(datap, (nblocks - 1) * sizeof(u_long));
|
||||
if (fs->lfs_version == 1)
|
||||
ssp->ss_ocreate = time.tv_sec;
|
||||
else {
|
||||
ssp->ss_create = time.tv_sec;
|
||||
ssp->ss_serial = ++fs->lfs_serial;
|
||||
ssp->ss_ident = fs->lfs_ident;
|
||||
}
|
||||
ssp->ss_datasum = cksum(datap, (nblocks - 1) * el_size);
|
||||
ssp->ss_sumsum =
|
||||
cksum(&ssp->ss_datasum, LFS_SUMMARY_SIZE - sizeof(ssp->ss_sumsum));
|
||||
cksum(&ssp->ss_datasum, fs->lfs_sumsize - sizeof(ssp->ss_sumsum));
|
||||
free(datap, M_SEGMENT);
|
||||
|
||||
fs->lfs_bfree -= (fsbtodb(fs, ninos) + btodb(LFS_SUMMARY_SIZE));
|
||||
datap = dp = NULL;
|
||||
#ifdef DIAGNOSTIC
|
||||
if (fs->lfs_bfree < btofsb(fs, ninos * fs->lfs_ibsize) + btofsb(fs, fs->lfs_sumsize))
|
||||
panic("lfs_writeseg: No diskspace for summary");
|
||||
#endif
|
||||
fs->lfs_bfree -= (btofsb(fs, ninos * fs->lfs_ibsize) +
|
||||
btofsb(fs, fs->lfs_sumsize));
|
||||
|
||||
strategy = devvp->v_op[VOFFSET(vop_strategy)];
|
||||
|
||||
@ -1507,14 +1565,14 @@ lfs_writeseg(fs, sp)
|
||||
if(devvp==NULL)
|
||||
panic("devvp is NULL");
|
||||
for (bpp = sp->bpp,i = nblocks; i;) {
|
||||
cbp = lfs_newbuf(devvp, (*bpp)->b_blkno, CHUNKSIZE);
|
||||
cbp = lfs_newbuf(fs, devvp, (*bpp)->b_blkno, CHUNKSIZE);
|
||||
cbp->b_dev = i_dev;
|
||||
cbp->b_flags |= B_ASYNC | B_BUSY;
|
||||
cbp->b_bcount = 0;
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if(datosn(fs, (*bpp)->b_blkno + btodb((*bpp)->b_bcount) - 1) !=
|
||||
datosn(fs, cbp->b_blkno)) {
|
||||
if(dtosn(fs, dbtofsb(fs, (*bpp)->b_blkno) + btofsb(fs, (*bpp)->b_bcount) - 1) !=
|
||||
dtosn(fs, dbtofsb(fs, cbp->b_blkno))) {
|
||||
panic("lfs_writeseg: Segment overwrite");
|
||||
}
|
||||
#endif
|
||||
@ -1527,7 +1585,7 @@ lfs_writeseg(fs, sp)
|
||||
#ifdef LFS_TRACK_IOS
|
||||
for(j=0;j<LFS_THROTTLE;j++) {
|
||||
if(fs->lfs_pending[j]==LFS_UNUSED_DADDR) {
|
||||
fs->lfs_pending[j] = cbp->b_blkno;
|
||||
fs->lfs_pending[j] = dbtofsb(fs, cbp->b_blkno);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1554,15 +1612,16 @@ lfs_writeseg(fs, sp)
|
||||
LFS_UNLOCK_BUF(bp);
|
||||
bp->b_flags &= ~(B_ERROR | B_READ | B_DELWRI |
|
||||
B_GATHERED);
|
||||
vn = bp->b_vp;
|
||||
vp = bp->b_vp;
|
||||
if (bp->b_flags & B_CALL) {
|
||||
/* if B_CALL, it was created with newbuf */
|
||||
lfs_freebuf(bp);
|
||||
bp = NULL;
|
||||
} else {
|
||||
bremfree(bp);
|
||||
bp->b_flags |= B_DONE;
|
||||
if(vn)
|
||||
reassignbuf(bp, vn);
|
||||
if(vp)
|
||||
reassignbuf(bp, vp);
|
||||
brelse(bp);
|
||||
}
|
||||
|
||||
@ -1575,22 +1634,25 @@ lfs_writeseg(fs, sp)
|
||||
* sort of block. Only do this for our mount point,
|
||||
* not for, e.g., inode blocks that are attached to
|
||||
* the devvp.
|
||||
* XXX KS - Shouldn't we set *both* if both types
|
||||
* of blocks are present (traverse the dirty list?)
|
||||
*/
|
||||
if(i>1 && vn && *bpp && (*bpp)->b_vp != vn
|
||||
&& (*bpp)->b_vp && (bp=vn->v_dirtyblkhd.lh_first)!=NULL &&
|
||||
vn->v_mount == fs->lfs_ivnode->v_mount)
|
||||
if((i == 1 ||
|
||||
(i > 1 && vp && *bpp && (*bpp)->b_vp != vp)) &&
|
||||
(bp = vp->v_dirtyblkhd.lh_first) != NULL &&
|
||||
vp->v_mount == fs->lfs_ivnode->v_mount)
|
||||
{
|
||||
ip = VTOI(vn);
|
||||
ip = VTOI(vp);
|
||||
#ifdef DEBUG_LFS
|
||||
printf("lfs_writeseg: marking ino %d\n",ip->i_number);
|
||||
printf("lfs_writeseg: marking ino %d\n",
|
||||
ip->i_number);
|
||||
#endif
|
||||
if(bp->b_flags & B_CALL)
|
||||
LFS_SET_UINO(ip, IN_CLEANING);
|
||||
else
|
||||
LFS_SET_UINO(ip, IN_MODIFIED);
|
||||
}
|
||||
/* if(vn->v_dirtyblkhd.lh_first == NULL) */
|
||||
wakeup(vn);
|
||||
wakeup(vp);
|
||||
}
|
||||
++cbp->b_vp->v_numoutput;
|
||||
splx(s);
|
||||
@ -1632,17 +1694,14 @@ lfs_writeseg(fs, sp)
|
||||
}
|
||||
|
||||
void
|
||||
lfs_writesuper(fs, daddr)
|
||||
struct lfs *fs;
|
||||
daddr_t daddr;
|
||||
lfs_writesuper(struct lfs *fs, daddr_t daddr)
|
||||
{
|
||||
struct buf *bp;
|
||||
dev_t i_dev;
|
||||
int (*strategy) __P((void *));
|
||||
int (*strategy)(void *);
|
||||
int s;
|
||||
struct vop_strategy_args vop_strategy_a;
|
||||
|
||||
#ifdef LFS_CANNOT_ROLLFW
|
||||
/*
|
||||
* If we can write one superblock while another is in
|
||||
* progress, we risk not having a complete checkpoint if we crash.
|
||||
@ -1654,16 +1713,17 @@ lfs_writesuper(fs, daddr)
|
||||
}
|
||||
fs->lfs_sbactive = daddr;
|
||||
splx(s);
|
||||
#endif
|
||||
i_dev = VTOI(fs->lfs_ivnode)->i_dev;
|
||||
strategy = VTOI(fs->lfs_ivnode)->i_devvp->v_op[VOFFSET(vop_strategy)];
|
||||
|
||||
/* Set timestamp of this version of the superblock */
|
||||
if (fs->lfs_version == 1)
|
||||
fs->lfs_otstamp = time.tv_sec;
|
||||
fs->lfs_tstamp = time.tv_sec;
|
||||
|
||||
/* Checksum the superblock and copy it into a buffer. */
|
||||
fs->lfs_cksum = lfs_sb_cksum(&(fs->lfs_dlfs));
|
||||
bp = lfs_newbuf(VTOI(fs->lfs_ivnode)->i_devvp, daddr, LFS_SBPAD);
|
||||
bp = lfs_newbuf(fs, VTOI(fs->lfs_ivnode)->i_devvp, fsbtodb(fs, daddr), LFS_SBPAD);
|
||||
*(struct dlfs *)bp->b_data = fs->lfs_dlfs;
|
||||
|
||||
bp->b_dev = i_dev;
|
||||
@ -1687,25 +1747,19 @@ lfs_writesuper(fs, daddr)
|
||||
* chain.
|
||||
*/
|
||||
int
|
||||
lfs_match_fake(fs, bp)
|
||||
struct lfs *fs;
|
||||
struct buf *bp;
|
||||
lfs_match_fake(struct lfs *fs, struct buf *bp)
|
||||
{
|
||||
return (bp->b_flags & B_CALL);
|
||||
}
|
||||
|
||||
int
|
||||
lfs_match_data(fs, bp)
|
||||
struct lfs *fs;
|
||||
struct buf *bp;
|
||||
lfs_match_data(struct lfs *fs, struct buf *bp)
|
||||
{
|
||||
return (bp->b_lblkno >= 0);
|
||||
}
|
||||
|
||||
int
|
||||
lfs_match_indir(fs, bp)
|
||||
struct lfs *fs;
|
||||
struct buf *bp;
|
||||
lfs_match_indir(struct lfs *fs, struct buf *bp)
|
||||
{
|
||||
int lbn;
|
||||
|
||||
@ -1714,9 +1768,7 @@ lfs_match_indir(fs, bp)
|
||||
}
|
||||
|
||||
int
|
||||
lfs_match_dindir(fs, bp)
|
||||
struct lfs *fs;
|
||||
struct buf *bp;
|
||||
lfs_match_dindir(struct lfs *fs, struct buf *bp)
|
||||
{
|
||||
int lbn;
|
||||
|
||||
@ -1725,9 +1777,7 @@ lfs_match_dindir(fs, bp)
|
||||
}
|
||||
|
||||
int
|
||||
lfs_match_tindir(fs, bp)
|
||||
struct lfs *fs;
|
||||
struct buf *bp;
|
||||
lfs_match_tindir(struct lfs *fs, struct buf *bp)
|
||||
{
|
||||
int lbn;
|
||||
|
||||
@ -1743,8 +1793,7 @@ lfs_match_tindir(fs, bp)
|
||||
* released via brelse.
|
||||
*/
|
||||
void
|
||||
lfs_callback(bp)
|
||||
struct buf *bp;
|
||||
lfs_callback(struct buf *bp)
|
||||
{
|
||||
struct lfs *fs;
|
||||
#ifdef LFS_TRACK_IOS
|
||||
@ -1760,7 +1809,7 @@ lfs_callback(bp)
|
||||
wakeup(&fs->lfs_iocount);
|
||||
#ifdef LFS_TRACK_IOS
|
||||
for(j=0;j<LFS_THROTTLE;j++) {
|
||||
if(fs->lfs_pending[j]==bp->b_blkno) {
|
||||
if(fs->lfs_pending[j]==dbtofsb(fs, bp->b_blkno)) {
|
||||
fs->lfs_pending[j] = LFS_UNUSED_DADDR;
|
||||
wakeup(&(fs->lfs_pending[j]));
|
||||
break;
|
||||
@ -1772,16 +1821,13 @@ lfs_callback(bp)
|
||||
}
|
||||
|
||||
void
|
||||
lfs_supercallback(bp)
|
||||
struct buf *bp;
|
||||
lfs_supercallback(struct buf *bp)
|
||||
{
|
||||
struct lfs *fs;
|
||||
|
||||
fs = (struct lfs *)bp->b_saveaddr;
|
||||
#ifdef LFS_CANNOT_ROLLFW
|
||||
fs->lfs_sbactive = 0;
|
||||
wakeup(&fs->lfs_sbactive);
|
||||
#endif
|
||||
if (--fs->lfs_iocount < LFS_THROTTLE)
|
||||
wakeup(&fs->lfs_iocount);
|
||||
lfs_freebuf(bp);
|
||||
@ -1802,10 +1848,7 @@ lfs_supercallback(bp)
|
||||
*/
|
||||
|
||||
void
|
||||
lfs_shellsort(bp_array, lb_array, nmemb)
|
||||
struct buf **bp_array;
|
||||
ufs_daddr_t *lb_array;
|
||||
int nmemb;
|
||||
lfs_shellsort(struct buf **bp_array, ufs_daddr_t *lb_array, int nmemb)
|
||||
{
|
||||
static int __rsshell_increments[] = { 4, 1, 0 };
|
||||
int incr, *incrp, t1, t2;
|
||||
@ -1831,8 +1874,7 @@ lfs_shellsort(bp_array, lb_array, nmemb)
|
||||
* Check VXLOCK. Return 1 if the vnode is locked. Otherwise, vget it.
|
||||
*/
|
||||
int
|
||||
lfs_vref(vp)
|
||||
struct vnode *vp;
|
||||
lfs_vref(struct vnode *vp)
|
||||
{
|
||||
/*
|
||||
* If we return 1 here during a flush, we risk vinvalbuf() not
|
||||
@ -1853,8 +1895,7 @@ lfs_vref(vp)
|
||||
* inline vrele here to avoid the vn_lock and VOP_INACTIVE call at the end.
|
||||
*/
|
||||
void
|
||||
lfs_vunref(vp)
|
||||
struct vnode *vp;
|
||||
lfs_vunref(struct vnode *vp)
|
||||
{
|
||||
/*
|
||||
* Analogous to lfs_vref, if the node is flushing, fake it.
|
||||
@ -1867,8 +1908,8 @@ lfs_vunref(vp)
|
||||
#ifdef DIAGNOSTIC
|
||||
if(vp->v_usecount<=0) {
|
||||
printf("lfs_vunref: inum is %d\n", VTOI(vp)->i_number);
|
||||
printf("lfs_vunref: flags are 0x%x\n", vp->v_flag);
|
||||
printf("lfs_vunref: usecount = %d\n", vp->v_usecount);
|
||||
printf("lfs_vunref: flags are 0x%lx\n", (u_long)vp->v_flag);
|
||||
printf("lfs_vunref: usecount = %ld\n", (long)vp->v_usecount);
|
||||
panic("lfs_vunref: v_usecount<0");
|
||||
}
|
||||
#endif
|
||||
@ -1898,8 +1939,7 @@ lfs_vunref(vp)
|
||||
* cleaning at the head of the list, instead.
|
||||
*/
|
||||
void
|
||||
lfs_vunref_head(vp)
|
||||
struct vnode *vp;
|
||||
lfs_vunref_head(struct vnode *vp)
|
||||
{
|
||||
simple_lock(&vp->v_interlock);
|
||||
#ifdef DIAGNOSTIC
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs_subr.c,v 1.17 2000/09/09 04:49:55 perseant Exp $ */
|
||||
/* $NetBSD: lfs_subr.c,v 1.18 2001/07/13 20:30:24 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
@ -90,8 +90,7 @@
|
||||
* remaining space in the directory.
|
||||
*/
|
||||
int
|
||||
lfs_blkatoff(v)
|
||||
void *v;
|
||||
lfs_blkatoff(void *v)
|
||||
{
|
||||
struct vop_blkatoff_args /* {
|
||||
struct vnode *a_vp;
|
||||
@ -127,9 +126,7 @@ lfs_blkatoff(v)
|
||||
* Single thread the segment writer.
|
||||
*/
|
||||
void
|
||||
lfs_seglock(fs, flags)
|
||||
struct lfs *fs;
|
||||
unsigned long flags;
|
||||
lfs_seglock(struct lfs *fs, unsigned long flags)
|
||||
{
|
||||
struct segment *sp;
|
||||
int s;
|
||||
@ -148,7 +145,7 @@ lfs_seglock(fs, flags)
|
||||
fs->lfs_lockpid = curproc->p_pid;
|
||||
|
||||
sp = fs->lfs_sp = malloc(sizeof(struct segment), M_SEGMENT, M_WAITOK);
|
||||
sp->bpp = malloc(((LFS_SUMMARY_SIZE - sizeof(SEGSUM)) /
|
||||
sp->bpp = malloc(((fs->lfs_sumsize - SEGSUM_SIZE(fs)) /
|
||||
sizeof(ufs_daddr_t) + 1) * sizeof(struct buf *),
|
||||
M_SEGMENT, M_WAITOK);
|
||||
sp->seg_flags = flags;
|
||||
@ -171,8 +168,7 @@ lfs_seglock(fs, flags)
|
||||
* Single thread the segment writer.
|
||||
*/
|
||||
void
|
||||
lfs_segunlock(fs)
|
||||
struct lfs *fs;
|
||||
lfs_segunlock(struct lfs *fs)
|
||||
{
|
||||
struct segment *sp;
|
||||
unsigned long sync, ckp;
|
||||
@ -240,13 +236,15 @@ lfs_segunlock(fs)
|
||||
ckp = sp->seg_flags & SEGM_CKP;
|
||||
if (sp->bpp != sp->cbpp) {
|
||||
/* Free allocated segment summary */
|
||||
fs->lfs_offset -= btodb(LFS_SUMMARY_SIZE);
|
||||
fs->lfs_offset -= btofsb(fs, fs->lfs_sumsize);
|
||||
lfs_freebuf(*sp->bpp);
|
||||
} else
|
||||
printf ("unlock to 0 with no summary");
|
||||
|
||||
free(sp->bpp, M_SEGMENT);
|
||||
sp->bpp = NULL;
|
||||
free(sp, M_SEGMENT);
|
||||
fs->lfs_sp = NULL;
|
||||
|
||||
/*
|
||||
* If the I/O count is non-zero, sleep until it reaches zero.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs_syscalls.c,v 1.56 2000/12/03 07:34:49 perseant Exp $ */
|
||||
/* $NetBSD: lfs_syscalls.c,v 1.57 2001/07/13 20:30:24 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
@ -95,8 +95,8 @@
|
||||
#define FVG_UNLOCK 0x01 /* Needs to be unlocked */
|
||||
#define FVG_PUT 0x02 /* Needs to be vput() */
|
||||
|
||||
struct buf *lfs_fakebuf __P((struct vnode *, int, size_t, caddr_t));
|
||||
int lfs_fasthashget __P((dev_t, ino_t, int *, struct vnode **));
|
||||
struct buf *lfs_fakebuf(struct vnode *, int, size_t, caddr_t);
|
||||
int lfs_fasthashget(dev_t, ino_t, int *, struct vnode **);
|
||||
|
||||
int debug_cleaner = 0;
|
||||
int clean_vnlocked = 0;
|
||||
@ -121,6 +121,9 @@ extern TAILQ_HEAD(bqueues, buf) bufqueues[BQUEUES];
|
||||
|
||||
#define LFS_VREF_THRESHOLD 128
|
||||
|
||||
static int lfs_bmapv(struct proc *, fsid_t *, BLOCK_INFO *, int);
|
||||
static int lfs_markv(struct proc *, fsid_t *, BLOCK_INFO *, int);
|
||||
|
||||
/*
|
||||
* sys_lfs_markv:
|
||||
*
|
||||
@ -134,17 +137,98 @@ extern TAILQ_HEAD(bqueues, buf) bufqueues[BQUEUES];
|
||||
* 0 on success
|
||||
* -1/errno is return on error.
|
||||
*/
|
||||
#ifdef USE_64BIT_SYSCALLS
|
||||
int
|
||||
sys_lfs_markv(p, v, retval)
|
||||
struct proc *p;
|
||||
void *v;
|
||||
register_t *retval;
|
||||
sys_lfs_markv(struct proc *p, void *v, register_t *retval)
|
||||
{
|
||||
struct sys_lfs_markv_args /* {
|
||||
syscallarg(fsid_t *) fsidp;
|
||||
syscallarg(struct block_info *) blkiov;
|
||||
syscallarg(int) blkcnt;
|
||||
} */ *uap = v;
|
||||
BLOCK_INFO *blkiov;
|
||||
int blkcnt, error;
|
||||
fsid_t fsid;
|
||||
|
||||
if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
|
||||
return (error);
|
||||
|
||||
if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0)
|
||||
return (error);
|
||||
|
||||
blkcnt = SCARG(uap, blkcnt);
|
||||
blkiov = malloc(blkcnt * sizeof(BLOCK_INFO), M_SEGMENT, M_WAITOK);
|
||||
if ((error = copyin(SCARG(uap, blkiov), blkiov,
|
||||
blkcnt * sizeof(BLOCK_INFO))) != 0)
|
||||
goto out;
|
||||
|
||||
if ((error = lfs_markv(p, &fsid, blkiov, blkcnt)) == 0)
|
||||
copyout(blkiov, SCARG(uap, blkiov),
|
||||
blkcnt * sizeof(BLOCK_INFO));
|
||||
out:
|
||||
free(blkiov, M_SEGMENT);
|
||||
return error;
|
||||
}
|
||||
#else
|
||||
int
|
||||
sys_lfs_markv(struct proc *p, void *v, register_t *retval)
|
||||
{
|
||||
struct sys_lfs_markv_args /* {
|
||||
syscallarg(fsid_t *) fsidp;
|
||||
syscallarg(struct block_info *) blkiov;
|
||||
syscallarg(int) blkcnt;
|
||||
} */ *uap = v;
|
||||
BLOCK_INFO *blkiov;
|
||||
BLOCK_INFO_15 *blkiov15;
|
||||
int i, blkcnt, error;
|
||||
fsid_t fsid;
|
||||
|
||||
if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
|
||||
return (error);
|
||||
|
||||
if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0)
|
||||
return (error);
|
||||
|
||||
blkcnt = SCARG(uap, blkcnt);
|
||||
blkiov = malloc(blkcnt * sizeof(BLOCK_INFO), M_SEGMENT, M_WAITOK);
|
||||
blkiov15 = malloc(blkcnt * sizeof(BLOCK_INFO_15), M_SEGMENT, M_WAITOK);
|
||||
if ((error = copyin(SCARG(uap, blkiov), blkiov15,
|
||||
blkcnt * sizeof(BLOCK_INFO_15))) != 0)
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < blkcnt; i++) {
|
||||
blkiov[i].bi_inode = blkiov15[i].bi_inode;
|
||||
blkiov[i].bi_lbn = blkiov15[i].bi_lbn;
|
||||
blkiov[i].bi_daddr = blkiov15[i].bi_daddr;
|
||||
blkiov[i].bi_segcreate = blkiov15[i].bi_segcreate;
|
||||
blkiov[i].bi_version = blkiov15[i].bi_version;
|
||||
blkiov[i].bi_bp = blkiov15[i].bi_bp;
|
||||
blkiov[i].bi_size = blkiov15[i].bi_size;
|
||||
}
|
||||
|
||||
if ((error = lfs_markv(p, &fsid, blkiov, blkcnt)) == 0) {
|
||||
for (i = 0; i < blkcnt; i++) {
|
||||
blkiov15[i].bi_inode = blkiov[i].bi_inode;
|
||||
blkiov15[i].bi_lbn = blkiov[i].bi_lbn;
|
||||
blkiov15[i].bi_daddr = blkiov[i].bi_daddr;
|
||||
blkiov15[i].bi_segcreate = blkiov[i].bi_segcreate;
|
||||
blkiov15[i].bi_version = blkiov[i].bi_version;
|
||||
blkiov15[i].bi_bp = blkiov[i].bi_bp;
|
||||
blkiov15[i].bi_size = blkiov[i].bi_size;
|
||||
}
|
||||
copyout(blkiov15, SCARG(uap, blkiov),
|
||||
blkcnt * sizeof(BLOCK_INFO_15));
|
||||
}
|
||||
out:
|
||||
free(blkiov, M_SEGMENT);
|
||||
free(blkiov15, M_SEGMENT);
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
lfs_markv(struct proc *p, fsid_t *fsidp, BLOCK_INFO *blkiov, int blkcnt)
|
||||
{
|
||||
BLOCK_INFO *blkp;
|
||||
IFILE *ifp;
|
||||
struct buf *bp, *nbp;
|
||||
@ -155,11 +239,9 @@ sys_lfs_markv(p, v, retval)
|
||||
#ifdef DEBUG_LFS
|
||||
int vputc=0, iwritten=0;
|
||||
#endif
|
||||
fsid_t fsid;
|
||||
void *start;
|
||||
ino_t lastino;
|
||||
ufs_daddr_t b_daddr, v_daddr;
|
||||
int origcnt, cnt, error, lfs_fastvget_unlock;
|
||||
int cnt, error, lfs_fastvget_unlock;
|
||||
int do_again=0;
|
||||
int s;
|
||||
#ifdef CHECK_COPYIN
|
||||
@ -171,26 +253,14 @@ sys_lfs_markv(p, v, retval)
|
||||
int numlocked=0, numrefed=0;
|
||||
ino_t maxino;
|
||||
|
||||
if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0)
|
||||
return (error);
|
||||
|
||||
if ((mntp = vfs_getvfs(&fsid)) == NULL)
|
||||
if ((mntp = vfs_getvfs(fsidp)) == NULL)
|
||||
return (ENOENT);
|
||||
|
||||
fs = VFSTOUFS(mntp)->um_lfs;
|
||||
|
||||
if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
|
||||
return (error);
|
||||
|
||||
|
||||
maxino = (dbtofsb(fs, VTOI(fs->lfs_ivnode)->i_ffs_blocks) -
|
||||
maxino = (fragstoblks(fs, fsbtofrags(fs, VTOI(fs->lfs_ivnode)->i_ffs_blocks)) -
|
||||
fs->lfs_cleansz - fs->lfs_segtabsz) * fs->lfs_ifpb;
|
||||
|
||||
origcnt = cnt = SCARG(uap, blkcnt);
|
||||
start = malloc(cnt * sizeof(BLOCK_INFO), M_SEGMENT, M_WAITOK);
|
||||
error = copyin(SCARG(uap, blkiov), start, cnt * sizeof(BLOCK_INFO));
|
||||
if (error)
|
||||
goto err1;
|
||||
cnt = blkcnt;
|
||||
|
||||
if ((error = vfs_busy(mntp, LK_NOWAIT, NULL)) != 0)
|
||||
return (error);
|
||||
@ -212,20 +282,20 @@ sys_lfs_markv(p, v, retval)
|
||||
#ifdef DEBUG_LFS
|
||||
/* Run through and count the inodes */
|
||||
lastino = LFS_UNUSED_INUM;
|
||||
for(blkp = start; cnt--; ++blkp) {
|
||||
for(blkp = blkiov; cnt--; ++blkp) {
|
||||
if(lastino != blkp->bi_inode) {
|
||||
lastino = blkp->bi_inode;
|
||||
vputc++;
|
||||
}
|
||||
}
|
||||
cnt = origcnt;
|
||||
cnt = blkcnt;
|
||||
printf("[%d/",vputc);
|
||||
iwritten=0;
|
||||
#endif /* DEBUG_LFS */
|
||||
/* these were inside the initialization for the for loop */
|
||||
v_daddr = LFS_UNUSED_DADDR;
|
||||
lastino = LFS_UNUSED_INUM;
|
||||
for (blkp = start; cnt--; ++blkp)
|
||||
for (blkp = blkiov; cnt--; ++blkp)
|
||||
{
|
||||
if(blkp->bi_daddr == LFS_FORCE_WRITE)
|
||||
printf("lfs_markv: warning: force-writing ino %d lbn %d\n",
|
||||
@ -238,12 +308,11 @@ sys_lfs_markv(p, v, retval)
|
||||
*/
|
||||
for(j=0;j<LFS_THROTTLE;j++) {
|
||||
if(fs->lfs_pending[j] != LFS_UNUSED_DADDR
|
||||
&& datosn(fs,fs->lfs_pending[j])==datosn(fs,blkp->bi_daddr)
|
||||
&& dtosn(fs,fs->lfs_pending[j])==dtosn(fs,blkp->bi_daddr)
|
||||
&& blkp->bi_daddr != LFS_FORCE_WRITE)
|
||||
{
|
||||
printf("lfs_markv: attempt to clean pending segment? (#%d)\n",
|
||||
datosn(fs, fs->lfs_pending[j]));
|
||||
/* free(start,M_SEGMENT); */
|
||||
dtosn(fs, fs->lfs_pending[j]));
|
||||
/* return (EBUSY); */
|
||||
}
|
||||
}
|
||||
@ -316,7 +385,7 @@ sys_lfs_markv(p, v, retval)
|
||||
#ifdef DEBUG_LFS
|
||||
printf("lfs_markv: lfs_fastvget failed with %d (ino %d, segment %d)\n",
|
||||
error, blkp->bi_inode,
|
||||
datosn(fs, blkp->bi_daddr));
|
||||
dtosn(fs, blkp->bi_daddr));
|
||||
#endif /* DEBUG_LFS */
|
||||
/*
|
||||
* If we got EAGAIN, that means that the
|
||||
@ -376,13 +445,13 @@ sys_lfs_markv(p, v, retval)
|
||||
b_daddr = 0;
|
||||
if(blkp->bi_daddr != LFS_FORCE_WRITE) {
|
||||
if (VOP_BMAP(vp, blkp->bi_lbn, NULL, &b_daddr, NULL) ||
|
||||
b_daddr != blkp->bi_daddr)
|
||||
dbtofsb(fs, b_daddr) != blkp->bi_daddr)
|
||||
{
|
||||
if(datosn(fs,b_daddr)
|
||||
== datosn(fs,blkp->bi_daddr))
|
||||
if(dtosn(fs,dbtofsb(fs, b_daddr))
|
||||
== dtosn(fs,blkp->bi_daddr))
|
||||
{
|
||||
printf("lfs_markv: wrong da same seg: %x vs %x\n",
|
||||
blkp->bi_daddr, b_daddr);
|
||||
blkp->bi_daddr, dbtofsb(fs, b_daddr));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -416,7 +485,7 @@ sys_lfs_markv(p, v, retval)
|
||||
bp = lfs_fakebuf(vp, blkp->bi_lbn,
|
||||
blkp->bi_size, blkp->bi_bp);
|
||||
/* Pretend we used bread() to get it */
|
||||
bp->b_blkno = blkp->bi_daddr;
|
||||
bp->b_blkno = fsbtodb(fs, blkp->bi_daddr);
|
||||
} else {
|
||||
/* Indirect block */
|
||||
bp = getblk(vp, blkp->bi_lbn, blkp->bi_size, 0, 0);
|
||||
@ -465,7 +534,6 @@ sys_lfs_markv(p, v, retval)
|
||||
* we'd be unhappy at recovery time.
|
||||
*/
|
||||
lfs_segwrite(mntp, SEGM_SYNC|SEGM_CLEAN|SEGM_CKP);
|
||||
free(start, M_SEGMENT);
|
||||
|
||||
lfs_segunlock(fs);
|
||||
|
||||
@ -506,7 +574,7 @@ sys_lfs_markv(p, v, retval)
|
||||
goto again;
|
||||
}
|
||||
if(bp->b_flags & B_DELWRI)
|
||||
fs->lfs_avail += btodb(bp->b_bcount);
|
||||
fs->lfs_avail += btofsb(fs, bp->b_bcount);
|
||||
bremfree(bp);
|
||||
splx(s);
|
||||
brelse(bp);
|
||||
@ -514,7 +582,6 @@ sys_lfs_markv(p, v, retval)
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
free(start, M_SEGMENT);
|
||||
lfs_segunlock(fs);
|
||||
vfs_unbusy(mntp);
|
||||
#ifdef DEBUG_LFS
|
||||
@ -524,11 +591,6 @@ sys_lfs_markv(p, v, retval)
|
||||
#endif
|
||||
|
||||
return (error);
|
||||
|
||||
err1:
|
||||
printf("lfs_markv err1\n");
|
||||
free(start, M_SEGMENT);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -539,18 +601,98 @@ sys_lfs_markv(p, v, retval)
|
||||
* 0 on success
|
||||
* -1/errno is return on error.
|
||||
*/
|
||||
|
||||
#ifdef USE_64BIT_SYSCALLS
|
||||
int
|
||||
sys_lfs_bmapv(p, v, retval)
|
||||
struct proc *p;
|
||||
void *v;
|
||||
register_t *retval;
|
||||
sys_lfs_bmapv(struct proc *p, void *v, register_t *retval)
|
||||
{
|
||||
struct sys_lfs_bmapv_args /* {
|
||||
syscallarg(fsid_t *) fsidp;
|
||||
syscallarg(struct block_info *) blkiov;
|
||||
syscallarg(int) blkcnt;
|
||||
} */ *uap = v;
|
||||
BLOCK_INFO *blkiov;
|
||||
int blkcnt, error;
|
||||
fsid_t fsid;
|
||||
|
||||
if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
|
||||
return (error);
|
||||
|
||||
if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0)
|
||||
return (error);
|
||||
|
||||
blkcnt = SCARG(uap, blkcnt);
|
||||
blkiov = malloc(blkcnt * sizeof(BLOCK_INFO), M_SEGMENT, M_WAITOK);
|
||||
if ((error = copyin(SCARG(uap, blkiov), blkiov,
|
||||
blkcnt * sizeof(BLOCK_INFO))) != 0)
|
||||
goto out;
|
||||
|
||||
if ((error = lfs_bmapv(p, &fsid, blkiov, blkcnt)) == 0)
|
||||
copyout(blkiov, SCARG(uap, blkiov),
|
||||
blkcnt * sizeof(BLOCK_INFO));
|
||||
out:
|
||||
free(blkiov, M_SEGMENT);
|
||||
return error;
|
||||
}
|
||||
#else
|
||||
int
|
||||
sys_lfs_bmapv(struct proc *p, void *v, register_t *retval)
|
||||
{
|
||||
struct sys_lfs_bmapv_args /* {
|
||||
syscallarg(fsid_t *) fsidp;
|
||||
syscallarg(struct block_info *) blkiov;
|
||||
syscallarg(int) blkcnt;
|
||||
} */ *uap = v;
|
||||
BLOCK_INFO *blkiov;
|
||||
BLOCK_INFO_15 *blkiov15;
|
||||
int i, blkcnt, error;
|
||||
fsid_t fsid;
|
||||
|
||||
if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
|
||||
return (error);
|
||||
|
||||
if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0)
|
||||
return (error);
|
||||
|
||||
blkcnt = SCARG(uap, blkcnt);
|
||||
blkiov = malloc(blkcnt * sizeof(BLOCK_INFO), M_SEGMENT, M_WAITOK);
|
||||
blkiov15 = malloc(blkcnt * sizeof(BLOCK_INFO_15), M_SEGMENT, M_WAITOK);
|
||||
if ((error = copyin(SCARG(uap, blkiov), blkiov15,
|
||||
blkcnt * sizeof(BLOCK_INFO_15))) != 0)
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < blkcnt; i++) {
|
||||
blkiov[i].bi_inode = blkiov15[i].bi_inode;
|
||||
blkiov[i].bi_lbn = blkiov15[i].bi_lbn;
|
||||
blkiov[i].bi_daddr = blkiov15[i].bi_daddr;
|
||||
blkiov[i].bi_segcreate = blkiov15[i].bi_segcreate;
|
||||
blkiov[i].bi_version = blkiov15[i].bi_version;
|
||||
blkiov[i].bi_bp = blkiov15[i].bi_bp;
|
||||
blkiov[i].bi_size = blkiov15[i].bi_size;
|
||||
}
|
||||
|
||||
if ((error = lfs_bmapv(p, &fsid, blkiov, blkcnt)) == 0) {
|
||||
for (i = 0; i < blkcnt; i++) {
|
||||
blkiov15[i].bi_inode = blkiov[i].bi_inode;
|
||||
blkiov15[i].bi_lbn = blkiov[i].bi_lbn;
|
||||
blkiov15[i].bi_daddr = blkiov[i].bi_daddr;
|
||||
blkiov15[i].bi_segcreate = blkiov[i].bi_segcreate;
|
||||
blkiov15[i].bi_version = blkiov[i].bi_version;
|
||||
blkiov15[i].bi_bp = blkiov[i].bi_bp;
|
||||
blkiov15[i].bi_size = blkiov[i].bi_size;
|
||||
}
|
||||
copyout(blkiov15, SCARG(uap, blkiov),
|
||||
blkcnt * sizeof(BLOCK_INFO_15));
|
||||
}
|
||||
out:
|
||||
free(blkiov, M_SEGMENT);
|
||||
free(blkiov15, M_SEGMENT);
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
lfs_bmapv(struct proc *p, fsid_t *fsidp, BLOCK_INFO *blkiov, int blkcnt)
|
||||
{
|
||||
BLOCK_INFO *blkp;
|
||||
IFILE *ifp;
|
||||
struct buf *bp;
|
||||
@ -559,11 +701,9 @@ sys_lfs_bmapv(p, v, retval)
|
||||
struct mount *mntp;
|
||||
struct ufsmount *ump;
|
||||
struct vnode *vp;
|
||||
fsid_t fsid;
|
||||
void *start;
|
||||
ino_t lastino;
|
||||
ufs_daddr_t v_daddr;
|
||||
int origcnt, cnt, error, need_unlock=0;
|
||||
int cnt, error, need_unlock=0;
|
||||
int numlocked=0, numrefed=0;
|
||||
#ifdef LFS_TRACK_IOS
|
||||
int j;
|
||||
@ -571,26 +711,14 @@ sys_lfs_bmapv(p, v, retval)
|
||||
|
||||
lfs_cleaner_pid = p->p_pid;
|
||||
|
||||
if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
|
||||
return (error);
|
||||
|
||||
if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0)
|
||||
return (error);
|
||||
if ((mntp = vfs_getvfs(&fsid)) == NULL)
|
||||
if ((mntp = vfs_getvfs(fsidp)) == NULL)
|
||||
return (ENOENT);
|
||||
|
||||
ump = VFSTOUFS(mntp);
|
||||
if ((error = vfs_busy(mntp, LK_NOWAIT, NULL)) != 0)
|
||||
return (error);
|
||||
|
||||
origcnt = cnt = SCARG(uap, blkcnt);
|
||||
start = malloc(cnt * sizeof(BLOCK_INFO), M_SEGMENT, M_WAITOK);
|
||||
error = copyin(SCARG(uap, blkiov), start, cnt * sizeof(BLOCK_INFO));
|
||||
if (error) {
|
||||
free(start, M_SEGMENT);
|
||||
vfs_unbusy(mntp);
|
||||
return (error);
|
||||
}
|
||||
cnt = blkcnt;
|
||||
|
||||
fs = VFSTOUFS(mntp)->um_lfs;
|
||||
|
||||
@ -599,13 +727,12 @@ sys_lfs_bmapv(p, v, retval)
|
||||
/* these were inside the initialization for the for loop */
|
||||
v_daddr = LFS_UNUSED_DADDR;
|
||||
lastino = LFS_UNUSED_INUM;
|
||||
for (blkp = start; cnt--; ++blkp)
|
||||
for (blkp = blkiov; cnt--; ++blkp)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (datosn(fs, fs->lfs_curseg) == datosn(fs, blkp->bi_daddr)) {
|
||||
if (dtosn(fs, fs->lfs_curseg) == dtosn(fs, blkp->bi_daddr)) {
|
||||
printf("lfs_bmapv: attempt to clean current segment? (#%d)\n",
|
||||
datosn(fs, fs->lfs_curseg));
|
||||
free(start,M_SEGMENT);
|
||||
dtosn(fs, fs->lfs_curseg));
|
||||
vfs_unbusy(mntp);
|
||||
return (EBUSY);
|
||||
}
|
||||
@ -618,11 +745,10 @@ sys_lfs_bmapv(p, v, retval)
|
||||
*/
|
||||
for(j=0;j<LFS_THROTTLE;j++) {
|
||||
if(fs->lfs_pending[j] != LFS_UNUSED_DADDR
|
||||
&& datosn(fs,fs->lfs_pending[j])==datosn(fs,blkp->bi_daddr))
|
||||
&& dtosn(fs,fs->lfs_pending[j])==dtosn(fs,blkp->bi_daddr))
|
||||
{
|
||||
printf("lfs_bmapv: attempt to clean pending segment? (#%d)\n",
|
||||
datosn(fs, fs->lfs_pending[j]));
|
||||
free(start,M_SEGMENT);
|
||||
dtosn(fs, fs->lfs_pending[j]));
|
||||
vfs_unbusy(mntp);
|
||||
return (EBUSY);
|
||||
}
|
||||
@ -737,6 +863,7 @@ sys_lfs_bmapv(p, v, retval)
|
||||
blkp->bi_daddr = LFS_UNUSED_DADDR;
|
||||
continue;
|
||||
}
|
||||
blkp->bi_daddr = dbtofsb(fs, blkp->bi_daddr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -758,8 +885,6 @@ sys_lfs_bmapv(p, v, retval)
|
||||
numrefed);
|
||||
}
|
||||
|
||||
copyout(start, SCARG(uap, blkiov), origcnt * sizeof(BLOCK_INFO));
|
||||
free(start, M_SEGMENT);
|
||||
vfs_unbusy(mntp);
|
||||
|
||||
return 0;
|
||||
@ -774,10 +899,7 @@ sys_lfs_bmapv(p, v, retval)
|
||||
* -1/errno is return on error.
|
||||
*/
|
||||
int
|
||||
sys_lfs_segclean(p, v, retval)
|
||||
struct proc *p;
|
||||
void *v;
|
||||
register_t *retval;
|
||||
sys_lfs_segclean(struct proc *p, void *v, register_t *retval)
|
||||
{
|
||||
struct sys_lfs_segclean_args /* {
|
||||
syscallarg(fsid_t *) fsidp;
|
||||
@ -801,7 +923,7 @@ sys_lfs_segclean(p, v, retval)
|
||||
|
||||
fs = VFSTOUFS(mntp)->um_lfs;
|
||||
|
||||
if (datosn(fs, fs->lfs_curseg) == SCARG(uap, segment))
|
||||
if (dtosn(fs, fs->lfs_curseg) == SCARG(uap, segment))
|
||||
return (EBUSY);
|
||||
|
||||
if ((error = vfs_busy(mntp, LK_NOWAIT, NULL)) != 0)
|
||||
@ -818,13 +940,16 @@ sys_lfs_segclean(p, v, retval)
|
||||
return (EALREADY);
|
||||
}
|
||||
|
||||
fs->lfs_avail += fsbtodb(fs, fs->lfs_ssize);
|
||||
fs->lfs_avail += segtod(fs, 1);
|
||||
if (sup->su_flags & SEGUSE_SUPERBLOCK)
|
||||
fs->lfs_avail -= btodb(LFS_SBPAD);
|
||||
fs->lfs_bfree += sup->su_nsums * btodb(LFS_SUMMARY_SIZE) +
|
||||
fsbtodb(fs, sup->su_ninos);
|
||||
fs->lfs_dmeta -= sup->su_nsums * btodb(LFS_SUMMARY_SIZE) +
|
||||
fsbtodb(fs, sup->su_ninos);
|
||||
fs->lfs_avail -= btofsb(fs, LFS_SBPAD);
|
||||
if (fs->lfs_version > 1 && SCARG(uap, segment) == 0 &&
|
||||
fs->lfs_start < btofsb(fs, LFS_LABELPAD))
|
||||
fs->lfs_avail -= btofsb(fs, LFS_LABELPAD) - fs->lfs_start;
|
||||
fs->lfs_bfree += sup->su_nsums * btofsb(fs, fs->lfs_sumsize) +
|
||||
btofsb(fs, sup->su_ninos * fs->lfs_ibsize);
|
||||
fs->lfs_dmeta -= sup->su_nsums * btofsb(fs, fs->lfs_sumsize) +
|
||||
btofsb(fs, sup->su_ninos * fs->lfs_ibsize);
|
||||
if (fs->lfs_dmeta < 0)
|
||||
fs->lfs_dmeta = 0;
|
||||
sup->su_flags &= ~SEGUSE_DIRTY;
|
||||
@ -855,10 +980,7 @@ sys_lfs_segclean(p, v, retval)
|
||||
* -1/errno is return on error.
|
||||
*/
|
||||
int
|
||||
sys_lfs_segwait(p, v, retval)
|
||||
struct proc *p;
|
||||
void *v;
|
||||
register_t *retval;
|
||||
sys_lfs_segwait(struct proc *p, void *v, register_t *retval)
|
||||
{
|
||||
struct sys_lfs_segwait_args /* {
|
||||
syscallarg(fsid_t *) fsidp;
|
||||
@ -921,11 +1043,7 @@ sys_lfs_segwait(p, v, retval)
|
||||
extern struct lock ufs_hashlock;
|
||||
|
||||
int
|
||||
lfs_fasthashget(dev, ino, need_unlock, vpp)
|
||||
dev_t dev;
|
||||
ino_t ino;
|
||||
int *need_unlock;
|
||||
struct vnode **vpp;
|
||||
lfs_fasthashget(dev_t dev, ino_t ino, int *need_unlock, struct vnode **vpp)
|
||||
{
|
||||
struct inode *ip;
|
||||
|
||||
@ -969,13 +1087,7 @@ lfs_fasthashget(dev, ino, need_unlock, vpp)
|
||||
}
|
||||
|
||||
int
|
||||
lfs_fastvget(mp, ino, daddr, vpp, dinp, need_unlock)
|
||||
struct mount *mp;
|
||||
ino_t ino;
|
||||
ufs_daddr_t daddr;
|
||||
struct vnode **vpp;
|
||||
struct dinode *dinp;
|
||||
int *need_unlock;
|
||||
lfs_fastvget(struct mount *mp, ino_t ino, ufs_daddr_t daddr, struct vnode **vpp, struct dinode *dinp, int *need_unlock)
|
||||
{
|
||||
struct inode *ip;
|
||||
struct vnode *vp;
|
||||
@ -983,17 +1095,19 @@ lfs_fastvget(mp, ino, daddr, vpp, dinp, need_unlock)
|
||||
dev_t dev;
|
||||
int error;
|
||||
struct buf *bp;
|
||||
struct lfs *fs;
|
||||
|
||||
ump = VFSTOUFS(mp);
|
||||
dev = ump->um_dev;
|
||||
fs = ump->um_lfs;
|
||||
*need_unlock = 0;
|
||||
|
||||
/*
|
||||
* Wait until the filesystem is fully mounted before allowing vget
|
||||
* to complete. This prevents possible problems with roll-forward.
|
||||
*/
|
||||
while(ump->um_lfs->lfs_flags & LFS_NOTYET) {
|
||||
tsleep(&ump->um_lfs->lfs_flags, PRIBIO+1, "lfs_fnotyet", 0);
|
||||
while(fs->lfs_flags & LFS_NOTYET) {
|
||||
tsleep(&fs->lfs_flags, PRIBIO+1, "lfs_fnotyet", 0);
|
||||
}
|
||||
/*
|
||||
* This is playing fast and loose. Someone may have the inode
|
||||
@ -1037,7 +1151,7 @@ lfs_fastvget(mp, ino, daddr, vpp, dinp, need_unlock)
|
||||
* the i_devvp initialization.
|
||||
* Ask Kirk.
|
||||
*/
|
||||
ip->i_lfs = ump->um_lfs;
|
||||
ip->i_lfs = fs;
|
||||
|
||||
/* Read in the disk contents for the inode, copy into the inode. */
|
||||
if (dinp) {
|
||||
@ -1055,8 +1169,8 @@ lfs_fastvget(mp, ino, daddr, vpp, dinp, need_unlock)
|
||||
if(ip->i_number != ino)
|
||||
panic("lfs_fastvget: I was fed the wrong inode!");
|
||||
} else {
|
||||
error = bread(ump->um_devvp, daddr,
|
||||
(int)ump->um_lfs->lfs_bsize, NOCRED, &bp);
|
||||
error = bread(ump->um_devvp, fsbtodb(fs, daddr), fs->lfs_ibsize,
|
||||
NOCRED, &bp);
|
||||
if (error) {
|
||||
printf("lfs_fastvget: bread failed with %d\n",error);
|
||||
/*
|
||||
@ -1073,8 +1187,7 @@ lfs_fastvget(mp, ino, daddr, vpp, dinp, need_unlock)
|
||||
*vpp = NULL;
|
||||
return (error);
|
||||
}
|
||||
ip->i_din.ffs_din =
|
||||
*lfs_ifind(ump->um_lfs, ino, bp);
|
||||
ip->i_din.ffs_din = *lfs_ifind(fs, ino, bp);
|
||||
brelse(bp);
|
||||
}
|
||||
ip->i_ffs_effnlink = ip->i_ffs_nlink;
|
||||
@ -1117,24 +1230,20 @@ lfs_fastvget(mp, ino, daddr, vpp, dinp, need_unlock)
|
||||
}
|
||||
|
||||
struct buf *
|
||||
lfs_fakebuf(vp, lbn, size, uaddr)
|
||||
struct vnode *vp;
|
||||
int lbn;
|
||||
size_t size;
|
||||
caddr_t uaddr;
|
||||
lfs_fakebuf(struct vnode *vp, int lbn, size_t size, caddr_t uaddr)
|
||||
{
|
||||
struct buf *bp;
|
||||
int error;
|
||||
|
||||
#ifndef ALLOW_VFLUSH_CORRUPTION
|
||||
bp = lfs_newbuf(vp, lbn, size);
|
||||
bp = lfs_newbuf(VTOI(vp)->i_lfs, vp, lbn, size);
|
||||
error = copyin(uaddr, bp->b_data, size);
|
||||
if(error) {
|
||||
lfs_freebuf(bp);
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
bp = lfs_newbuf(vp, lbn, 0);
|
||||
bp = lfs_newbuf(VTOI(vp)->i_lfs, vp, lbn, 0);
|
||||
bp->b_flags |= B_INVAL;
|
||||
bp->b_saveaddr = uaddr;
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs_vfsops.c,v 1.65 2001/05/30 11:57:19 mrg Exp $ */
|
||||
/* $NetBSD: lfs_vfsops.c,v 1.66 2001/07/13 20:30:25 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
@ -104,7 +104,7 @@
|
||||
#include <ufs/lfs/lfs.h>
|
||||
#include <ufs/lfs/lfs_extern.h>
|
||||
|
||||
int lfs_mountfs __P((struct vnode *, struct mount *, struct proc *));
|
||||
int lfs_mountfs(struct vnode *, struct mount *, struct proc *);
|
||||
|
||||
extern const struct vnodeopv_desc lfs_vnodeop_opv_desc;
|
||||
extern const struct vnodeopv_desc lfs_specop_opv_desc;
|
||||
@ -214,12 +214,7 @@ lfs_mountroot()
|
||||
* mount system call
|
||||
*/
|
||||
int
|
||||
lfs_mount(mp, path, data, ndp, p)
|
||||
struct mount *mp;
|
||||
const char *path;
|
||||
void *data;
|
||||
struct nameidata *ndp;
|
||||
struct proc *p;
|
||||
lfs_mount(struct mount *mp, const char *path, void *data, struct nameidata *ndp, struct proc *p)
|
||||
{
|
||||
struct vnode *devvp;
|
||||
struct ufs_args args;
|
||||
@ -323,7 +318,6 @@ lfs_mount(mp, path, data, ndp, p)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef LFS_DO_ROLLFORWARD
|
||||
/*
|
||||
* Roll-forward code.
|
||||
*/
|
||||
@ -346,8 +340,10 @@ update_meta(struct lfs *fs, ino_t ino, int version, ufs_daddr_t lbn,
|
||||
int num;
|
||||
|
||||
if ((error = lfs_rf_valloc(fs, ino, version, p, &vp)) != 0) {
|
||||
#ifdef DEBUG_LFS_RFW
|
||||
printf("update_meta: ino %d: lfs_rf_valloc returned %d\n", ino,
|
||||
error);
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -359,7 +355,7 @@ update_meta(struct lfs *fs, ino_t ino, int version, ufs_daddr_t lbn,
|
||||
/* No need to write, the block is already on disk */
|
||||
if (bp->b_flags & B_DELWRI) {
|
||||
LFS_UNLOCK_BUF(bp);
|
||||
fs->lfs_avail += btodb(bp->b_bcount);
|
||||
fs->lfs_avail += btofsb(fs, bp->b_bcount);
|
||||
}
|
||||
bp->b_flags |= B_INVAL;
|
||||
brelse(bp);
|
||||
@ -381,7 +377,9 @@ update_meta(struct lfs *fs, ino_t ino, int version, ufs_daddr_t lbn,
|
||||
|
||||
error = ufs_bmaparray(vp, lbn, &odaddr, &a[0], &num, NULL);
|
||||
if (error) {
|
||||
#ifdef DEBUG_LFS_RFW
|
||||
printf("update_meta: ufs_bmaparray returned %d\n", error);
|
||||
#endif
|
||||
vput(vp);
|
||||
return error;
|
||||
}
|
||||
@ -389,13 +387,13 @@ update_meta(struct lfs *fs, ino_t ino, int version, ufs_daddr_t lbn,
|
||||
case 0:
|
||||
ooff = ip->i_ffs_db[lbn];
|
||||
if (ooff == UNWRITTEN)
|
||||
ip->i_ffs_blocks += btodb(size);
|
||||
ip->i_ffs_blocks += btofsb(fs, size);
|
||||
ip->i_ffs_db[lbn] = ndaddr;
|
||||
break;
|
||||
case 1:
|
||||
ooff = ip->i_ffs_ib[a[0].in_off];
|
||||
if (ooff == UNWRITTEN)
|
||||
ip->i_ffs_blocks += btodb(size);
|
||||
ip->i_ffs_blocks += btofsb(fs, size);
|
||||
ip->i_ffs_ib[a[0].in_off] = ndaddr;
|
||||
break;
|
||||
default:
|
||||
@ -405,7 +403,7 @@ update_meta(struct lfs *fs, ino_t ino, int version, ufs_daddr_t lbn,
|
||||
|
||||
ooff = ((ufs_daddr_t *)bp->b_data)[ap->in_off];
|
||||
if (ooff == UNWRITTEN)
|
||||
ip->i_ffs_blocks += btodb(size);
|
||||
ip->i_ffs_blocks += btofsb(fs, size);
|
||||
((ufs_daddr_t *)bp->b_data)[ap->in_off] = ndaddr;
|
||||
(void) VOP_BWRITE(bp);
|
||||
}
|
||||
@ -413,31 +411,32 @@ update_meta(struct lfs *fs, ino_t ino, int version, ufs_daddr_t lbn,
|
||||
|
||||
/* Update segment usage information. */
|
||||
if (odaddr > 0) {
|
||||
LFS_SEGENTRY(sup, fs, datosn(fs, odaddr), bp);
|
||||
LFS_SEGENTRY(sup, fs, dtosn(fs, dbtofsb(fs, odaddr)), bp);
|
||||
#ifdef DIAGNOSTIC
|
||||
if (sup->su_nbytes < size) {
|
||||
panic("update_meta: negative bytes "
|
||||
"(segment %d short by %ld)\n",
|
||||
datosn(fs, odaddr), (long)size - sup->su_nbytes);
|
||||
dtosn(fs, dbtofsb(fs, odaddr)), (long)size - sup->su_nbytes);
|
||||
sup->su_nbytes = size;
|
||||
}
|
||||
#endif
|
||||
sup->su_nbytes -= size;
|
||||
VOP_BWRITE(bp);
|
||||
}
|
||||
LFS_SEGENTRY(sup, fs, datosn(fs, ndaddr), bp);
|
||||
LFS_SEGENTRY(sup, fs, dtosn(fs, ndaddr), bp);
|
||||
sup->su_nbytes += size;
|
||||
VOP_BWRITE(bp);
|
||||
|
||||
/* Fix this so it can be released */
|
||||
/* ip->i_lfs_effnblks = ip->i_ffs_blocks; */
|
||||
|
||||
#ifdef DEBUG_LFS_RFW
|
||||
/* Now look again to make sure it worked */
|
||||
ufs_bmaparray(vp, lbn, &odaddr, &a[0], &num, NULL );
|
||||
if (odaddr != ndaddr)
|
||||
if (dbtofsb(fs, odaddr) != ndaddr)
|
||||
printf("update_meta: failed setting ino %d lbn %d to %x\n",
|
||||
ino, lbn, ndaddr);
|
||||
|
||||
#endif
|
||||
vput(vp);
|
||||
return 0;
|
||||
}
|
||||
@ -461,9 +460,11 @@ update_inoblk(struct lfs *fs, daddr_t offset, struct ucred *cred,
|
||||
* Get the inode, update times and perms.
|
||||
* DO NOT update disk blocks, we do that separately.
|
||||
*/
|
||||
error = bread(devvp, offset, fs->lfs_bsize, cred, &dbp);
|
||||
error = bread(devvp, fsbtodb(fs, offset), fs->lfs_ibsize, cred, &dbp);
|
||||
if (error) {
|
||||
#ifdef DEBUG_LFS_RFW
|
||||
printf("update_inoblk: bread returned %d\n", error);
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
dip = ((struct dinode *)(dbp->b_data)) + INOPB(fs);
|
||||
@ -474,7 +475,9 @@ update_inoblk(struct lfs *fs, daddr_t offset, struct ucred *cred,
|
||||
error = lfs_rf_valloc(fs, dip->di_inumber, dip->di_gen,
|
||||
p, &vp);
|
||||
if (error) {
|
||||
#ifdef DEBUG_LFS_RFW
|
||||
printf("update_inoblk: lfs_rf_valloc returned %d\n", error);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
ip = VTOI(vp);
|
||||
@ -502,17 +505,17 @@ update_inoblk(struct lfs *fs, daddr_t offset, struct ucred *cred,
|
||||
/* Record change in location */
|
||||
LFS_IENTRY(ifp, fs, dip->di_inumber, ibp);
|
||||
daddr = ifp->if_daddr;
|
||||
ifp->if_daddr = dbp->b_blkno;
|
||||
ifp->if_daddr = dbtofsb(fs, dbp->b_blkno);
|
||||
error = VOP_BWRITE(ibp); /* Ifile */
|
||||
/* And do segment accounting */
|
||||
if (datosn(fs, daddr) != datosn(fs, dbp->b_blkno)) {
|
||||
if (dtosn(fs, daddr) != dtosn(fs, dbtofsb(fs, dbp->b_blkno))) {
|
||||
if (daddr > 0) {
|
||||
LFS_SEGENTRY(sup, fs, datosn(fs, daddr),
|
||||
LFS_SEGENTRY(sup, fs, dtosn(fs, daddr),
|
||||
ibp);
|
||||
sup->su_nbytes -= DINODE_SIZE;
|
||||
VOP_BWRITE(ibp);
|
||||
}
|
||||
LFS_SEGENTRY(sup, fs, datosn(fs, dbp->b_blkno),
|
||||
LFS_SEGENTRY(sup, fs, dtosn(fs, dbtofsb(fs, dbp->b_blkno)),
|
||||
ibp);
|
||||
sup->su_nbytes += DINODE_SIZE;
|
||||
VOP_BWRITE(ibp);
|
||||
@ -541,21 +544,22 @@ check_segsum(struct lfs *fs, daddr_t offset,
|
||||
FINFO *fip;
|
||||
SEGUSE *sup;
|
||||
size_t size;
|
||||
u_int64_t serial;
|
||||
|
||||
devvp = VTOI(fs->lfs_ivnode)->i_devvp;
|
||||
/*
|
||||
* If the segment has a superblock and we're at the top
|
||||
* of the segment, skip the superblock.
|
||||
*/
|
||||
if(sntoda(fs, datosn(fs, offset)) == offset) {
|
||||
LFS_SEGENTRY(sup, fs, datosn(fs, offset), bp);
|
||||
if(sntod(fs, dtosn(fs, offset)) == offset) {
|
||||
LFS_SEGENTRY(sup, fs, dtosn(fs, offset), bp);
|
||||
if(sup->su_flags & SEGUSE_SUPERBLOCK)
|
||||
offset += btodb(LFS_SBPAD);
|
||||
offset += btofsb(fs, LFS_SBPAD);
|
||||
brelse(bp);
|
||||
}
|
||||
|
||||
/* Read in the segment summary */
|
||||
error = bread(devvp, offset, LFS_SUMMARY_SIZE, cred, &bp);
|
||||
error = bread(devvp, offset, fs->lfs_sumsize, cred, &bp);
|
||||
if(error)
|
||||
return -1;
|
||||
|
||||
@ -563,7 +567,7 @@ check_segsum(struct lfs *fs, daddr_t offset,
|
||||
ssp = (SEGSUM *)bp->b_data;
|
||||
if(flags & CHECK_CKSUM) {
|
||||
if(ssp->ss_sumsum != cksum(&ssp->ss_datasum,
|
||||
LFS_SUMMARY_SIZE -
|
||||
fs->lfs_sumsize -
|
||||
sizeof(ssp->ss_sumsum))) {
|
||||
#ifdef DEBUG_LFS_RFW
|
||||
printf("Sumsum error at 0x%x\n", offset);
|
||||
@ -581,6 +585,24 @@ check_segsum(struct lfs *fs, daddr_t offset,
|
||||
if (ssp->ss_create < fs->lfs_tstamp) {
|
||||
#ifdef DEBUG_LFS_RFW
|
||||
printf("Old data at 0x%x\n", offset);
|
||||
#endif
|
||||
offset = -1;
|
||||
goto err1;
|
||||
}
|
||||
}
|
||||
if (fs->lfs_version > 1) {
|
||||
serial = ssp->ss_serial;
|
||||
if (serial != fs->lfs_serial + 1) {
|
||||
#ifdef DEBUG_LFS_RFW
|
||||
printf("Unexpected serial number at 0x%x\n", offset);
|
||||
#endif
|
||||
offset = -1;
|
||||
goto err1;
|
||||
}
|
||||
if (ssp->ss_ident != fs->lfs_ident) {
|
||||
#ifdef DEBUG_LFS_RFW
|
||||
printf("Incorrect fsid (0x%x vs 0x%x) at 0x%x\n",
|
||||
ssp->ss_ident, fs->lfs_ident, offset);
|
||||
#endif
|
||||
offset = -1;
|
||||
goto err1;
|
||||
@ -589,14 +611,14 @@ check_segsum(struct lfs *fs, daddr_t offset,
|
||||
if(pseg_flags)
|
||||
*pseg_flags = ssp->ss_flags;
|
||||
oldoffset = offset;
|
||||
offset += btodb(LFS_SUMMARY_SIZE);
|
||||
offset += btofsb(fs, fs->lfs_sumsize);
|
||||
|
||||
ninos = howmany(ssp->ss_ninos, INOPB(fs));
|
||||
iaddr = (daddr_t *)(bp->b_data + LFS_SUMMARY_SIZE - sizeof(daddr_t));
|
||||
iaddr = (daddr_t *)(bp->b_data + fs->lfs_sumsize - sizeof(daddr_t));
|
||||
if(flags & CHECK_CKSUM) {
|
||||
/* Count blocks */
|
||||
nblocks = 0;
|
||||
fip = (FINFO *)(bp->b_data + sizeof(SEGSUM));
|
||||
fip = (FINFO *)(bp->b_data + SEGSUM_SIZE(fs));
|
||||
for(i = 0; i < ssp->ss_nfinfo; ++i) {
|
||||
nblocks += fip->fi_nblocks;
|
||||
if(fip->fi_nblocks <= 0)
|
||||
@ -612,13 +634,13 @@ check_segsum(struct lfs *fs, daddr_t offset,
|
||||
}
|
||||
|
||||
/* Handle individual blocks */
|
||||
fip = (FINFO *)(bp->b_data + sizeof(SEGSUM));
|
||||
fip = (FINFO *)(bp->b_data + SEGSUM_SIZE(fs));
|
||||
for(i = 0; i < ssp->ss_nfinfo || ninos; ++i) {
|
||||
/* Inode block? */
|
||||
if(ninos && *iaddr == offset) {
|
||||
if(flags & CHECK_CKSUM) {
|
||||
/* Read in the head and add to the buffer */
|
||||
error = bread(devvp, offset, fs->lfs_bsize,
|
||||
error = bread(devvp, fsbtodb(fs, offset), fs->lfs_bsize,
|
||||
cred, &dbp);
|
||||
if(error) {
|
||||
offset = -1;
|
||||
@ -635,7 +657,7 @@ check_segsum(struct lfs *fs, daddr_t offset,
|
||||
goto err2;
|
||||
}
|
||||
}
|
||||
offset += fsbtodb(fs,1);
|
||||
offset += btofsb(fs, fs->lfs_ibsize);
|
||||
--iaddr;
|
||||
--ninos;
|
||||
--i; /* compensate */
|
||||
@ -648,7 +670,7 @@ check_segsum(struct lfs *fs, daddr_t offset,
|
||||
if (j == fip->fi_nblocks - 1)
|
||||
size = fip->fi_lastlength;
|
||||
if(flags & CHECK_CKSUM) {
|
||||
error = bread(devvp, offset, size, cred, &dbp);
|
||||
error = bread(devvp, fsbtodb(fs, offset), size, cred, &dbp);
|
||||
if(error) {
|
||||
offset = -1;
|
||||
goto err2;
|
||||
@ -664,7 +686,7 @@ check_segsum(struct lfs *fs, daddr_t offset,
|
||||
update_meta(fs, fip->fi_ino, fip->fi_version,
|
||||
fip->fi_blocks[j], offset, size, p);
|
||||
}
|
||||
offset += btodb(size);
|
||||
offset += btofsb(fs, size);
|
||||
}
|
||||
fip = (FINFO *)(((char *)fip) + sizeof(FINFO)
|
||||
+ (fip->fi_nblocks - 1) * sizeof(ufs_daddr_t));
|
||||
@ -673,24 +695,26 @@ check_segsum(struct lfs *fs, daddr_t offset,
|
||||
if((flags & CHECK_CKSUM) &&
|
||||
ssp->ss_datasum != cksum(datap, nblocks * sizeof(u_long)))
|
||||
{
|
||||
#ifdef DEBUG_LFS_RFW
|
||||
printf("Datasum error at 0x%x (wanted %x got %x)\n", offset,
|
||||
ssp->ss_datasum, cksum(datap, nblocks *
|
||||
sizeof(u_long)));
|
||||
#endif
|
||||
offset = -1;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
/* If we're at the end of the segment, move to the next */
|
||||
if(datosn(fs, offset + btodb(LFS_SUMMARY_SIZE + fs->lfs_bsize)) !=
|
||||
datosn(fs, offset)) {
|
||||
if (datosn(fs, offset) == datosn(fs, ssp->ss_next)) {
|
||||
if(dtosn(fs, offset + btofsb(fs, fs->lfs_sumsize + fs->lfs_bsize)) !=
|
||||
dtosn(fs, offset)) {
|
||||
if (dtosn(fs, offset) == dtosn(fs, ssp->ss_next)) {
|
||||
offset = -1;
|
||||
goto err2;
|
||||
}
|
||||
offset = ssp->ss_next;
|
||||
#ifdef DEBUG_LFS_RFW
|
||||
printf("LFS roll forward: moving on to offset 0x%x "
|
||||
" -> segment %d\n", offset, datosn(fs,offset));
|
||||
" -> segment %d\n", offset, dtosn(fs,offset));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -713,19 +737,18 @@ check_segsum(struct lfs *fs, daddr_t offset,
|
||||
bp->b_flags |= B_AGE;
|
||||
brelse(bp);
|
||||
|
||||
/* XXX should we update the serial number even for bad psegs? */
|
||||
if ((flags & CHECK_UPDATE) && offset > 0 && fs->lfs_version > 1)
|
||||
fs->lfs_serial = serial;
|
||||
return offset;
|
||||
}
|
||||
#endif /* LFS_DO_ROLLFORWARD */
|
||||
|
||||
/*
|
||||
* Common code for mount and mountroot
|
||||
* LFS specific
|
||||
*/
|
||||
int
|
||||
lfs_mountfs(devvp, mp, p)
|
||||
struct vnode *devvp;
|
||||
struct mount *mp;
|
||||
struct proc *p;
|
||||
lfs_mountfs(struct vnode *devvp, struct mount *mp, struct proc *p)
|
||||
{
|
||||
extern struct vnode *rootvp;
|
||||
struct dlfs *tdfs, *dfs, *adfs;
|
||||
@ -735,15 +758,13 @@ lfs_mountfs(devvp, mp, p)
|
||||
struct buf *bp, *abp;
|
||||
struct partinfo dpart;
|
||||
dev_t dev;
|
||||
int error, i, ronly, size;
|
||||
int error, i, ronly, secsize, fsbsize;
|
||||
struct ucred *cred;
|
||||
CLEANERINFO *cip;
|
||||
SEGUSE *sup;
|
||||
#ifdef LFS_DO_ROLLFORWARD
|
||||
int flags, dirty;
|
||||
daddr_t offset, oldoffset, lastgoodpseg;
|
||||
int flags, dirty, do_rollforward;
|
||||
daddr_t offset, oldoffset, lastgoodpseg, sb_addr;
|
||||
int sn, curseg;
|
||||
#endif
|
||||
|
||||
cred = p ? p->p_ucred : NOCRED;
|
||||
/*
|
||||
@ -764,27 +785,61 @@ lfs_mountfs(devvp, mp, p)
|
||||
if (error)
|
||||
return (error);
|
||||
if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, p) != 0)
|
||||
size = DEV_BSIZE;
|
||||
secsize = DEV_BSIZE;
|
||||
else
|
||||
size = dpart.disklab->d_secsize;
|
||||
secsize = dpart.disklab->d_secsize;
|
||||
|
||||
/* Don't free random space on error. */
|
||||
bp = NULL;
|
||||
abp = NULL;
|
||||
ump = NULL;
|
||||
|
||||
/* Read in the superblock. */
|
||||
error = bread(devvp, LFS_LABELPAD / size, LFS_SBPAD, cred, &bp);
|
||||
if (error)
|
||||
goto out;
|
||||
dfs = (struct dlfs *)bp->b_data;
|
||||
sb_addr = LFS_LABELPAD / secsize;
|
||||
while(1) {
|
||||
/* Read in the superblock. */
|
||||
error = bread(devvp, sb_addr, LFS_SBPAD, cred, &bp);
|
||||
if (error)
|
||||
goto out;
|
||||
dfs = (struct dlfs *)bp->b_data;
|
||||
|
||||
/* Check the basics. */
|
||||
if (dfs->dlfs_magic != LFS_MAGIC || dfs->dlfs_bsize > MAXBSIZE ||
|
||||
dfs->dlfs_version > LFS_VERSION ||
|
||||
dfs->dlfs_bsize < sizeof(struct dlfs)) {
|
||||
error = EINVAL; /* XXX needs translation */
|
||||
goto out;
|
||||
/* Check the basics. */
|
||||
if (dfs->dlfs_magic != LFS_MAGIC || dfs->dlfs_bsize >= MAXBSIZE ||
|
||||
dfs->dlfs_version > LFS_VERSION ||
|
||||
dfs->dlfs_bsize < sizeof(struct dlfs)) {
|
||||
#ifdef DEBUG_LFS
|
||||
printf("lfs_mountfs: primary superblock sanity failed\n");
|
||||
#endif
|
||||
error = EINVAL; /* XXX needs translation */
|
||||
goto out;
|
||||
}
|
||||
if (dfs->dlfs_inodefmt > LFS_MAXINODEFMT)
|
||||
printf("lfs_mountfs: warning: unknown inode format %d\n",
|
||||
dfs->dlfs_inodefmt);
|
||||
|
||||
if (dfs->dlfs_version == 1)
|
||||
fsbsize = secsize;
|
||||
else {
|
||||
fsbsize = 1 << (dfs->dlfs_bshift - dfs->dlfs_blktodb +
|
||||
dfs->dlfs_fsbtodb);
|
||||
/*
|
||||
* Could be, if the frag size is large enough, that we
|
||||
* don't have the "real" primary superblock. If that's
|
||||
* the case, get the real one, and try again.
|
||||
*/
|
||||
if (sb_addr != dfs->dlfs_sboffs[0] <<
|
||||
dfs->dlfs_fsbtodb) {
|
||||
/* #ifdef DEBUG_LFS */
|
||||
printf("lfs_mountfs: sb daddr 0x%x is not right, trying 0x%x\n",
|
||||
sb_addr, dfs->dlfs_sboffs[0] <<
|
||||
dfs->dlfs_fsbtodb);
|
||||
/* #endif */
|
||||
sb_addr = dfs->dlfs_sboffs[0] <<
|
||||
dfs->dlfs_fsbtodb;
|
||||
brelse(bp);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -794,29 +849,44 @@ lfs_mountfs(devvp, mp, p)
|
||||
*/
|
||||
|
||||
if (dfs->dlfs_sboffs[1] &&
|
||||
dfs->dlfs_sboffs[1]-(LFS_LABELPAD/size) > LFS_SBPAD/size)
|
||||
dfs->dlfs_sboffs[1] - LFS_LABELPAD / fsbsize > LFS_SBPAD / fsbsize)
|
||||
{
|
||||
error = bread(devvp, dfs->dlfs_sboffs[1], LFS_SBPAD, cred, &abp);
|
||||
error = bread(devvp, dfs->dlfs_sboffs[1] * (fsbsize / secsize),
|
||||
LFS_SBPAD, cred, &abp);
|
||||
if (error)
|
||||
goto out;
|
||||
adfs = (struct dlfs *)abp->b_data;
|
||||
|
||||
if (adfs->dlfs_tstamp < dfs->dlfs_tstamp) /* XXX 1s? */
|
||||
tdfs = adfs;
|
||||
else
|
||||
tdfs = dfs;
|
||||
if (dfs->dlfs_version == 1) {
|
||||
/* 1s resolution comparison */
|
||||
if (adfs->dlfs_tstamp < dfs->dlfs_tstamp)
|
||||
tdfs = adfs;
|
||||
else
|
||||
tdfs = dfs;
|
||||
} else {
|
||||
/* monotonic infinite-resolution comparison */
|
||||
if (adfs->dlfs_serial < dfs->dlfs_serial)
|
||||
tdfs = adfs;
|
||||
else
|
||||
tdfs = dfs;
|
||||
}
|
||||
|
||||
/* Check the basics. */
|
||||
if (tdfs->dlfs_magic != LFS_MAGIC ||
|
||||
tdfs->dlfs_bsize > MAXBSIZE ||
|
||||
tdfs->dlfs_version > LFS_VERSION ||
|
||||
tdfs->dlfs_bsize < sizeof(struct dlfs)) {
|
||||
#ifdef DEBUG_LFS
|
||||
printf("lfs_mountfs: alt superblock sanity failed\n");
|
||||
#endif
|
||||
error = EINVAL; /* XXX needs translation */
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
#ifdef DEBUG_LFS
|
||||
printf("lfs_mountfs: invalid alt superblock daddr=0x%x\n",
|
||||
dfs->dlfs_sboffs[1]);
|
||||
#endif
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@ -825,13 +895,18 @@ lfs_mountfs(devvp, mp, p)
|
||||
fs = malloc(sizeof(struct lfs), M_UFSMNT, M_WAITOK);
|
||||
memcpy(&fs->lfs_dlfs, tdfs, sizeof(struct dlfs));
|
||||
|
||||
#ifdef LFS_DO_ROLLFORWARD
|
||||
/* Compatibility */
|
||||
if (fs->lfs_version < 2) {
|
||||
fs->lfs_sumsize = LFS_V1_SUMMARY_SIZE;
|
||||
fs->lfs_ibsize = fs->lfs_bsize;
|
||||
fs->lfs_start = fs->lfs_sboffs[0];
|
||||
fs->lfs_tstamp = fs->lfs_otstamp;
|
||||
fs->lfs_fsbtodb = 0;
|
||||
}
|
||||
|
||||
/* Before rolling forward, lock so vget will sleep for other procs */
|
||||
fs->lfs_flags = LFS_NOTYET;
|
||||
fs->lfs_rfpid = p->p_pid;
|
||||
#else
|
||||
fs->lfs_flags = 0;
|
||||
#endif
|
||||
|
||||
ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK);
|
||||
memset((caddr_t)ump, 0, sizeof *ump);
|
||||
@ -846,14 +921,13 @@ lfs_mountfs(devvp, mp, p)
|
||||
abp = NULL;
|
||||
|
||||
/* Set up the I/O information */
|
||||
fs->lfs_devbsize = secsize;
|
||||
fs->lfs_iocount = 0;
|
||||
fs->lfs_diropwait = 0;
|
||||
fs->lfs_activesb = 0;
|
||||
fs->lfs_uinodes = 0;
|
||||
fs->lfs_ravail = 0;
|
||||
#ifdef LFS_CANNOT_ROLLFW
|
||||
fs->lfs_sbactive = 0;
|
||||
#endif
|
||||
#ifdef LFS_TRACK_IOS
|
||||
for (i=0;i<LFS_THROTTLE;i++)
|
||||
fs->lfs_pending[i] = LFS_UNUSED_DADDR;
|
||||
@ -884,8 +958,8 @@ lfs_mountfs(devvp, mp, p)
|
||||
ump->um_mountp = mp;
|
||||
ump->um_dev = dev;
|
||||
ump->um_devvp = devvp;
|
||||
ump->um_bptrtodb = 0;
|
||||
ump->um_seqinc = 1 << fs->lfs_fsbtodb;
|
||||
ump->um_bptrtodb = fs->lfs_fsbtodb;
|
||||
ump->um_seqinc = fragstofsb(fs, fs->lfs_frag);
|
||||
ump->um_nindir = fs->lfs_nindir;
|
||||
ump->um_lognindir = ffs(fs->lfs_nindir) - 1;
|
||||
for (i = 0; i < MAXQUOTAS; i++)
|
||||
@ -898,102 +972,135 @@ lfs_mountfs(devvp, mp, p)
|
||||
* artificially increment the reference count and keep a pointer
|
||||
* to it in the incore copy of the superblock.
|
||||
*/
|
||||
if ((error = VFS_VGET(mp, LFS_IFILE_INUM, &vp)) != 0)
|
||||
if ((error = VFS_VGET(mp, LFS_IFILE_INUM, &vp)) != 0) {
|
||||
#ifdef DEBUG
|
||||
printf("lfs_mountfs: ifile vget failed, error=%d\n", error);
|
||||
#endif
|
||||
goto out;
|
||||
}
|
||||
fs->lfs_ivnode = vp;
|
||||
VREF(vp);
|
||||
vput(vp);
|
||||
|
||||
#ifdef LFS_DO_ROLLFORWARD
|
||||
/*
|
||||
* Roll forward.
|
||||
*
|
||||
* We don't automatically roll forward for v1 filesystems, because
|
||||
* of the danger that the clock was turned back between the last
|
||||
* checkpoint and crash. This would roll forward garbage.
|
||||
*
|
||||
* v2 filesystems don't have this problem because they use a
|
||||
* monotonically increasing serial number instead of a timestamp.
|
||||
*/
|
||||
/*
|
||||
* Phase I:
|
||||
* Find the address of the last good partial segment that was written
|
||||
* after the checkpoint. Mark the segments in question dirty, so
|
||||
* they won't be reallocated.
|
||||
*/
|
||||
lastgoodpseg = oldoffset = offset = fs->lfs_offset;
|
||||
flags = 0x0;
|
||||
#ifdef DEBUG_LFS_RFW
|
||||
printf("LFS roll forward phase 1: starting at offset 0x%x\n", offset);
|
||||
#ifdef LFS_DO_ROLLFORWARD
|
||||
do_rollforward = !fs->lfs_ronly;
|
||||
#else
|
||||
do_rollforward = (fs->lfs_version > 1 && !fs->lfs_ronly &&
|
||||
!(fs->lfs_pflags & LFS_PF_CLEAN));
|
||||
#endif
|
||||
LFS_SEGENTRY(sup, fs, datosn(fs, offset), bp);
|
||||
if (!(sup->su_flags & SEGUSE_DIRTY))
|
||||
--fs->lfs_nclean;
|
||||
sup->su_flags |= SEGUSE_DIRTY;
|
||||
(void) VOP_BWRITE(bp);
|
||||
while ((offset = check_segsum(fs, offset, cred, CHECK_CKSUM, &flags,
|
||||
p)) > 0) {
|
||||
if(sntoda(fs, oldoffset) != sntoda(fs, offset)) {
|
||||
LFS_SEGENTRY(sup, fs, datosn(fs, oldoffset), bp);
|
||||
if (!(sup->su_flags & SEGUSE_DIRTY))
|
||||
--fs->lfs_nclean;
|
||||
sup->su_flags |= SEGUSE_DIRTY;
|
||||
(void) VOP_BWRITE(bp);
|
||||
}
|
||||
if (do_rollforward) {
|
||||
/*
|
||||
* Phase I: Find the address of the last good partial
|
||||
* segment that was written after the checkpoint. Mark
|
||||
* the segments in question dirty, so they won't be
|
||||
* reallocated.
|
||||
*/
|
||||
lastgoodpseg = oldoffset = offset = fs->lfs_offset;
|
||||
flags = 0x0;
|
||||
#ifdef DEBUG_LFS_RFW
|
||||
printf("LFS roll forward phase 1: starting at offset 0x%x\n",
|
||||
offset);
|
||||
#endif
|
||||
LFS_SEGENTRY(sup, fs, dtosn(fs, offset), bp);
|
||||
if (!(sup->su_flags & SEGUSE_DIRTY))
|
||||
--fs->lfs_nclean;
|
||||
sup->su_flags |= SEGUSE_DIRTY;
|
||||
(void) VOP_BWRITE(bp);
|
||||
while ((offset = check_segsum(fs, offset, cred, CHECK_CKSUM,
|
||||
&flags, p)) > 0)
|
||||
{
|
||||
if(sntod(fs, oldoffset) != sntod(fs, offset)) {
|
||||
LFS_SEGENTRY(sup, fs, dtosn(fs, oldoffset),
|
||||
bp);
|
||||
if (!(sup->su_flags & SEGUSE_DIRTY))
|
||||
--fs->lfs_nclean;
|
||||
sup->su_flags |= SEGUSE_DIRTY;
|
||||
(void) VOP_BWRITE(bp);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LFS_RFW
|
||||
printf("LFS roll forward phase 1: offset=0x%x\n", offset);
|
||||
if(flags & SS_DIROP) {
|
||||
printf("lfs_mountfs: dirops at 0x%x\n", oldoffset);
|
||||
if(!(flags & SS_CONT))
|
||||
printf("lfs_mountfs: dirops end at 0x%x\n",
|
||||
printf("LFS roll forward phase 1: offset=0x%x\n",
|
||||
offset);
|
||||
if(flags & SS_DIROP) {
|
||||
printf("lfs_mountfs: dirops at 0x%x\n",
|
||||
oldoffset);
|
||||
if(!(flags & SS_CONT))
|
||||
printf("lfs_mountfs: dirops end "
|
||||
"at 0x%x\n", oldoffset);
|
||||
}
|
||||
#endif
|
||||
if(!(flags & SS_CONT))
|
||||
lastgoodpseg = offset;
|
||||
oldoffset = offset;
|
||||
}
|
||||
#endif
|
||||
if(!(flags & SS_CONT))
|
||||
lastgoodpseg = offset;
|
||||
oldoffset = offset;
|
||||
}
|
||||
#ifdef DEBUG_LFS_RFW
|
||||
if (flags & SS_CONT) {
|
||||
printf("LFS roll forward: warning: incomplete dirops discarded\n");
|
||||
}
|
||||
printf("LFS roll forward phase 1: completed: lastgoodpseg=0x%x\n",
|
||||
lastgoodpseg);
|
||||
if (flags & SS_CONT) {
|
||||
printf("LFS roll forward: warning: incomplete "
|
||||
"dirops discarded\n");
|
||||
}
|
||||
printf("LFS roll forward phase 1: completed: "
|
||||
"lastgoodpseg=0x%x\n", lastgoodpseg);
|
||||
#endif
|
||||
oldoffset = fs->lfs_offset;
|
||||
if (fs->lfs_offset != lastgoodpseg) {
|
||||
/* Don't overwrite what we're trying to preserve */
|
||||
offset = fs->lfs_offset;
|
||||
fs->lfs_offset = lastgoodpseg;
|
||||
fs->lfs_curseg = sntod(fs, dtosn(fs, fs->lfs_offset));
|
||||
for (sn = curseg = dtosn(fs, fs->lfs_curseg);;) {
|
||||
sn = (sn + 1) % fs->lfs_nseg;
|
||||
if (sn == curseg)
|
||||
panic("lfs_mountfs: no clean segments");
|
||||
LFS_SEGENTRY(sup, fs, sn, bp);
|
||||
dirty = (sup->su_flags & SEGUSE_DIRTY);
|
||||
brelse(bp);
|
||||
if (!dirty)
|
||||
break;
|
||||
}
|
||||
fs->lfs_nextseg = sntod(fs, sn);
|
||||
|
||||
/* Don't accidentally overwrite what we're trying to preserve */
|
||||
offset = fs->lfs_offset;
|
||||
fs->lfs_offset = lastgoodpseg;
|
||||
fs->lfs_curseg = sntoda(fs, datosn(fs, fs->lfs_offset));
|
||||
for (sn = curseg = datosn(fs, fs->lfs_curseg);;) {
|
||||
sn = (sn + 1) % fs->lfs_nseg;
|
||||
if (sn == curseg)
|
||||
panic("lfs_mountfs: no clean segments");
|
||||
LFS_SEGENTRY(sup, fs, sn, bp);
|
||||
dirty = (sup->su_flags & SEGUSE_DIRTY);
|
||||
brelse(bp);
|
||||
if (!dirty)
|
||||
break;
|
||||
}
|
||||
fs->lfs_nextseg = sntoda(fs, sn);
|
||||
|
||||
/*
|
||||
* Phase II: Roll forward from the first superblock.
|
||||
*/
|
||||
while (offset != lastgoodpseg) {
|
||||
/*
|
||||
* Phase II: Roll forward from the first superblock.
|
||||
*/
|
||||
while (offset != lastgoodpseg) {
|
||||
#ifdef DEBUG_LFS_RFW
|
||||
printf("LFS roll forward phase 2: 0x%x\n", offset);
|
||||
printf("LFS roll forward phase 2: 0x%x\n",
|
||||
offset);
|
||||
#endif
|
||||
oldoffset = offset;
|
||||
offset = check_segsum(fs, offset, cred, CHECK_UPDATE, NULL, p);
|
||||
}
|
||||
|
||||
/*
|
||||
* Finish: flush our changes to disk.
|
||||
*/
|
||||
lfs_segwrite(fs->lfs_ivnode->v_mount, SEGM_CKP | SEGM_SYNC);
|
||||
offset = check_segsum(fs, offset, cred,
|
||||
CHECK_UPDATE, NULL, p);
|
||||
}
|
||||
|
||||
/*
|
||||
* Finish: flush our changes to disk.
|
||||
*/
|
||||
lfs_segwrite(mp, SEGM_CKP | SEGM_SYNC);
|
||||
printf("lfs_mountfs: roll forward recovered %d blocks\n",
|
||||
lastgoodpseg - oldoffset);
|
||||
}
|
||||
#ifdef DEBUG_LFS_RFW
|
||||
printf("LFS roll forward complete\n");
|
||||
printf("LFS roll forward complete\n");
|
||||
#endif
|
||||
}
|
||||
/* If writing, sb is not clean; record in case of immediate crash */
|
||||
if (!fs->lfs_ronly) {
|
||||
fs->lfs_pflags &= ~LFS_PF_CLEAN;
|
||||
lfs_writesuper(fs, fs->lfs_sboffs[0]);
|
||||
}
|
||||
|
||||
/* Allow vget now that roll-forward is complete */
|
||||
fs->lfs_flags &= ~(LFS_NOTYET);
|
||||
wakeup(&fs->lfs_flags);
|
||||
#endif /* LFS_DO_ROLLFORWARD */
|
||||
|
||||
/*
|
||||
* Initialize the ifile cleaner info with information from
|
||||
@ -1010,7 +1117,7 @@ lfs_mountfs(devvp, mp, p)
|
||||
* Mark the current segment as ACTIVE, since we're going to
|
||||
* be writing to it.
|
||||
*/
|
||||
LFS_SEGENTRY(sup, fs, datosn(fs, fs->lfs_offset), bp);
|
||||
LFS_SEGENTRY(sup, fs, dtosn(fs, fs->lfs_offset), bp);
|
||||
sup->su_flags |= SEGUSE_DIRTY | SEGUSE_ACTIVE;
|
||||
(void) VOP_BWRITE(bp); /* Ifile */
|
||||
|
||||
@ -1035,14 +1142,11 @@ out:
|
||||
* unmount system call
|
||||
*/
|
||||
int
|
||||
lfs_unmount(mp, mntflags, p)
|
||||
struct mount *mp;
|
||||
int mntflags;
|
||||
struct proc *p;
|
||||
lfs_unmount(struct mount *mp, int mntflags, struct proc *p)
|
||||
{
|
||||
struct ufsmount *ump;
|
||||
struct lfs *fs;
|
||||
int error, flags, ronly;
|
||||
int error, flags, ronly, s;
|
||||
extern int lfs_allclean_wakeup;
|
||||
|
||||
flags = 0;
|
||||
@ -1070,14 +1174,26 @@ lfs_unmount(mp, mntflags, p)
|
||||
#endif
|
||||
if ((error = vflush(mp, fs->lfs_ivnode, flags)) != 0)
|
||||
return (error);
|
||||
fs->lfs_clean = 1;
|
||||
if ((error = VFS_SYNC(mp, 1, p->p_ucred, p)) != 0)
|
||||
return (error);
|
||||
if (fs->lfs_ivnode->v_dirtyblkhd.lh_first)
|
||||
panic("lfs_unmount: still dirty blocks on ifile vnode\n");
|
||||
|
||||
/* Explicitly write the superblock, to update serial and pflags */
|
||||
fs->lfs_pflags |= LFS_PF_CLEAN;
|
||||
lfs_writesuper(fs, fs->lfs_sboffs[0]);
|
||||
lfs_writesuper(fs, fs->lfs_sboffs[1]);
|
||||
|
||||
/* Finish with the Ifile, now that we're done with it */
|
||||
vrele(fs->lfs_ivnode);
|
||||
vgone(fs->lfs_ivnode);
|
||||
|
||||
/* Wait for superblock writes to complete */
|
||||
s = splbio();
|
||||
while (fs->lfs_iocount)
|
||||
tsleep(&fs->lfs_iocount, PRIBIO + 1, "lfs_umount", 0);
|
||||
splx(s);
|
||||
|
||||
ronly = !fs->lfs_ronly;
|
||||
if (ump->um_devvp->v_type != VBAD)
|
||||
ump->um_devvp->v_specmountpoint = NULL;
|
||||
@ -1101,10 +1217,7 @@ lfs_unmount(mp, mntflags, p)
|
||||
* Get file system statistics.
|
||||
*/
|
||||
int
|
||||
lfs_statfs(mp, sbp, p)
|
||||
struct mount *mp;
|
||||
struct statfs *sbp;
|
||||
struct proc *p;
|
||||
lfs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p)
|
||||
{
|
||||
struct lfs *fs;
|
||||
struct ufsmount *ump;
|
||||
@ -1117,11 +1230,12 @@ lfs_statfs(mp, sbp, p)
|
||||
sbp->f_type = 0;
|
||||
sbp->f_bsize = fs->lfs_fsize;
|
||||
sbp->f_iosize = fs->lfs_bsize;
|
||||
sbp->f_blocks = dbtofrags(fs, LFS_EST_NONMETA(fs));
|
||||
sbp->f_bfree = dbtofrags(fs, LFS_EST_BFREE(fs));
|
||||
sbp->f_bavail = dbtofrags(fs, (long)LFS_EST_BFREE(fs) -
|
||||
sbp->f_blocks = fsbtofrags(fs, LFS_EST_NONMETA(fs));
|
||||
sbp->f_bfree = fsbtofrags(fs, LFS_EST_BFREE(fs));
|
||||
sbp->f_bavail = fsbtofrags(fs, (long)LFS_EST_BFREE(fs) -
|
||||
(long)LFS_EST_RSVD(fs));
|
||||
sbp->f_files = dbtofsb(fs,fs->lfs_bfree) * INOPB(fs);
|
||||
|
||||
sbp->f_files = fs->lfs_bfree / btofsb(fs, fs->lfs_ibsize) * INOPB(fs);
|
||||
sbp->f_ffree = sbp->f_files - fs->lfs_nfiles;
|
||||
if (sbp != &mp->mnt_stat) {
|
||||
bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
|
||||
@ -1139,11 +1253,7 @@ lfs_statfs(mp, sbp, p)
|
||||
* Note: we are always called with the filesystem marked `MPBUSY'.
|
||||
*/
|
||||
int
|
||||
lfs_sync(mp, waitfor, cred, p)
|
||||
struct mount *mp;
|
||||
int waitfor;
|
||||
struct ucred *cred;
|
||||
struct proc *p;
|
||||
lfs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)
|
||||
{
|
||||
int error;
|
||||
struct lfs *fs;
|
||||
@ -1173,10 +1283,7 @@ extern struct lock ufs_hashlock;
|
||||
* Detection and handling of mount points must be done by the calling routine.
|
||||
*/
|
||||
int
|
||||
lfs_vget(mp, ino, vpp)
|
||||
struct mount *mp;
|
||||
ino_t ino;
|
||||
struct vnode **vpp;
|
||||
lfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
|
||||
{
|
||||
struct lfs *fs;
|
||||
struct inode *ip;
|
||||
@ -1187,9 +1294,7 @@ lfs_vget(mp, ino, vpp)
|
||||
ufs_daddr_t daddr;
|
||||
dev_t dev;
|
||||
int error;
|
||||
#ifdef LFS_ATIME_IFILE
|
||||
struct timespec ts;
|
||||
#endif
|
||||
|
||||
ump = VFSTOUFS(mp);
|
||||
dev = ump->um_dev;
|
||||
@ -1224,9 +1329,11 @@ lfs_vget(mp, ino, vpp)
|
||||
/* XXX bounds-check this too */
|
||||
LFS_IENTRY(ifp, fs, ino, bp);
|
||||
daddr = ifp->if_daddr;
|
||||
#ifdef LFS_ATIME_IFILE
|
||||
ts = ifp->if_atime; /* structure copy */
|
||||
#endif
|
||||
if (fs->lfs_version > 1) {
|
||||
ts.tv_sec = ifp->if_atime_sec;
|
||||
ts.tv_nsec = ifp->if_atime_nsec;
|
||||
}
|
||||
|
||||
brelse(bp);
|
||||
if (daddr == LFS_UNUSED_DADDR) {
|
||||
*vpp = NULLVP;
|
||||
@ -1258,7 +1365,9 @@ lfs_vget(mp, ino, vpp)
|
||||
ip->i_lfs = ump->um_lfs;
|
||||
|
||||
/* Read in the disk contents for the inode, copy into the inode. */
|
||||
error = bread(ump->um_devvp, daddr, (int)fs->lfs_bsize, NOCRED, &bp);
|
||||
error = bread(ump->um_devvp, fsbtodb(fs, daddr),
|
||||
(fs->lfs_version == 1 ? fs->lfs_bsize : fs->lfs_fsize),
|
||||
NOCRED, &bp);
|
||||
if (error) {
|
||||
/*
|
||||
* The inode does not contain anything useful, so it would
|
||||
@ -1274,10 +1383,10 @@ lfs_vget(mp, ino, vpp)
|
||||
ip->i_din.ffs_din = *lfs_ifind(fs, ino, bp);
|
||||
ip->i_ffs_effnlink = ip->i_ffs_nlink;
|
||||
ip->i_lfs_effnblks = ip->i_ffs_blocks;
|
||||
#ifdef LFS_ATIME_IFILE
|
||||
ip->i_ffs_atime = ts.tv_sec;
|
||||
ip->i_ffs_atimensec = ts.tv_nsec;
|
||||
#endif
|
||||
if (fs->lfs_version > 1) {
|
||||
ip->i_ffs_atime = ts.tv_sec;
|
||||
ip->i_ffs_atimensec = ts.tv_nsec;
|
||||
}
|
||||
brelse(bp);
|
||||
|
||||
/*
|
||||
@ -1322,10 +1431,7 @@ lfs_vget(mp, ino, vpp)
|
||||
* generational number.
|
||||
*/
|
||||
int
|
||||
lfs_fhtovp(mp, fhp, vpp)
|
||||
struct mount *mp;
|
||||
struct fid *fhp;
|
||||
struct vnode **vpp;
|
||||
lfs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp)
|
||||
{
|
||||
struct ufid *ufhp;
|
||||
|
||||
@ -1340,9 +1446,7 @@ lfs_fhtovp(mp, fhp, vpp)
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
lfs_vptofh(vp, fhp)
|
||||
struct vnode *vp;
|
||||
struct fid *fhp;
|
||||
lfs_vptofh(struct vnode *vp, struct fid *fhp)
|
||||
{
|
||||
struct inode *ip;
|
||||
struct ufid *ufhp;
|
||||
@ -1356,14 +1460,7 @@ lfs_vptofh(vp, fhp)
|
||||
}
|
||||
|
||||
int
|
||||
lfs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
|
||||
int *name;
|
||||
u_int namelen;
|
||||
void *oldp;
|
||||
size_t *oldlenp;
|
||||
void *newp;
|
||||
size_t newlen;
|
||||
struct proc *p;
|
||||
lfs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen, struct proc *p)
|
||||
{
|
||||
extern int lfs_writeindir, lfs_dostats, lfs_clean_vnhead;
|
||||
extern struct lfs_stats lfs_stats;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs_vnops.c,v 1.50 2001/01/22 12:17:43 jdolecek Exp $ */
|
||||
/* $NetBSD: lfs_vnops.c,v 1.51 2001/07/13 20:30:25 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
@ -100,7 +100,7 @@
|
||||
#include <ufs/lfs/lfs_extern.h>
|
||||
|
||||
/* Global vfs data structures for lfs. */
|
||||
int (**lfs_vnodeop_p) __P((void *));
|
||||
int (**lfs_vnodeop_p)(void *);
|
||||
const struct vnodeopv_entry_desc lfs_vnodeop_entries[] = {
|
||||
{ &vop_default_desc, vn_default_error },
|
||||
{ &vop_lookup_desc, ufs_lookup }, /* lookup */
|
||||
@ -148,12 +148,12 @@ const struct vnodeopv_entry_desc lfs_vnodeop_entries[] = {
|
||||
{ &vop_truncate_desc, lfs_truncate }, /* truncate */
|
||||
{ &vop_update_desc, lfs_update }, /* update */
|
||||
{ &vop_bwrite_desc, lfs_bwrite }, /* bwrite */
|
||||
{ (struct vnodeop_desc*)NULL, (int(*) __P((void *)))NULL }
|
||||
{ (struct vnodeop_desc*)NULL, (int(*)(void *))NULL }
|
||||
};
|
||||
const struct vnodeopv_desc lfs_vnodeop_opv_desc =
|
||||
{ &lfs_vnodeop_p, lfs_vnodeop_entries };
|
||||
|
||||
int (**lfs_specop_p) __P((void *));
|
||||
int (**lfs_specop_p)(void *);
|
||||
const struct vnodeopv_entry_desc lfs_specop_entries[] = {
|
||||
{ &vop_default_desc, vn_default_error },
|
||||
{ &vop_lookup_desc, spec_lookup }, /* lookup */
|
||||
@ -199,12 +199,12 @@ const struct vnodeopv_entry_desc lfs_specop_entries[] = {
|
||||
{ &vop_truncate_desc, spec_truncate }, /* truncate */
|
||||
{ &vop_update_desc, lfs_update }, /* update */
|
||||
{ &vop_bwrite_desc, vn_bwrite }, /* bwrite */
|
||||
{ (struct vnodeop_desc*)NULL, (int(*) __P((void *)))NULL }
|
||||
{ (struct vnodeop_desc*)NULL, (int(*)(void *))NULL }
|
||||
};
|
||||
const struct vnodeopv_desc lfs_specop_opv_desc =
|
||||
{ &lfs_specop_p, lfs_specop_entries };
|
||||
|
||||
int (**lfs_fifoop_p) __P((void *));
|
||||
int (**lfs_fifoop_p)(void *);
|
||||
const struct vnodeopv_entry_desc lfs_fifoop_entries[] = {
|
||||
{ &vop_default_desc, vn_default_error },
|
||||
{ &vop_lookup_desc, fifo_lookup }, /* lookup */
|
||||
@ -250,7 +250,7 @@ const struct vnodeopv_entry_desc lfs_fifoop_entries[] = {
|
||||
{ &vop_truncate_desc, fifo_truncate }, /* truncate */
|
||||
{ &vop_update_desc, lfs_update }, /* update */
|
||||
{ &vop_bwrite_desc, lfs_bwrite }, /* bwrite */
|
||||
{ (struct vnodeop_desc*)NULL, (int(*) __P((void *)))NULL }
|
||||
{ (struct vnodeop_desc*)NULL, (int(*)(void *))NULL }
|
||||
};
|
||||
const struct vnodeopv_desc lfs_fifoop_opv_desc =
|
||||
{ &lfs_fifoop_p, lfs_fifoop_entries };
|
||||
@ -259,9 +259,7 @@ const struct vnodeopv_desc lfs_fifoop_opv_desc =
|
||||
* A function version of LFS_ITIMES, for the UFS functions which call ITIMES
|
||||
*/
|
||||
void
|
||||
lfs_itimes(ip, acc, mod, cre)
|
||||
struct inode *ip;
|
||||
struct timespec *acc, *mod, *cre;
|
||||
lfs_itimes(struct inode *ip, struct timespec *acc, struct timespec *mod, struct timespec *cre)
|
||||
{
|
||||
LFS_ITIMES(ip, acc, mod, cre);
|
||||
}
|
||||
@ -275,8 +273,7 @@ lfs_itimes(ip, acc, mod, cre)
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
lfs_fsync(v)
|
||||
void *v;
|
||||
lfs_fsync(void *v)
|
||||
{
|
||||
struct vop_fsync_args /* {
|
||||
struct vnode *a_vp;
|
||||
@ -299,8 +296,7 @@ lfs_fsync(v)
|
||||
* Take IN_ADIROP off, then call ufs_inactive.
|
||||
*/
|
||||
int
|
||||
lfs_inactive(v)
|
||||
void *v;
|
||||
lfs_inactive(void *v)
|
||||
{
|
||||
struct vop_inactive_args /* {
|
||||
struct vnode *a_vp;
|
||||
@ -327,12 +323,11 @@ lfs_inactive(v)
|
||||
* is decremented during segment write, when VDIROP is taken off.
|
||||
*/
|
||||
#define SET_DIROP(vp) lfs_set_dirop(vp)
|
||||
static int lfs_set_dirop __P((struct vnode *));
|
||||
static int lfs_set_dirop(struct vnode *);
|
||||
extern int lfs_dirvcount;
|
||||
|
||||
static int
|
||||
lfs_set_dirop(vp)
|
||||
struct vnode *vp;
|
||||
lfs_set_dirop(struct vnode *vp)
|
||||
{
|
||||
struct lfs *fs;
|
||||
int error;
|
||||
@ -342,7 +337,7 @@ lfs_set_dirop(vp)
|
||||
* We might need one directory block plus supporting indirect blocks,
|
||||
* plus an inode block and ifile page for the new vnode.
|
||||
*/
|
||||
if ((error = lfs_reserve(fs, vp, fsbtodb(fs, NIADDR + 3))) != 0)
|
||||
if ((error = lfs_reserve(fs, vp, btofsb(fs, (NIADDR + 3) << fs->lfs_bshift))) != 0)
|
||||
return (error);
|
||||
if (fs->lfs_dirops == 0)
|
||||
lfs_check(vp, LFS_UNUSED_LBN, 0);
|
||||
@ -364,7 +359,7 @@ lfs_set_dirop(vp)
|
||||
#endif
|
||||
if((error = tsleep(&lfs_dirvcount, PCATCH|PUSER,
|
||||
"lfs_maxdirop", 0)) !=0) {
|
||||
lfs_reserve(fs, vp, -fsbtodb(fs, NIADDR + 3));
|
||||
lfs_reserve(fs, vp, -btofsb(fs, (NIADDR + 3) << fs->lfs_bshift));
|
||||
return error;
|
||||
}
|
||||
}
|
||||
@ -388,7 +383,7 @@ lfs_set_dirop(vp)
|
||||
wakeup(&(fs)->lfs_writer); \
|
||||
lfs_check((vp),LFS_UNUSED_LBN,0); \
|
||||
} \
|
||||
lfs_reserve(fs, vp, -fsbtodb(fs, NIADDR + 3)); /* XXX */ \
|
||||
lfs_reserve((fs), vp, -btofsb((fs), (NIADDR + 3) << (fs)->lfs_bshift)); /* XXX */ \
|
||||
lfs_vunref(vp); \
|
||||
}
|
||||
|
||||
@ -406,8 +401,7 @@ lfs_set_dirop(vp)
|
||||
|
||||
#define UNMARK_VNODE(vp) lfs_unmark_vnode(vp)
|
||||
|
||||
void lfs_unmark_vnode(vp)
|
||||
struct vnode *vp;
|
||||
void lfs_unmark_vnode(struct vnode *vp)
|
||||
{
|
||||
struct inode *ip;
|
||||
|
||||
@ -419,8 +413,7 @@ void lfs_unmark_vnode(vp)
|
||||
}
|
||||
|
||||
int
|
||||
lfs_symlink(v)
|
||||
void *v;
|
||||
lfs_symlink(void *v)
|
||||
{
|
||||
struct vop_symlink_args /* {
|
||||
struct vnode *a_dvp;
|
||||
@ -445,8 +438,7 @@ lfs_symlink(v)
|
||||
}
|
||||
|
||||
int
|
||||
lfs_mknod(v)
|
||||
void *v;
|
||||
lfs_mknod(void *v)
|
||||
{
|
||||
struct vop_mknod_args /* {
|
||||
struct vnode *a_dvp;
|
||||
@ -518,8 +510,7 @@ lfs_mknod(v)
|
||||
}
|
||||
|
||||
int
|
||||
lfs_create(v)
|
||||
void *v;
|
||||
lfs_create(void *v)
|
||||
{
|
||||
struct vop_create_args /* {
|
||||
struct vnode *a_dvp;
|
||||
@ -543,8 +534,7 @@ lfs_create(v)
|
||||
}
|
||||
|
||||
int
|
||||
lfs_whiteout(v)
|
||||
void *v;
|
||||
lfs_whiteout(void *v)
|
||||
{
|
||||
struct vop_whiteout_args /* {
|
||||
struct vnode *a_dvp;
|
||||
@ -564,8 +554,7 @@ lfs_whiteout(v)
|
||||
}
|
||||
|
||||
int
|
||||
lfs_mkdir(v)
|
||||
void *v;
|
||||
lfs_mkdir(void *v)
|
||||
{
|
||||
struct vop_mkdir_args /* {
|
||||
struct vnode *a_dvp;
|
||||
@ -589,8 +578,7 @@ lfs_mkdir(v)
|
||||
}
|
||||
|
||||
int
|
||||
lfs_remove(v)
|
||||
void *v;
|
||||
lfs_remove(void *v)
|
||||
{
|
||||
struct vop_remove_args /* {
|
||||
struct vnode *a_dvp;
|
||||
@ -632,8 +620,7 @@ lfs_remove(v)
|
||||
}
|
||||
|
||||
int
|
||||
lfs_rmdir(v)
|
||||
void *v;
|
||||
lfs_rmdir(void *v)
|
||||
{
|
||||
struct vop_rmdir_args /* {
|
||||
struct vnodeop_desc *a_desc;
|
||||
@ -672,8 +659,7 @@ lfs_rmdir(v)
|
||||
}
|
||||
|
||||
int
|
||||
lfs_link(v)
|
||||
void *v;
|
||||
lfs_link(void *v)
|
||||
{
|
||||
struct vop_link_args /* {
|
||||
struct vnode *a_dvp;
|
||||
@ -694,8 +680,7 @@ lfs_link(v)
|
||||
}
|
||||
|
||||
int
|
||||
lfs_rename(v)
|
||||
void *v;
|
||||
lfs_rename(void *v)
|
||||
{
|
||||
struct vop_rename_args /* {
|
||||
struct vnode *a_fdvp;
|
||||
@ -754,8 +739,7 @@ lfs_rename(v)
|
||||
|
||||
/* XXX hack to avoid calling ITIMES in getattr */
|
||||
int
|
||||
lfs_getattr(v)
|
||||
void *v;
|
||||
lfs_getattr(void *v)
|
||||
{
|
||||
struct vop_getattr_args /* {
|
||||
struct vnode *a_vp;
|
||||
@ -766,6 +750,7 @@ lfs_getattr(v)
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct inode *ip = VTOI(vp);
|
||||
struct vattr *vap = ap->a_vap;
|
||||
struct lfs *fs = ip->i_lfs;
|
||||
/*
|
||||
* Copy from inode table
|
||||
*/
|
||||
@ -792,7 +777,7 @@ lfs_getattr(v)
|
||||
vap->va_blocksize = MAXBSIZE;
|
||||
else
|
||||
vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
|
||||
vap->va_bytes = dbtob((u_quad_t)ip->i_ffs_blocks);
|
||||
vap->va_bytes = fsbtob(fs, (u_quad_t)ip->i_ffs_blocks);
|
||||
vap->va_type = vp->v_type;
|
||||
vap->va_filerev = ip->i_modrev;
|
||||
return (0);
|
||||
@ -807,8 +792,7 @@ lfs_getattr(v)
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
lfs_close(v)
|
||||
void *v;
|
||||
lfs_close(void *v)
|
||||
{
|
||||
struct vop_close_args /* {
|
||||
struct vnode *a_vp;
|
||||
@ -835,8 +819,7 @@ lfs_close(v)
|
||||
int lfs_no_inactive = 0;
|
||||
|
||||
int
|
||||
lfs_reclaim(v)
|
||||
void *v;
|
||||
lfs_reclaim(void *v)
|
||||
{
|
||||
struct vop_reclaim_args /* {
|
||||
struct vnode *a_vp;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ufs_readwrite.c,v 1.31 2001/03/26 06:47:34 chs Exp $ */
|
||||
/* $NetBSD: ufs_readwrite.c,v 1.32 2001/07/13 20:30:26 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993
|
||||
@ -374,10 +374,10 @@ WRITE(void *v)
|
||||
}
|
||||
#ifdef LFS_READWRITE
|
||||
if (!error)
|
||||
error = lfs_reserve(fs, vp, fsbtodb(fs, NIADDR + 1));
|
||||
error = lfs_reserve(fs, vp, btofsb(fs, (NIADDR + 1) << fs->lfs_bshift));
|
||||
(void)VOP_BWRITE(bp);
|
||||
if (!error)
|
||||
lfs_reserve(fs, vp, fsbtodb(fs, -(NIADDR + 1)));
|
||||
lfs_reserve(fs, vp, -btofsb(fs, (NIADDR + 1) << fs->lfs_bshift));
|
||||
#else
|
||||
if (ioflag & IO_SYNC)
|
||||
(void)bwrite(bp);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dumplfs.c,v 1.18 2001/01/05 03:27:26 lukem Exp $ */
|
||||
/* $NetBSD: dumplfs.c,v 1.19 2001/07/13 20:30:21 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
@ -45,7 +45,7 @@ __COPYRIGHT(
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)dumplfs.c 8.5 (Berkeley) 5/24/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: dumplfs.c,v 1.18 2001/01/05 03:27:26 lukem Exp $");
|
||||
__RCSID("$NetBSD: dumplfs.c,v 1.19 2001/07/13 20:30:21 perseant Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -67,20 +67,18 @@ __RCSID("$NetBSD: dumplfs.c,v 1.18 2001/01/05 03:27:26 lukem Exp $");
|
||||
#include <unistd.h>
|
||||
#include "extern.h"
|
||||
|
||||
static void addseg __P((char *));
|
||||
static void dump_cleaner_info __P((struct lfs *, void *));
|
||||
static void dump_dinode __P((struct dinode *));
|
||||
static void dump_ifile __P((int, struct lfs *, int, int));
|
||||
static int dump_ipage_ifile __P((int, IFILE *, int));
|
||||
static int dump_ipage_segusage __P((struct lfs *, int, IFILE *, int));
|
||||
static void dump_segment __P((int, int, daddr_t, struct lfs *, int));
|
||||
static int dump_sum __P((int, struct lfs *, SEGSUM *, int, daddr_t));
|
||||
static void dump_super __P((struct lfs *));
|
||||
static void usage __P((void));
|
||||
static void addseg(char *);
|
||||
static void dump_cleaner_info(struct lfs *, void *);
|
||||
static void dump_dinode(struct dinode *);
|
||||
static void dump_ifile(int, struct lfs *, int, int, int);
|
||||
static int dump_ipage_ifile(struct lfs *, int, char *, int);
|
||||
static int dump_ipage_segusage(struct lfs *, int, char *, int);
|
||||
static void dump_segment(int, int, daddr_t, struct lfs *, int);
|
||||
static int dump_sum(int, struct lfs *, SEGSUM *, int, daddr_t);
|
||||
static void dump_super(struct lfs *);
|
||||
static void usage(void);
|
||||
|
||||
int main __P((int, char *[]));
|
||||
|
||||
extern u_long cksum __P((void *, size_t));
|
||||
extern u_long cksum(void *, size_t);
|
||||
|
||||
typedef struct seglist SEGLIST;
|
||||
struct seglist {
|
||||
@ -95,42 +93,40 @@ char *special;
|
||||
#define print_suheader \
|
||||
(void)printf("segnum\tflags\tnbytes\tninos\tnsums\tlastmod\n")
|
||||
|
||||
#define print_suentry(i, sp) \
|
||||
(void)printf("%d\t%c%c%c\t%d\t%d\t%d\t%s", i, \
|
||||
(((sp)->su_flags & SEGUSE_ACTIVE) ? 'A' : ' '), \
|
||||
(((sp)->su_flags & SEGUSE_DIRTY) ? 'D' : 'C'), \
|
||||
(((sp)->su_flags & SEGUSE_SUPERBLOCK) ? 'S' : ' '), \
|
||||
(sp)->su_nbytes, (sp)->su_ninos, (sp)->su_nsums, \
|
||||
ctime((time_t *)&(sp)->su_lastmod))
|
||||
#define print_suentry(i, sp, fs) \
|
||||
(void)printf("%d\t%c%c%c\t%d\t%d\t%d\t%s", i, \
|
||||
(((sp)->su_flags & SEGUSE_ACTIVE) ? 'A' : ' '), \
|
||||
(((sp)->su_flags & SEGUSE_DIRTY) ? 'D' : 'C'), \
|
||||
(((sp)->su_flags & SEGUSE_SUPERBLOCK) ? 'S' : ' '), \
|
||||
(sp)->su_nbytes, (sp)->su_ninos, (sp)->su_nsums, \
|
||||
((fs)->lfs_version == 1 ? ctime((time_t *)&(sp)->su_olastmod) : \
|
||||
ctime((time_t *)&(sp)->su_lastmod)))
|
||||
|
||||
/* Ifile formats */
|
||||
#define print_iheader \
|
||||
(void)printf("inum\tstatus\tversion\tdaddr\t\tfreeptr\n")
|
||||
#define print_ientry(i, ip) \
|
||||
if (ip->if_daddr == LFS_UNUSED_DADDR) \
|
||||
if ((ip)->if_daddr == LFS_UNUSED_DADDR) \
|
||||
(void)printf("%d\tFREE\t%d\t \t\t%d\n", \
|
||||
i, ip->if_version, ip->if_nextfree); \
|
||||
i, (ip)->if_version, (ip)->if_nextfree); \
|
||||
else \
|
||||
(void)printf("%d\tINUSE\t%d\t%8X \n", \
|
||||
i, ip->if_version, ip->if_daddr)
|
||||
|
||||
#define datobyte(fs, da) /* disk address to bytes */ \
|
||||
(((off_t)(da)) << ((fs)->lfs_bshift - (fs)->lfs_fsbtodb))
|
||||
i, (ip)->if_version, (ip)->if_daddr)
|
||||
#define fsbtobyte(fs, b) fsbtob((fs), (off_t)((b)))
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct lfs lfs_sb1, lfs_sb2, *lfs_master;
|
||||
daddr_t seg_addr, idaddr, sbdaddr;
|
||||
int ch, do_allsb, do_ientries, fd, segnum;
|
||||
int ch, do_allsb, do_ientries, do_segentries, fd, segnum;
|
||||
|
||||
do_allsb = 0;
|
||||
do_ientries = 0;
|
||||
do_segentries = 0;
|
||||
idaddr = 0x0;
|
||||
sbdaddr = 0x0;
|
||||
while ((ch = getopt(argc, argv, "ab:iI:s:")) != -1)
|
||||
while ((ch = getopt(argc, argv, "ab:iI:Ss:")) != -1)
|
||||
switch(ch) {
|
||||
case 'a': /* Dump all superblocks */
|
||||
do_allsb = 1;
|
||||
@ -139,11 +135,14 @@ main(argc, argv)
|
||||
sbdaddr = strtol(optarg, NULL, 0);
|
||||
break;
|
||||
case 'i': /* Dump ifile entries */
|
||||
do_ientries = 1;
|
||||
do_ientries = !do_ientries;
|
||||
break;
|
||||
case 'I': /* Use this ifile inode */
|
||||
idaddr = strtol(optarg, NULL, 0);
|
||||
break;
|
||||
case 'S':
|
||||
do_segentries = !do_segentries;
|
||||
break;
|
||||
case 's': /* Dump out these segments */
|
||||
addseg(optarg);
|
||||
break;
|
||||
@ -161,24 +160,37 @@ main(argc, argv)
|
||||
err(1, "%s", special);
|
||||
|
||||
if (sbdaddr == 0x0) {
|
||||
/* Read the first superblock */
|
||||
/* Read the proto-superblock */
|
||||
get(fd, LFS_LABELPAD, &(lfs_sb1.lfs_dlfs), sizeof(struct dlfs));
|
||||
|
||||
/* If that wasn't the real first sb, get the real first sb */
|
||||
if (lfs_sb1.lfs_version > 1 &&
|
||||
lfs_sb1.lfs_sboffs[0] > btofsb(&lfs_sb1, LFS_LABELPAD))
|
||||
get(fd, fsbtob(&lfs_sb1, lfs_sb1.lfs_sboffs[0]),
|
||||
&(lfs_sb1.lfs_dlfs), sizeof(struct dlfs));
|
||||
|
||||
/*
|
||||
* Read the second superblock and figure out which check point is
|
||||
* most up to date.
|
||||
*/
|
||||
get(fd,
|
||||
datobyte(&lfs_sb1, lfs_sb1.lfs_sboffs[1]),
|
||||
fsbtobyte(&lfs_sb1, lfs_sb1.lfs_sboffs[1]),
|
||||
&(lfs_sb2.lfs_dlfs), sizeof(struct dlfs));
|
||||
|
||||
lfs_master = &lfs_sb1;
|
||||
if (lfs_sb1.lfs_tstamp > lfs_sb2.lfs_tstamp) {
|
||||
lfs_master = &lfs_sb2;
|
||||
sbdaddr =
|
||||
btodb(datobyte(&lfs_sb1, lfs_sb1.lfs_sboffs[1]));
|
||||
} else
|
||||
sbdaddr = btodb(LFS_LABELPAD);
|
||||
if (lfs_sb1.lfs_version > 1) {
|
||||
if (lfs_sb1.lfs_serial > lfs_sb2.lfs_serial) {
|
||||
lfs_master = &lfs_sb2;
|
||||
sbdaddr = lfs_sb1.lfs_sboffs[1];
|
||||
} else
|
||||
sbdaddr = lfs_sb1.lfs_sboffs[0];
|
||||
} else {
|
||||
if (lfs_sb1.lfs_otstamp > lfs_sb2.lfs_otstamp) {
|
||||
lfs_master = &lfs_sb2;
|
||||
sbdaddr = lfs_sb1.lfs_sboffs[1];
|
||||
} else
|
||||
sbdaddr = lfs_sb1.lfs_sboffs[0];
|
||||
}
|
||||
} else {
|
||||
/* Read the first superblock */
|
||||
get(fd, dbtob((off_t)sbdaddr), &(lfs_sb1.lfs_dlfs),
|
||||
@ -186,24 +198,32 @@ main(argc, argv)
|
||||
lfs_master = &lfs_sb1;
|
||||
}
|
||||
|
||||
/* Compatibility */
|
||||
if (lfs_master->lfs_version == 1) {
|
||||
lfs_master->lfs_sumsize = LFS_V1_SUMMARY_SIZE;
|
||||
lfs_master->lfs_ibsize = lfs_master->lfs_bsize;
|
||||
lfs_master->lfs_start = lfs_master->lfs_sboffs[0];
|
||||
lfs_master->lfs_tstamp = lfs_master->lfs_otstamp;
|
||||
lfs_master->lfs_fsbtodb = 0;
|
||||
}
|
||||
|
||||
(void)printf("Master Superblock at 0x%x:\n", sbdaddr);
|
||||
dump_super(lfs_master);
|
||||
|
||||
dump_ifile(fd, lfs_master, do_ientries, idaddr);
|
||||
dump_ifile(fd, lfs_master, do_ientries, do_segentries, idaddr);
|
||||
|
||||
if (seglist != NULL)
|
||||
for (; seglist != NULL; seglist = seglist->next) {
|
||||
seg_addr = lfs_master->lfs_sboffs[0] + seglist->num *
|
||||
(lfs_master->lfs_ssize << lfs_master->lfs_fsbtodb);
|
||||
dump_segment(fd,
|
||||
seglist->num, seg_addr, lfs_master, do_allsb);
|
||||
seg_addr = sntod(lfs_master, seglist->num);
|
||||
dump_segment(fd, seglist->num, seg_addr, lfs_master,
|
||||
do_allsb);
|
||||
}
|
||||
else
|
||||
for (segnum = 0, seg_addr = lfs_master->lfs_sboffs[0];
|
||||
segnum < lfs_master->lfs_nseg; segnum++, seg_addr +=
|
||||
lfs_master->lfs_ssize << lfs_master->lfs_fsbtodb)
|
||||
dump_segment(fd,
|
||||
segnum, seg_addr, lfs_master, do_allsb);
|
||||
for (segnum = 0, seg_addr = sntod(lfs_master, 0);
|
||||
segnum < lfs_master->lfs_nseg;
|
||||
segnum++, seg_addr = sntod(lfs_master, segnum))
|
||||
dump_segment(fd, segnum, seg_addr, lfs_master,
|
||||
do_allsb);
|
||||
|
||||
(void)close(fd);
|
||||
exit(0);
|
||||
@ -215,13 +235,9 @@ main(argc, argv)
|
||||
* printed out rather than making this code incredibly efficient.
|
||||
*/
|
||||
static void
|
||||
dump_ifile(fd, lfsp, do_ientries, addr)
|
||||
int fd;
|
||||
struct lfs *lfsp;
|
||||
int do_ientries;
|
||||
daddr_t addr;
|
||||
dump_ifile(int fd, struct lfs *lfsp, int do_ientries, int do_segentries, daddr_t addr)
|
||||
{
|
||||
IFILE *ipage;
|
||||
char *ipage;
|
||||
struct dinode *dip, *dpage;
|
||||
daddr_t *addrp, *dindir, *iaddrp, *indir;
|
||||
int block_limit, i, inum, j, nblocks, psize;
|
||||
@ -232,7 +248,7 @@ dump_ifile(fd, lfsp, do_ientries, addr)
|
||||
|
||||
if (!(dpage = malloc(psize)))
|
||||
err(1, "malloc");
|
||||
get(fd, datobyte(lfsp, addr), dpage, psize);
|
||||
get(fd, fsbtobyte(lfsp, addr), dpage, psize);
|
||||
|
||||
for (dip = dpage + INOPB(lfsp) - 1; dip >= dpage; --dip)
|
||||
if (dip->di_inumber == LFS_IFILE_INUM)
|
||||
@ -254,16 +270,20 @@ dump_ifile(fd, lfsp, do_ientries, addr)
|
||||
err(1, "malloc");
|
||||
for (inum = 0, addrp = dip->di_db, i = 0; i < block_limit;
|
||||
i++, addrp++) {
|
||||
get(fd, datobyte(lfsp, *addrp), ipage, psize);
|
||||
get(fd, fsbtobyte(lfsp, *addrp), ipage, psize);
|
||||
if (i < lfsp->lfs_cleansz) {
|
||||
dump_cleaner_info(lfsp, ipage);
|
||||
print_suheader;
|
||||
if (do_segentries)
|
||||
print_suheader;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i < (lfsp->lfs_segtabsz + lfsp->lfs_cleansz)) {
|
||||
inum = dump_ipage_segusage(lfsp, inum, ipage,
|
||||
lfsp->lfs_sepb);
|
||||
if (do_segentries)
|
||||
inum = dump_ipage_segusage(lfsp, inum, ipage,
|
||||
lfsp->lfs_sepb);
|
||||
else
|
||||
inum = (i < lfsp->lfs_segtabsz + lfsp->lfs_cleansz - 1);
|
||||
if (!inum) {
|
||||
if(!do_ientries)
|
||||
goto e0;
|
||||
@ -271,8 +291,7 @@ dump_ifile(fd, lfsp, do_ientries, addr)
|
||||
print_iheader;
|
||||
}
|
||||
} else
|
||||
inum = dump_ipage_ifile(inum, ipage, lfsp->lfs_ifpb);
|
||||
|
||||
inum = dump_ipage_ifile(lfsp, inum, ipage, lfsp->lfs_ifpb);
|
||||
}
|
||||
|
||||
if (nblocks <= NDADDR)
|
||||
@ -281,21 +300,23 @@ dump_ifile(fd, lfsp, do_ientries, addr)
|
||||
/* Dump out blocks off of single indirect block */
|
||||
if (!(indir = malloc(psize)))
|
||||
err(1, "malloc");
|
||||
get(fd, datobyte(lfsp, dip->di_ib[0]), indir, psize);
|
||||
get(fd, fsbtobyte(lfsp, dip->di_ib[0]), indir, psize);
|
||||
block_limit = MIN(i + lfsp->lfs_nindir, nblocks);
|
||||
for (addrp = indir; i < block_limit; i++, addrp++) {
|
||||
if (*addrp == LFS_UNUSED_DADDR)
|
||||
break;
|
||||
get(fd, datobyte(lfsp, *addrp), ipage, psize);
|
||||
get(fd, fsbtobyte(lfsp, *addrp), ipage, psize);
|
||||
if (i < lfsp->lfs_cleansz) {
|
||||
dump_cleaner_info(lfsp, ipage);
|
||||
continue;
|
||||
} else
|
||||
i -= lfsp->lfs_cleansz;
|
||||
}
|
||||
|
||||
if (i < lfsp->lfs_segtabsz) {
|
||||
inum = dump_ipage_segusage(lfsp, inum, ipage,
|
||||
lfsp->lfs_sepb);
|
||||
if (i < lfsp->lfs_segtabsz + lfsp->lfs_cleansz) {
|
||||
if (do_segentries)
|
||||
inum = dump_ipage_segusage(lfsp, inum, ipage,
|
||||
lfsp->lfs_sepb);
|
||||
else
|
||||
inum = (i < lfsp->lfs_segtabsz + lfsp->lfs_cleansz - 1);
|
||||
if (!inum) {
|
||||
if(!do_ientries)
|
||||
goto e1;
|
||||
@ -303,7 +324,7 @@ dump_ifile(fd, lfsp, do_ientries, addr)
|
||||
print_iheader;
|
||||
}
|
||||
} else
|
||||
inum = dump_ipage_ifile(inum, ipage, lfsp->lfs_ifpb);
|
||||
inum = dump_ipage_ifile(lfsp, inum, ipage, lfsp->lfs_ifpb);
|
||||
}
|
||||
|
||||
if (nblocks <= lfsp->lfs_nindir * lfsp->lfs_ifpb)
|
||||
@ -312,25 +333,28 @@ dump_ifile(fd, lfsp, do_ientries, addr)
|
||||
/* Get the double indirect block */
|
||||
if (!(dindir = malloc(psize)))
|
||||
err(1, "malloc");
|
||||
get(fd, datobyte(lfsp, dip->di_ib[1]), dindir, psize);
|
||||
get(fd, fsbtobyte(lfsp, dip->di_ib[1]), dindir, psize);
|
||||
for (iaddrp = dindir, j = 0; j < lfsp->lfs_nindir; j++, iaddrp++) {
|
||||
if (*iaddrp == LFS_UNUSED_DADDR)
|
||||
break;
|
||||
get(fd, datobyte(lfsp, *iaddrp), indir, psize);
|
||||
get(fd, fsbtobyte(lfsp, *iaddrp), indir, psize);
|
||||
block_limit = MIN(i + lfsp->lfs_nindir, nblocks);
|
||||
for (addrp = indir; i < block_limit; i++, addrp++) {
|
||||
if (*addrp == LFS_UNUSED_DADDR)
|
||||
break;
|
||||
get(fd, datobyte(lfsp, *addrp), ipage, psize);
|
||||
get(fd, fsbtobyte(lfsp, *addrp), ipage, psize);
|
||||
if (i < lfsp->lfs_cleansz) {
|
||||
dump_cleaner_info(lfsp, ipage);
|
||||
continue;
|
||||
} else
|
||||
i -= lfsp->lfs_cleansz;
|
||||
}
|
||||
|
||||
if (i < lfsp->lfs_segtabsz) {
|
||||
inum = dump_ipage_segusage(lfsp,
|
||||
inum, ipage, lfsp->lfs_sepb);
|
||||
if (i < lfsp->lfs_segtabsz + lfsp->lfs_cleansz) {
|
||||
if (do_segentries)
|
||||
inum = dump_ipage_segusage(lfsp,
|
||||
inum, ipage, lfsp->lfs_sepb);
|
||||
else
|
||||
inum = (i < lfsp->lfs_segtabsz +
|
||||
lfsp->lfs_cleansz - 1);
|
||||
if (!inum) {
|
||||
if(!do_ientries)
|
||||
goto e2;
|
||||
@ -338,7 +362,7 @@ dump_ifile(fd, lfsp, do_ientries, addr)
|
||||
print_iheader;
|
||||
}
|
||||
} else
|
||||
inum = dump_ipage_ifile(inum,
|
||||
inum = dump_ipage_ifile(lfsp, inum,
|
||||
ipage, lfsp->lfs_ifpb);
|
||||
}
|
||||
}
|
||||
@ -349,27 +373,24 @@ e0: free(dpage);
|
||||
}
|
||||
|
||||
static int
|
||||
dump_ipage_ifile(i, pp, tot)
|
||||
int i;
|
||||
IFILE *pp;
|
||||
int tot;
|
||||
dump_ipage_ifile(struct lfs *lfsp, int i, char *pp, int tot)
|
||||
{
|
||||
IFILE *ip;
|
||||
int cnt, max;
|
||||
char *ip;
|
||||
int cnt, max, entsize;
|
||||
|
||||
if (lfsp->lfs_version == 1)
|
||||
entsize = sizeof(IFILE_V1);
|
||||
else
|
||||
entsize = sizeof(IFILE);
|
||||
max = i + tot;
|
||||
|
||||
for (ip = pp, cnt = i; cnt < max; cnt++, ip++)
|
||||
print_ientry(cnt, ip);
|
||||
for (ip = pp, cnt = i; cnt < max; cnt++, ip += entsize)
|
||||
print_ientry(cnt, (IFILE *)ip);
|
||||
return (max);
|
||||
}
|
||||
|
||||
static int
|
||||
dump_ipage_segusage(lfsp, i, pp, tot)
|
||||
struct lfs *lfsp;
|
||||
int i;
|
||||
IFILE *pp;
|
||||
int tot;
|
||||
dump_ipage_segusage(struct lfs *lfsp, int i, char *pp, int tot)
|
||||
{
|
||||
SEGUSE *sp;
|
||||
int cnt, max;
|
||||
@ -377,16 +398,20 @@ dump_ipage_segusage(lfsp, i, pp, tot)
|
||||
|
||||
max = i + tot;
|
||||
for (sp = (SEGUSE *)pp, cnt = i;
|
||||
cnt < lfsp->lfs_nseg && cnt < max; cnt++, sp++) {
|
||||
cnt < lfsp->lfs_nseg && cnt < max; cnt++) {
|
||||
if (seglist == NULL)
|
||||
print_suentry(cnt, sp);
|
||||
print_suentry(cnt, sp, lfsp);
|
||||
else {
|
||||
for (slp = seglist; slp != NULL; slp = slp->next)
|
||||
if (cnt == slp->num) {
|
||||
print_suentry(cnt, sp);
|
||||
print_suentry(cnt, sp, lfsp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (lfsp->lfs_version > 1)
|
||||
++sp;
|
||||
else
|
||||
sp = (SEGUSE *)((SEGUSE_V1 *)sp + 1);
|
||||
}
|
||||
if (max >= lfsp->lfs_nseg)
|
||||
return (0);
|
||||
@ -395,8 +420,7 @@ dump_ipage_segusage(lfsp, i, pp, tot)
|
||||
}
|
||||
|
||||
static void
|
||||
dump_dinode(dip)
|
||||
struct dinode *dip;
|
||||
dump_dinode(struct dinode *dip)
|
||||
{
|
||||
int i;
|
||||
time_t at, mt, ct;
|
||||
@ -405,18 +429,18 @@ dump_dinode(dip)
|
||||
mt = dip->di_mtime;
|
||||
ct = dip->di_ctime;
|
||||
|
||||
(void)printf("%s%d\t%s%d\t%s%d\t%s%d\t%s%llu\n",
|
||||
(void)printf(" %so%o\t%s%d\t%s%d\t%s%d\t%s%llu\n",
|
||||
"mode ", dip->di_mode,
|
||||
"nlink ", dip->di_nlink,
|
||||
"uid ", dip->di_uid,
|
||||
"gid ", dip->di_gid,
|
||||
"size ", (long long)dip->di_size);
|
||||
(void)printf("%s%s%s%s%s%s",
|
||||
(void)printf(" %s%s %s%s %s%s",
|
||||
"atime ", ctime(&at),
|
||||
"mtime ", ctime(&mt),
|
||||
"ctime ", ctime(&ct));
|
||||
(void)printf("inum %d\n", dip->di_inumber);
|
||||
(void)printf("Direct Addresses\n");
|
||||
(void)printf(" inum %d\n", dip->di_inumber);
|
||||
(void)printf(" Direct Addresses\n");
|
||||
for (i = 0; i < NDADDR; i++) {
|
||||
(void)printf("\t0x%x", dip->di_db[i]);
|
||||
if ((i % 6) == 5)
|
||||
@ -428,11 +452,7 @@ dump_dinode(dip)
|
||||
}
|
||||
|
||||
static int
|
||||
dump_sum(fd, lfsp, sp, segnum, addr)
|
||||
struct lfs *lfsp;
|
||||
SEGSUM *sp;
|
||||
int fd, segnum;
|
||||
daddr_t addr;
|
||||
dump_sum(int fd, struct lfs *lfsp, SEGSUM *sp, int segnum, daddr_t addr)
|
||||
{
|
||||
FINFO *fp;
|
||||
daddr_t *dp;
|
||||
@ -443,14 +463,20 @@ dump_sum(fd, lfsp, sp, segnum, addr)
|
||||
|
||||
if (sp->ss_magic != SS_MAGIC ||
|
||||
sp->ss_sumsum != (ck = cksum(&sp->ss_datasum,
|
||||
LFS_SUMMARY_SIZE - sizeof(sp->ss_sumsum)))) {
|
||||
lfsp->lfs_sumsize - sizeof(sp->ss_sumsum)))) {
|
||||
/* Don't print "corrupt" if we're just too close to the edge */
|
||||
if (datosn(lfsp, addr + fsbtodb(lfsp, lfsp->lfs_bsize)) ==
|
||||
datosn(lfsp, addr))
|
||||
if (dtosn(lfsp, addr + fsbtodb(lfsp, 1)) ==
|
||||
dtosn(lfsp, addr))
|
||||
(void)printf("dumplfs: %s %d address 0x%x\n",
|
||||
"corrupt summary block; segment", segnum,
|
||||
addr);
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
if (lfsp->lfs_version > 1 && sp->ss_ident != lfsp->lfs_ident) {
|
||||
(void)printf("dumplfs: %s %d address 0x%x\n",
|
||||
"summary from a former life; segment", segnum,
|
||||
addr);
|
||||
return (0);
|
||||
}
|
||||
|
||||
(void)printf("Segment Summary Info at 0x%x\n", addr);
|
||||
@ -462,22 +488,28 @@ dump_sum(fd, lfsp, sp, segnum, addr)
|
||||
(sp->ss_flags & SS_CONT) ? 'C' : '-',
|
||||
"sumsum ", sp->ss_sumsum,
|
||||
"datasum ", sp->ss_datasum );
|
||||
(void)printf("\tcreate %s", ctime((time_t *)&sp->ss_create));
|
||||
if (lfsp->lfs_version == 1)
|
||||
(void)printf("\tcreate %s\n", ctime((time_t *)&sp->ss_ident));
|
||||
else {
|
||||
(void)printf("\tcreate %s", ctime((time_t *)&sp->ss_create));
|
||||
(void)printf(" roll_id %-8x", sp->ss_ident);
|
||||
(void)printf(" serial %lld\n", (long long)sp->ss_serial);
|
||||
}
|
||||
|
||||
/* Dump out inode disk addresses */
|
||||
dp = (daddr_t *)sp;
|
||||
dp += LFS_SUMMARY_SIZE / sizeof(daddr_t);
|
||||
inop = malloc(1 << lfsp->lfs_bshift);
|
||||
dp += lfsp->lfs_sumsize / sizeof(daddr_t);
|
||||
inop = malloc(lfsp->lfs_bsize);
|
||||
printf(" Inode addresses:");
|
||||
numbytes = 0;
|
||||
for (dp--, i = 0; i < sp->ss_ninos; dp--) {
|
||||
numbytes += lfsp->lfs_bsize; /* add bytes for inode block */
|
||||
numbytes += lfsp->lfs_ibsize; /* add bytes for inode block */
|
||||
printf("\t0x%x {", *dp);
|
||||
get(fd, datobyte(lfsp, *dp), inop, (1 << lfsp->lfs_bshift));
|
||||
get(fd, fsbtobyte(lfsp, *dp), inop, lfsp->lfs_ibsize);
|
||||
for (j = 0; i < sp->ss_ninos && j < INOPB(lfsp); j++, i++) {
|
||||
if (j > 0)
|
||||
(void)printf(", ");
|
||||
(void)printf("%d", inop[j].di_inumber);
|
||||
(void)printf("%dv%d", inop[j].di_inumber, inop[j].di_gen);
|
||||
}
|
||||
(void)printf("}");
|
||||
if (((i/INOPB(lfsp)) % 4) == 3)
|
||||
@ -486,7 +518,11 @@ dump_sum(fd, lfsp, sp, segnum, addr)
|
||||
free(inop);
|
||||
|
||||
printf("\n");
|
||||
for (fp = (FINFO *)(sp + 1), i = 0; i < sp->ss_nfinfo; i++) {
|
||||
if (lfsp->lfs_version == 1)
|
||||
fp = (FINFO *)((SEGSUM_V1 *)sp + 1);
|
||||
else
|
||||
fp = (FINFO *)(sp + 1);
|
||||
for (i = 0; i < sp->ss_nfinfo; 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);
|
||||
@ -508,61 +544,69 @@ dump_sum(fd, lfsp, sp, segnum, addr)
|
||||
}
|
||||
|
||||
static void
|
||||
dump_segment(fd, segnum, addr, lfsp, dump_sb)
|
||||
int fd, segnum;
|
||||
daddr_t addr;
|
||||
struct lfs *lfsp;
|
||||
int dump_sb;
|
||||
dump_segment(int fd, int segnum, daddr_t addr, struct lfs *lfsp, int dump_sb)
|
||||
{
|
||||
struct lfs lfs_sb, *sbp;
|
||||
SEGSUM *sump;
|
||||
char sumblock[LFS_SUMMARY_SIZE];
|
||||
char *sumblock;
|
||||
int did_one, nbytes, sb;
|
||||
off_t sum_offset;
|
||||
daddr_t new_addr;
|
||||
|
||||
(void)printf("\nSEGMENT %d (Disk Address 0x%x)\n",
|
||||
/* addr >> (lfsp->lfs_segshift - daddr_shift), */
|
||||
datosn(lfsp, addr),
|
||||
addr);
|
||||
sum_offset = datobyte(lfsp, addr);
|
||||
(void)printf("\nSEGMENT %d (Disk Address 0x%x)\n", dtosn(lfsp, addr),
|
||||
addr);
|
||||
sum_offset = fsbtobyte(lfsp, addr);
|
||||
sumblock = malloc(lfsp->lfs_sumsize);
|
||||
|
||||
if (lfsp->lfs_version > 1 && segnum == 0) {
|
||||
/* First segment eats the label as well as the superblock */
|
||||
sum_offset += fragroundup(lfsp, LFS_LABELPAD);
|
||||
addr += btofsb(lfsp, fragroundup(lfsp, LFS_LABELPAD));
|
||||
printf("Disklabel at 0x0\n");
|
||||
}
|
||||
|
||||
sb = 0;
|
||||
did_one = 0;
|
||||
do {
|
||||
get(fd, sum_offset, sumblock, LFS_SUMMARY_SIZE);
|
||||
get(fd, sum_offset, sumblock, lfsp->lfs_sumsize);
|
||||
sump = (SEGSUM *)sumblock;
|
||||
if (sump->ss_sumsum != cksum (&sump->ss_datasum,
|
||||
LFS_SUMMARY_SIZE - sizeof(sump->ss_sumsum))) {
|
||||
if ((lfsp->lfs_version > 1 &&
|
||||
sump->ss_ident != lfsp->lfs_ident) ||
|
||||
sump->ss_sumsum != cksum (&sump->ss_datasum,
|
||||
lfsp->lfs_sumsize - sizeof(sump->ss_sumsum))) {
|
||||
sbp = (struct lfs *)sump;
|
||||
if ((sb = (sbp->lfs_magic == LFS_MAGIC))) {
|
||||
printf("Superblock at 0x%x\n",
|
||||
(unsigned)btofsb(lfsp, sum_offset));
|
||||
if (dump_sb) {
|
||||
get(fd, sum_offset, &(lfs_sb.lfs_dlfs),
|
||||
sizeof(struct dlfs));
|
||||
(void)printf("\nSuperblock at 0x%x:\n",
|
||||
(unsigned)btodb(sum_offset));
|
||||
dump_super(&lfs_sb);
|
||||
(void)printf("%s","\n");
|
||||
}
|
||||
sum_offset += LFS_SBPAD;
|
||||
if (lfsp->lfs_version > 1)
|
||||
sum_offset += fragroundup(lfsp, LFS_SBPAD);
|
||||
else
|
||||
sum_offset += LFS_SBPAD;
|
||||
} else if (did_one)
|
||||
break;
|
||||
else {
|
||||
printf("Segment at 0x%x corrupt\n", addr);
|
||||
printf("Segment at 0x%x empty or corrupt\n",
|
||||
addr);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
nbytes = dump_sum(fd, lfsp, sump, segnum, sum_offset >>
|
||||
(lfsp->lfs_bshift - lfsp->lfs_fsbtodb));
|
||||
nbytes = dump_sum(fd, lfsp, sump, segnum,
|
||||
btofsb(lfsp, sum_offset));
|
||||
if (nbytes)
|
||||
sum_offset += LFS_SUMMARY_SIZE + nbytes;
|
||||
sum_offset += lfsp->lfs_sumsize + nbytes;
|
||||
else
|
||||
sum_offset = 0;
|
||||
did_one = 1;
|
||||
}
|
||||
/* If the segment ends right on a boundary, it still ends */
|
||||
new_addr = sum_offset >> (lfsp->lfs_bshift - lfsp->lfs_fsbtodb);
|
||||
if (datosn(lfsp, new_addr) != datosn(lfsp, addr))
|
||||
new_addr = btofsb(lfsp, sum_offset);
|
||||
/* printf("end daddr = 0x%lx\n", (long)new_addr); */
|
||||
if (dtosn(lfsp, new_addr) != dtosn(lfsp, addr))
|
||||
break;
|
||||
} while (sum_offset);
|
||||
|
||||
@ -570,86 +614,89 @@ dump_segment(fd, segnum, addr, lfsp, dump_sb)
|
||||
}
|
||||
|
||||
static void
|
||||
dump_super(lfsp)
|
||||
struct lfs *lfsp;
|
||||
dump_super(struct lfs *lfsp)
|
||||
{
|
||||
int i;
|
||||
|
||||
(void)printf("%s0x%x\t%s0x%x\t%s%d\t%s%d\n",
|
||||
"magic ", lfsp->lfs_magic,
|
||||
"version ", lfsp->lfs_version,
|
||||
"size ", lfsp->lfs_size,
|
||||
"ssize ", lfsp->lfs_ssize);
|
||||
(void)printf("%s%d\t\t%s%d\t%s%d\t%s%d\n",
|
||||
"dsize ", lfsp->lfs_dsize,
|
||||
"bsize ", lfsp->lfs_bsize,
|
||||
"fsize ", lfsp->lfs_fsize,
|
||||
"frag ", lfsp->lfs_frag);
|
||||
|
||||
(void)printf("%s%d\t\t%s%d\t%s%d\t%s%d\n",
|
||||
"minfree ", lfsp->lfs_minfree,
|
||||
"inopb ", lfsp->lfs_inopb,
|
||||
"ifpb ", lfsp->lfs_ifpb,
|
||||
"nindir ", lfsp->lfs_nindir);
|
||||
|
||||
(void)printf("%s%d\t\t%s%d\t%s%d\t%s%d\n",
|
||||
"nseg ", lfsp->lfs_nseg,
|
||||
"nspf ", lfsp->lfs_nspf,
|
||||
"cleansz ", lfsp->lfs_cleansz,
|
||||
"segtabsz ", lfsp->lfs_segtabsz);
|
||||
|
||||
(void)printf("%s0x%x\t%s%d\t%s0x%llX\t%s%d\n",
|
||||
"segmask ", lfsp->lfs_segmask,
|
||||
"segshift ", lfsp->lfs_segshift,
|
||||
"bmask ", (long long)lfsp->lfs_bmask,
|
||||
"bshift ", lfsp->lfs_bshift);
|
||||
|
||||
(void)printf("%s0x%llX\t\t%s%d\t%s0x%llX\t%s%u\n",
|
||||
"ffmask ", (long long)lfsp->lfs_ffmask,
|
||||
"ffshift ", lfsp->lfs_ffshift,
|
||||
"fbmask ", (long long)lfsp->lfs_fbmask,
|
||||
"fbshift ", lfsp->lfs_fbshift);
|
||||
|
||||
(void)printf("%s%d\t%s%d\t%s0x%x\t%s0x%llx\n",
|
||||
"sushift ", lfsp->lfs_sushift,
|
||||
"fsbtodb ", lfsp->lfs_fsbtodb,
|
||||
"cksum ", lfsp->lfs_cksum,
|
||||
"maxfilesize ", (long long)lfsp->lfs_maxfilesize);
|
||||
|
||||
(void)printf("%s%d\t%s%d\t%s%d\n",
|
||||
"nclean ", lfsp->lfs_nclean,
|
||||
"dmeta ", lfsp->lfs_dmeta,
|
||||
"minfreeseg ", lfsp->lfs_minfreeseg);
|
||||
|
||||
(void)printf("Superblock disk addresses:\t");
|
||||
for (i = 0; i < LFS_MAXNUMSB; i++) {
|
||||
(void)printf(" 0x%x", lfsp->lfs_sboffs[i]);
|
||||
if ( i == (LFS_MAXNUMSB >> 1))
|
||||
(void)printf("\n\t\t\t\t");
|
||||
}
|
||||
(void)printf("\n");
|
||||
|
||||
(void)printf("Checkpoint Info\n");
|
||||
(void)printf("%s%d\t%s0x%x\t%s%d\n",
|
||||
"free ", lfsp->lfs_free,
|
||||
"idaddr ", lfsp->lfs_idaddr,
|
||||
"ifile ", lfsp->lfs_ifile);
|
||||
(void)printf("%s%d\t%s%d\t%s%d\n",
|
||||
"uinodes ", lfsp->lfs_uinodes,
|
||||
"bfree ", lfsp->lfs_bfree,
|
||||
"avail ", lfsp->lfs_avail);
|
||||
(void)printf("%s%d\t%s0x%x\t%s0x%x\n%s0x%x\t%s0x%x\t",
|
||||
"nfiles ", lfsp->lfs_nfiles,
|
||||
"lastseg ", lfsp->lfs_lastseg,
|
||||
"nextseg ", lfsp->lfs_nextseg,
|
||||
"curseg ", lfsp->lfs_curseg,
|
||||
"offset ", lfsp->lfs_offset);
|
||||
(void)printf("tstamp %s", ctime((time_t *)&lfsp->lfs_tstamp));
|
||||
(void)printf(" %s0x%-8x %s0x%-8x %s%-10d\n",
|
||||
"magic ", lfsp->lfs_magic,
|
||||
"version ", lfsp->lfs_version,
|
||||
"size ", lfsp->lfs_size);
|
||||
(void)printf(" %s%-10d %s%-10d %s%-10d\n",
|
||||
"ssize ", lfsp->lfs_ssize,
|
||||
"dsize ", lfsp->lfs_dsize,
|
||||
"bsize ", lfsp->lfs_bsize);
|
||||
(void)printf(" %s%-10d %s%-10d %s%-10d\n",
|
||||
"fsize ", lfsp->lfs_fsize,
|
||||
"frag ", lfsp->lfs_frag,
|
||||
"minfree ", lfsp->lfs_minfree);
|
||||
(void)printf(" %s%-10d %s%-10d %s%-10d\n",
|
||||
"inopb ", lfsp->lfs_inopb,
|
||||
"ifpb ", lfsp->lfs_ifpb,
|
||||
"nindir ", lfsp->lfs_nindir);
|
||||
(void)printf(" %s%-10d %s%-10d %s%-10d\n",
|
||||
"nseg ", lfsp->lfs_nseg,
|
||||
"sepb ", lfsp->lfs_sepb,
|
||||
"cleansz ", lfsp->lfs_cleansz);
|
||||
(void)printf(" %s%-10d %s0x%-8x %s%-10d\n",
|
||||
"segtabsz ", lfsp->lfs_segtabsz,
|
||||
"segmask ", lfsp->lfs_segmask,
|
||||
"segshift ", lfsp->lfs_segshift);
|
||||
(void)printf(" %s0x%-8qx %s%-10d %s0x%-8qX\n",
|
||||
"bmask ", (long long)lfsp->lfs_bmask,
|
||||
"bshift ", lfsp->lfs_bshift,
|
||||
"ffmask ", (long long)lfsp->lfs_ffmask);
|
||||
(void)printf(" %s%-10d %s0x%-8qx %s%u\n",
|
||||
"ffshift ", lfsp->lfs_ffshift,
|
||||
"fbmask ", (long long)lfsp->lfs_fbmask,
|
||||
"fbshift ", lfsp->lfs_fbshift);
|
||||
|
||||
(void)printf(" %s%-10d %s%-10d %s0x%-8x\n",
|
||||
"sushift ", lfsp->lfs_sushift,
|
||||
"fsbtodb ", lfsp->lfs_fsbtodb,
|
||||
"cksum ", lfsp->lfs_cksum);
|
||||
(void)printf(" %s%-10d %s%-10d %s%-10d\n",
|
||||
"nclean ", lfsp->lfs_nclean,
|
||||
"dmeta ", lfsp->lfs_dmeta,
|
||||
"minfreeseg ", lfsp->lfs_minfreeseg);
|
||||
(void)printf(" %s0x%-8x %s%-9d %s%-10d\n",
|
||||
"roll_id ", lfsp->lfs_ident,
|
||||
"interleave ", lfsp->lfs_interleave,
|
||||
"sumsize ", lfsp->lfs_sumsize);
|
||||
(void)printf(" %s0x%-8qx\n",
|
||||
"maxfilesize ", (long long)lfsp->lfs_maxfilesize);
|
||||
|
||||
|
||||
(void)printf(" Superblock disk addresses:\n ");
|
||||
for (i = 0; i < LFS_MAXNUMSB; i++) {
|
||||
(void)printf(" 0x%-8x", lfsp->lfs_sboffs[i]);
|
||||
if (i == (LFS_MAXNUMSB >> 1))
|
||||
(void)printf("\n ");
|
||||
}
|
||||
(void)printf("\n");
|
||||
|
||||
(void)printf(" Checkpoint Info\n");
|
||||
(void)printf(" %s%-10d %s0x%-8x %s%-10d\n",
|
||||
"free ", lfsp->lfs_free,
|
||||
"idaddr ", lfsp->lfs_idaddr,
|
||||
"ifile ", lfsp->lfs_ifile);
|
||||
(void)printf(" %s%-10d %s%-10d %s%-10d\n",
|
||||
"uinodes ", lfsp->lfs_uinodes,
|
||||
"bfree ", lfsp->lfs_bfree,
|
||||
"avail ", lfsp->lfs_avail);
|
||||
(void)printf(" %s%-10d %s0x%-8x %s0x%-8x\n",
|
||||
"nfiles ", lfsp->lfs_nfiles,
|
||||
"lastseg ", lfsp->lfs_lastseg,
|
||||
"nextseg ", lfsp->lfs_nextseg);
|
||||
(void)printf(" %s0x%-8x %s0x%-8x %s%-10lld\n",
|
||||
"curseg ", lfsp->lfs_curseg,
|
||||
"offset ", lfsp->lfs_offset,
|
||||
"serial ", (long long)lfsp->lfs_serial);
|
||||
(void)printf(" tstamp %s", ctime((time_t *)&lfsp->lfs_tstamp));
|
||||
}
|
||||
|
||||
static void
|
||||
addseg(arg)
|
||||
char *arg;
|
||||
addseg(char *arg)
|
||||
{
|
||||
SEGLIST *p;
|
||||
|
||||
@ -661,13 +708,15 @@ addseg(arg)
|
||||
}
|
||||
|
||||
static void
|
||||
dump_cleaner_info(lfsp, ipage)
|
||||
struct lfs *lfsp;
|
||||
void *ipage;
|
||||
dump_cleaner_info(struct lfs *lfsp, void *ipage)
|
||||
{
|
||||
CLEANERINFO *cip;
|
||||
|
||||
cip = (CLEANERINFO *)ipage;
|
||||
if (lfsp->lfs_version > 1) {
|
||||
(void)printf("free_head %d\n", cip->free_head);
|
||||
(void)printf("free_tail %d\n", cip->free_tail);
|
||||
}
|
||||
(void)printf("clean\t%d\tdirty\t%d\n",
|
||||
cip->clean, cip->dirty);
|
||||
(void)printf("bfree\t%d\tavail\t%d\n\n",
|
||||
@ -675,8 +724,8 @@ dump_cleaner_info(lfsp, ipage)
|
||||
}
|
||||
|
||||
static void
|
||||
usage()
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr, "usage: dumplfs [-ai] [-s segnum] file\n");
|
||||
(void)fprintf(stderr, "usage: dumplfs [-aiS] [-b daddr] [-I daddr] [-s segnum] file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: extern.h,v 1.4 1998/03/01 02:26:12 fvdl Exp $ */
|
||||
/* $NetBSD: extern.h,v 1.5 2001/07/13 20:30:21 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
@ -35,6 +35,6 @@
|
||||
* @(#)extern.h 8.2 (Berkeley) 4/28/95
|
||||
*/
|
||||
|
||||
void get __P((int, off_t, void *, size_t));
|
||||
void get(int, off_t, void *, size_t);
|
||||
|
||||
extern char *special;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: misc.c,v 1.5 1998/03/03 07:35:50 thorpej Exp $ */
|
||||
/* $NetBSD: misc.c,v 1.6 2001/07/13 20:30:21 perseant Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
@ -39,7 +39,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)misc.c 8.2 (Berkeley) 4/28/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: misc.c,v 1.5 1998/03/03 07:35:50 thorpej Exp $");
|
||||
__RCSID("$NetBSD: misc.c,v 1.6 2001/07/13 20:30:21 perseant Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -54,11 +54,7 @@ __RCSID("$NetBSD: misc.c,v 1.5 1998/03/03 07:35:50 thorpej Exp $");
|
||||
#include "extern.h"
|
||||
|
||||
void
|
||||
get(fd, off, p, len)
|
||||
int fd;
|
||||
off_t off;
|
||||
void *p;
|
||||
size_t len;
|
||||
get(int fd, off_t off, void *p, size_t len)
|
||||
{
|
||||
int rbytes;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user