Author: ae
Date: Sun Aug  5 14:48:28 2012
New Revision: 239068
URL: http://svn.freebsd.org/changeset/base/239068

Log:
  Teach the ZFS use new partitions API when probing.
  Note: now ZFS does probe only for partitions with type "freebsd-zfs"
  and "freebsd".

Modified:
  head/sys/boot/i386/loader/main.c
  head/sys/boot/zfs/zfs.c

Modified: head/sys/boot/i386/loader/main.c
==============================================================================
--- head/sys/boot/i386/loader/main.c    Sun Aug  5 14:38:53 2012        
(r239067)
+++ head/sys/boot/i386/loader/main.c    Sun Aug  5 14:48:28 2012        
(r239068)
@@ -356,25 +356,17 @@ static void
 i386_zfs_probe(void)
 {
     char devname[32];
-    int unit, slice;
+    int unit;
 
     /*
      * Open all the disks we can find and see if we can reconstruct
-     * ZFS pools from them. Bogusly assumes that the disks are named
-     * diskN, diskNpM or diskNsM.
+     * ZFS pools from them.
      */
     for (unit = 0; unit < MAXBDDEV; unit++) {
+       if (bd_unit2bios(unit) == -1)
+           break;
        sprintf(devname, "disk%d:", unit);
-       if (zfs_probe_dev(devname, NULL) == ENXIO)
-           continue;
-       for (slice = 1; slice <= 128; slice++) {
-           sprintf(devname, "disk%dp%d:", unit, slice);
-           zfs_probe_dev(devname, NULL);
-       }
-       for (slice = 1; slice <= 4; slice++) {
-           sprintf(devname, "disk%ds%d:", unit, slice);
-           zfs_probe_dev(devname, NULL);
-       }
+       zfs_probe_dev(devname, NULL);
     }
 }
 #endif

Modified: head/sys/boot/zfs/zfs.c
==============================================================================
--- head/sys/boot/zfs/zfs.c     Sun Aug  5 14:38:53 2012        (r239067)
+++ head/sys/boot/zfs/zfs.c     Sun Aug  5 14:48:28 2012        (r239068)
@@ -33,10 +33,11 @@ __FBSDID("$FreeBSD$");
  *     Stand-alone file reading package.
  */
 
+#include <sys/disk.h>
 #include <sys/param.h>
-#include <sys/disklabel.h>
 #include <sys/time.h>
 #include <sys/queue.h>
+#include <part.h>
 #include <stddef.h>
 #include <stdarg.h>
 #include <string.h>
@@ -376,21 +377,103 @@ zfs_dev_init(void)
        return (0);
 }
 
-int
-zfs_probe_dev(const char *devname, uint64_t *pool_guid)
+struct zfs_probe_args {
+       int             fd;
+       const char      *devname;
+       uint64_t        *pool_guid;
+       uint16_t        secsz;
+};
+
+static int
+zfs_diskread(void *arg, void *buf, size_t blocks, off_t offset)
+{
+       struct zfs_probe_args *ppa;
+
+       ppa = (struct zfs_probe_args *)arg;
+       return (vdev_read(NULL, (void *)(uintptr_t)ppa->fd,
+           offset * ppa->secsz, buf, blocks * ppa->secsz));
+}
+
+static int
+zfs_probe(int fd, uint64_t *pool_guid)
 {
        spa_t *spa;
-       int fd;
        int ret;
 
-       fd = open(devname, O_RDONLY);
-       if (fd == -1)
-               return (ENXIO);
        ret = vdev_probe(vdev_read, (void *)(uintptr_t)fd, &spa);
-       if (ret != 0)
-               close(fd);
-       else if (pool_guid != NULL)
+       if (ret == 0 && pool_guid != NULL)
                *pool_guid = spa->spa_guid;
+       return (ret);
+}
+
+static void
+zfs_probe_partition(void *arg, const char *partname,
+    const struct ptable_entry *part)
+{
+       struct zfs_probe_args *ppa, pa;
+       struct ptable *table;
+       char devname[32];
+       int ret;
+
+       /* Probe only freebsd-zfs and freebsd partitions */
+       if (part->type != PART_FREEBSD &&
+           part->type != PART_FREEBSD_ZFS)
+               return;
+
+       ppa = (struct zfs_probe_args *)arg;
+       strncpy(devname, ppa->devname, strlen(ppa->devname) - 1);
+       sprintf(devname, "%s%s:", devname, partname);
+       pa.fd = open(devname, O_RDONLY);
+       if (pa.fd == -1)
+               return;
+       ret = zfs_probe(pa.fd, ppa->pool_guid);
+       if (ret == 0)
+               return;
+       /* Do we have BSD label here? */
+       if (part->type == PART_FREEBSD) {
+               pa.devname = devname;
+               pa.pool_guid = ppa->pool_guid;
+               pa.secsz = ppa->secsz;
+               table = ptable_open(&pa, part->end - part->start + 1,
+                   ppa->secsz, zfs_diskread);
+               if (table != NULL) {
+                       ptable_iterate(table, &pa, zfs_probe_partition);
+                       ptable_close(table);
+               }
+       }
+       close(pa.fd);
+}
+
+int
+zfs_probe_dev(const char *devname, uint64_t *pool_guid)
+{
+       struct ptable *table;
+       struct zfs_probe_args pa;
+       off_t mediasz;
+       int ret;
+
+       pa.fd = open(devname, O_RDONLY);
+       if (pa.fd == -1)
+               return (ENXIO);
+       /* Probe the whole disk */
+       ret = zfs_probe(pa.fd, pool_guid);
+       if (ret == 0)
+               return (0);
+       /* Probe each partition */
+       ret = ioctl(pa.fd, DIOCGMEDIASIZE, &mediasz);
+       if (ret == 0)
+               ret = ioctl(pa.fd, DIOCGSECTORSIZE, &pa.secsz);
+       if (ret == 0) {
+               pa.devname = devname;
+               pa.pool_guid = pool_guid;
+               table = ptable_open(&pa, mediasz / pa.secsz, pa.secsz,
+                   zfs_diskread);
+               if (table != NULL) {
+                       ptable_iterate(table, &pa, zfs_probe_partition);
+                       ptable_close(table);
+               }
+       }
+       close(pa.fd);
        return (0);
 }
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to