+#ifdef CONFIG_SOFTWARE_SUSPEND
+/*
+ * Find the swap type that corresponds to given device (if any).
+ *
+ * @offset - number of the PAGE_SIZE-sized block of the device, starting
+ * from 0, in which the swap header is expected to be located.
+ *
+ * This is needed for the suspend to disk (aka swsusp).
+ */
+int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p)
+{
+ struct block_device *bdev = NULL;
+ int i;
+
+ if (device)
+ bdev = bdget(device);
+
+ spin_lock(&swap_lock);
+ for (i = 0; i < nr_swapfiles; i++) {
+ struct swap_info_struct *sis = swap_info + i;
+
+ if (!(sis->flags & SWP_WRITEOK))
+ continue;
+
+ if (!bdev) {
+ if (bdev_p)
+ *bdev_p = sis->bdev;
+
+ spin_unlock(&swap_lock);
+ return i;
+ }
+ if (bdev == sis->bdev) {
+ struct swap_extent *se;
+
+ se = list_entry(sis->extent_list.next,
+ struct swap_extent, list);
+ if (se->start_block == offset) {
+ if (bdev_p)
+ *bdev_p = sis->bdev;
+
+ spin_unlock(&swap_lock);
+ bdput(bdev);
+ return i;
+ }
+ }
+ }
+ spin_unlock(&swap_lock);
+ if (bdev)
+ bdput(bdev);
+
+ return -ENODEV;
+}
+