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>
This commit is contained in:
parent
16f75bb35d
commit
e1042ba099
|
@ -109,7 +109,7 @@ static inline osd_id exofs_oi_objno(struct exofs_i_info *oi)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct exofs_io_state;
|
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 exofs_io_state {
|
||||||
struct kref kref;
|
struct kref kref;
|
||||||
|
@ -137,6 +137,8 @@ struct exofs_io_state {
|
||||||
unsigned out_attr_len;
|
unsigned out_attr_len;
|
||||||
struct osd_attr *out_attr;
|
struct osd_attr *out_attr;
|
||||||
|
|
||||||
|
bool reading;
|
||||||
|
|
||||||
/* Variable array of size numdevs */
|
/* Variable array of size numdevs */
|
||||||
unsigned numdevs;
|
unsigned numdevs;
|
||||||
struct exofs_per_dev_state {
|
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,
|
int exofs_read_kern(struct osd_dev *od, u8 *cred, struct osd_obj_id *obj,
|
||||||
u64 offset, void *p, unsigned length);
|
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,
|
int exofs_get_io_state(struct exofs_layout *layout,
|
||||||
struct exofs_io_state **ios);
|
struct exofs_io_state **ios);
|
||||||
void exofs_put_io_state(struct exofs_io_state *ios);
|
void exofs_put_io_state(struct exofs_io_state *ios);
|
||||||
|
|
|
@ -110,13 +110,6 @@ static int pcol_try_alloc(struct page_collect *pcol)
|
||||||
{
|
{
|
||||||
unsigned pages;
|
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 */
|
/* TODO: easily support bio chaining */
|
||||||
pages = exofs_max_io_pages(&pcol->sbi->layout, pcol->expected_pages);
|
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)
|
static int read_exec(struct page_collect *pcol)
|
||||||
{
|
{
|
||||||
struct exofs_i_info *oi = exofs_i(pcol->inode);
|
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;
|
struct page_collect *pcol_copy = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!pcol->pages)
|
if (!pcol->pages)
|
||||||
return 0;
|
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->pages = pcol->pages;
|
||||||
ios->nr_pages = pcol->nr_pages;
|
ios->nr_pages = pcol->nr_pages;
|
||||||
ios->length = pcol->length;
|
|
||||||
ios->offset = pcol->pg_first << PAGE_CACHE_SHIFT;
|
|
||||||
|
|
||||||
if (pcol->read_4_write) {
|
if (pcol->read_4_write) {
|
||||||
exofs_oi_read(oi, pcol->ios);
|
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)
|
static int write_exec(struct page_collect *pcol)
|
||||||
{
|
{
|
||||||
struct exofs_i_info *oi = exofs_i(pcol->inode);
|
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;
|
struct page_collect *pcol_copy = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!pcol->pages)
|
if (!pcol->pages)
|
||||||
return 0;
|
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);
|
pcol_copy = kmalloc(sizeof(*pcol_copy), GFP_KERNEL);
|
||||||
if (!pcol_copy) {
|
if (!pcol_copy) {
|
||||||
EXOFS_ERR("write_exec: Failed to kmalloc(pcol)\n");
|
EXOFS_ERR("write_exec: Failed to kmalloc(pcol)\n");
|
||||||
|
@ -523,10 +532,9 @@ static int write_exec(struct page_collect *pcol)
|
||||||
|
|
||||||
*pcol_copy = *pcol;
|
*pcol_copy = *pcol;
|
||||||
|
|
||||||
|
ios = pcol->ios;
|
||||||
ios->pages = pcol_copy->pages;
|
ios->pages = pcol_copy->pages;
|
||||||
ios->nr_pages = pcol_copy->nr_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->done = writepages_done;
|
||||||
ios->private = pcol_copy;
|
ios->private = pcol_copy;
|
||||||
|
|
||||||
|
|
|
@ -69,8 +69,8 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int exofs_get_io_state(struct exofs_layout *layout,
|
int exofs_get_rw_state(struct exofs_layout *layout, bool is_reading,
|
||||||
struct exofs_io_state **pios)
|
u64 offset, u64 length, struct exofs_io_state **pios)
|
||||||
{
|
{
|
||||||
struct exofs_io_state *ios;
|
struct exofs_io_state *ios;
|
||||||
|
|
||||||
|
@ -87,10 +87,20 @@ int exofs_get_io_state(struct exofs_layout *layout,
|
||||||
|
|
||||||
ios->layout = layout;
|
ios->layout = layout;
|
||||||
ios->obj.partition = layout->s_pid;
|
ios->obj.partition = layout->s_pid;
|
||||||
|
ios->offset = offset;
|
||||||
|
ios->length = length;
|
||||||
|
ios->reading = is_reading;
|
||||||
|
|
||||||
*pios = ios;
|
*pios = ios;
|
||||||
return 0;
|
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)
|
void exofs_put_io_state(struct exofs_io_state *ios)
|
||||||
{
|
{
|
||||||
if (ios) {
|
if (ios) {
|
||||||
|
|
Loading…
Reference in New Issue