Support creating a file system to a regular file.

This commit is contained in:
pooka 2009-04-09 10:37:55 +00:00
parent 997f95acb2
commit 93636c41f9
2 changed files with 122 additions and 38 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: newfs_sysvbfs.8,v 1.3 2007/08/04 10:45:36 pooka Exp $
.\" $NetBSD: newfs_sysvbfs.8,v 1.4 2009/04/09 10:37:55 pooka Exp $
.\"
.\" Copyright (c) 1993
.\" The Regents of the University of California. All rights reserved.
@ -29,7 +29,7 @@
.\"
.\" @(#)newlfs.8 8.1 (Berkeley) 6/19/93
.\"
.Dd September 21, 2005
.Dd April 9, 2009
.Dt NEWFS_SYSVBFS 8
.Os
.Sh NAME
@ -37,17 +37,30 @@
.Nd construct a new System V Boot File System
.Sh SYNOPSIS
.Nm
.Op Fl FZ
.Op Fl s Ar sectors
.Ar special
.Sh DESCRIPTION
.Nm
builds a System V boot file system on the specified special
device basing its defaults on the information in the disk label.
Before running
builds a System V boot file system on the specified special.
If it is a device, the size information will be taken from the disk label and
before running
.Nm
the disk must be labeled using
.Xr disklabel 8 ;
the proper fstype is
.Dq SysVBFS .
Otherwise, the size must be specified on the command line.
.Pp
The following arguments are supported:
.Bl -tag -width Fl
.It Fl F
Create file system to a regular file.
.It Fl Z
Fill file with zeroes instead of creating a sparse file.
.It Fl s Ar sectors
Create file system with specified number of disk sectors.
.El
.Sh SEE ALSO
.Xr disklabel 5 ,
.Xr disktab 5 ,

View File

@ -1,4 +1,4 @@
/* $NetBSD: newfs_sysvbfs.c,v 1.3 2009/02/25 23:59:30 joerg Exp $ */
/* $NetBSD: newfs_sysvbfs.c,v 1.4 2009/04/09 10:37:55 pooka Exp $ */
/*-
* Copyright (c) 2004 The NetBSD Foundation, Inc.
@ -31,6 +31,7 @@
#include <sys/types.h>
#include <sys/param.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -54,42 +55,111 @@ main(int argc, char **argv)
struct disklabel d;
struct partition *p;
struct stat st;
uint32_t partsize;
int Fflag, Zflag;
int part;
int fd;
int fd, ch;
if (argc != 2)
if (argc < 2)
usage();
device = argv[1];
if ((fd = open(device, O_RDWR)) == -1) {
perror("open device");
exit(EXIT_FAILURE);
Fflag = Zflag = partsize = 0;
while ((ch = getopt(argc, argv, "Fs:Z")) != -1) {
switch (ch) {
case 'F':
Fflag = 1;
break;
case 's':
partsize = atoi(optarg);
break;
case 'Z':
Zflag = 1;
break;
default:
usage();
/*NOTREACHED*/
}
}
if (fstat(fd, &st) != 0) {
perror("device stat");
goto err_exit;
}
if (!S_ISCHR(st.st_mode)) {
fprintf(stderr, "WARNING: not a raw device.\n");
argc -= optind;
argv += optind;
if (argc != 1)
usage();
device = argv[0];
if (!Fflag) {
if ((fd = open(device, O_RDWR)) == -1) {
perror("open device");
exit(EXIT_FAILURE);
}
if (fstat(fd, &st) != 0) {
perror("device stat");
goto err_exit;
}
if (!S_ISCHR(st.st_mode)) {
fprintf(stderr, "WARNING: not a raw device.\n");
}
part = DISKPART(st.st_rdev);
if (ioctl(fd, DIOCGDINFO, &d) == -1) {
perror("disklabel");
goto err_exit;
}
p = &d.d_partitions[part];
printf("partition = %d\n", part);
printf("size=%d offset=%d fstype=%d secsize=%d\n",
p->p_size, p->p_offset, p->p_fstype, d.d_secsize);
if (p->p_fstype != FS_SYSVBFS) {
fprintf(stderr, "not a SysVBFS partition.\n");
goto err_exit;
}
partsize = p->p_size;
} else {
off_t filesize;
uint8_t zbuf[8192] = {0, };
if (partsize == 0) {
warnx("-F requires -s");
exit(EXIT_FAILURE);
}
filesize = partsize << BFS_BSHIFT;
fd = open(device, O_RDWR|O_CREAT|O_TRUNC, 0666);
if (fd == -1) {
perror("open file");
exit(EXIT_FAILURE);
}
if (Zflag) {
while (filesize > 0) {
size_t writenow = MIN(filesize, sizeof(zbuf));
if (write(fd, zbuf, writenow) != writenow) {
perror("zwrite");
exit(EXIT_FAILURE);
}
filesize -= writenow;
}
} else {
if (lseek(fd, filesize-1, SEEK_SET) == -1) {
perror("lseek");
exit(EXIT_FAILURE);
}
if (write(fd, zbuf, 1) != 1) {
perror("write");
exit(EXIT_FAILURE);
}
if (lseek(fd, 0, SEEK_SET) == -1) {
perror("lseek 2");
exit(EXIT_FAILURE);
}
}
}
part = DISKPART(st.st_rdev);
if (ioctl(fd, DIOCGDINFO, &d) == -1) {
perror("disklabel");
goto err_exit;
}
p = &d.d_partitions[part];
printf("partition = %d\n", part);
printf("size=%d offset=%d fstype=%d secsize=%d\n",
p->p_size, p->p_offset, p->p_fstype, d.d_secsize);
if (p->p_fstype != FS_SYSVBFS) {
fprintf(stderr, "not a SysVBFS partition.\n");
goto err_exit;
}
if (bfs_newfs(fd, p->p_size) != 0)
if (bfs_newfs(fd, partsize) != 0)
goto err_exit;
close(fd);
@ -108,7 +178,7 @@ bfs_newfs(int fd, uint32_t nsectors)
struct bfs_inode *inode = (void *)buf;
struct bfs_dirent *dirent = (void *)buf;
time_t t = time(0);
int err;
int error;
/* Super block */
memset(buf, 0, DEV_BSIZE);
@ -120,7 +190,7 @@ bfs_newfs(int fd, uint32_t nsectors)
bfs->compaction.from_backup = 0xffffffff;
bfs->compaction.to_backup = 0xffffffff;
if ((err = lseek(fd, 0, SEEK_SET)) == -1) {
if ((error = lseek(fd, 0, SEEK_SET)) == -1) {
perror("seek super block");
return -1;
}
@ -166,6 +236,7 @@ static void
usage(void)
{
(void)fprintf(stderr, "usage: %s special-device\n", getprogname());
(void)fprintf(stderr, "usage: %s [-FsZ] special-device\n",
getprogname());
exit(EXIT_FAILURE);
}