Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 154f807e authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 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
parents 9b6a3df3 ae0b7448
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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";
@@ -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;
+4 −0
Original line number Diff line number Diff line
@@ -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);
+24 −15
Original line number Diff line number Diff line
@@ -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;
@@ -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)
@@ -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;
@@ -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, "%llu", (unsigned long long)ti->len);
	for (i = 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);

	*ctr_str = str;
	return str_size;
@@ -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)) {
@@ -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) {
@@ -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) {
@@ -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);

@@ -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);

@@ -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);

@@ -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);

@@ -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;

@@ -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;
+4 −2
Original line number Diff line number Diff line
@@ -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
@@ -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)
{
@@ -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++;

	/*
+1 −1
Original line number Diff line number Diff line
@@ -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);

Loading