Skip to content

Commit

Permalink
dm snapshot: use dm-bufio
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mikulas Patocka authored and Mike Snitzer committed Jan 15, 2014
1 parent 2cadabd commit 55494bf
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 7 deletions.
1 change: 1 addition & 0 deletions drivers/md/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
22 changes: 22 additions & 0 deletions drivers/md/dm-bufio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1350,6 +1350,28 @@ void dm_bufio_release_move(struct dm_buffer *b, sector_t new_block)
}
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;
Expand Down
7 changes: 7 additions & 0 deletions drivers/md/dm-bufio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
39 changes: 32 additions & 7 deletions drivers/md/dm-snap-persistent.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 55494bf

Please sign in to comment.