#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>
{
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;
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);
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;
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;
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);
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);
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;
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
-