summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libexec/lfs_cleanerd/clean.h63
-rw-r--r--libexec/lfs_cleanerd/cleanerd.c131
-rw-r--r--libexec/lfs_cleanerd/lfs_cleanerd.811
-rw-r--r--libexec/lfs_cleanerd/library.c220
-rw-r--r--libexec/lfs_cleanerd/misc.c10
-rw-r--r--libexec/lfs_cleanerd/print.c49
-rw-r--r--sbin/dump_lfs/Makefile3
-rw-r--r--sbin/dump_lfs/lfs_inode.c80
-rw-r--r--sbin/fsck_lfs/dir.c12
-rw-r--r--sbin/fsck_lfs/inode.c66
-rw-r--r--sbin/fsck_lfs/pass0.c35
-rw-r--r--sbin/fsck_lfs/pass1.c11
-rw-r--r--sbin/fsck_lfs/pass5.c45
-rw-r--r--sbin/fsck_lfs/setup.c174
-rw-r--r--sbin/fsck_lfs/utilities.c33
-rw-r--r--sbin/newfs_lfs/config.h17
-rw-r--r--sbin/newfs_lfs/extern.h17
-rw-r--r--sbin/newfs_lfs/lfs.c533
-rw-r--r--sbin/newfs_lfs/misc.c7
-rw-r--r--sbin/newfs_lfs/newfs.c78
-rw-r--r--sbin/newfs_lfs/newfs_lfs.827
-rw-r--r--sys/ufs/lfs/TODO42
-rw-r--r--sys/ufs/lfs/lfs.h306
-rw-r--r--sys/ufs/lfs/lfs_alloc.c173
-rw-r--r--sys/ufs/lfs/lfs_balloc.c36
-rw-r--r--sys/ufs/lfs/lfs_bio.c81
-rw-r--r--sys/ufs/lfs/lfs_cksum.c9
-rw-r--r--sys/ufs/lfs/lfs_debug.c28
-rw-r--r--sys/ufs/lfs/lfs_extern.h187
-rw-r--r--sys/ufs/lfs/lfs_inode.c82
-rw-r--r--sys/ufs/lfs/lfs_segment.c416
-rw-r--r--sys/ufs/lfs/lfs_subr.c18
-rw-r--r--sys/ufs/lfs/lfs_syscalls.c341
-rw-r--r--sys/ufs/lfs/lfs_vfsops.c491
-rw-r--r--sys/ufs/lfs/lfs_vnops.c77
-rw-r--r--sys/ufs/ufs/ufs_readwrite.c6
-rw-r--r--usr.sbin/dumplfs/dumplfs.c495
-rw-r--r--usr.sbin/dumplfs/extern.h4
-rw-r--r--usr.sbin/dumplfs/misc.c10
39 files changed, 2550 insertions, 1874 deletions
diff --git a/libexec/lfs_cleanerd/clean.h b/libexec/lfs_cleanerd/clean.h
index bb258dc0559..64361c91c56 100644
--- a/libexec/lfs_cleanerd/clean.h
+++ b/libexec/lfs_cleanerd/clean.h
@@ -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 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 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) \
+ ((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
diff --git a/libexec/lfs_cleanerd/cleanerd.c b/libexec/lfs_cleanerd/cleanerd.c
index 988589e4a78..c55506cb88c 100644
--- a/libexec/lfs_cleanerd/cleanerd.c
+++ b/libexec/lfs_cleanerd/cleanerd.c
@@ -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);
}
diff --git a/libexec/lfs_cleanerd/lfs_cleanerd.8 b/libexec/lfs_cleanerd/lfs_cleanerd.8
index daf85becba4..25deb49b800 100644
--- a/libexec/lfs_cleanerd/lfs_cleanerd.8
+++ b/libexec/lfs_cleanerd/lfs_cleanerd.8
@@ -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
diff --git a/libexec/lfs_cleanerd/library.c b/libexec/lfs_cleanerd/library.c
index 6bc97054596..178021d1773 100644
--- a/libexec/lfs_cleanerd/library.c
+++ b/libexec/lfs_cleanerd/library.c
@@ -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;
diff --git a/libexec/lfs_cleanerd/misc.c b/libexec/lfs_cleanerd/misc.c
index 49644888346..724b231289d 100644
--- a/libexec/lfs_cleanerd/misc.c
+++ b/libexec/lfs_cleanerd/misc.c
@@ -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;
diff --git a/libexec/lfs_cleanerd/print.c b/libexec/lfs_cleanerd/print.c
index 3da35524f77..96352d545da 100644
--- a/libexec/lfs_cleanerd/print.c
+++ b/libexec/lfs_cleanerd/print.c
@@ -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);
}
diff --git a/sbin/dump_lfs/Makefile b/sbin/dump_lfs/Makefile
index f94b91165dd..66ceccdcfcf 100644
--- a/sbin/dump_lfs/Makefile
+++ b/sbin/dump_lfs/Makefile
@@ -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
diff --git a/sbin/dump_lfs/lfs_inode.c b/sbin/dump_lfs/lfs_inode.c
index 86ad80a5763..a729789b111 100644
--- a/sbin/dump_lfs/lfs_inode.c
+++ b/sbin/dump_lfs/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++)
diff --git a/sbin/fsck_lfs/dir.c b/sbin/fsck_lfs/dir.c
index dbb48179ea2..2536fd64469 100644
--- a/sbin/fsck_lfs/dir.c
+++ b/sbin/fsck_lfs/dir.c
@@ -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);
}
diff --git a/sbin/fsck_lfs/inode.c b/sbin/fsck_lfs/inode.c
index e5e3d60db83..2a64c315d1b 100644
--- a/sbin/fsck_lfs/inode.c
+++ b/sbin/fsck_lfs/inode.c
@@ -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 > maxfsblock) {
+ return (1);
+ }
+ if (blk + cnt < sntod(&sblock, 0)) {
return (1);
}
- if (blk > fsbtodb(&sblock, maxfsblock)) {
+ 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)
diff --git a/sbin/fsck_lfs/pass0.c b/sbin/fsck_lfs/pass0.c
index d5fdab3d75a..7fc485489dd 100644
--- a/sbin/fsck_lfs/pass0.c
+++ b/sbin/fsck_lfs/pass0.c
@@ -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);
}
diff --git a/sbin/fsck_lfs/pass1.c b/sbin/fsck_lfs/pass1.c
index aacdd741ede..9104882dd34 100644
--- a/sbin/fsck_lfs/pass1.c
+++ b/sbin/fsck_lfs/pass1.c
@@ -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)) {
diff --git a/sbin/fsck_lfs/pass5.c b/sbin/fsck_lfs/pass5.c
index 4750be57a53..7733544e77e 100644
--- a/sbin/fsck_lfs/pass5.c
+++ b/sbin/fsck_lfs/pass5.c
@@ -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();
}
}
diff --git a/sbin/fsck_lfs/setup.c b/sbin/fsck_lfs/setup.c
index 986d07816e9..ca046fac6f6 100644
--- a/sbin/fsck_lfs/setup.c
+++ b/sbin/fsck_lfs/setup.c
@@ -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)
{
@@ -218,6 +238,22 @@ setup(const char *dev)
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.
* Read in the second superblock too, and take whichever
@@ -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,
diff --git a/sbin/fsck_lfs/utilities.c b/sbin/fsck_lfs/utilities.c
index 470bf3dde71..df558375f71 100644
--- a/sbin/fsck_lfs/utilities.c
+++ b/sbin/fsck_lfs/utilities.c
@@ -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);
diff --git a/sbin/newfs_lfs/config.h b/sbin/newfs_lfs/config.h
index bf7c4de62ce..614d6f24b4e 100644
--- a/sbin/newfs_lfs/config.h
+++ b/sbin/newfs_lfs/config.h
@@ -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
diff --git a/sbin/newfs_lfs/extern.h b/sbin/newfs_lfs/extern.h
index db754074a98..cbd87694ec7 100644
--- a/sbin/newfs_lfs/extern.h
+++ b/sbin/newfs_lfs/extern.h
@@ -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;
diff --git a/sbin/newfs_lfs/lfs.c b/sbin/newfs_lfs/lfs.c
index 624a2654370..28ffb1833a2 100644
--- a/sbin/newfs_lfs/lfs.c
+++ b/sbin/newfs_lfs/lfs.c
@@ -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;
-
- j = 1;
- for (segp = segtable + 1, i = 1; i < lfsp->lfs_nseg; i++, segp++) {
+ lfsp->lfs_idaddr = label_fsb + sb_fsb +
+ btofsb(lfsp, lfsp->lfs_sumsize);
+
+ 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;
diff --git a/sbin/newfs_lfs/misc.c b/sbin/newfs_lfs/misc.c
index 898791405fe..b3f27f037d0 100644
--- a/sbin/newfs_lfs/misc.c
+++ b/sbin/newfs_lfs/misc.c
@@ -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;
diff --git a/sbin/newfs_lfs/newfs.c b/sbin/newfs_lfs/newfs.c
index 6205537c795..eadbf7f2cb8 100644
--- a/sbin/newfs_lfs/newfs.c
+++ b/sbin/newfs_lfs/newfs.c
@@ -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);
}
diff --git a/sbin/newfs_lfs/newfs_lfs.8 b/sbin/newfs_lfs/newfs_lfs.8
index 5567fce2b32..f146b6c7fa9 100644
--- a/sbin/newfs_lfs/newfs_lfs.8
+++ b/sbin/newfs_lfs/newfs_lfs.8
@@ -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 ,
diff --git a/sys/ufs/lfs/TODO b/sys/ufs/lfs/TODO
index 4f7593ee4b4..c60e2b69c4a 100644
--- a/sys/ufs/lfs/TODO
+++ b/sys/ufs/lfs/TODO
@@ -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
diff --git a/sys/ufs/lfs/lfs.h b/sys/ufs/lfs/lfs.h
index f9d103437c5..8da9d720eb1 100644
--- a/sys/ufs/lfs/lfs.h
+++ b/sys/ufs/lfs/lfs.h
@@ -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 */
-
-#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;
+ 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 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 */
diff --git a/sys/ufs/lfs/lfs_alloc.c b/sys/ufs/lfs/lfs_alloc.c
index 1562679e67c..7b030efe39e 100644
--- a/sys/ufs/lfs/lfs_alloc.c
+++ b/sys/ufs/lfs/lfs_alloc.c
@@ -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);
}
diff --git a/sys/ufs/lfs/lfs_balloc.c b/sys/ufs/lfs/lfs_balloc.c
index 85bede076d7..5698f983644 100644
--- a/sys/ufs/lfs/lfs_balloc.c
+++ b/sys/ufs/lfs/lfs_balloc.c
@@ -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;
diff --git a/sys/ufs/lfs/lfs_bio.c b/sys/ufs/lfs/lfs_bio.c
index 413401b35c1..75d95554df0 100644
--- a/sys/ufs/lfs/lfs_bio.c
+++ b/sys/ufs/lfs/lfs_bio.c
@@ -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;
diff --git a/sys/ufs/lfs/lfs_cksum.c b/sys/ufs/lfs/lfs_cksum.c
index 4f0be883bc0..ea460f87803 100644
--- a/sys/ufs/lfs/lfs_cksum.c
+++ b/sys/ufs/lfs/lfs_cksum.c
@@ -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;
diff --git a/sys/ufs/lfs/lfs_debug.c b/sys/ufs/lfs/lfs_debug.c
index ca233082c7b..17268c1dc7b 100644
--- a/sys/ufs/lfs/lfs_debug.c
+++ b/sys/ufs/lfs/lfs_debug.c
@@ -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 */
diff --git a/sys/ufs/lfs/lfs_extern.h b/sys/ufs/lfs/lfs_extern.h
index 443934931e0..dd9bfcfe3a7 100644
--- a/sys/ufs/lfs/lfs_extern.h
+++ b/sys/ufs/lfs/lfs_extern.h
@@ -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 *));
-
-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 *));
+void lfs_unmark_vnode(struct vnode *);
+void lfs_itimes(struct inode *, struct timespec *, struct timespec *,
+ struct timespec *);
+
+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 *);
diff --git a/sys/ufs/lfs/lfs_inode.c b/sys/ufs/lfs/lfs_inode.c
index d7702e9869e..65e1d0596cf 100644
--- a/sys/ufs/lfs/lfs_inode.c
+++ b/sys/ufs/lfs/lfs_inode.c
@@ -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);
diff --git a/sys/ufs/lfs/lfs_segment.c b/sys/ufs/lfs/lfs_segment.c
index ffd1f6a057b..3f67278822f 100644
--- a/sys/ufs/lfs/lfs_segment.c
+++ b/sys/ufs/lfs/lfs_segment.c
@@ -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)
-
-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));
+ ((fs)->lfs_fsbpseg - ((fs)->lfs_offset - (fs)->lfs_curseg) > \
+ fragstofsb((fs), (fs)->lfs_frag))
+
+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,22 +888,26 @@ 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 =
(ino == LFS_IFILE_INUM && !(bp->b_flags & B_GATHERED));
@@ -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,22 +1162,28 @@ 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;
+ }
+ 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_create = time.tv_sec;
- ssp->ss_datasum = cksum(datap, (nblocks - 1) * sizeof(u_long));
+ 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
diff --git a/sys/ufs/lfs/lfs_subr.c b/sys/ufs/lfs/lfs_subr.c
index 505ccaf6269..f7d83144776 100644
--- a/sys/ufs/lfs/lfs_subr.c
+++ b/sys/ufs/lfs/lfs_subr.c
@@ -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.
diff --git a/sys/ufs/lfs/lfs_syscalls.c b/sys/ufs/lfs/lfs_syscalls.c
index 4fd33a803ee..b650e8956e2 100644
--- a/sys/ufs/lfs/lfs_syscalls.c
+++ b/sys/ufs/lfs/lfs_syscalls.c
@@ -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(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(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;
+ 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(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(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;
+ 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
diff --git a/sys/ufs/lfs/lfs_vfsops.c b/sys/ufs/lfs/lfs_vfsops.c
index 88bc550ccb5..45c809f68b6 100644
--- a/sys/ufs/lfs/lfs_vfsops.c
+++ b/sys/ufs/lfs/lfs_vfsops.c
@@ -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);
@@ -586,17 +590,35 @@ check_segsum(struct lfs *fs, daddr_t offset,
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;
+ }
+ }
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 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
+ 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);
+ printf("LFS roll forward phase 1: starting at offset 0x%x\n",
+ offset);
#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);
- }
+ 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;
- }
+ 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;
diff --git a/sys/ufs/lfs/lfs_vnops.c b/sys/ufs/lfs/lfs_vnops.c
index 1f48bd913b4..bd24cd0fa5f 100644
--- a/sys/ufs/lfs/lfs_vnops.c
+++ b/sys/ufs/lfs/lfs_vnops.c
@@ -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;
diff --git a/sys/ufs/ufs/ufs_readwrite.c b/sys/ufs/ufs/ufs_readwrite.c
index 9222905f4b3..b26971c935e 100644
--- a/sys/ufs/ufs/ufs_readwrite.c
+++ b/sys/ufs/ufs/ufs_readwrite.c
@@ -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);
diff --git a/usr.sbin/dumplfs/dumplfs.c b/usr.sbin/dumplfs/dumplfs.c
index 74673dbfd90..39b8f063566 100644
--- a/usr.sbin/dumplfs/dumplfs.c
+++ b/usr.sbin/dumplfs/dumplfs.c
@@ -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);
}
diff --git a/usr.sbin/dumplfs/extern.h b/usr.sbin/dumplfs/extern.h
index b6ea7a9b0b3..64fe5038b1b 100644
--- a/usr.sbin/dumplfs/extern.h
+++ b/usr.sbin/dumplfs/extern.h
@@ -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;
diff --git a/usr.sbin/dumplfs/misc.c b/usr.sbin/dumplfs/misc.c
index 325ffeb0da3..aa52b595dd2 100644
--- a/usr.sbin/dumplfs/misc.c
+++ b/usr.sbin/dumplfs/misc.c
@@ -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;