Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[firefly-linux-kernel-4.4.55.git] / drivers / md / dm-table.c
index f221812b7dbcf0d3bae7c5171fe9e184c781d7d7..8f8783533ac7e13383aed49eff8a40ba3a0218bf 100644 (file)
@@ -860,14 +860,17 @@ EXPORT_SYMBOL(dm_consume_args);
 static int dm_table_set_type(struct dm_table *t)
 {
        unsigned i;
-       unsigned bio_based = 0, request_based = 0;
+       unsigned bio_based = 0, request_based = 0, hybrid = 0;
        struct dm_target *tgt;
        struct dm_dev_internal *dd;
        struct list_head *devices;
+       unsigned live_md_type;
 
        for (i = 0; i < t->num_targets; i++) {
                tgt = t->targets + i;
-               if (dm_target_request_based(tgt))
+               if (dm_target_hybrid(tgt))
+                       hybrid = 1;
+               else if (dm_target_request_based(tgt))
                        request_based = 1;
                else
                        bio_based = 1;
@@ -879,6 +882,19 @@ static int dm_table_set_type(struct dm_table *t)
                }
        }
 
+       if (hybrid && !bio_based && !request_based) {
+               /*
+                * The targets can work either way.
+                * Determine the type from the live device.
+                * Default to bio-based if device is new.
+                */
+               live_md_type = dm_get_md_type(t->md);
+               if (live_md_type == DM_TYPE_REQUEST_BASED)
+                       request_based = 1;
+               else
+                       bio_based = 1;
+       }
+
        if (bio_based) {
                /* We must use this table as bio-based */
                t->type = DM_TYPE_BIO_BASED;