Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-2.6-dm
Browse files Browse the repository at this point in the history
* git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-2.6-dm:
  dm snapshot: fix on disk chunk size validation
  dm exception store: split set_chunk_size
  dm snapshot: fix header corruption race on invalidation
  dm snapshot: refactor zero_disk_area to use chunk_io
  dm log: userspace add luid to distinguish between concurrent log instances
  dm raid1: do not allow log_failure variable to unset after being set
  dm log: remove incorrect field from userspace table output
  dm log: fix userspace status output
  dm stripe: expose correct io hints
  dm table: add more context to terse warning messages
  dm table: fix queue_limit checking device iterator
  dm snapshot: implement iterate devices
  dm multipath: fix oops when request based io fails when no paths
  • Loading branch information
torvalds committed Sep 5, 2009
2 parents 9b6a3df + ae0b744 commit 154f807
Show file tree
Hide file tree
Showing 13 changed files with 198 additions and 81 deletions.
13 changes: 13 additions & 0 deletions drivers/md/dm-exception-store.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,14 @@ static int set_chunk_size(struct dm_exception_store *store,
*/
chunk_size_ulong = round_up(chunk_size_ulong, PAGE_SIZE >> 9);

return dm_exception_store_set_chunk_size(store, chunk_size_ulong,
error);
}

