The attached patch changes the behaviour of geom_vol_ffs so that:
- It works even if the file system doesn't fill the partition
completely (it only checks for file system > mediasize).
- It does not attach to providers it doesn't know how to handle.
- It does not attach to sunlabel providers if the slice number is 2.
- It does not attach to bsdlabel providers if the partition type
isn't FS_BSDFFS.
- It does not attach to providers that are attached to consumers
of other types than "DEV".
The last check is to avoid connecting to submirrors, components of a
RAID5, one specific path of a multipathed fibre channel disk, etc.
(Hopefully, there will be a GEOM_FCAL class that implements load
sharing and fault tolerance in multipathed systems?:-) )
The big question is how to make sure geom_vol_ffs doesn't get the
chance to taste (and attach) before, say, geom_mirror does.
What do you think about this approach?
--
Per Kristian Hove
Dept. of Mathematical Sciences
Norwegian University of Science and Technology
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 <sys/bio.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/disklabel.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
@@ -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;
}
_______________________________________________
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "[EMAIL PROTECTED]"