summaryrefslogtreecommitdiffstats
path: root/sbin/newfs/mkfs.c
diff options
context:
space:
mode:
authorjmallett <jmallett@FreeBSD.org>2003-01-29 22:52:27 +0000
committerjmallett <jmallett@FreeBSD.org>2003-01-29 22:52:27 +0000
commitdfe5702c03d4af01ff41b80583f44a490df92dc5 (patch)
treee1435925939de1c4aef43d7be5845967744a2958 /sbin/newfs/mkfs.c
parent98a90e953daedddb3bf314a0b2ff19df0afc7383 (diff)
downloadFreeBSD-src-dfe5702c03d4af01ff41b80583f44a490df92dc5.zip
FreeBSD-src-dfe5702c03d4af01ff41b80583f44a490df92dc5.tar.gz
Back out conversion to libufs, for now. It seems to cause problems.
Reported by: phk
Diffstat (limited to 'sbin/newfs/mkfs.c')
-rw-r--r--sbin/newfs/mkfs.c119
1 files changed, 99 insertions, 20 deletions
diff --git a/sbin/newfs/mkfs.c b/sbin/newfs/mkfs.c
index 968611b..4b78f9b 100644
--- a/sbin/newfs/mkfs.c
+++ b/sbin/newfs/mkfs.c
@@ -80,10 +80,18 @@ static const char rcsid[] =
#define UMASK 0755
#define POWEROF2(num) (((num) & ((num) - 1)) == 0)
-struct uufsd disk;
+static union {
+ struct fs fs;
+ char pad[SBLOCKSIZE];
+} fsun;
+#define sblock fsun.fs
static struct csum *fscs;
-#define sblock disk.d_fs
-#define acg disk.d_cg
+
+static union {
+ struct cg cg;
+ char pad[MAXBSIZE];
+} cgun;
+#define acg cgun.cg
union dinode {
struct ufs1_dinode dp1;
@@ -105,8 +113,10 @@ static void initcg(int, time_t);
static int isblock(struct fs *, unsigned char *, int);
static void iput(union dinode *, ino_t);
static int makedir(struct direct *, int);
+static void rdfs(ufs2_daddr_t, int, char *);
static void setblock(struct fs *, unsigned char *, int);
static void wtfs(ufs2_daddr_t, int, char *);
+static void wtfsflush(void);
void
mkfs(struct partition *pp, char *fsys)
@@ -118,12 +128,6 @@ mkfs(struct partition *pp, char *fsys)
int width;
char tmpbuf[100]; /* XXX this will break in about 2,500 years */
- /*
- * Our blocks == sector size, and the version of UFS we are using is
- * specified by Oflag.
- */
- disk.d_bsize = sectorsize;
- disk.d_ufs = Oflag;
if (Rflag)
utime = 1000000000;
else
@@ -483,13 +487,13 @@ mkfs(struct partition *pp, char *fsys)
sblock.fs_old_cstotal.cs_nifree = sblock.fs_cstotal.cs_nifree;
sblock.fs_old_cstotal.cs_nffree = sblock.fs_cstotal.cs_nffree;
}
- if (!Nflag)
- sbwrite(&disk, 1);
+ wtfs(sblock.fs_sblockloc / sectorsize, SBLOCKSIZE, (char *)&sblock);
for (i = 0; i < sblock.fs_cssize; i += sblock.fs_bsize)
wtfs(fsbtodb(&sblock, sblock.fs_csaddr + numfrags(&sblock, i)),
sblock.fs_cssize - i < sblock.fs_bsize ?
sblock.fs_cssize - i : sblock.fs_bsize,
((char *)fscs) + i);
+ wtfsflush();
/*
* Update information about this partion in pack
* label, to that it may be updated on disk.
@@ -765,8 +769,8 @@ alloc(int size, int mode)
{
int i, d, blkno, frag;
- bread(&disk, fsbtodb(&sblock, cgtod(&sblock, 0)), (char *)&acg,
- sblock.fs_cgsize);
+ rdfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize,
+ (char *)&acg);
if (acg.cg_magic != CG_MAGIC) {
printf("cg 0: bad magic number\n");
return (0);
@@ -802,7 +806,6 @@ goth:
for (i = frag; i < sblock.fs_frag; i++)
setbit(cg_blksfree(&acg), d + i);
}
- /* XXX cgwrite(&disk, 0)??? */
wtfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize,
(char *)&acg);
return ((ufs2_daddr_t)d);
@@ -818,8 +821,8 @@ iput(union dinode *ip, ino_t ino)
int c;
c = ino_to_cg(&sblock, ino);
- bread(&disk, fsbtodb(&sblock, cgtod(&sblock, 0)), (char *)&acg,
- sblock.fs_cgsize);
+ rdfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize,
+ (char *)&acg);
if (acg.cg_magic != CG_MAGIC) {
printf("cg 0: bad magic number\n");
exit(31);
@@ -835,25 +838,101 @@ iput(union dinode *ip, ino_t ino)
exit(32);
}
d = fsbtodb(&sblock, ino_to_fsba(&sblock, ino));
- bread(&disk, d, (char *)iobuf, sblock.fs_bsize);
+ rdfs(d, sblock.fs_bsize, (char *)iobuf);
if (sblock.fs_magic == FS_UFS1_MAGIC)
((struct ufs1_dinode *)iobuf)[ino_to_fsbo(&sblock, ino)] =
ip->dp1;
else
((struct ufs2_dinode *)iobuf)[ino_to_fsbo(&sblock, ino)] =
ip->dp2;
- wtfs(d, sblock.fs_size, (char *)iobuf);
+ wtfs(d, sblock.fs_bsize, (char *)iobuf);
+}
+
+/*
+ * read a block from the file system
+ */
+void
+rdfs(ufs2_daddr_t bno, int size, char *bf)
+{
+ int n;
+
+ wtfsflush();
+ if (lseek(fso, (off_t)bno * sectorsize, 0) < 0) {
+ printf("seek error: %ld\n", (long)bno);
+ err(33, "rdfs");
+ }
+ n = read(fso, bf, size);
+ if (n != size) {
+ printf("read error: %ld\n", (long)bno);
+ err(34, "rdfs");
+ }
+}
+
+#define WCSIZE (128 * 1024)
+ufs2_daddr_t wc_sect; /* units of sectorsize */
+int wc_end; /* bytes */
+static char wc[WCSIZE]; /* bytes */
+
+/*
+ * Flush dirty write behind buffer.
+ */
+static void
+wtfsflush()
+{
+ int n;
+ if (wc_end) {
+ if (lseek(fso, (off_t)wc_sect * sectorsize, SEEK_SET) < 0) {
+ printf("seek error: %ld\n", (long)wc_sect);
+ err(35, "wtfs - writecombine");
+ }
+ n = write(fso, wc, wc_end);
+ if (n != wc_end) {
+ printf("write error: %ld\n", (long)wc_sect);
+ err(36, "wtfs - writecombine");
+ }
+ wc_end = 0;
+ }
}
/*
- * possibly write to disk
+ * write a block to the file system
*/
static void
wtfs(ufs2_daddr_t bno, int size, char *bf)
{
+ int done, n;
+
if (Nflag)
return;
- bwrite(&disk, bno, bf, size);
+ done = 0;
+ if (wc_end == 0 && size <= WCSIZE) {
+ wc_sect = bno;
+ bcopy(bf, wc, size);
+ wc_end = size;
+ if (wc_end < WCSIZE)
+ return;
+ done = 1;
+ }
+ if ((off_t)wc_sect * sectorsize + wc_end == (off_t)bno * sectorsize &&
+ wc_end + size <= WCSIZE) {
+ bcopy(bf, wc + wc_end, size);
+ wc_end += size;
+ if (wc_end < WCSIZE)
+ return;
+ done = 1;
+ }
+ wtfsflush();
+ if (done)
+ return;
+ if (lseek(fso, (off_t)bno * sectorsize, SEEK_SET) < 0) {
+ printf("seek error: %ld\n", (long)bno);
+ err(35, "wtfs");
+ }
+ n = write(fso, bf, size);
+ if (n != size) {
+ printf("write error: %ld\n", (long)bno);
+ err(36, "wtfs");
+ }
}
/*
OpenPOWER on IntegriCloud