dm snapshot: use dm-bufio
authorMikulas Patocka <mpatocka@redhat.com>
Tue, 14 Jan 2014 00:12:36 +0000 (19:12 -0500)
committerMike Snitzer <snitzer@redhat.com>
Wed, 15 Jan 2014 04:23:02 +0000 (23:23 -0500)
Use dm-bufio for initial loading of the exceptions.
Introduce a new function dm_bufio_forget that frees the given buffer.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
drivers/md/Kconfig
drivers/md/dm-bufio.c
drivers/md/dm-bufio.h
drivers/md/dm-snap-persistent.c

index 7441344bd214aa08a4fca7e976492b6342a198fb..39b540a13369d87c06f8606df626b7fafe1c77a1 100644 (file)
@@ -238,6 +238,7 @@ config DM_CRYPT
 config DM_SNAPSHOT
        tristate "Snapshot target"
        depends on BLK_DEV_DM
+       select DM_BUFIO
        ---help---
          Allow volume managers to take writable snapshots of a device.
 
index 54bdd923316f92818d509f06986c9a9a3b7b1927..d865937219157a248da57574e6ab8b2aa835b17c 100644 (file)
@@ -1350,6 +1350,28 @@ retry:
 }
 EXPORT_SYMBOL_GPL(dm_bufio_release_move);
 
+/*
+ * Free the given buffer.
+ *
+ * This is just a hint, if the buffer is in use or dirty, this function
+ * does nothing.
+ */
+void dm_bufio_forget(struct dm_bufio_client *c, sector_t block)
+{
+       struct dm_buffer *b;
+
+       dm_bufio_lock(c);
+
+       b = __find(c, block);
+       if (b && likely(!b->hold_count) && likely(!b->state)) {
+               __unlink_buffer(b);
+               __free_buffer_wake(b);
+       }
+
+       dm_bufio_unlock(c);
+}
+EXPORT_SYMBOL(dm_bufio_forget);
+
 unsigned dm_bufio_get_block_size(struct dm_bufio_client *c)
 {
        return c->block_size;
index b142946a9e32ea23dcc241b5120ba00fe09e5287..3dac37627ba4595369b20022e12d6a2f6dd8ddb6 100644 (file)
@@ -108,6 +108,13 @@ int dm_bufio_issue_flush(struct dm_bufio_client *c);
  */
 void dm_bufio_release_move(struct dm_buffer *b, sector_t new_block);
 
+/*
+ * Free the given buffer.
+ * This is just a hint, if the buffer is in use or dirty, this function
+ * does nothing.
+ */
+void dm_bufio_forget(struct dm_bufio_client *c, sector_t block);
+
 unsigned dm_bufio_get_block_size(struct dm_bufio_client *c);
 sector_t dm_bufio_get_device_size(struct dm_bufio_client *c);
 sector_t dm_bufio_get_block_number(struct dm_buffer *b);
index ba792ae068b7f5b09ea25b97ae104cc9d71239ec..169275050c0b76ccf41bdbec58812728bde9b461 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/dm-io.h>
+#include "dm-bufio.h"
 
 #define DM_MSG_PREFIX "persistent snapshot"
 #define DM_CHUNK_SIZE_DEFAULT_SECTORS 32       /* 16KB */
@@ -495,27 +496,51 @@ static int read_exceptions(struct pstore *ps,
                           void *callback_context)
 {
        int r, full = 1;
+       struct dm_bufio_client *client;
+
+       client = dm_bufio_client_create(dm_snap_cow(ps->store->snap)->bdev,
+                                       ps->store->chunk_size << SECTOR_SHIFT,
+                                       1, 0, NULL, NULL);
+
+       if (IS_ERR(client))
+               return PTR_ERR(client);
 
        /*
         * Keeping reading chunks and inserting exceptions until
         * we find a partially full area.
         */
        for (ps->current_area = 0; full; ps->current_area++) {
-               r = area_io(ps, READ);
-               if (r)
-                       return r;
+               struct dm_buffer *bp;
+               void *area;
+               chunk_t chunk = area_location(ps, ps->current_area);
+
+               area = dm_bufio_read(client, chunk, &bp);
+               if (unlikely(IS_ERR(area))) {
+                       r = PTR_ERR(area);
+                       goto ret_destroy_bufio;
+               }
 
-               r = insert_exceptions(ps, ps->area, callback, callback_context,
+               r = insert_exceptions(ps, area, callback, callback_context,
                                      &full);
-               if (r)
-                       return r;
+
+               dm_bufio_release(bp);
+
+               dm_bufio_forget(client, chunk);
+
+               if (unlikely(r))
+                       goto ret_destroy_bufio;
        }
 
        ps->current_area--;
 
        skip_metadata(ps);
 
-       return 0;
+       r = 0;
+
+ret_destroy_bufio:
+       dm_bufio_client_destroy(client);
+
+       return r;
 }
 
 static struct pstore *get_info(struct dm_exception_store *store)