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