Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 176539
b: refs/heads/master
c: fc56f6f
h: refs/heads/master
i:
  176537: d1c6300
  176535: a9304df
v: v3
  • Loading branch information
Mike Snitzer authored and Alasdair G Kergon committed Dec 10, 2009
1 parent 3d21e2d commit 8aba792
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 58 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 985903bb3a6d98623360ab6c855417f638840029
refs/heads/master: fc56f6fbcca3672c63c93c65f45105faacfc13cb
30 changes: 11 additions & 19 deletions trunk/drivers/md/dm-exception-store.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
}

/* Validate the chunk size against the device block size */
if (chunk_size % (bdev_logical_block_size(store->cow->bdev) >> 9)) {
if (chunk_size %
(bdev_logical_block_size(dm_snap_cow(store->snap)->bdev) >> 9)) {
*error = "Chunk size is not a multiple of device blocksize";
return -EINVAL;
}
Expand All @@ -190,6 +191,7 @@ int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
}

int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
struct dm_snapshot *snap,
unsigned *args_used,
struct dm_exception_store **store)
{
Expand All @@ -198,7 +200,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
struct dm_exception_store *tmp_store;
char persistent;

if (argc < 3) {
if (argc < 2) {
ti->error = "Insufficient exception store arguments";
return -EINVAL;
}
Expand All @@ -209,7 +211,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
return -ENOMEM;
}

persistent = toupper(*argv[1]);
persistent = toupper(*argv[0]);
if (persistent == 'P')
type = get_type("P");
else if (persistent == 'N')
Expand All @@ -227,32 +229,23 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
}

tmp_store->type = type;
tmp_store->ti = ti;
tmp_store->snap = snap;

r = dm_get_device(ti, argv[0], 0, 0,
FMODE_READ | FMODE_WRITE, &tmp_store->cow);
if (r) {
ti->error = "Cannot get COW device";
goto bad_cow;
}

r = set_chunk_size(tmp_store, argv[2], &ti->error);
r = set_chunk_size(tmp_store, argv[1], &ti->error);
if (r)
goto bad_ctr;
goto bad;

r = type->ctr(tmp_store, 0, NULL);
if (r) {
ti->error = "Exception store type constructor failed";
goto bad_ctr;
goto bad;
}

*args_used = 3;
*args_used = 2;
*store = tmp_store;
return 0;

bad_ctr:
dm_put_device(ti, tmp_store->cow);
bad_cow:
bad:
put_type(type);
bad_type:
kfree(tmp_store);
Expand All @@ -263,7 +256,6 @@ EXPORT_SYMBOL(dm_exception_store_create);
void dm_exception_store_destroy(struct dm_exception_store *store)
{
store->type->dtr(store);
dm_put_device(store->ti, store->cow);
put_type(store->type);
kfree(store);
}
Expand Down
12 changes: 9 additions & 3 deletions trunk/drivers/md/dm-exception-store.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,11 @@ struct dm_exception_store_type {
struct list_head list;
};

struct dm_snapshot;

struct dm_exception_store {
struct dm_exception_store_type *type;
struct dm_target *ti;

struct dm_dev *cow;
struct dm_snapshot *snap;

/* Size of data blocks saved - must be a power of 2 */
unsigned chunk_size;
Expand All @@ -108,6 +108,11 @@ struct dm_exception_store {
void *context;
};

/*
* Obtain the cow device used by a given snapshot.
*/
struct dm_dev *dm_snap_cow(struct dm_snapshot *snap);

/*
* Funtions to manipulate consecutive chunks
*/
Expand Down Expand Up @@ -173,6 +178,7 @@ int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
char **error);

