aboutsummaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
Diffstat (limited to 'sbin')
-rw-r--r--sbin/fsck_ffs/setup.c90
-rw-r--r--sbin/newfs/mkfs.c31
2 files changed, 83 insertions, 38 deletions
diff --git a/sbin/fsck_ffs/setup.c b/sbin/fsck_ffs/setup.c
index f97a3fed0f83..62e27053a2b8 100644
--- a/sbin/fsck_ffs/setup.c
+++ b/sbin/fsck_ffs/setup.c
@@ -36,6 +36,7 @@ static const char sccsid[] = "@(#)setup.c 8.10 (Berkeley) 5/9/95";
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/disk.h>
#include <sys/stat.h>
#define FSTYPENAMES
#include <sys/disklabel.h>
@@ -465,7 +466,9 @@ sblock_init(void)
static int
calcsb(char *dev, int devfd, struct fs *fs)
{
- struct fsrecovery fsr;
+ struct fsrecovery *fsr;
+ char *fsrbuf;
+ u_int secsize;
/*
* We need fragments-per-group and the partition-size.
@@ -475,32 +478,62 @@ calcsb(char *dev, int devfd, struct fs *fs)
* overwritten by a boot block, we fail. But usually they are
* there and we can use them.
*/
- if (blread(devfd, (char *)&fsr,
- (SBLOCK_UFS2 - sizeof(fsr)) / dev_bsize, sizeof(fsr)) ||
- fsr.fsr_magic != FS_UFS2_MAGIC)
+ if (ioctl(devfd, DIOCGSECTORSIZE, &secsize) == -1)
+ return (0);
+ fsrbuf = Malloc(secsize);
+ if (fsrbuf == NULL)
+ errx(EEXIT, "calcsb: cannot allocate recovery buffer");
+ if (blread(devfd, fsrbuf,
+ (SBLOCK_UFS2 - secsize) / dev_bsize, secsize) != 0)
+ return (0);
+ fsr = (struct fsrecovery *)&fsrbuf[secsize - sizeof *fsr];
+ if (fsr->fsr_magic != FS_UFS2_MAGIC)
return (0);
memset(fs, 0, sizeof(struct fs));
- fs->fs_fpg = fsr.fsr_fpg;
- fs->fs_fsbtodb = fsr.fsr_fsbtodb;
- fs->fs_sblkno = fsr.fsr_sblkno;
- fs->fs_magic = fsr.fsr_magic;
- fs->fs_ncg = fsr.fsr_ncg;
+ fs->fs_fpg = fsr->fsr_fpg;
+ fs->fs_fsbtodb = fsr->fsr_fsbtodb;
+ fs->fs_sblkno = fsr->fsr_sblkno;
+ fs->fs_magic = fsr->fsr_magic;
+ fs->fs_ncg = fsr->fsr_ncg;
+ free(fsrbuf);
return (1);
}
/*
* Check to see if recovery information exists.
+ * Return 1 if it exists or cannot be created.
+ * Return 0 if it does not exist and can be created.
*/
static int
chkrecovery(int devfd)
{
- struct fsrecovery fsr;
+ struct fsrecovery *fsr;
+ char *fsrbuf;
+ u_int secsize;
- if (blread(devfd, (char *)&fsr,
- (SBLOCK_UFS2 - sizeof(fsr)) / dev_bsize, sizeof(fsr)) ||
- fsr.fsr_magic != FS_UFS2_MAGIC)
- return (0);
- return (1);
+ /*
+ * Could not determine if backup material exists, so do not
+ * offer to create it.
+ */
+ if (ioctl(devfd, DIOCGSECTORSIZE, &secsize) == -1 ||
+ (fsrbuf = Malloc(secsize)) == NULL ||
+ blread(devfd, fsrbuf, (SBLOCK_UFS2 - secsize) / dev_bsize,
+ secsize) != 0)
+ return (1);
+ /*
+ * Recovery material has already been created, so do not
+ * need to create it again.
+ */
+ fsr = (struct fsrecovery *)&fsrbuf[secsize - sizeof *fsr];
+ if (fsr->fsr_magic == FS_UFS2_MAGIC) {
+ free(fsrbuf);
+ return (1);
+ }
+ /*
+ * Recovery material has not been created and can be if desired.
+ */
+ free(fsrbuf);
+ return (0);
}
/*
@@ -511,17 +544,24 @@ chkrecovery(int devfd)
static void
saverecovery(int readfd, int writefd)
{
- struct fsrecovery fsr;
+ struct fsrecovery *fsr;
+ char *fsrbuf;
+ u_int secsize;
if (sblock.fs_magic != FS_UFS2_MAGIC ||
- blread(readfd, (char *)&fsr,
- (SBLOCK_UFS2 - sizeof(fsr)) / dev_bsize, sizeof(fsr)))
+ ioctl(readfd, DIOCGSECTORSIZE, &secsize) == -1 ||
+ (fsrbuf = Malloc(secsize)) == NULL ||
+ blread(readfd, fsrbuf, (SBLOCK_UFS2 - secsize) / dev_bsize,
+ secsize) != 0) {
+ printf("RECOVERY DATA COULD NOT BE CREATED\n");
return;
- fsr.fsr_magic = sblock.fs_magic;
- fsr.fsr_fpg = sblock.fs_fpg;
- fsr.fsr_fsbtodb = sblock.fs_fsbtodb;
- fsr.fsr_sblkno = sblock.fs_sblkno;
- fsr.fsr_ncg = sblock.fs_ncg;
- blwrite(writefd, (char *)&fsr, (SBLOCK_UFS2 - sizeof(fsr)) / dev_bsize,
- sizeof(fsr));
+ }
+ fsr = (struct fsrecovery *)&fsrbuf[secsize - sizeof *fsr];
+ fsr->fsr_magic = sblock.fs_magic;
+ fsr->fsr_fpg = sblock.fs_fpg;
+ fsr->fsr_fsbtodb = sblock.fs_fsbtodb;
+ fsr->fsr_sblkno = sblock.fs_sblkno;
+ fsr->fsr_ncg = sblock.fs_ncg;
+ blwrite(writefd, fsrbuf, (SBLOCK_UFS2 - secsize) / secsize, secsize);
+ free(fsrbuf);
}
diff --git a/sbin/newfs/mkfs.c b/sbin/newfs/mkfs.c
index 3cbfad8c49d7..dbfab4536bd6 100644
--- a/sbin/newfs/mkfs.c
+++ b/sbin/newfs/mkfs.c
@@ -121,7 +121,8 @@ mkfs(struct partition *pp, char *fsys)
ino_t maxinum;
int minfragsperinode; /* minimum ratio of frags to inodes */
char tmpbuf[100]; /* XXX this will break in about 2,500 years */
- struct fsrecovery fsr;
+ struct fsrecovery *fsr;
+ char *fsrbuf;
union {
struct fs fdummy;
char cdummy[SBLOCKSIZE];
@@ -442,6 +443,8 @@ restart:
sblock.fs_sbsize = fragroundup(&sblock, sizeof(struct fs));
if (sblock.fs_sbsize > SBLOCKSIZE)
sblock.fs_sbsize = SBLOCKSIZE;
+ if (sblock.fs_sbsize < realsectorsize)
+ sblock.fs_sbsize = realsectorsize;
sblock.fs_minfree = minfree;
if (metaspace > 0 && metaspace < sblock.fs_fpg / 2)
sblock.fs_metaspace = blknum(&sblock, metaspace);
@@ -514,7 +517,7 @@ restart:
/*
* Wipe out old UFS1 superblock(s) if necessary.
*/
- if (!Nflag && Oflag != 1) {
+ if (!Nflag && Oflag != 1 && realsectorsize <= SBLOCK_UFS1) {
i = bread(&disk, part_ofs + SBLOCK_UFS1 / disk.d_bsize, chdummy, SBLOCKSIZE);
if (i == -1)
err(1, "can't read old UFS1 superblock: %s", disk.d_error);
@@ -623,18 +626,20 @@ restart:
* The recovery information only works for UFS2 filesystems.
*/
if (sblock.fs_magic == FS_UFS2_MAGIC) {
- i = bread(&disk,
- part_ofs + (SBLOCK_UFS2 - sizeof(fsr)) / disk.d_bsize,
- (char *)&fsr, sizeof(fsr));
- if (i == -1)
+ if ((fsrbuf = malloc(realsectorsize)) == NULL || bread(&disk,
+ part_ofs + (SBLOCK_UFS2 - realsectorsize) / disk.d_bsize,
+ fsrbuf, realsectorsize) == -1)
err(1, "can't read recovery area: %s", disk.d_error);
- fsr.fsr_magic = sblock.fs_magic;
- fsr.fsr_fpg = sblock.fs_fpg;
- fsr.fsr_fsbtodb = sblock.fs_fsbtodb;
- fsr.fsr_sblkno = sblock.fs_sblkno;
- fsr.fsr_ncg = sblock.fs_ncg;
- wtfs((SBLOCK_UFS2 - sizeof(fsr)) / disk.d_bsize, sizeof(fsr),
- (char *)&fsr);
+ fsr =
+ (struct fsrecovery *)&fsrbuf[realsectorsize - sizeof *fsr];
+ fsr->fsr_magic = sblock.fs_magic;
+ fsr->fsr_fpg = sblock.fs_fpg;
+ fsr->fsr_fsbtodb = sblock.fs_fsbtodb;
+ fsr->fsr_sblkno = sblock.fs_sblkno;
+ fsr->fsr_ncg = sblock.fs_ncg;
+ wtfs((SBLOCK_UFS2 - realsectorsize) / disk.d_bsize,
+ realsectorsize, fsrbuf);
+ free(fsrbuf);
}
/*
* Update information about this partition in pack