Skip to content

Commit

Permalink
dm snapshot: test chunk size against both origin and snapshot
Browse files Browse the repository at this point in the history
Validate chunk size against both origin and snapshot sector size

Don't allow chunk size smaller than either origin or snapshot logical
sector size. Reading or writing data not aligned to sector size is not
allowed and causes immediate errors.

This requires us to open the origin before initialising the
exception store and to export dm_snap_origin.

Cc: stable@kernel.org
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Reviewed-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
  • Loading branch information
Mikulas Patocka authored and Alasdair G Kergon committed Aug 12, 2010
1 parent 1e5554c commit c241104
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 17 deletions.
4 changes: 3 additions & 1 deletion drivers/md/dm-exception-store.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,9 @@ 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(dm_snap_cow(store->snap)->bdev) >> 9)) {
(bdev_logical_block_size(dm_snap_cow(store->snap)->bdev) >> 9) ||
chunk_size %
(bdev_logical_block_size(dm_snap_origin(store->snap)->bdev) >> 9)) {
*error = "Chunk size is not a multiple of device blocksize";
return -EINVAL;
}
Expand Down
3 changes: 2 additions & 1 deletion drivers/md/dm-exception-store.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,9 @@ struct dm_exception_store {
};

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

/*
Expand Down
36 changes: 21 additions & 15 deletions drivers/md/dm-snap.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,12 @@ struct dm_snapshot {
#define RUNNING_MERGE 0
#define SHUTDOWN_MERGE 1

struct dm_dev *dm_snap_origin(struct dm_snapshot *s)
{
return s->origin;
}
EXPORT_SYMBOL(dm_snap_origin);

struct dm_dev *dm_snap_cow(struct dm_snapshot *s)
{
return s->cow;
Expand Down Expand Up @@ -1065,10 +1071,6 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
origin_mode = FMODE_WRITE;
}

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

s = kmalloc(sizeof(*s), GFP_KERNEL);
if (!s) {
ti->error = "Cannot allocate snapshot context private "
Expand All @@ -1077,6 +1079,16 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
goto bad;
}

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

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

cow_path = argv[0];
argv++;
argc--;
Expand All @@ -1097,12 +1109,6 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
argv += args_used;
argc -= args_used;

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

s->ti = ti;
s->valid = 1;
s->active = 0;
Expand Down Expand Up @@ -1212,15 +1218,15 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
dm_exception_table_exit(&s->complete, exception_cache);

bad_hash_tables:
dm_put_device(ti, s->origin);

bad_origin:
dm_exception_store_destroy(s->store);

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

bad_cow:
dm_put_device(ti, s->origin);

bad_origin:
kfree(s);

bad:
Expand Down Expand Up @@ -1314,12 +1320,12 @@ static void snapshot_dtr(struct dm_target *ti)

mempool_destroy(s->pending_pool);

dm_put_device(ti, s->origin);

dm_exception_store_destroy(s->store);

dm_put_device(ti, s->cow);

dm_put_device(ti, s->origin);

kfree(s);
}

Expand Down

0 comments on commit c241104

Please sign in to comment.