int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
struct dm_snapshot *snap,
unsigned *args_used,
struct dm_exception_store **store);
void dm_exception_store_destroy(struct dm_exception_store *store);
Expand Down
12 changes: 6 additions & 6 deletions trunk/drivers/md/dm-snap-persistent.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ static int chunk_io(struct pstore *ps, void *area, chunk_t chunk, int rw,
int metadata)
{
struct dm_io_region where = {
.bdev = ps->store->cow->bdev,
.bdev = dm_snap_cow(ps->store->snap)->bdev,
.sector = ps->store->chunk_size * chunk,
.count = ps->store->chunk_size,
};
Expand Down Expand Up @@ -294,7 +294,8 @@ static int read_header(struct pstore *ps, int *new_snapshot)
*/
if (!ps->store->chunk_size) {
ps->store->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS,
bdev_logical_block_size(ps->store->cow->bdev) >> 9);
bdev_logical_block_size(dm_snap_cow(ps->store->snap)->
bdev) >> 9);
ps->store->chunk_mask = ps->store->chunk_size - 1;
ps->store->chunk_shift = ffs(ps->store->chunk_size) - 1;
chunk_size_supplied = 0;
Expand Down Expand Up @@ -497,7 +498,7 @@ static void persistent_usage(struct dm_exception_store *store,
struct pstore *ps = get_info(store);

*sectors_allocated = ps->next_free * store->chunk_size;
*total_sectors = get_dev_size(store->cow->bdev);
*total_sectors = get_dev_size(dm_snap_cow(store->snap)->bdev);

/*
* First chunk is the fixed header.
Expand Down Expand Up @@ -596,7 +597,7 @@ static int persistent_prepare_exception(struct dm_exception_store *store,
struct pstore *ps = get_info(store);
uint32_t stride;
chunk_t next_free;
sector_t size = get_dev_size(store->cow->bdev);
sector_t size = get_dev_size(dm_snap_cow(store->snap)->bdev);

/* Is there enough room ? */
if (size < ((ps->next_free + 1) * store->chunk_size))
Expand Down Expand Up @@ -733,8 +734,7 @@ static unsigned persistent_status(struct dm_exception_store *store,
case STATUSTYPE_INFO:
break;
case STATUSTYPE_TABLE:
DMEMIT(" %s P %llu", store->cow->name,
(unsigned long long)store->chunk_size);
DMEMIT(" P %llu", (unsigned long long)store->chunk_size);
}

return sz;
Expand Down
7 changes: 3 additions & 4 deletions trunk/drivers/md/dm-snap-transient.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static int transient_prepare_exception(struct dm_exception_store *store,
struct dm_exception *e)
{
struct transient_c *tc = store->context;
sector_t size = get_dev_size(store->cow->bdev);
sector_t size = get_dev_size(dm_snap_cow(store->snap)->bdev);

if (size < (tc->next_free + store->chunk_size))
return -1;
Expand All @@ -65,7 +65,7 @@ static void transient_usage(struct dm_exception_store *store,
sector_t *metadata_sectors)
{
*sectors_allocated = ((struct transient_c *) store->context)->next_free;
*total_sectors = get_dev_size(store->cow->bdev);
*total_sectors = get_dev_size(dm_snap_cow(store->snap)->bdev);
*metadata_sectors = 0;
}

Expand Down Expand Up @@ -94,8 +94,7 @@ static unsigned transient_status(struct dm_exception_store *store,
case STATUSTYPE_INFO:
break;
case STATUSTYPE_TABLE:
DMEMIT(" %s N %llu", store->cow->name,
(unsigned long long)store->chunk_size);
DMEMIT(" N %llu", (unsigned long long)store->chunk_size);
}

return sz;
Expand Down
74 changes: 49 additions & 25 deletions trunk/drivers/md/dm-snap.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ struct dm_snapshot {
struct rw_semaphore lock;

struct dm_dev *origin;
struct dm_dev *cow;

struct dm_target *ti;

/* List of snapshots per Origin */
struct list_head list;
Expand Down Expand Up @@ -97,6 +100,12 @@ struct dm_snapshot {
struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
};

struct dm_dev *dm_snap_cow(struct dm_snapshot *s)
{
return s->cow;
}
EXPORT_SYMBOL(dm_snap_cow);

static struct workqueue_struct *ksnapd;
static void flush_queued_bios(struct work_struct *work);

Expand Down Expand Up @@ -558,7 +567,7 @@ static int init_hash_tables(struct dm_snapshot *s)
* Calculate based on the size of the original volume or
* the COW volume...
*/
cow_dev_size = get_dev_size(s->store->cow->bdev);
cow_dev_size = get_dev_size(s->cow->bdev);
origin_dev_size = get_dev_size(s->origin->bdev);
max_buckets = calc_max_buckets();

Expand Down Expand Up @@ -596,45 +605,55 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
struct dm_snapshot *s;
int i;
int r = -EINVAL;
char *origin_path;
struct dm_exception_store *store;
char *origin_path, *cow_path;
unsigned args_used;

if (argc != 4) {
ti->error = "requires exactly 4 arguments";
r = -EINVAL;
goto bad_args;
goto bad;
}

origin_path = argv[0];
argv++;
argc--;

r = dm_exception_store_create(ti, argc, argv, &args_used, &store);
s = kmalloc(sizeof(*s), GFP_KERNEL);
if (!s) {
ti->error = "Cannot allocate snapshot context private "
"structure";
r = -ENOMEM;
goto bad;
}

cow_path = argv[0];
argv++;
argc--;

r = dm_get_device(ti, cow_path, 0, 0,
FMODE_READ | FMODE_WRITE, &s->cow);
if (r) {
ti->error = "Cannot get COW device";
goto bad_cow;
}

r = dm_exception_store_create(ti, argc, argv, s, &args_used, &s->store);
if (r) {
ti->error = "Couldn't create exception store";
r = -EINVAL;
goto bad_args;
goto bad_store;
}

argv += args_used;
argc -= args_used;

s = kmalloc(sizeof(*s), GFP_KERNEL);
if (!s) {
ti->error = "Cannot allocate snapshot context private "
"structure";
r = -ENOMEM;
goto bad_snap;
}

r = dm_get_device(ti, origin_path, 0, ti->len, FMODE_READ, &s->origin);
if (r) {
ti->error = "Cannot get origin device";
goto bad_origin;
}

s->store = store;
s->ti = ti;
s->valid = 1;
s->active = 0;
atomic_set(&s->pending_exceptions_count, 0);
Expand Down Expand Up @@ -723,12 +742,15 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
dm_put_device(ti, s->origin);

bad_origin:
kfree(s);
dm_exception_store_destroy(s->store);

bad_snap:
dm_exception_store_destroy(store);
bad_store:
dm_put_device(ti, s->cow);

bad_args:
bad_cow:
kfree(s);

bad:
return r;
}

Expand Down Expand Up @@ -777,6 +799,8 @@ static void snapshot_dtr(struct dm_target *ti)

dm_exception_store_destroy(s->store);

dm_put_device(ti, s->cow);

kfree(s);
}

Expand Down Expand Up @@ -839,7 +863,7 @@ static void __invalidate_snapshot(struct dm_snapshot *s, int err)

s->valid = 0;

dm_table_event(s->store->ti->table);
dm_table_event(s->ti->table);
}

