Whamcloud - gitweb
minor fix for buffer offsets.
[fs/lustre-release.git] / lustre / obdfilter / filter_io_24.c
index eced509..a368f74 100644 (file)
@@ -29,8 +29,6 @@
 #include <linux/pagemap.h> // XXX kill me soon
 #include <linux/version.h>
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-
 #define DEBUG_SUBSYSTEM S_FILTER
 
 #include <linux/iobuf.h>
@@ -86,10 +84,8 @@ static int filter_direct_io(int rw, struct dentry *dchild, struct kiobuf *iobuf,
 {
         struct obd_device *obd = exp->exp_obd;
         struct inode *inode = dchild->d_inode;
-        struct page *page;
-        unsigned long *b = iobuf->blocks;
-        int rc, i, create = (rw == OBD_BRW_WRITE), blocks_per_page;
-        int *cr, cleanup_phase = 0, *created = NULL;
+        int rc, create = (rw == OBD_BRW_WRITE), blocks_per_page;
+        int cleanup_phase = 0, *created = NULL;
         int committed = 0;
         ENTRY;
 
@@ -107,22 +103,11 @@ static int filter_direct_io(int rw, struct dentry *dchild, struct kiobuf *iobuf,
                 GOTO(cleanup, rc);
         cleanup_phase = 2;
 
-        down(&exp->exp_obd->u.filter.fo_alloc_lock);
-        for (i = 0, cr = created, b = iobuf->blocks; i < iobuf->nr_pages; i++){
-                page = iobuf->maplist[i];
-
-                rc = fsfilt_map_inode_page(obd, inode, page, b, cr, create);
-                if (rc) {
-                        CERROR("ino %lu, blk %lu cr %u create %d: rc %d\n",
-                               inode->i_ino, *b, *cr, create, rc);
-                        up(&exp->exp_obd->u.filter.fo_alloc_lock);
-                        GOTO(cleanup, rc);
-                }
-
-                b += blocks_per_page;
-                cr += blocks_per_page;
-        }
-        up(&exp->exp_obd->u.filter.fo_alloc_lock);
+        rc = fsfilt_map_inode_pages(obd, inode, iobuf->maplist,
+                                    iobuf->nr_pages, iobuf->blocks, created,
+                                    create, &obd->u.filter.fo_alloc_lock);
+        if (rc)
+                GOTO(cleanup, rc);
 
         filter_tally_write(&obd->u.filter, iobuf->maplist, iobuf->nr_pages,
                            iobuf->blocks, blocks_per_page);
@@ -157,14 +142,11 @@ static int filter_direct_io(int rw, struct dentry *dchild, struct kiobuf *iobuf,
         if (rc < 0)
                 GOTO(cleanup, rc);
 
-        rc = brw_kiovec(WRITE, 1, &iobuf, inode->i_dev, iobuf->blocks,
-                        1 << inode->i_blkbits);
+        rc = fsfilt_send_bio(obd, inode, iobuf);
+
         CDEBUG(D_INFO, "tried to write %d pages, rc = %d\n",
                iobuf->nr_pages, rc);
-        if (rc != (1 << inode->i_blkbits) * iobuf->nr_pages * blocks_per_page)
-                CERROR("short write?  expected %d, wrote %d\n",
-                       (1 << inode->i_blkbits) * iobuf->nr_pages *
-                       blocks_per_page, rc);
+
         if (rc > 0)
                 rc = 0;
 
@@ -225,16 +207,17 @@ static int filter_range_is_mapped(struct inode *inode, obd_size offset, int len)
 
 int filter_commitrw_write(struct obd_export *exp, struct obdo *oa, int objcount,
                           struct obd_ioobj *obj, int niocount,
-                          struct niobuf_local *res, struct obd_trans_info *oti)
+                          struct niobuf_local *res, struct obd_trans_info *oti,
+                          int rc)
 {
         struct obd_device *obd = exp->exp_obd;
-        struct obd_run_ctxt saved;
+        struct lvfs_run_ctxt saved;
         struct niobuf_local *lnb;
         struct fsfilt_objinfo fso;
         struct iattr iattr = { 0 };
         struct kiobuf *iobuf;
         struct inode *inode = NULL;
-        int rc = 0, i, n, cleanup_phase = 0, err;
+        int i, n, cleanup_phase = 0, err;
         unsigned long now = jiffies; /* DEBUGGING OST TIMEOUTS */
         void *wait_handle;
         ENTRY;
@@ -242,12 +225,15 @@ int filter_commitrw_write(struct obd_export *exp, struct obdo *oa, int objcount,
         LASSERT(objcount == 1);
         LASSERT(current->journal_info == NULL);
 
+        if (rc != 0)
+                GOTO(cleanup, rc);
+
         rc = alloc_kiovec(1, &iobuf);
         if (rc)
                 GOTO(cleanup, rc);
         cleanup_phase = 1;
 
-#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,4,18))
+#ifdef HAVE_KIOBUF_DOVARY
         iobuf->dovary = 0; /* this prevents corruption, not present in 2.4.20 */
 #endif
         rc = expand_kiobuf(iobuf, obj->ioo_bufcnt);
@@ -285,7 +271,7 @@ int filter_commitrw_write(struct obd_export *exp, struct obdo *oa, int objcount,
                         iattr.ia_size = this_size;
         }
 
-        push_ctxt(&saved, &obd->obd_ctxt, NULL);
+        push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
         cleanup_phase = 2;
 
         down(&inode->i_sem);
@@ -311,7 +297,6 @@ int filter_commitrw_write(struct obd_export *exp, struct obdo *oa, int objcount,
         if (time_after(jiffies, now + 15 * HZ))
                 CERROR("slow direct_io %lus\n", (jiffies - now) / HZ);
 
-        filter_grant_commit(exp, niocount, res);
         err = fsfilt_commit_wait(obd, inode, wait_handle);
         if (err)
                 rc = err;
@@ -319,27 +304,24 @@ int filter_commitrw_write(struct obd_export *exp, struct obdo *oa, int objcount,
                 LASSERT(oti->oti_transno <= obd->obd_last_committed);
         if (time_after(jiffies, now + 15 * HZ))
                 CERROR("slow commitrw commit %lus\n", (jiffies - now) / HZ);
-
 cleanup:
+        filter_grant_commit(exp, niocount, res);
+
         switch (cleanup_phase) {
         case 2:
-                pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+                pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
                 LASSERT(current->journal_info == NULL);
         case 1:
                 free_kiovec(1, &iobuf);
         case 0:
                 for (i = 0, lnb = res; i < obj->ioo_bufcnt; i++, lnb++) {
-                        /* flip_.. gets a ref, while free_page only frees
-                         * when it decrefs to 0 */
-                        if (rc == 0)
-                                flip_into_page_cache(inode, lnb->page);
-                        __free_page(lnb->page);
+                        filter_release_write_page(&obd->u.filter,
+                                                  res->dentry->d_inode, lnb,
+                                                  rc);
                 }
+
                 f_dput(res->dentry);
         }
 
         RETURN(rc);
 }
-
-#endif
-