Index: geom_vol_ffs.c =================================================================== RCS file: /usr/ncvs/src/sys/geom/geom_vol_ffs.c,v retrieving revision 1.8 diff -u -r1.8 geom_vol_ffs.c --- geom_vol_ffs.c 2 May 2003 08:21:02 -0000 1.8 +++ geom_vol_ffs.c 9 Jun 2003 19:30:40 -0000 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -45,6 +46,16 @@ static int superblocks[] = SBLOCKSEARCH; +#define LABELSIZE (148 + 16 * MAXPARTITIONS) +struct g_bsd_softc { + off_t labeloffset; + off_t mbroffset; + off_t rawoffset; + struct disklabel ondisk; + u_char label[LABELSIZE]; + u_char labelsum[16]; +}; + struct g_vol_ffs_softc { char * vol; }; @@ -59,10 +70,11 @@ g_vol_ffs_taste(struct g_class *mp, struct g_provider *pp, int flags) { struct g_geom *gp; - struct g_consumer *cp; + struct g_consumer *cp, *tp; struct g_vol_ffs_softc *ms; int error, sb, superblock; struct fs *fs; + const char *pclass; g_trace(G_T_TOPOLOGY, "vol_taste(%s,%s)", mp->name, pp->name); g_topology_assert(); @@ -71,18 +83,58 @@ * XXX This is a really weak way to make sure we don't recurse. * Probably ought to use BIO_GETATTR to check for this. */ + pclass = pp->geom->class->name; if (flags == G_TF_NORMAL && - !strcmp(pp->geom->class->name, VOL_FFS_CLASS_NAME)) + !strcmp(pclass, VOL_FFS_CLASS_NAME)) return (NULL); gp = g_slice_new(mp, 1, pp, &cp, &ms, sizeof(*ms), g_vol_ffs_start); if (gp == NULL) return (NULL); + /* We can only attach to providers we know how to handle */ + if (strcmp(pclass, "APPLE") && + strcmp(pclass, "BDE") && + strcmp(pclass, "BSD") && + strcmp(pclass, "DISK") && + strcmp(pclass, "GPT") && + strcmp(pclass, "MBR") && + strcmp(pclass, "PC98") && + strcmp(pclass, "SUN")) { + return (NULL); + } + /* Don't attach to slice 2 in sunlabels */ + if (!strcmp(pclass, "SUN") && pp->index == 2) { + return (NULL); + } + /* Don't attach to non-4.2BSD partitions in bsdlabels */ + if (!strcmp(pclass, "BSD")) { + struct g_bsd_softc *ms; + struct g_slicer *gsp; + u_int8_t type; + + gsp = pp->geom->softc; + ms = gsp->softc; + type = ms->ondisk.d_partitions[pp->index].p_fstype; + if (type != FS_BSDFFS) { + return (NULL); + } + } + /* Don't attach to providers that have consumers of + * types other than "DEV" attached to them */ + LIST_FOREACH(tp, &pp->consumers, consumers) { + const char *name = tp->geom->class->name; + + if (strcmp(name, VOL_FFS_CLASS_NAME) && + strcmp(name, "DEV")) { + return (NULL); + continue; + } + } g_topology_unlock(); /* * Walk through the standard places that superblocks hide and look * for UFS magic. If we find magic, then check that the size in the - * superblock corresponds to the size of the underlying provider. + * superblock does not exceed the size of the underlying provider. * Finally, look for a volume label and create an appropriate * provider based on that. */ @@ -93,14 +145,12 @@ continue; /* Check for magic and make sure things are the right size */ if (fs->fs_magic == FS_UFS1_MAGIC) { - if (fs->fs_old_size * fs->fs_fsize != - (int32_t) pp->mediasize) { + if (fs->fs_old_size * fs->fs_fsize > pp->mediasize) { g_free(fs); continue; } } else if (fs->fs_magic == FS_UFS2_MAGIC) { - if (fs->fs_size * fs->fs_fsize != - (int64_t) pp->mediasize) { + if (fs->fs_size * fs->fs_fsize > pp->mediasize) { g_free(fs); continue; }