static void get_pending_exception(struct dm_snap_pending_exception *pe)
Expand Down Expand Up @@ -977,7 +1001,7 @@ static void start_copy(struct dm_snap_pending_exception *pe)
src.sector = chunk_to_sector(s->store, pe->e.old_chunk);
src.count = min((sector_t)s->store->chunk_size, dev_size - src.sector);

dest.bdev = s->store->cow->bdev;
dest.bdev = s->cow->bdev;
dest.sector = chunk_to_sector(s->store, pe->e.new_chunk);
dest.count = src.count;

Expand Down Expand Up @@ -1038,7 +1062,7 @@ __find_pending_exception(struct dm_snapshot *s,
static void remap_exception(struct dm_snapshot *s, struct dm_exception *e,
struct bio *bio, chunk_t chunk)
{
bio->bi_bdev = s->store->cow->bdev;
bio->bi_bdev = s->cow->bdev;
bio->bi_sector = chunk_to_sector(s->store,
dm_chunk_number(e->new_chunk) +
(chunk - e->old_chunk)) +
Expand All @@ -1056,7 +1080,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
struct dm_snap_pending_exception *pe = NULL;

if (unlikely(bio_empty_barrier(bio))) {
bio->bi_bdev = s->store->cow->bdev;
bio->bi_bdev = s->cow->bdev;
return DM_MAPIO_REMAPPED;
}

Expand Down Expand Up @@ -1200,7 +1224,7 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
* to make private copies if the output is to
* make sense.
*/
DMEMIT("%s", snap->origin->name);
DMEMIT("%s %s", snap->origin->name, snap->cow->name);
snap->store->type->status(snap->store, type, result + sz,
maxlen - sz);
break;
Expand Down Expand Up @@ -1240,7 +1264,7 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
goto next_snapshot;

/* Nothing to do if writing beyond end of snapshot */
if (bio->bi_sector >= dm_table_get_size(snap->store->ti->table))
if (bio->bi_sector >= dm_table_get_size(snap->ti->table))
goto next_snapshot;

/*
Expand Down

0 comments on commit 8aba792

Please sign in to comment.