int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
unsigned long chunk_size_ulong,
char **error)
{
/* Check chunk_size is a power of 2 */
if (!is_power_of_2(chunk_size_ulong)) {
*error = "Chunk size is not a power of 2";
Expand All @@ -183,6 +191,11 @@ static int set_chunk_size(struct dm_exception_store *store,
return -EINVAL;
}

if (chunk_size_ulong > INT_MAX >> SECTOR_SHIFT) {
*error = "Chunk size is too high";
return -EINVAL;
}

store->chunk_size = chunk_size_ulong;
store->chunk_mask = chunk_size_ulong - 1;
store->chunk_shift = ffs(chunk_size_ulong) - 1;
Expand Down
4 changes: 4 additions & 0 deletions drivers/md/dm-exception-store.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ static inline chunk_t sector_to_chunk(struct dm_exception_store *store,
int dm_exception_store_type_register(struct dm_exception_store_type *type);
int dm_exception_store_type_unregister(struct dm_exception_store_type *type);

int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
unsigned long chunk_size_ulong,
char **error);

int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
unsigned *args_used,
struct dm_exception_store **store);
Expand Down
39 changes: 24 additions & 15 deletions drivers/md/dm-log-userspace-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ struct log_c {
struct dm_target *ti;
uint32_t region_size;
region_t region_count;
uint64_t luid;
char uuid[DM_UUID_LEN];

char *usr_argv_str;
Expand Down Expand Up @@ -63,7 +64,7 @@ static int userspace_do_request(struct log_c *lc, const char *uuid,
* restored.
*/
retry:
r = dm_consult_userspace(uuid, request_type, data,
r = dm_consult_userspace(uuid, lc->luid, request_type, data,
data_size, rdata, rdata_size);

if (r != -ESRCH)
Expand All @@ -74,14 +75,15 @@ static int userspace_do_request(struct log_c *lc, const char *uuid,
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(2*HZ);
DMWARN("Attempting to contact userspace log server...");
r = dm_consult_userspace(uuid, DM_ULOG_CTR, lc->usr_argv_str,
r = dm_consult_userspace(uuid, lc->luid, DM_ULOG_CTR,
lc->usr_argv_str,
strlen(lc->usr_argv_str) + 1,
NULL, NULL);
if (!r)
break;
}
DMINFO("Reconnected to userspace log server... DM_ULOG_CTR complete");
r = dm_consult_userspace(uuid, DM_ULOG_RESUME, NULL,
r = dm_consult_userspace(uuid, lc->luid, DM_ULOG_RESUME, NULL,
0, NULL, NULL);
if (!r)
goto retry;
Expand Down Expand Up @@ -111,10 +113,9 @@ static int build_constructor_string(struct dm_target *ti,
return -ENOMEM;
}

for (i = 0, str_size = 0; i < argc; i++)
str_size += sprintf(str + str_size, "%s ", argv[i]);
str_size += sprintf(str + str_size, "%llu",
(unsigned long long)ti->len);
str_size = sprintf(str, "%llu", (unsigned long long)ti->len);
for (i = 0; i < argc; i++)
str_size += sprintf(str + str_size, " %s", argv[i]);

*ctr_str = str;
return str_size;
Expand Down Expand Up @@ -154,6 +155,9 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
return -ENOMEM;
}

/* The ptr value is sufficient for local unique id */
lc->luid = (uint64_t)lc;

lc->ti = ti;

if (strlen(argv[0]) > (DM_UUID_LEN - 1)) {
Expand All @@ -173,7 +177,7 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
}

/* Send table string */
r = dm_consult_userspace(lc->uuid, DM_ULOG_CTR,
r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_CTR,
ctr_str, str_size, NULL, NULL);

if (r == -ESRCH) {
Expand All @@ -183,7 +187,7 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,

/* Since the region size does not change, get it now */
rdata_size = sizeof(rdata);
r = dm_consult_userspace(lc->uuid, DM_ULOG_GET_REGION_SIZE,
r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_GET_REGION_SIZE,
NULL, 0, (char *)&rdata, &rdata_size);

if (r) {
Expand Down Expand Up @@ -212,7 +216,7 @@ static void userspace_dtr(struct dm_dirty_log *log)
int r;
struct log_c *lc = log->context;

r = dm_consult_userspace(lc->uuid, DM_ULOG_DTR,
r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_DTR,
NULL, 0,
NULL, NULL);

Expand All @@ -227,7 +231,7 @@ static int userspace_presuspend(struct dm_dirty_log *log)
int r;
struct log_c *lc = log->context;

r = dm_consult_userspace(lc->uuid, DM_ULOG_PRESUSPEND,
r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_PRESUSPEND,
NULL, 0,
NULL, NULL);

Expand All @@ -239,7 +243,7 @@ static int userspace_postsuspend(struct dm_dirty_log *log)
int r;
struct log_c *lc = log->context;

r = dm_consult_userspace(lc->uuid, DM_ULOG_POSTSUSPEND,
r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_POSTSUSPEND,
NULL, 0,
NULL, NULL);

Expand All @@ -252,7 +256,7 @@ static int userspace_resume(struct dm_dirty_log *log)
struct log_c *lc = log->context;

lc->in_sync_hint = 0;
r = dm_consult_userspace(lc->uuid, DM_ULOG_RESUME,
r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_RESUME,
NULL, 0,
NULL, NULL);

Expand Down Expand Up @@ -561,6 +565,7 @@ static int userspace_status(struct dm_dirty_log *log, status_type_t status_type,
char *result, unsigned maxlen)
{
int r = 0;
char *table_args;
size_t sz = (size_t)maxlen;
struct log_c *lc = log->context;

Expand All @@ -577,8 +582,12 @@ static int userspace_status(struct dm_dirty_log *log, status_type_t status_type,
break;
case STATUSTYPE_TABLE:
sz = 0;
DMEMIT("%s %u %s %s", log->type->name, lc->usr_argc + 1,
lc->uuid, lc->usr_argv_str);
table_args = strstr(lc->usr_argv_str, " ");
BUG_ON(!table_args); /* There will always be a ' ' */
table_args++;

DMEMIT("%s %u %s %s ", log->type->name, lc->usr_argc,
lc->uuid, table_args);
break;
}
return (r) ? 0 : (int)sz;
Expand Down
6 changes: 4 additions & 2 deletions drivers/md/dm-log-userspace-transfer.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ static void cn_ulog_callback(void *data)

/**
* dm_consult_userspace
* @uuid: log's uuid (must be DM_UUID_LEN in size)
* @uuid: log's universal unique identifier (must be DM_UUID_LEN in size)
* @luid: log's local unique identifier
* @request_type: found in include/linux/dm-log-userspace.h
* @data: data to tx to the server
* @data_size: size of data in bytes
Expand All @@ -163,7 +164,7 @@ static void cn_ulog_callback(void *data)
*
* Returns: 0 on success, -EXXX on failure
**/
int dm_consult_userspace(const char *uuid, int request_type,
int dm_consult_userspace(const char *uuid, uint64_t luid, int request_type,
char *data, size_t data_size,
char *rdata, size_t *rdata_size)
{
Expand All @@ -190,6 +191,7 @@ int dm_consult_userspace(const char *uuid, int request_type,

memset(tfr, 0, DM_ULOG_PREALLOCED_SIZE - overhead_size);
memcpy(tfr->uuid, uuid, DM_UUID_LEN);
tfr->luid = luid;
tfr->seq = dm_ulog_seq++;

/*
Expand Down
2 changes: 1 addition & 1 deletion drivers/md/dm-log-userspace-transfer.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

int dm_ulog_tfr_init(void);
void dm_ulog_tfr_exit(void);
int dm_consult_userspace(const char *uuid, int request_type,
int dm_consult_userspace(const char *uuid, uint64_t luid, int request_type,
char *data, size_t data_size,
char *rdata, size_t *rdata_size);

Expand Down
8 changes: 7 additions & 1 deletion drivers/md/dm-raid1.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,13 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
*/
dm_rh_inc_pending(ms->rh, &sync);
dm_rh_inc_pending(ms->rh, &nosync);
ms->log_failure = dm_rh_flush(ms->rh) ? 1 : 0;

/*
* If the flush fails on a previous call and succeeds here,
* we must not reset the log_failure variable. We need
* userspace interaction to do that.
*/
ms->log_failure = dm_rh_flush(ms->rh) ? 1 : ms->log_failure;

/*
* Dispatch io.
Expand Down
Loading

0 comments on commit 154f807

Please sign in to comment.