g_label_ufs.c revision 155797
1995Shx147065/*- 2995Shx147065 * Copyright (c) 2002, 2003 Gordon Tetlow 3995Shx147065 * All rights reserved. 4995Shx147065 * 5995Shx147065 * Redistribution and use in source and binary forms, with or without 6995Shx147065 * modification, are permitted provided that the following conditions 7995Shx147065 * are met: 8995Shx147065 * 1. Redistributions of source code must retain the above copyright 9995Shx147065 * notice, this list of conditions and the following disclaimer. 10995Shx147065 * 2. Redistributions in binary form must reproduce the above copyright 11995Shx147065 * notice, this list of conditions and the following disclaimer in the 12995Shx147065 * documentation and/or other materials provided with the distribution. 13995Shx147065 * 14995Shx147065 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15995Shx147065 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16995Shx147065 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17995Shx147065 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18995Shx147065 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19995Shx147065 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20995Shx147065 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21995Shx147065 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22995Shx147065 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23995Shx147065 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24995Shx147065 * SUCH DAMAGE. 25995Shx147065 */ 26995Shx147065 27995Shx147065#include <sys/cdefs.h> 28995Shx147065__FBSDID("$FreeBSD: head/sys/geom/label/g_label_ufs.c 155797 2006-02-18 03:00:49Z pjd $"); 29995Shx147065 30995Shx147065#include <sys/param.h> 31995Shx147065#include <sys/systm.h> 32995Shx147065#include <sys/kernel.h> 33995Shx147065#include <sys/malloc.h> 34995Shx147065 35995Shx147065#include <ufs/ufs/dinode.h> 36995Shx147065#include <ufs/ffs/fs.h> 37995Shx147065 38995Shx147065#include <geom/geom.h> 39995Shx147065#include <geom/label/g_label.h> 40995Shx147065 41995Shx147065#define G_LABEL_UFS_DIR "ufs" 42995Shx147065 43995Shx147065static const int superblocks[] = SBLOCKSEARCH; 44995Shx147065 45995Shx147065static void 46995Shx147065g_label_ufs_taste(struct g_consumer *cp, char *label, size_t size) 47995Shx147065{ 48995Shx147065 struct g_provider *pp; 49995Shx147065 int sb, superblock; 50995Shx147065 struct fs *fs; 51995Shx147065 52995Shx147065 g_topology_assert_not(); 53995Shx147065 pp = cp->provider; 54995Shx147065 label[0] = '\0'; 55995Shx147065 56995Shx147065 if (SBLOCKSIZE % cp->provider->sectorsize != 0) 57995Shx147065 return (0); 58995Shx147065 59995Shx147065 /* 60995Shx147065 * Walk through the standard places that superblocks hide and look 61995Shx147065 * for UFS magic. If we find magic, then check that the size in the 62995Shx147065 * superblock corresponds to the size of the underlying provider. 63995Shx147065 * Finally, look for a volume label and create an appropriate 64995Shx147065 * provider based on that. 65995Shx147065 */ 66995Shx147065 for (sb = 0; (superblock = superblocks[sb]) != -1; sb++) { 67 /* 68 * Take care not to issue an invalid I/O request. The offset of 69 * the superblock candidate must be multiples of the provider's 70 * sector size, otherwise an FFS can't exist on the provider 71 * anyway. 72 */ 73 if (superblock % cp->provider->sectorsize != 0) 74 continue; 75 76 fs = (struct fs *)g_read_data(cp, superblock, SBLOCKSIZE, NULL); 77 if (fs == NULL) 78 continue; 79 /* Check for magic and make sure things are the right size */ 80 if (fs->fs_magic == FS_UFS1_MAGIC) { 81 G_LABEL_DEBUG(1, "UFS1 file system detected on %s.", 82 pp->name); 83 if (fs->fs_old_size * fs->fs_fsize != 84 (int32_t)pp->mediasize) { 85 g_free(fs); 86 continue; 87 } 88 } else if (fs->fs_magic == FS_UFS2_MAGIC) { 89 G_LABEL_DEBUG(1, "UFS2 file system detected on %s.", 90 pp->name); 91 if (fs->fs_fsize <= 0 || 92 pp->mediasize / fs->fs_fsize != fs->fs_size) { 93 g_free(fs); 94 continue; 95 } 96 } else { 97 g_free(fs); 98 continue; 99 } 100 /* Check for volume label */ 101 if (fs->fs_volname[0] == '\0') { 102 g_free(fs); 103 continue; 104 } 105 strlcpy(label, fs->fs_volname, size); 106 g_free(fs); 107 break; 108 } 109} 110 111const struct g_label_desc g_label_ufs = { 112 .ld_taste = g_label_ufs_taste, 113 .ld_dir = G_LABEL_UFS_DIR 114}; 115