sblock.c revision 109766
11556Srgrimes/*
21556Srgrimes * Copyright (c) 2002 Juli Mallett.  All rights reserved.
31556Srgrimes *
41556Srgrimes * This software was written by Juli Mallett <jmallett@FreeBSD.org> for the
51556Srgrimes * FreeBSD project.  Redistribution and use in source and binary forms, with
61556Srgrimes * or without modification, are permitted provided that the following
71556Srgrimes * conditions are met:
81556Srgrimes *
91556Srgrimes * 1. Redistribution of source code must retain the above copyright notice,
101556Srgrimes *    this list of conditions and the following disclaimer.
111556Srgrimes * 2. Redistribution in binary form must reproduce the above copyright
121556Srgrimes *    notice, this list of conditions and the following disclaimer in the
131556Srgrimes *    documentation and/or other materials provided with the distribution.
141556Srgrimes *
151556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
161556Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
171556Srgrimes * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
181556Srgrimes * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
191556Srgrimes * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
201556Srgrimes * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
211556Srgrimes * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
221556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
231556Srgrimes * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
241556Srgrimes * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
251556Srgrimes * POSSIBILITY OF SUCH DAMAGE.
261556Srgrimes */
271556Srgrimes
281556Srgrimes#include <sys/cdefs.h>
291556Srgrimes__FBSDID("$FreeBSD: head/lib/libufs/sblock.c 109766 2003-01-23 23:58:22Z jmallett $");
301556Srgrimes
311556Srgrimes#include <sys/param.h>
321556Srgrimes#include <sys/mount.h>
331556Srgrimes#include <sys/disklabel.h>
341556Srgrimes#include <sys/stat.h>
3520413Ssteve
361556Srgrimes#include <ufs/ufs/ufsmount.h>
371556Srgrimes#include <ufs/ufs/dinode.h>
381556Srgrimes#include <ufs/ffs/fs.h>
391556Srgrimes
401556Srgrimes#include <errno.h>
4135773Scharnier#include <stdio.h>
4220413Ssteve#include <string.h>
4335773Scharnier#include <unistd.h>
4435773Scharnier
4535773Scharnier#include <libufs.h>
461556Srgrimes
471556Srgrimesstatic int superblocks[] = SBLOCKSEARCH;
481556Srgrimes
491556Srgrimesint
501556Srgrimessbread(struct uufsd *disk)
511556Srgrimes{
521556Srgrimes	struct fs *fs;
531556Srgrimes	int sb, superblock;
541556Srgrimes
551556Srgrimes	ERROR(disk, NULL);
5611738Sache
571556Srgrimes	fs = &disk->d_fs;
581556Srgrimes	superblock = superblocks[0];
5927874Sbrian
601556Srgrimes	for (sb = 0; (superblock = superblocks[sb]) != -1; sb++) {
611556Srgrimes		if (bread(disk, superblock, disk->d_sb, SBLOCKSIZE) == -1) {
621556Srgrimes			ERROR(disk, "non-existent or truncated superblock");
631556Srgrimes			return -1;
6428037Sbrian		}
651556Srgrimes		if (fs->fs_magic == FS_UFS1_MAGIC)
661556Srgrimes			disk->d_ufs = 1;
671556Srgrimes		if ((fs->fs_magic == FS_UFS2_MAGIC) &&
681556Srgrimes		    (fs->fs_sblockloc == superblock))
691556Srgrimes			disk->d_ufs = 2;
701556Srgrimes		if ((fs->fs_bsize <= MAXBSIZE) &&
711556Srgrimes		    (fs->fs_bsize >= sizeof(*fs))) {
721556Srgrimes			if (disk->d_ufs)
731556Srgrimes				break;
741556Srgrimes		}
751556Srgrimes		disk->d_ufs = 0;
761556Srgrimes	}
771556Srgrimes	if (superblock == -1 || disk->d_ufs == 0) {
7830073Sdanny		/*
791556Srgrimes		 * Other error cases will result in errno being set, here we
8028037Sbrian		 * must set it to indicate no superblock could be found with
815233Sbde		 * which to associate this disk/filesystem.
8227874Sbrian		 */
8327874Sbrian		ERROR(disk, "no usable known superblock found");
8427874Sbrian		errno = ENOENT;
851556Srgrimes		return -1;
8627874Sbrian	}
8728037Sbrian	disk->d_bsize = fs->fs_fsize / fsbtodb(fs, 1);
8811738Sache	disk->d_sblock = superblock / disk->d_bsize;
891556Srgrimes	return 0;
9030073Sdanny}
915233Sbde
9230073Sdannyint
931556Srgrimessbwrite(struct uufsd *disk, int all)
941556Srgrimes{
955233Sbde	struct fs *fs;
965233Sbde	int i;
975233Sbde
985233Sbde	ERROR(disk, NULL);
991556Srgrimes
10028037Sbrian	fs = &disk->d_fs;
10128037Sbrian
10228037Sbrian	if (bwrite(disk, disk->d_sblock, fs, SBLOCKSIZE) == -1) {
1031556Srgrimes		ERROR(disk, "failed to write superblock");
1041556Srgrimes		return -1;
1051556Srgrimes	}
1061556Srgrimes	if (all) {
1071556Srgrimes		for (i = 0; i < fs->fs_ncg; i++)
1081556Srgrimes			if (bwrite(disk, fsbtodb(fs, cgsblock(fs, i)),
1091556Srgrimes			    fs, SBLOCKSIZE) == -1) {
1101556Srgrimes				ERROR(disk, "failed to update a superblock");
1111556Srgrimes				return -1;
1125233Sbde			}
1135233Sbde	}
1145233Sbde	return 0;
1155233Sbde}
1165233Sbde