exofs: Add offset/length to exofs_get_io_state
authorBoaz Harrosh <bharrosh@panasas.com>
Tue, 16 Nov 2010 18:09:58 +0000 (20:09 +0200)
committerBoaz Harrosh <bharrosh@panasas.com>
Sun, 7 Aug 2011 02:35:31 +0000 (19:35 -0700)
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>
fs/exofs/exofs.h
fs/exofs/inode.c
fs/exofs/ios.c

index 9f62349a5a5c7a240d560310ad04ec9573919116..fd913ddfd48b505bd3208877ccfc7c0d03fc3d2e 100644 (file)
@@ -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);
index 8472c098445ddbe332c0ee33aa10988cb03a9b15..ba9f0bedcbafa09dd0af69bd524b421067c66bde 100644 (file)
@@ -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;
 
index fbb47ba2cd71fbece4d9d0b26653c4b159e4062e..096405e51b94589b5eee38a2a2c61bba5da29f52 100644 (file)
@@ -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) {