sblock.c revision 203782
199193Sjmallett/* 299193Sjmallett * Copyright (c) 2002 Juli Mallett. All rights reserved. 399193Sjmallett * 499193Sjmallett * This software was written by Juli Mallett <jmallett@FreeBSD.org> for the 599193Sjmallett * FreeBSD project. Redistribution and use in source and binary forms, with 699193Sjmallett * or without modification, are permitted provided that the following 799193Sjmallett * conditions are met: 899193Sjmallett * 999193Sjmallett * 1. Redistribution of source code must retain the above copyright notice, 1099193Sjmallett * this list of conditions and the following disclaimer. 1199193Sjmallett * 2. Redistribution in binary form must reproduce the above copyright 1299193Sjmallett * notice, this list of conditions and the following disclaimer in the 1399193Sjmallett * documentation and/or other materials provided with the distribution. 1499193Sjmallett * 1599193Sjmallett * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1699193Sjmallett * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 1799193Sjmallett * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 1899193Sjmallett * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 1999193Sjmallett * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 2099193Sjmallett * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 2199193Sjmallett * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2299193Sjmallett * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 2399193Sjmallett * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 2499193Sjmallett * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2599193Sjmallett * POSSIBILITY OF SUCH DAMAGE. 2699193Sjmallett */ 2799193Sjmallett 2899193Sjmallett#include <sys/cdefs.h> 2999193Sjmallett__FBSDID("$FreeBSD: head/lib/libufs/sblock.c 203782 2010-02-11 17:30:30Z imp $"); 3099193Sjmallett 3199193Sjmallett#include <sys/param.h> 3299193Sjmallett#include <sys/mount.h> 3399193Sjmallett#include <sys/disklabel.h> 3499193Sjmallett#include <sys/stat.h> 3599193Sjmallett 3699193Sjmallett#include <ufs/ufs/ufsmount.h> 3799193Sjmallett#include <ufs/ufs/dinode.h> 3899193Sjmallett#include <ufs/ffs/fs.h> 3999193Sjmallett 4099193Sjmallett#include <errno.h> 4199193Sjmallett#include <stdio.h> 4299193Sjmallett#include <string.h> 4399193Sjmallett#include <unistd.h> 4499193Sjmallett 4599193Sjmallett#include <libufs.h> 4699193Sjmallett 4799193Sjmallettstatic int superblocks[] = SBLOCKSEARCH; 4899193Sjmallett 4999193Sjmallettint 5099193Sjmallettsbread(struct uufsd *disk) 5199193Sjmallett{ 5299193Sjmallett struct fs *fs; 5399193Sjmallett int sb, superblock; 5499193Sjmallett 55109462Sjmallett ERROR(disk, NULL); 5699193Sjmallett 5799193Sjmallett fs = &disk->d_fs; 5899193Sjmallett superblock = superblocks[0]; 5999193Sjmallett 6099193Sjmallett for (sb = 0; (superblock = superblocks[sb]) != -1; sb++) { 6199193Sjmallett if (bread(disk, superblock, disk->d_sb, SBLOCKSIZE) == -1) { 62109462Sjmallett ERROR(disk, "non-existent or truncated superblock"); 63116084Sjmallett return (-1); 6499193Sjmallett } 6599193Sjmallett if (fs->fs_magic == FS_UFS1_MAGIC) 6699193Sjmallett disk->d_ufs = 1; 67111111Sjmallett if (fs->fs_magic == FS_UFS2_MAGIC && 68111111Sjmallett fs->fs_sblockloc == superblock) 6999193Sjmallett disk->d_ufs = 2; 70111111Sjmallett if (fs->fs_bsize <= MAXBSIZE && 71111111Sjmallett (size_t)fs->fs_bsize >= sizeof(*fs)) { 7299193Sjmallett if (disk->d_ufs) 7399193Sjmallett break; 7499193Sjmallett } 7599193Sjmallett disk->d_ufs = 0; 7699193Sjmallett } 7799193Sjmallett if (superblock == -1 || disk->d_ufs == 0) { 7899193Sjmallett /* 7999193Sjmallett * Other error cases will result in errno being set, here we 8099193Sjmallett * must set it to indicate no superblock could be found with 8199193Sjmallett * which to associate this disk/filesystem. 8299193Sjmallett */ 83109462Sjmallett ERROR(disk, "no usable known superblock found"); 8499193Sjmallett errno = ENOENT; 85116084Sjmallett return (-1); 8699193Sjmallett } 8799193Sjmallett disk->d_bsize = fs->fs_fsize / fsbtodb(fs, 1); 8899193Sjmallett disk->d_sblock = superblock / disk->d_bsize; 89116084Sjmallett return (0); 9099193Sjmallett} 9199193Sjmallett 9299193Sjmallettint 9399193Sjmallettsbwrite(struct uufsd *disk, int all) 9499193Sjmallett{ 9599193Sjmallett struct fs *fs; 96203782Simp unsigned i; 9799193Sjmallett 98109462Sjmallett ERROR(disk, NULL); 9999222Sjmallett 10099193Sjmallett fs = &disk->d_fs; 10199193Sjmallett 102109913Sjmallett if (!disk->d_sblock) { 103109913Sjmallett disk->d_sblock = disk->d_fs.fs_sblockloc / disk->d_bsize; 104109913Sjmallett } 105109913Sjmallett 10699193Sjmallett if (bwrite(disk, disk->d_sblock, fs, SBLOCKSIZE) == -1) { 107109462Sjmallett ERROR(disk, "failed to write superblock"); 108116084Sjmallett return (-1); 10999193Sjmallett } 11099193Sjmallett if (all) { 11199193Sjmallett for (i = 0; i < fs->fs_ncg; i++) 11299193Sjmallett if (bwrite(disk, fsbtodb(fs, cgsblock(fs, i)), 11399193Sjmallett fs, SBLOCKSIZE) == -1) { 114109462Sjmallett ERROR(disk, "failed to update a superblock"); 115116084Sjmallett return (-1); 11699193Sjmallett } 11799193Sjmallett } 118116084Sjmallett return (0); 11999193Sjmallett} 120