sblock.c revision 116084
118334Speter/*
2132718Skan * Copyright (c) 2002 Juli Mallett.  All rights reserved.
3169689Skan *
4169689Skan * This software was written by Juli Mallett <jmallett@FreeBSD.org> for the
518334Speter * FreeBSD project.  Redistribution and use in source and binary forms, with
690075Sobrien * or without modification, are permitted provided that the following
718334Speter * conditions are met:
890075Sobrien *
990075Sobrien * 1. Redistribution of source code must retain the above copyright notice,
1090075Sobrien *    this list of conditions and the following disclaimer.
1190075Sobrien * 2. Redistribution in binary form must reproduce the above copyright
1218334Speter *    notice, this list of conditions and the following disclaimer in the
1390075Sobrien *    documentation and/or other materials provided with the distribution.
1490075Sobrien *
1590075Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1690075Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1718334Speter * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1818334Speter * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
1990075Sobrien * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20169689Skan * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21169689Skan * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2218334Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
2318334Speter * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2418334Speter * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2518334Speter * POSSIBILITY OF SUCH DAMAGE.
2618334Speter */
2718334Speter
2818334Speter#include <sys/cdefs.h>
2918334Speter__FBSDID("$FreeBSD: head/lib/libufs/sblock.c 116084 2003-06-09 09:32:29Z jmallett $");
3018334Speter
3150397Sobrien#include <sys/param.h>
3250397Sobrien#include <sys/mount.h>
3318334Speter#include <sys/disklabel.h>
3418334Speter#include <sys/stat.h>
3518334Speter
3618334Speter#include <ufs/ufs/ufsmount.h>
3718334Speter#include <ufs/ufs/dinode.h>
3818334Speter#include <ufs/ffs/fs.h>
3918334Speter
4018334Speter#include <errno.h>
4150397Sobrien#include <stdio.h>
4250397Sobrien#include <string.h>
43169689Skan#include <unistd.h>
44169689Skan
45169689Skan#include <libufs.h>
4650397Sobrien
4750397Sobrienstatic int superblocks[] = SBLOCKSEARCH;
4850397Sobrien
49132718Skanint
50132718Skansbread(struct uufsd *disk)
5118334Speter{
5218334Speter	struct fs *fs;
53117395Skan	int sb, superblock;
5452284Sobrien
5590075Sobrien	ERROR(disk, NULL);
5690075Sobrien
5750397Sobrien	fs = &disk->d_fs;
58169689Skan	superblock = superblocks[0];
5990075Sobrien
6090075Sobrien	for (sb = 0; (superblock = superblocks[sb]) != -1; sb++) {
61117395Skan		if (bread(disk, superblock, disk->d_sb, SBLOCKSIZE) == -1) {
62132718Skan			ERROR(disk, "non-existent or truncated superblock");
6318334Speter			return (-1);
64169689Skan		}
65169689Skan		if (fs->fs_magic == FS_UFS1_MAGIC)
66169689Skan			disk->d_ufs = 1;
67169689Skan		if (fs->fs_magic == FS_UFS2_MAGIC &&
68169689Skan		    fs->fs_sblockloc == superblock)
69169689Skan			disk->d_ufs = 2;
70169689Skan		if (fs->fs_bsize <= MAXBSIZE &&
71169689Skan		    (size_t)fs->fs_bsize >= sizeof(*fs)) {
72169689Skan			if (disk->d_ufs)
73169689Skan				break;
74169689Skan		}
75169689Skan		disk->d_ufs = 0;
76169689Skan	}
77169689Skan	if (superblock == -1 || disk->d_ufs == 0) {
78169689Skan		/*
79169689Skan		 * Other error cases will result in errno being set, here we
80169689Skan		 * must set it to indicate no superblock could be found with
81169689Skan		 * which to associate this disk/filesystem.
82169689Skan		 */
83169689Skan		ERROR(disk, "no usable known superblock found");
84169689Skan		errno = ENOENT;
85169689Skan		return (-1);
86169689Skan	}
87169689Skan	disk->d_bsize = fs->fs_fsize / fsbtodb(fs, 1);
88169689Skan	disk->d_sblock = superblock / disk->d_bsize;
89169689Skan	return (0);
90132718Skan}
91132718Skan
92132718Skanint
93132718Skansbwrite(struct uufsd *disk, int all)
94132718Skan{
95132718Skan	struct fs *fs;
96132718Skan	int i;
97132718Skan
98169689Skan	ERROR(disk, NULL);
99169689Skan
100169689Skan	fs = &disk->d_fs;
101169689Skan
102132718Skan	if (!disk->d_sblock) {
103132718Skan		disk->d_sblock = disk->d_fs.fs_sblockloc / disk->d_bsize;
104132718Skan	}
105132718Skan
106132718Skan	if (bwrite(disk, disk->d_sblock, fs, SBLOCKSIZE) == -1) {
107132718Skan		ERROR(disk, "failed to write superblock");
108132718Skan		return (-1);
109132718Skan	}
110132718Skan	if (all) {
111132718Skan		for (i = 0; i < fs->fs_ncg; i++)
112132718Skan			if (bwrite(disk, fsbtodb(fs, cgsblock(fs, i)),
113132718Skan			    fs, SBLOCKSIZE) == -1) {
114132718Skan				ERROR(disk, "failed to update a superblock");
115132718Skan				return (-1);
116132718Skan			}
117169689Skan	}
118169689Skan	return (0);
119169689Skan}
120132718Skan