diff options
| -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 9f62349a5a5c..fd913ddfd48b 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) | |||
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | struct exofs_io_state; | 111 | struct exofs_io_state; |
| 112 | typedef void (*exofs_io_done_fn)(struct exofs_io_state *or, void *private); | 112 | typedef void (*exofs_io_done_fn)(struct exofs_io_state *ios, void *private); |
| 113 | 113 | ||
| 114 | struct exofs_io_state { | 114 | struct exofs_io_state { |
| 115 | struct kref kref; | 115 | struct kref kref; |
| @@ -137,6 +137,8 @@ struct exofs_io_state { | |||
| 137 | unsigned out_attr_len; | 137 | unsigned out_attr_len; |
| 138 | struct osd_attr *out_attr; | 138 | struct osd_attr *out_attr; |
| 139 | 139 | ||
| 140 | bool reading; | ||
| 141 | |||
| 140 | /* Variable array of size numdevs */ | 142 | /* Variable array of size numdevs */ |
| 141 | unsigned numdevs; | 143 | unsigned numdevs; |
| 142 | struct exofs_per_dev_state { | 144 | struct exofs_per_dev_state { |
| @@ -218,6 +220,8 @@ void exofs_make_credential(u8 cred_a[OSD_CAP_LEN], | |||
| 218 | int exofs_read_kern(struct osd_dev *od, u8 *cred, struct osd_obj_id *obj, | 220 | int exofs_read_kern(struct osd_dev *od, u8 *cred, struct osd_obj_id *obj, |
| 219 | u64 offset, void *p, unsigned length); | 221 | u64 offset, void *p, unsigned length); |
| 220 | 222 | ||
| 223 | int exofs_get_rw_state(struct exofs_layout *layout, bool is_reading, | ||
| 224 | u64 offset, u64 length, struct exofs_io_state **ios); | ||
| 221 | int exofs_get_io_state(struct exofs_layout *layout, | 225 | int exofs_get_io_state(struct exofs_layout *layout, |
| 222 | struct exofs_io_state **ios); | 226 | struct exofs_io_state **ios); |
| 223 | void exofs_put_io_state(struct exofs_io_state *ios); | 227 | void exofs_put_io_state(struct exofs_io_state *ios); |
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 8472c098445d..ba9f0bedcbaf 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c | |||
| @@ -110,13 +110,6 @@ static int pcol_try_alloc(struct page_collect *pcol) | |||
| 110 | { | 110 | { |
| 111 | unsigned pages; | 111 | unsigned pages; |
| 112 | 112 | ||
| 113 | if (!pcol->ios) { /* First time allocate io_state */ | ||
| 114 | int ret = exofs_get_io_state(&pcol->sbi->layout, &pcol->ios); | ||
| 115 | |||
| 116 | if (ret) | ||
| 117 | return ret; | ||
| 118 | } | ||
| 119 | |||
| 120 | /* TODO: easily support bio chaining */ | 113 | /* TODO: easily support bio chaining */ |
| 121 | pages = exofs_max_io_pages(&pcol->sbi->layout, pcol->expected_pages); | 114 | pages = exofs_max_io_pages(&pcol->sbi->layout, pcol->expected_pages); |
| 122 | 115 | ||
| @@ -269,17 +262,25 @@ static void _unlock_pcol_pages(struct page_collect *pcol, int ret, int rw) | |||
| 269 | static int read_exec(struct page_collect *pcol) | 262 | static int read_exec(struct page_collect *pcol) |
| 270 | { | 263 | { |
| 271 | struct exofs_i_info *oi = exofs_i(pcol->inode); | 264 | struct exofs_i_info *oi = exofs_i(pcol->inode); |
| 272 | struct exofs_io_state *ios = pcol->ios; | 265 | struct exofs_io_state *ios; |
| 273 | struct page_collect *pcol_copy = NULL; | 266 | struct page_collect *pcol_copy = NULL; |
| 274 | int ret; | 267 | int ret; |
| 275 | 268 | ||
| 276 | if (!pcol->pages) | 269 | if (!pcol->pages) |
| 277 | return 0; | 270 | return 0; |
| 278 | 271 | ||
| 272 | if (!pcol->ios) { | ||
| 273 | int ret = exofs_get_rw_state(&pcol->sbi->layout, true, | ||
| 274 | pcol->pg_first << PAGE_CACHE_SHIFT, | ||
| 275 | pcol->length, &pcol->ios); | ||
| 276 | |||
| 277 | if (ret) | ||
| 278 | return ret; | ||
| 279 | } | ||
| 280 | |||
| 281 | ios = pcol->ios; | ||
| 279 | ios->pages = pcol->pages; | 282 | ios->pages = pcol->pages; |
| 280 | ios->nr_pages = pcol->nr_pages; | 283 | ios->nr_pages = pcol->nr_pages; |
| 281 | ios->length = pcol->length; | ||
| 282 | ios->offset = pcol->pg_first << PAGE_CACHE_SHIFT; | ||
| 283 | 284 | ||
| 284 | if (pcol->read_4_write) { | 285 | if (pcol->read_4_write) { |
| 285 | exofs_oi_read(oi, pcol->ios); | 286 | exofs_oi_read(oi, pcol->ios); |
| @@ -507,13 +508,21 @@ static void writepages_done(struct exofs_io_state *ios, void *p) | |||
| 507 | static int write_exec(struct page_collect *pcol) | 508 | static int write_exec(struct page_collect *pcol) |
| 508 | { | 509 | { |
| 509 | struct exofs_i_info *oi = exofs_i(pcol->inode); | 510 | struct exofs_i_info *oi = exofs_i(pcol->inode); |
| 510 | struct exofs_io_state *ios = pcol->ios; | 511 | struct exofs_io_state *ios; |
| 511 | struct page_collect *pcol_copy = NULL; | 512 | struct page_collect *pcol_copy = NULL; |
| 512 | int ret; | 513 | int ret; |
| 513 | 514 | ||
| 514 | if (!pcol->pages) | 515 | if (!pcol->pages) |
| 515 | return 0; | 516 | return 0; |
| 516 | 517 | ||
| 518 | BUG_ON(pcol->ios); | ||
| 519 | ret = exofs_get_rw_state(&pcol->sbi->layout, false, | ||
| 520 | pcol->pg_first << PAGE_CACHE_SHIFT, | ||
| 521 | pcol->length, &pcol->ios); | ||
| 522 | |||
| 523 | if (unlikely(ret)) | ||
| 524 | goto err; | ||
| 525 | |||
| 517 | pcol_copy = kmalloc(sizeof(*pcol_copy), GFP_KERNEL); | 526 | pcol_copy = kmalloc(sizeof(*pcol_copy), GFP_KERNEL); |
| 518 | if (!pcol_copy) { | 527 | if (!pcol_copy) { |
| 519 | EXOFS_ERR("write_exec: Failed to kmalloc(pcol)\n"); | 528 | EXOFS_ERR("write_exec: Failed to kmalloc(pcol)\n"); |
| @@ -523,10 +532,9 @@ static int write_exec(struct page_collect *pcol) | |||
| 523 | 532 | ||
| 524 | *pcol_copy = *pcol; | 533 | *pcol_copy = *pcol; |
| 525 | 534 | ||
| 535 | ios = pcol->ios; | ||
| 526 | ios->pages = pcol_copy->pages; | 536 | ios->pages = pcol_copy->pages; |
| 527 | ios->nr_pages = pcol_copy->nr_pages; | 537 | ios->nr_pages = pcol_copy->nr_pages; |
| 528 | ios->offset = pcol_copy->pg_first << PAGE_CACHE_SHIFT; | ||
| 529 | ios->length = pcol_copy->length; | ||
| 530 | ios->done = writepages_done; | 538 | ios->done = writepages_done; |
| 531 | ios->private = pcol_copy; | 539 | ios->private = pcol_copy; |
| 532 | 540 | ||
diff --git a/fs/exofs/ios.c b/fs/exofs/ios.c index fbb47ba2cd71..096405e51b94 100644 --- a/fs/exofs/ios.c +++ b/fs/exofs/ios.c | |||
| @@ -69,8 +69,8 @@ out: | |||
| 69 | return ret; | 69 | return ret; |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | int exofs_get_io_state(struct exofs_layout *layout, | 72 | int exofs_get_rw_state(struct exofs_layout *layout, bool is_reading, |
| 73 | struct exofs_io_state **pios) | 73 | u64 offset, u64 length, struct exofs_io_state **pios) |
| 74 | { | 74 | { |
| 75 | struct exofs_io_state *ios; | 75 | struct exofs_io_state *ios; |
| 76 | 76 | ||
| @@ -87,10 +87,20 @@ int exofs_get_io_state(struct exofs_layout *layout, | |||
| 87 | 87 | ||
| 88 | ios->layout = layout; | 88 | ios->layout = layout; |
| 89 | ios->obj.partition = layout->s_pid; | 89 | ios->obj.partition = layout->s_pid; |
| 90 | ios->offset = offset; | ||
| 91 | ios->length = length; | ||
| 92 | ios->reading = is_reading; | ||
| 93 | |||
| 90 | *pios = ios; | 94 | *pios = ios; |
| 91 | return 0; | 95 | return 0; |
| 92 | } | 96 | } |
| 93 | 97 | ||
| 98 | int exofs_get_io_state(struct exofs_layout *layout, | ||
| 99 | struct exofs_io_state **ios) | ||
| 100 | { | ||
| 101 | return exofs_get_rw_state(layout, true, 0, 0, ios); | ||
| 102 | } | ||
| 103 | |||
| 94 | void exofs_put_io_state(struct exofs_io_state *ios) | 104 | void exofs_put_io_state(struct exofs_io_state *ios) |
| 95 | { | 105 | { |
| 96 | if (ios) { | 106 | if (ios) { |
