[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[dm-devel] [PATCH 2/3]: region based notifications for dm-io



This patch moves all targets using dm-io to the new interface.
Also, in dm-log.c, a potention memory leak has been fixed.

Signed-off-by: Stefan Bader <shbader de ibm com>

---
drivers/md/dm-exception-store.c |   31 +++++++++++-----
drivers/md/dm-log.c             |   76 ++++++++++++++++++++++++----------------
drivers/md/dm-raid1.c           |   29 +++++++++------
drivers/md/dm-snap.c            |    2 -
drivers/md/kcopyd.c             |   36 +++++++++++-------
drivers/md/kcopyd.h             |    4 +-
6 files changed, 111 insertions(+), 67 deletions(-)
This patch moves all targets using dm-io to the new interface.
Also, in dm-log.c, a potention memory leak has been fixed.

Signed-off-by: Stefan Bader <shbader de ibm com>

---
 drivers/md/dm-exception-store.c |   31 +++++++++++-----
 drivers/md/dm-log.c             |   76 ++++++++++++++++++++++++----------------
 drivers/md/dm-raid1.c           |   29 +++++++++------
 drivers/md/dm-snap.c            |    2 -
 drivers/md/kcopyd.c             |   36 +++++++++++-------
 drivers/md/kcopyd.h             |    4 +-
 6 files changed, 111 insertions(+), 67 deletions(-)

Index: linux-2.6.22-rc2/drivers/md/dm-exception-store.c
===================================================================
--- linux-2.6.22-rc2.orig/drivers/md/dm-exception-store.c
+++ linux-2.6.22-rc2/drivers/md/dm-exception-store.c
@@ -161,20 +161,31 @@ static void free_area(struct pstore *ps)
  */
 static int chunk_io(struct pstore *ps, uint32_t chunk, int rw)
 {
-	struct io_region where = {
+	struct dm_io_region where = {
 		.bdev = ps->snap->cow->bdev,
 		.sector = ps->snap->chunk_size * chunk,
 		.count = ps->snap->chunk_size,
 	};
-	struct dm_io_request io_req = {
-		.bi_rw = rw,
+	struct dm_io_request_new *io_req;
+	int rc;
+
+	io_req = dm_io_request_create(ps->io_client, GFP_NOIO);
+	if (!io_req)
+		return -ENOMEM;
+
+
+	*io_req = (struct dm_io_request_new) {
+		.rw = rw | BIO_RW_SYNC,
 		.mem.type = DM_IO_VMA,
 		.mem.ptr.vma = ps->area,
-		.client = ps->io_client,
-		.notify.fn = NULL,
 	};
 
-	return dm_io(&io_req, 1, &where, NULL);
+	dm_io_request_submit(io_req, 1, &where);
+	rc = dm_io_request_wait_for_completion(io_req) != 0L ? -EIO : 0;
+
+	dm_io_request_put(io_req);
+
+	return rc;
 }
 
 /*
@@ -221,8 +232,8 @@ static int read_header(struct pstore *ps
 		chunk_size_supplied = 0;
 	}
 
-	ps->io_client = dm_io_client_create(sectors_to_pages(ps->snap->
-							     chunk_size));
+	ps->io_client = dm_io_client_create_new(
+				sectors_to_pages(ps->snap->chunk_size)*4, 1);
 	if (IS_ERR(ps->io_client))
 		return PTR_ERR(ps->io_client);
 
@@ -267,8 +278,8 @@ static int read_header(struct pstore *ps
 	ps->snap->chunk_mask = chunk_size - 1;
 	ps->snap->chunk_shift = ffs(chunk_size) - 1;
 
-	r = dm_io_client_resize(sectors_to_pages(ps->snap->chunk_size),
-				ps->io_client);
+	r = dm_io_client_resize_new(ps->io_client,
+			sectors_to_pages(ps->snap->chunk_size)*4, 1);
 	if (r)
 		return r;
 
Index: linux-2.6.22-rc2/drivers/md/dm-log.c
===================================================================
--- linux-2.6.22-rc2.orig/drivers/md/dm-log.c
+++ linux-2.6.22-rc2/drivers/md/dm-log.c
@@ -149,7 +149,7 @@ struct log_c {
 		FORCESYNC,	/* Force a sync to happen */
 	} sync;
 
-	struct dm_io_request io_req;
+	struct dm_io_client *client;
 
 	/*
 	 * Disk log fields
@@ -158,7 +158,7 @@ struct log_c {
 	struct dm_dev *log_dev;
 	struct log_header header;
 
-	struct io_region header_location;
+	struct dm_io_region header_location;
 	struct log_header *disk_header;
 };
 
@@ -204,11 +204,28 @@ static void header_from_disk(struct log_
 
 static int rw_header(struct log_c *lc, int rw)
 {
-	lc->io_req.bi_rw = rw;
-	lc->io_req.mem.ptr.vma = lc->disk_header;
-	lc->io_req.notify.fn = NULL;
+	struct dm_io_request_new *io_req;
+	int rc;
 
-	return dm_io(&lc->io_req, 1, &lc->header_location, NULL);
+	io_req = dm_io_request_create(lc->client, GFP_NOIO);
+	if (!io_req)
+		return -ENOMEM;
+
+	*io_req = (struct dm_io_request_new) {
+		.rw = rw | BIO_RW_SYNC,
+		.mem.type = DM_IO_VMA,
+		.mem.ptr.vma = lc->disk_header,
+	};
+
+	rc = dm_io_request_submit(io_req, 1, &lc->header_location);
+	if (!rc) {
+		if (dm_io_request_wait_for_completion(io_req) != 0L)
+			rc = -EIO;
+	}
+
+	dm_io_request_put(io_req);
+
+	return rc;
 }
 
 static int read_header(struct log_c *log)
@@ -317,8 +334,7 @@ static int create_log_context(struct dir
 		lc->clean_bits = vmalloc(bitset_size);
 		if (!lc->clean_bits) {
 			DMWARN("couldn't allocate clean bitset");
-			kfree(lc);
-			return -ENOMEM;
+			goto create_clean_bits_failed;
 		}
 		lc->disk_header = NULL;
 	} else {
@@ -333,21 +349,18 @@ static int create_log_context(struct dir
 		buf_size = dm_round_up((LOG_OFFSET << SECTOR_SHIFT) +
 				       bitset_size, ti->limits.hardsect_size);
 		lc->header_location.count = buf_size >> SECTOR_SHIFT;
-		lc->io_req.mem.type = DM_IO_VMA;
-		lc->io_req.client = dm_io_client_create(dm_div_up(buf_size,
-								   PAGE_SIZE));
-		if (IS_ERR(lc->io_req.client)) {
-			r = PTR_ERR(lc->io_req.client);
+
+		lc->client = dm_io_client_create_new(2, 1);
+		if (IS_ERR(lc->client)) {
+			r = PTR_ERR(lc->client);
 			DMWARN("couldn't allocate disk io client");
-			kfree(lc);
-			return -ENOMEM;
+			goto create_client_failed;
 		}
 
 		lc->disk_header = vmalloc(buf_size);
 		if (!lc->disk_header) {
 			DMWARN("couldn't allocate disk log buffer");
-			kfree(lc);
-			return -ENOMEM;
+			goto create_disk_header_failed;
 		}
 
 		lc->clean_bits = (void *)lc->disk_header +
@@ -359,11 +372,7 @@ static int create_log_context(struct dir
 	lc->sync_bits = vmalloc(bitset_size);
 	if (!lc->sync_bits) {
 		DMWARN("couldn't allocate sync bitset");
-		if (!dev)
-			vfree(lc->clean_bits);
-		vfree(lc->disk_header);
-		kfree(lc);
-		return -ENOMEM;
+		goto create_sync_bits_failed;
 	}
 	memset(lc->sync_bits, (sync == NOSYNC) ? -1 : 0, bitset_size);
 	lc->sync_count = (sync == NOSYNC) ? region_count : 0;
@@ -371,18 +380,27 @@ static int create_log_context(struct dir
 	lc->recovering_bits = vmalloc(bitset_size);
 	if (!lc->recovering_bits) {
 		DMWARN("couldn't allocate sync bitset");
-		vfree(lc->sync_bits);
-		if (!dev)
-			vfree(lc->clean_bits);
-		vfree(lc->disk_header);
-		kfree(lc);
-		return -ENOMEM;
+		goto create_recovering_bits_failed;
 	}
 	memset(lc->recovering_bits, 0, bitset_size);
 	lc->sync_search = 0;
 	log->context = lc;
 
 	return 0;
+
+    create_recovering_bits_failed:
+	vfree(lc->sync_bits);
+    create_sync_bits_failed:
+	if (!dev)
+		vfree(lc->clean_bits);
+	vfree(lc->disk_header);
+    create_disk_header_failed:
+	dm_io_client_destroy(lc->client);
+    create_client_failed:
+    create_clean_bits_failed:
+	kfree(lc);
+
+	return -ENOMEM;
 }
 
 static int core_ctr(struct dirty_log *log, struct dm_target *ti,
@@ -442,7 +460,7 @@ static void disk_dtr(struct dirty_log *l
 
 	dm_put_device(lc->ti, lc->log_dev);
 	vfree(lc->disk_header);
-	dm_io_client_destroy(lc->io_req.client);
+	dm_io_client_destroy(lc->client);
 	destroy_log_context(lc);
 }
 
Index: linux-2.6.22-rc2/drivers/md/dm-raid1.c
===================================================================
--- linux-2.6.22-rc2.orig/drivers/md/dm-raid1.c
+++ linux-2.6.22-rc2/drivers/md/dm-raid1.c
@@ -641,7 +641,7 @@ static int recover(struct mirror_set *ms
 {
 	int r;
 	unsigned int i;
-	struct io_region from, to[KCOPYD_MAX_REGIONS], *dest;
+	struct dm_io_region from, to[KCOPYD_MAX_REGIONS], *dest;
 	struct mirror *m;
 	unsigned long flags = 0;
 
@@ -761,11 +761,11 @@ static void do_reads(struct mirror_set *
  * RECOVERING:	delay the io until recovery completes
  * NOSYNC:	increment pending, just write to the default mirror
  *---------------------------------------------------------------*/
-static void write_callback(unsigned long error, void *context)
+static void write_callback(struct dm_io_notify_data *nd)
 {
 	unsigned int i;
 	int uptodate = 1;
-	struct bio *bio = (struct bio *) context;
+	struct bio *bio = (struct bio *) nd->context;
 	struct mirror_set *ms;
 
 	ms = bio_get_ms(bio);
@@ -778,14 +778,14 @@ static void write_callback(unsigned long
 	 * regions with the same code.
 	 */
 
-	if (error) {
+	if (nd->error_bits) {
 		/*
 		 * only error the io if all mirrors failed.
 		 * FIXME: bogus
 		 */
 		uptodate = 0;
 		for (i = 0; i < ms->nr_mirrors; i++)
-			if (!test_bit(i, &error)) {
+			if (!test_bit(i, &nd->error_bits)) {
 				uptodate = 1;
 				break;
 			}
@@ -796,15 +796,21 @@ static void write_callback(unsigned long
 static void do_write(struct mirror_set *ms, struct bio *bio)
 {
 	unsigned int i;
-	struct io_region io[KCOPYD_MAX_REGIONS+1];
+	struct dm_io_region io[KCOPYD_MAX_REGIONS+1];
 	struct mirror *m;
-	struct dm_io_request io_req = {
-		.bi_rw = WRITE,
+	struct dm_io_request_new *io_req;
+
+	io_req = dm_io_request_create(ms->io_client, GFP_NOIO);
+	if (!io_req)
+		return;
+
+	*io_req = (struct dm_io_request_new) {
+		.rw = WRITE,
 		.mem.type = DM_IO_BVEC,
 		.mem.ptr.bvec = bio->bi_io_vec + bio->bi_idx,
+		.notify.type = DM_IO_NOTIFY_REQUEST,
 		.notify.fn = write_callback,
 		.notify.context = bio,
-		.client = ms->io_client,
 	};
 
 	for (i = 0; i < ms->nr_mirrors; i++) {
@@ -817,7 +823,8 @@ static void do_write(struct mirror_set *
 
 	bio_set_ms(bio, ms);
 
-	(void) dm_io(&io_req, ms->nr_mirrors, io, NULL);
+	(void) dm_io_request_submit(io_req, ms->nr_mirrors, io);
+	dm_io_request_put(io_req);
 }
 
 static void do_writes(struct mirror_set *ms, struct bio_list *writes)
@@ -933,7 +940,7 @@ static struct mirror_set *alloc_context(
 	ms->in_sync = 0;
 	ms->default_mirror = &ms->mirror[DEFAULT_MIRROR];
 
-	ms->io_client = dm_io_client_create(DM_IO_PAGES);
+	ms->io_client = dm_io_client_create_new(256, nr_mirrors);
 	if (IS_ERR(ms->io_client)) {
 		ti->error = "Error creating dm_io client";
 		kfree(ms);
Index: linux-2.6.22-rc2/drivers/md/kcopyd.c
===================================================================
--- linux-2.6.22-rc2.orig/drivers/md/kcopyd.c
+++ linux-2.6.22-rc2/drivers/md/kcopyd.c
@@ -175,13 +175,13 @@ struct kcopyd_job {
 	 * Either READ or WRITE
 	 */
 	int rw;
-	struct io_region source;
+	struct dm_io_region source;
 
 	/*
 	 * The destinations for the transfer.
 	 */
 	unsigned int num_dests;
-	struct io_region dests[KCOPYD_MAX_REGIONS];
+	struct dm_io_region dests[KCOPYD_MAX_REGIONS];
 
 	sector_t offset;
 	unsigned int nr_pages;
@@ -310,13 +310,13 @@ static int run_complete_job(struct kcopy
 	return 0;
 }
 
-static void complete_io(unsigned long error, void *context)
+static void complete_io(struct dm_io_notify_data *nd)
 {
-	struct kcopyd_job *job = (struct kcopyd_job *) context;
+	struct kcopyd_job *job = (struct kcopyd_job *) nd->context;
 
-	if (error) {
+	if (nd->error_bits) {
 		if (job->rw == WRITE)
-			job->write_err |= error;
+			job->write_err |= nd->error_bits;
 		else
 			job->read_err = 1;
 
@@ -345,20 +345,28 @@ static void complete_io(unsigned long er
 static int run_io_job(struct kcopyd_job *job)
 {
 	int r;
-	struct dm_io_request io_req = {
-		.bi_rw = job->rw,
+	struct dm_io_request_new *io_req;
+
+	io_req = dm_io_request_create(job->kc->io_client, GFP_NOIO);
+	if (!io_req)
+		return -ENOMEM;
+
+	*io_req = (struct dm_io_request_new) {
+		.rw = job->rw,
 		.mem.type = DM_IO_PAGE_LIST,
 		.mem.ptr.pl = job->pages,
 		.mem.offset = job->offset,
+		.notify.type = DM_IO_NOTIFY_REQUEST,
 		.notify.fn = complete_io,
 		.notify.context = job,
-		.client = job->kc->io_client,
 	};
 
 	if (job->rw == READ)
-		r = dm_io(&io_req, 1, &job->source, NULL);
+		r = dm_io_request_submit(io_req, 1, &job->source);
 	else
-		r = dm_io(&io_req, job->num_dests, job->dests, NULL);
+		r = dm_io_request_submit(io_req, job->num_dests, job->dests);
+
+	dm_io_request_put(io_req);
 
 	return r;
 }
@@ -529,8 +537,8 @@ static void split_job(struct kcopyd_job 
 		segment_complete(0, 0u, job);
 }
 
-int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from,
-		unsigned int num_dests, struct io_region *dests,
+int kcopyd_copy(struct kcopyd_client *kc, struct dm_io_region *from,
+		unsigned int num_dests, struct dm_io_region *dests,
 		unsigned int flags, kcopyd_notify_fn fn, void *context)
 {
 	struct kcopyd_job *job;
@@ -677,7 +685,7 @@ int kcopyd_client_create(unsigned int nr
 		return r;
 	}
 
-	kc->io_client = dm_io_client_create(nr_pages);
+	kc->io_client = dm_io_client_create_new(nr_pages*4, KCOPYD_MAX_REGIONS);
 	if (IS_ERR(kc->io_client)) {
 		r = PTR_ERR(kc->io_client);
 		client_free_pages(kc);
Index: linux-2.6.22-rc2/drivers/md/kcopyd.h
===================================================================
--- linux-2.6.22-rc2.orig/drivers/md/kcopyd.h
+++ linux-2.6.22-rc2/drivers/md/kcopyd.h
@@ -35,8 +35,8 @@ void kcopyd_client_destroy(struct kcopyd
 typedef void (*kcopyd_notify_fn)(int read_err,
 				 unsigned int write_err, void *context);
 
-int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from,
-		unsigned int num_dests, struct io_region *dests,
+int kcopyd_copy(struct kcopyd_client *kc, struct dm_io_region *from,
+		unsigned int num_dests, struct dm_io_region *dests,
 		unsigned int flags, kcopyd_notify_fn fn, void *context);
 
 #endif
Index: linux-2.6.22-rc2/drivers/md/dm-snap.c
===================================================================
--- linux-2.6.22-rc2.orig/drivers/md/dm-snap.c
+++ linux-2.6.22-rc2/drivers/md/dm-snap.c
@@ -776,7 +776,7 @@ static void copy_callback(int read_err, 
 static void start_copy(struct pending_exception *pe)
 {
 	struct dm_snapshot *s = pe->snap;
-	struct io_region src, dest;
+	struct dm_io_region src, dest;
 	struct block_device *bdev = s->origin->bdev;
 	sector_t dev_size;
 

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]