[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
- From: "Stefan Bader" <Stefan Bader de ibm com>
- To: "device-mapper development" <dm-devel redhat com>, "Alasdair Kergon" <agk redhat com>
- Cc: wein de ibm com, heinzm redhat com
- Subject: [dm-devel] [PATCH 2/3]: region based notifications for dm-io
- Date: Tue, 5 Jun 2007 15:05:36 +0200
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]