}
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) {