diff options
author | Boaz Harrosh <bharrosh@panasas.com> | 2010-11-16 20:09:58 +0200 |
---|---|---|
committer | Boaz Harrosh <bharrosh@panasas.com> | 2011-08-06 19:35:31 -0700 |
commit | e1042ba0991aab80ced34f7dade6ec25f22b4304 (patch) | |
tree | 5953383f9235df91acfc2315a5c6fbdfb359ecf1 | |
parent | 16f75bb35d54b44356f496272c013f7ace5fa698 (diff) |
exofs: Add offset/length to exofs_get_io_state
In future raid code we will need to know the IO offset/length
and if it's a read or write to determine some of the array
sizes we'll need.
So add a new exofs_get_rw_state() API for use when
writeing/reading. All other simple cases are left using the
old way.
The major change to this is that now we need to call
exofs_get_io_state later at inode.c::read_exec and
inode.c::write_exec when we actually know these things. So this
patch is kept separate so I can test things apart from other
changes.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
-rw-r--r-- | fs/exofs/exofs.h | 6 | ||||
-rw-r--r-- | fs/exofs/inode.c | 34 | ||||
-rw-r--r-- | fs/exofs/ios.c | 14 |
3 files changed, 38 insertions, 16 deletions
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h index 9f62349a5a5..fd913ddfd48 100644 --- a/fs/exofs/exofs.h +++ b/fs/exofs/exofs.h @@ -109,7 +109,7 @@ static inline osd_id exofs_oi_objno(struct exofs_i_info *oi) } struct exofs_io_state; -typedef void (*exofs_io_done_fn)(struct exofs_io_state *or, void *private); +typedef void (*exofs_io_done_fn)(struct exofs_io_state *ios, void *private); struct exofs_io_state { struct kref kref; @@ -137,6 +137,8 @@ struct exofs_io_state { unsigned out_attr_len; struct osd_attr *out_attr; + bool reading; + /* Variable array of size numdevs */ unsigned numdevs; struct exofs_per_dev_state { @@ -218,6 +220,8 @@ void exofs_make_credential(u8 cred_a[OSD_CAP_LEN], int exofs_read_kern(struct osd_dev *od, u8 *cred, struct osd_obj_id *obj, u64 offset, void *p, unsigned length); +int exofs_get_rw_state(struct exofs_layout *layout, bool is_reading, + u64 offset, u64 length, struct exofs_io_state **ios); int exofs_get_io_state(struct exofs_layout *layout, struct exofs_io_state **ios); void exofs_put_io_state(struct exofs_io_state *ios); diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 8472c098445..ba9f0bedcba 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c @@ -110,13 +110,6 @@ static int pcol_try_alloc(struct page_collect *pcol) { unsigned pages; - if (!pcol->ios) { /* First time allocate io_state */ - int ret = exofs_get_io_state(&pcol->sbi->layout, &pcol->ios); - - if (ret) - return ret; - } - /* TODO: easily support bio chaining */ pages = exofs_max_io_pages(&pcol->sbi->layout, pcol->expected_pages); @@ -269,17 +262,25 @@ static void _unlock_pcol_pages(struct page_collect *pcol, int ret, int rw) static int read_exec(struct page_collect *pcol) { struct exofs_i_info *oi = exofs_i(pcol->inode); - struct exofs_io_state *ios = pcol->ios; + struct exofs_io_state *ios; struct page_collect *pcol_copy = NULL; int ret; if (!pcol->pages) return 0; + if (!pcol->ios) { + int ret = exofs_get_rw_state(&pcol->sbi->layout, true, + pcol->pg_first << PAGE_CACHE_SHIFT, + pcol->length, &pcol->ios); + + if (ret) + return ret; + } + + ios = pcol->ios; ios->pages = pcol->pages; ios->nr_pages = pcol->nr_pages; - ios->length = pcol->length; - ios->offset = pcol->pg_first << PAGE_CACHE_SHIFT; if (pcol->read_4_write) { exofs_oi_read(oi, pcol->ios); @@ -507,13 +508,21 @@ static void writepages_done(struct exofs_io_state *ios, void *p) static int write_exec(struct page_collect *pcol) { struct exofs_i_info *oi = exofs_i(pcol->inode); - struct exofs_io_state *ios = pcol->ios; + struct exofs_io_state *ios; struct page_collect *pcol_copy = NULL; int ret; if (!pcol->pages) return 0; + BUG_ON(pcol->ios); + ret = exofs_get_rw_state(&pcol->sbi->layout, false, + pcol->pg_first << PAGE_CACHE_SHIFT, + pcol->length, &pcol->ios); + + if (unlikely(ret)) + goto err; + pcol_copy = kmalloc(sizeof(*pcol_copy), GFP_KERNEL); if (!pcol_copy) { EXOFS_ERR("write_exec: Failed to kmalloc(pcol)\n"); @@ -523,10 +532,9 @@ static int write_exec(struct page_collect *pcol) *pcol_copy = *pcol; + ios = pcol->ios; ios->pages = pcol_copy->pages; ios->nr_pages = pcol_copy->nr_pages; - ios->offset = pcol_copy->pg_first << PAGE_CACHE_SHIFT; - ios->length = pcol_copy->length; ios->done = writepages_done; ios->private = pcol_copy; diff --git a/fs/exofs/ios.c b/fs/exofs/ios.c index fbb47ba2cd7..096405e51b9 100644 --- a/fs/exofs/ios.c +++ b/fs/exofs/ios.c @@ -69,8 +69,8 @@ out: return ret; } -int exofs_get_io_state(struct exofs_layout *layout, - struct exofs_io_state **pios) +int exofs_get_rw_state(struct exofs_layout *layout, bool is_reading, + u64 offset, u64 length, struct exofs_io_state **pios) { struct exofs_io_state *ios; @@ -87,10 +87,20 @@ int exofs_get_io_state(struct exofs_layout *layout, ios->layout = layout; ios->obj.partition = layout->s_pid; + ios->offset = offset; + ios->length = length; + ios->reading = is_reading; + *pios = ios; return 0; } +int exofs_get_io_state(struct exofs_layout *layout, + struct exofs_io_state **ios) +{ + return exofs_get_rw_state(layout, true, 0, 0, ios); +} + void exofs_put_io_state(struct exofs_io_state *ios) { if (ios) { |