}
 
 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;
        unsigned                out_attr_len;
        struct osd_attr         *out_attr;
 
+       bool                    reading;
+
        /* Variable array of size numdevs */
        unsigned numdevs;
        struct exofs_per_dev_state {
 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);
 
 {
        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);
 
 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);
 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");
 
        *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;
 
 
        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;
 
 
        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) {