sblock.c revision 256281
1154133Sharti/* 2154133Sharti * Copyright (c) 2002 Juli Mallett. All rights reserved. 3154133Sharti * 4154133Sharti * This software was written by Juli Mallett <jmallett@FreeBSD.org> for the 5154133Sharti * FreeBSD project. Redistribution and use in source and binary forms, with 6154133Sharti * or without modification, are permitted provided that the following 7154133Sharti * conditions are met: 8154133Sharti * 9154133Sharti * 1. Redistribution of source code must retain the above copyright notice, 10154133Sharti * this list of conditions and the following disclaimer. 11154133Sharti * 2. Redistribution in binary form must reproduce the above copyright 12154133Sharti * notice, this list of conditions and the following disclaimer in the 13154133Sharti * documentation and/or other materials provided with the distribution. 14154133Sharti * 15154133Sharti * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16154133Sharti * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17154133Sharti * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18154133Sharti * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19154133Sharti * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20154133Sharti * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21154133Sharti * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22154133Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23154133Sharti * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 24154133Sharti * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25154133Sharti * POSSIBILITY OF SUCH DAMAGE. 26154133Sharti */ 27154133Sharti 28154133Sharti#include <sys/cdefs.h> 29154133Sharti__FBSDID("$FreeBSD: stable/10/lib/libufs/sblock.c 207141 2010-04-24 07:05:35Z jeff $"); 30154133Sharti 31154133Sharti#include <sys/param.h> 32154133Sharti#include <sys/mount.h> 33154133Sharti#include <sys/disklabel.h> 34154133Sharti#include <sys/stat.h> 35154133Sharti 36154133Sharti#include <ufs/ufs/ufsmount.h> 37154133Sharti#include <ufs/ufs/dinode.h> 38154133Sharti#include <ufs/ffs/fs.h> 39154133Sharti 40154133Sharti#include <errno.h> 41154133Sharti#include <stdio.h> 42154133Sharti#include <string.h> 43154133Sharti#include <stdlib.h> 44154133Sharti#include <unistd.h> 45154133Sharti 46160341Sharti#include <libufs.h> 47154133Sharti 48154133Shartistatic int superblocks[] = SBLOCKSEARCH; 49154133Sharti 50154133Shartiint 51154133Shartisbread(struct uufsd *disk) 52160341Sharti{ 53160341Sharti uint8_t block[MAXBSIZE]; 54160341Sharti struct fs *fs; 55160341Sharti int sb, superblock; 56160341Sharti int i, size, blks; 57160341Sharti uint8_t *space; 58160341Sharti 59154133Sharti ERROR(disk, NULL); 60154133Sharti 61154133Sharti fs = &disk->d_fs; 62154133Sharti superblock = superblocks[0]; 63154133Sharti 64154133Sharti for (sb = 0; (superblock = superblocks[sb]) != -1; sb++) { 65154133Sharti if (bread(disk, superblock, disk->d_sb, SBLOCKSIZE) == -1) { 66154133Sharti ERROR(disk, "non-existent or truncated superblock"); 67154133Sharti return (-1); 68154133Sharti } 69154133Sharti if (fs->fs_magic == FS_UFS1_MAGIC) 70154133Sharti disk->d_ufs = 1; 71154133Sharti if (fs->fs_magic == FS_UFS2_MAGIC && 72154133Sharti fs->fs_sblockloc == superblock) 73154133Sharti disk->d_ufs = 2; 74154133Sharti if (fs->fs_bsize <= MAXBSIZE && 75154133Sharti (size_t)fs->fs_bsize >= sizeof(*fs)) { 76154133Sharti if (disk->d_ufs) 77154133Sharti break; 78154133Sharti } 79154133Sharti disk->d_ufs = 0; 80154133Sharti } 81154133Sharti if (superblock == -1 || disk->d_ufs == 0) { 82154133Sharti /* 83154133Sharti * Other error cases will result in errno being set, here we 84154133Sharti * must set it to indicate no superblock could be found with 85154133Sharti * which to associate this disk/filesystem. 86154133Sharti */ 87154133Sharti ERROR(disk, "no usable known superblock found"); 88154133Sharti errno = ENOENT; 89154133Sharti return (-1); 90154133Sharti } 91154133Sharti disk->d_bsize = fs->fs_fsize / fsbtodb(fs, 1); 92154133Sharti disk->d_sblock = superblock / disk->d_bsize; 93154133Sharti /* 94154133Sharti * Read in the superblock summary information. 95154133Sharti */ 96154133Sharti size = fs->fs_cssize; 97154133Sharti blks = howmany(size, fs->fs_fsize); 98154133Sharti size += fs->fs_ncg * sizeof(int32_t); 99154133Sharti space = malloc(size); 100154133Sharti if (space == NULL) { 101154133Sharti ERROR(disk, "failed to allocate space for summary information"); 102154133Sharti return (-1); 103160341Sharti } 104160341Sharti fs->fs_csp = (struct csum *)space; 105160341Sharti for (i = 0; i < blks; i += fs->fs_frag) { 106160341Sharti size = fs->fs_bsize; 107154133Sharti if (i + fs->fs_frag > blks) 108154133Sharti size = (blks - i) * fs->fs_fsize; 109154133Sharti if (bread(disk, fsbtodb(fs, fs->fs_csaddr + i), block, size) 110154133Sharti == -1) { 111154133Sharti ERROR(disk, "Failed to read sb summary information"); 112154133Sharti free(fs->fs_csp); 113160341Sharti return (-1); 114160341Sharti } 115160341Sharti bcopy(block, space, size); 116154133Sharti space += size; 117154133Sharti } 118154133Sharti fs->fs_maxcluster = (uint32_t *)space; 119154133Sharti disk->d_sbcsum = fs->fs_csp; 120154133Sharti 121160341Sharti return (0); 122154133Sharti} 123154133Sharti 124154133Shartiint 125154133Shartisbwrite(struct uufsd *disk, int all) 126154133Sharti{ 127154133Sharti struct fs *fs; 128160341Sharti int blks, size; 129160341Sharti uint8_t *space; 130160341Sharti unsigned i; 131160341Sharti 132160341Sharti ERROR(disk, NULL); 133160341Sharti 134160341Sharti fs = &disk->d_fs; 135160341Sharti 136154133Sharti if (!disk->d_sblock) { 137154133Sharti disk->d_sblock = disk->d_fs.fs_sblockloc / disk->d_bsize; 138154133Sharti } 139154133Sharti 140154133Sharti if (bwrite(disk, disk->d_sblock, fs, SBLOCKSIZE) == -1) { 141154133Sharti ERROR(disk, "failed to write superblock"); 142154133Sharti return (-1); 143160341Sharti } 144160341Sharti /* 145160341Sharti * Write superblock summary information. 146160341Sharti */ 147160341Sharti blks = howmany(fs->fs_cssize, fs->fs_fsize); 148160341Sharti space = (uint8_t *)disk->d_sbcsum; 149160341Sharti for (i = 0; i < blks; i += fs->fs_frag) { 150160341Sharti size = fs->fs_bsize; 151160341Sharti if (i + fs->fs_frag > blks) 152160341Sharti size = (blks - i) * fs->fs_fsize; 153160341Sharti if (bwrite(disk, fsbtodb(fs, fs->fs_csaddr + i), space, size) 154160341Sharti == -1) { 155160341Sharti ERROR(disk, "Failed to write sb summary information"); 156160341Sharti return (-1); 157160341Sharti } 158160341Sharti space += size; 159160341Sharti } 160160341Sharti if (all) { 161160341Sharti for (i = 0; i < fs->fs_ncg; i++) 162160341Sharti if (bwrite(disk, fsbtodb(fs, cgsblock(fs, i)), 163160341Sharti fs, SBLOCKSIZE) == -1) { 164160341Sharti ERROR(disk, "failed to update a superblock"); 165160341Sharti return (-1); 166154133Sharti } 167154133Sharti } 168160341Sharti return (0); 169160341Sharti} 170154133Sharti