type.c revision 109755
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/type.c 109755 2003-01-23 21:32:56Z 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> 42109506Sjmallett#include <fstab.h> 43109506Sjmallett#include <paths.h> 4499193Sjmallett#include <stdio.h> 4599193Sjmallett#include <stdlib.h> 4699193Sjmallett#include <string.h> 4799193Sjmallett#include <unistd.h> 4899193Sjmallett 4999193Sjmallett#include <libufs.h> 5099193Sjmallett 51109506Sjmallett/* Internally, track the 'name' value, it's ours. */ 52109506Sjmallett#define MINE_NAME 0x01 53109506Sjmallett 5499193Sjmallettstruct uufsd * 5599193Sjmallettufs_disk_ctor(const char *name) 5699193Sjmallett{ 5799193Sjmallett struct uufsd *new; 5899193Sjmallett 59109462Sjmallett new = NULL; 6099193Sjmallett 61109462Sjmallett ERROR(new, NULL); 62109462Sjmallett 6399193Sjmallett new = malloc(sizeof(*new)); 6499193Sjmallett if (new == NULL) { 65109462Sjmallett ERROR(new, "unable to allocate memory for disk"); 6699193Sjmallett return NULL; 6799193Sjmallett } 6899193Sjmallett 6999193Sjmallett if (ufs_disk_fillout(new, name) == -1) { 70109462Sjmallett ERROR(new, "could not fill out disk"); 7199193Sjmallett free(new); 7299193Sjmallett return NULL; 7399193Sjmallett } 7499193Sjmallett 7599193Sjmallett return new; 7699193Sjmallett} 7799193Sjmallett 7899193Sjmallettvoid 79109462Sjmallettufs_disk_dtor(struct uufsd **diskp) 8099193Sjmallett{ 81109462Sjmallett struct uufsd *disk; 82109462Sjmallett 83109462Sjmallett if (diskp != NULL) 84109462Sjmallett disk = *diskp; 85109462Sjmallett else 86109462Sjmallett return; 87109462Sjmallett 88109462Sjmallett ERROR(disk, NULL); 89109462Sjmallett 90109462Sjmallett ufs_disk_close(disk); 91109462Sjmallett free(disk); 92109462Sjmallett *diskp = NULL; 9399193Sjmallett} 9499193Sjmallett 9599193Sjmallettint 9699193Sjmallettufs_disk_close(struct uufsd *disk) 9799193Sjmallett{ 98109462Sjmallett ERROR(disk, NULL); 9999193Sjmallett close(disk->d_fd); 10099193Sjmallett if (disk->d_inoblock != NULL) { 10199193Sjmallett free(disk->d_inoblock); 10299193Sjmallett disk->d_inoblock = NULL; 10399193Sjmallett } 104109506Sjmallett if (disk->d_mine & MINE_NAME) { 105109506Sjmallett free((char *)(uintptr_t)disk->d_name); 106109506Sjmallett disk->d_name = NULL; 107109506Sjmallett } 10899193Sjmallett return 0; 10999193Sjmallett} 11099193Sjmallett 11199193Sjmallettint 11299193Sjmallettufs_disk_fillout(struct uufsd *disk, const char *name) 11399193Sjmallett{ 114109755Sjmallett if (ufs_disk_fillout_blank(disk, name) == -1) { 115109755Sjmallett return -1; 116109755Sjmallett } 117109755Sjmallett if (sbread(disk) == -1) { 118109755Sjmallett ERROR(disk, "could not read superblock to fill out disk"); 119109755Sjmallett return -1; 120109755Sjmallett } 121109755Sjmallett} 122109755Sjmallett 123109755Sjmallettint 124109755Sjmallettufs_disk_fillout_blank(struct uufsd *disk, const char *name) 125109755Sjmallett{ 126109506Sjmallett struct stat st; 127109506Sjmallett struct fstab *fs; 128109506Sjmallett const char *oname; 129109506Sjmallett char dev[MAXPATHLEN]; 13099193Sjmallett int fd; 13199193Sjmallett 132109462Sjmallett ERROR(disk, NULL); 13399222Sjmallett 134109506Sjmallett oname = name; 135109506Sjmallett fs = getfsfile(name); 136109506Sjmallett if (fs != NULL) 137109506Sjmallett name = fs->fs_spec; 138109506Sjmallettagain: if (stat(name, &st) < 0) { 139109506Sjmallett if (*name != '/') { 140109506Sjmallett if (*name == 'r') 141109506Sjmallett name++; 142109506Sjmallett snprintf(dev, sizeof(dev), "%s%s", _PATH_DEV, name); 143109506Sjmallett name = dev; 144109506Sjmallett goto again; 145109506Sjmallett } 146109506Sjmallett ERROR(disk, "could not find special device"); 147109506Sjmallett return -1; 148109506Sjmallett } 14999193Sjmallett fd = open(name, O_RDONLY); 15099193Sjmallett if (fd == -1) { 151109506Sjmallett ERROR(disk, "could not open special device"); 15299193Sjmallett return -1; 15399193Sjmallett } 15499193Sjmallett 15599193Sjmallett disk->d_bsize = 1; 156109509Sjmallett disk->d_ccg = 0; 15799193Sjmallett disk->d_fd = fd; 15899193Sjmallett disk->d_inoblock = NULL; 15999823Sjmallett disk->d_inomin = 0; 16099823Sjmallett disk->d_inomax = 0; 161109518Sjmallett disk->d_lcg = 0; 162109506Sjmallett disk->d_mine = 0; 163101687Sjmallett disk->d_ufs = 0; 164105737Sjmallett disk->d_error = NULL; 16599193Sjmallett 166109506Sjmallett if (oname != name) { 167109506Sjmallett name = strdup(name); 168109506Sjmallett if (name == NULL) { 169109506Sjmallett ERROR(disk, "could not allocate memory for disk name"); 170109506Sjmallett return -1; 171109506Sjmallett } 172109506Sjmallett disk->d_mine |= MINE_NAME; 173109506Sjmallett } 174109506Sjmallett disk->d_name = name; 175109506Sjmallett 17699193Sjmallett return 0; 17799193Sjmallett} 178