@@ -94,7 +94,7 @@ retry:
return -ESRCH;
}
-static int build_constructor_string(struct dm_target *ti,
+static int build_constructor_string(sector_t log_size,
unsigned argc, char **argv,
char **ctr_str)
{
@@ -114,7 +114,7 @@ static int build_constructor_string(struct dm_target *ti,
return -ENOMEM;
}
- str_size = sprintf(str, "%llu", (unsigned long long)ti->len);
+ str_size = sprintf(str, "%llu", (unsigned long long)log_size);
for (i = 0; i < argc; i++)
str_size += sprintf(str + str_size, " %s", argv[i]);
@@ -136,6 +136,7 @@ static int build_constructor_string(struct dm_target *ti,
* else.
*/
static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
+ sector_t log_size,
unsigned argc, char **argv)
{
int r = 0;
@@ -171,7 +172,9 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
spin_lock_init(&lc->flush_lock);
INIT_LIST_HEAD(&lc->flush_list);
- str_size = build_constructor_string(ti, argc - 1, argv + 1, &ctr_str);
+ str_size = build_constructor_string(log_size,
+ argc - 1, argv + 1,
+ &ctr_str);
if (str_size < 0) {
kfree(lc);
return str_size;
@@ -197,7 +200,7 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
}
lc->region_size = (uint32_t)rdata;
- lc->region_count = dm_sector_div_up(ti->len, lc->region_size);
+ lc->region_count = dm_sector_div_up(log_size, lc->region_size);
out:
if (r) {
@@ -146,6 +146,7 @@ EXPORT_SYMBOL(dm_dirty_log_type_unregister);
struct dm_dirty_log *dm_dirty_log_create(const char *type_name,
struct dm_target *ti,
+ sector_t log_size,
int (*flush_callback_fn)(struct dm_target *ti),
unsigned int argc, char **argv)
{
@@ -164,7 +165,7 @@ struct dm_dirty_log *dm_dirty_log_create(const char *type_name,
log->flush_callback_fn = flush_callback_fn;
log->type = type;
- if (type->ctr(log, ti, argc, argv)) {
+ if (type->ctr(log, ti, log_size, argc, argv)) {
kfree(log);
put_type(type);
return NULL;
@@ -335,9 +336,9 @@ static int read_header(struct log_c *log)
return 0;
}
-static int _check_region_size(struct dm_target *ti, uint32_t region_size)
+static int _check_region_size(sector_t log_size, uint32_t region_size)
{
- if (region_size < 2 || region_size > ti->len)
+ if (region_size < 2 || region_size > log_size)
return 0;
if (!is_power_of_2(region_size))
@@ -353,6 +354,7 @@ static int _check_region_size(struct dm_target *ti, uint32_t region_size)
*--------------------------------------------------------------*/
#define BYTE_SHIFT 3
static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
+ sector_t log_size,
unsigned int argc, char **argv,
struct dm_dev *dev)
{
@@ -382,12 +384,12 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
}
if (sscanf(argv[0], "%u", ®ion_size) != 1 ||
- !_check_region_size(ti, region_size)) {
+ !_check_region_size(log_size, region_size)) {
DMWARN("invalid region size %s", argv[0]);
return -EINVAL;
}
- region_count = dm_sector_div_up(ti->len, region_size);
+ region_count = dm_sector_div_up(log_size, region_size);
lc = kmalloc(sizeof(*lc), GFP_KERNEL);
if (!lc) {
@@ -507,9 +509,10 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
}
static int core_ctr(struct dm_dirty_log *log, struct dm_target *ti,
+ sector_t log_size,
unsigned int argc, char **argv)
{
- return create_log_context(log, ti, argc, argv, NULL);
+ return create_log_context(log, ti, log_size, argc, argv, NULL);
}
static void destroy_log_context(struct log_c *lc)
@@ -533,6 +536,7 @@ static void core_dtr(struct dm_dirty_log *log)
* argv contains log_device region_size followed optionally by [no]sync
*--------------------------------------------------------------*/
static int disk_ctr(struct dm_dirty_log *log, struct dm_target *ti,
+ sector_t log_size,
unsigned int argc, char **argv)
{
int r;
@@ -547,7 +551,7 @@ static int disk_ctr(struct dm_dirty_log *log, struct dm_target *ti,
if (r)
return r;
- r = create_log_context(log, ti, argc - 1, argv + 1, dev);
+ r = create_log_context(log, ti, log_size, argc - 1, argv + 1, dev);
if (r) {
dm_put_device(ti, dev);
return r;
@@ -968,8 +968,8 @@ static struct dm_dirty_log *create_dirty_log(struct dm_target *ti,
return NULL;
}
- dl = dm_dirty_log_create(argv[0], ti, mirror_flush, param_count,
- argv + 2);
+ dl = dm_dirty_log_create(argv[0], ti, ti->len, mirror_flush,
+ param_count, argv + 2);
if (!dl) {
ti->error = "Error creating mirror dirty log";
return NULL;
@@ -33,6 +33,7 @@ struct dm_dirty_log_type {
struct list_head list;
int (*ctr)(struct dm_dirty_log *log, struct dm_target *ti,
+ sector_t log_size,
unsigned argc, char **argv);
void (*dtr)(struct dm_dirty_log *log);
@@ -137,7 +138,7 @@ int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type);
* type->constructor/destructor() directly.
*/
struct dm_dirty_log *dm_dirty_log_create(const char *type_name,
- struct dm_target *ti,
+ struct dm_target *ti, sector_t log_size,
int (*flush_callback_fn)(struct dm_target *ti),
unsigned argc, char **argv);
void dm_dirty_log_destroy(struct dm_dirty_log *log);