]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/md/dm-table.c
atomic: use <linux/atomic.h>
[mirror_ubuntu-artful-kernel.git] / drivers / md / dm-table.c
index cb8380c9767fd3d5bb815d7fec4a46308b0270c5..bfe9c2333ceacecddd00d058615fc8a9f2867b1b 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
 #include <linux/delay.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
 
 #define DM_MSG_PREFIX "table"
 
@@ -362,6 +362,7 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md)
 static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev,
                                  sector_t start, sector_t len, void *data)
 {
+       struct request_queue *q;
        struct queue_limits *limits = data;
        struct block_device *bdev = dev->bdev;
        sector_t dev_size =
@@ -370,6 +371,22 @@ static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev,
                limits->logical_block_size >> SECTOR_SHIFT;
        char b[BDEVNAME_SIZE];
 
+       /*
+        * Some devices exist without request functions,
+        * such as loop devices not yet bound to backing files.
+        * Forbid the use of such devices.
+        */
+       q = bdev_get_queue(bdev);
+       if (!q || !q->make_request_fn) {
+               DMWARN("%s: %s is not yet initialised: "
+                      "start=%llu, len=%llu, dev_size=%llu",
+                      dm_device_name(ti->table->md), bdevname(bdev, b),
+                      (unsigned long long)start,
+                      (unsigned long long)len,
+                      (unsigned long long)dev_size);
+               return 1;
+       }
+
        if (!dev_size)
                return 0;
 
@@ -1346,7 +1363,8 @@ bool dm_table_supports_discards(struct dm_table *t)
                return 0;
 
        /*
-        * Ensure that at least one underlying device supports discards.
+        * Unless any target used by the table set discards_supported,
+        * require at least one underlying device to support discards.
         * t->devices includes internal dm devices such as mirror logs
         * so we need to use iterate_devices here, which targets
         * supporting discard must provide.
@@ -1354,6 +1372,9 @@ bool dm_table_supports_discards(struct dm_table *t)
        while (i < dm_table_get_num_targets(t)) {
                ti = dm_table_get_target(t, i++);
 
+               if (ti->discards_supported)
+                       return 1;
+
                if (ti->type->iterate_devices &&
                    ti->type->iterate_devices(ti, device_discard_capable, NULL))
                        return 1;