sblock.c revision 99222
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 99222 2002-07-01 18:19:20Z jmallett $"); 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 <fcntl.h> 4299193Sjmallett#include <stdio.h> 4399193Sjmallett#include <string.h> 4499193Sjmallett#include <unistd.h> 4599193Sjmallett 4699193Sjmallett#include <libufs.h> 4799193Sjmallett 4899193Sjmallettstatic int superblocks[] = SBLOCKSEARCH; 4999193Sjmallett 5099193Sjmallettint 5199193Sjmallettsbread(struct uufsd *disk) 5299193Sjmallett{ 5399193Sjmallett struct fs *fs; 5499193Sjmallett int sb, superblock; 5599193Sjmallett 5699193Sjmallett DEBUG(NULL); 5799193Sjmallett 5899193Sjmallett fs = &disk->d_fs; 5999193Sjmallett superblock = superblocks[0]; 6099193Sjmallett 6199193Sjmallett for (sb = 0; (superblock = superblocks[sb]) != -1; sb++) { 6299193Sjmallett if (bread(disk, superblock, disk->d_sb, SBLOCKSIZE) == -1) { 6399193Sjmallett DEBUG(NULL); 6499193Sjmallett return -1; 6599193Sjmallett } 6699193Sjmallett if (fs->fs_magic == FS_UFS1_MAGIC) 6799193Sjmallett disk->d_ufs = 1; 6899193Sjmallett if ((fs->fs_magic == FS_UFS2_MAGIC) && 6999193Sjmallett (fs->fs_sblockloc == numfrags(fs, superblock))) 7099193Sjmallett disk->d_ufs = 2; 7199193Sjmallett if ((fs->fs_bsize <= MAXBSIZE) && 7299193Sjmallett (fs->fs_bsize >= sizeof(*fs))) { 7399193Sjmallett if (disk->d_ufs) 7499193Sjmallett break; 7599193Sjmallett } 7699193Sjmallett disk->d_ufs = 0; 7799193Sjmallett } 7899193Sjmallett if (superblock == -1 || disk->d_ufs == 0) { 7999193Sjmallett /* 8099193Sjmallett * Other error cases will result in errno being set, here we 8199193Sjmallett * must set it to indicate no superblock could be found with 8299193Sjmallett * which to associate this disk/filesystem. 8399193Sjmallett */ 8499193Sjmallett DEBUG("no superblock found"); 8599193Sjmallett errno = ENOENT; 8699193Sjmallett return -1; 8799193Sjmallett } 8899193Sjmallett disk->d_bsize = fs->fs_fsize / fsbtodb(fs, 1); 8999193Sjmallett disk->d_sblock = superblock / disk->d_bsize; 9099193Sjmallett return 0; 9199193Sjmallett} 9299193Sjmallett 9399193Sjmallettint 9499193Sjmallettsbwrite(struct uufsd *disk, int all) 9599193Sjmallett{ 9699193Sjmallett struct fs *fs; 9799193Sjmallett int i, rofd; 9899193Sjmallett 9999222Sjmallett DEBUG(NULL); 10099222Sjmallett 10199193Sjmallett fs = &disk->d_fs; 10299193Sjmallett 10399193Sjmallett rofd = disk->d_fd; 10499193Sjmallett disk->d_fd = open(disk->d_name, O_WRONLY); 10599193Sjmallett if (disk->d_fd < 0) { 10699193Sjmallett DEBUG("open"); 10799193Sjmallett return -1; 10899193Sjmallett } 10999193Sjmallett if (bwrite(disk, disk->d_sblock, fs, SBLOCKSIZE) == -1) { 11099193Sjmallett DEBUG(NULL); 11199193Sjmallett return -1; 11299193Sjmallett } 11399193Sjmallett if (all) { 11499193Sjmallett for (i = 0; i < fs->fs_ncg; i++) 11599193Sjmallett if (bwrite(disk, fsbtodb(fs, cgsblock(fs, i)), 11699193Sjmallett fs, SBLOCKSIZE) == -1) { 11799193Sjmallett DEBUG(NULL); 11899193Sjmallett return -1; 11999193Sjmallett } 12099193Sjmallett } 12199193Sjmallett close(disk->d_fd); 12299193Sjmallett disk->d_fd = rofd; 12399193Sjmallett return 0; 12499193Sjmallett} 125