Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 59283
b: refs/heads/master
c: fcac03a
h: refs/heads/master
i:
  59281: 70f8b62
  59279: e6580ed
v: v3
  • Loading branch information
Milan Broz authored and Linus Torvalds committed Jul 12, 2007
1 parent c94a63d commit 189fb1d
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 596f138eede0c113aa655937c8be85fc15ccd61c
refs/heads/master: fcac03abd325e4f7a4cc8fe05fea2793b1c8eb75
48 changes: 43 additions & 5 deletions trunk/drivers/md/dm-exception-store.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ struct pstore {
uint32_t callback_count;
struct commit_callback *callbacks;
struct dm_io_client *io_client;

struct workqueue_struct *metadata_wq;
};

static unsigned sectors_to_pages(unsigned sectors)
Expand Down Expand Up @@ -156,10 +158,24 @@ static void free_area(struct pstore *ps)
ps->area = NULL;
}

struct mdata_req {
struct io_region *where;
struct dm_io_request *io_req;
struct work_struct work;
int result;
};

static void do_metadata(struct work_struct *work)
{
struct mdata_req *req = container_of(work, struct mdata_req, work);

req->result = dm_io(req->io_req, 1, req->where, NULL);
}

/*
* Read or write a chunk aligned and sized block of data from a device.
*/
static int chunk_io(struct pstore *ps, uint32_t chunk, int rw)
static int chunk_io(struct pstore *ps, uint32_t chunk, int rw, int metadata)
{
struct io_region where = {
.bdev = ps->snap->cow->bdev,
Expand All @@ -173,8 +189,23 @@ static int chunk_io(struct pstore *ps, uint32_t chunk, int rw)
.client = ps->io_client,
.notify.fn = NULL,
};
struct mdata_req req;

if (!metadata)
return dm_io(&io_req, 1, &where, NULL);

return dm_io(&io_req, 1, &where, NULL);
req.where = &where;
req.io_req = &io_req;

/*
* Issue the synchronous I/O from a different thread
* to avoid generic_make_request recursion.
*/
INIT_WORK(&req.work, do_metadata);
queue_work(ps->metadata_wq, &req.work);
flush_workqueue(ps->metadata_wq);

return req.result;
}

/*
Expand All @@ -189,7 +220,7 @@ static int area_io(struct pstore *ps, uint32_t area, int rw)
/* convert a metadata area index to a chunk index */
chunk = 1 + ((ps->exceptions_per_area + 1) * area);

r = chunk_io(ps, chunk, rw);
r = chunk_io(ps, chunk, rw, 0);
if (r)
return r;

Expand Down Expand Up @@ -230,7 +261,7 @@ static int read_header(struct pstore *ps, int *new_snapshot)
if (r)
return r;

r = chunk_io(ps, 0, READ);
r = chunk_io(ps, 0, READ, 1);
if (r)
goto bad;

Expand Down Expand Up @@ -292,7 +323,7 @@ static int write_header(struct pstore *ps)
dh->version = cpu_to_le32(ps->version);
dh->chunk_size = cpu_to_le32(ps->snap->chunk_size);

return chunk_io(ps, 0, WRITE);
return chunk_io(ps, 0, WRITE, 1);
}

/*
Expand Down Expand Up @@ -409,6 +440,7 @@ static void persistent_destroy(struct exception_store *store)
{
struct pstore *ps = get_info(store);

destroy_workqueue(ps->metadata_wq);
dm_io_client_destroy(ps->io_client);
vfree(ps->callbacks);
free_area(ps);
Expand Down Expand Up @@ -588,6 +620,12 @@ int dm_create_persistent(struct exception_store *store)
atomic_set(&ps->pending_count, 0);
ps->callbacks = NULL;

ps->metadata_wq = create_singlethread_workqueue("ksnaphd");
if (!ps->metadata_wq) {
DMERR("couldn't start header metadata update thread");
return -ENOMEM;
}

store->destroy = persistent_destroy;
store->read_metadata = persistent_read_metadata;
store->prepare_exception = persistent_prepare;
Expand Down

0 comments on commit 189fb1d

Please sign in to comment.