+ set_fs(oldfs);
+ error = (retval >= 0) ? 0 : retval;
+ return error;
+}
+
+
+struct inode *ioobj_to_inode(struct obd_conn *conn, struct obd_ioobj *o)
+{
+ struct inode *inode = NULL;
+ struct super_block *sb = conn->oc_dev->u.ext2.e2_sb;
+
+ if (!sb || !sb->s_dev) {
+ CDEBUG(D_SUPER, "fatal: device not initialized.\n");
+ EXIT;
+ return NULL;
+ }
+
+ if ( !o->ioo_id ) {
+ CDEBUG(D_INODE, "fatal: invalid obdo %lu\n", (long)o->ioo_id);
+ EXIT;
+ return NULL;
+ }
+
+ inode = filter_inode_from_obj(conn->oc_dev, o->ioo_id, S_IFREG);
+ if (!inode || inode->i_nlink == 0 || is_bad_inode(inode)) {
+ CERROR("from obdo - fatal: invalid inode %ld (%s).\n",
+ (long)o->ioo_id, inode ? inode->i_nlink ? "bad inode" :
+ "no links" : "NULL");
+ if (inode)
+ iput(inode);
+ EXIT;
+ return NULL;
+ }
+
+ return inode;
+}
+
+static int filter_preprw(int cmd, struct obd_conn *conn,
+ int objcount, struct obd_ioobj *obj,
+ int niocount, struct niobuf *nb,
+ struct niobuf *res)
+{
+ struct obd_ioobj *o = obj;
+ struct niobuf *b = nb;
+ struct niobuf *r = res;
+ int i;
+ ENTRY;
+
+ memset(res, 0, sizeof(*res) * niocount);
+
+ for (i = 0; i < objcount; i++, o++) {
+ int j;
+ for (j = 0; j < o->ioo_bufcnt; j++, b++, r++) {
+ struct inode *inode = ioobj_to_inode(conn, o);
+ struct page *page;
+
+ /* FIXME: we need to iput all inodes on error */
+ if (!inode)
+ RETURN(-EINVAL);
+
+ page = lustre_get_page(inode, b->offset >> PAGE_SHIFT);
+ if (IS_ERR(page))
+ RETURN(PTR_ERR(page));
+
+ if (cmd == OBD_BRW_WRITE) {
+ int rc = lustre_prepare_page(0, PAGE_SIZE,page);
+ if (rc)
+ CERROR("i %d j %d objcount %d bufcnt %d , rc %d, offset %Ld\n", i, j, objcount, o->ioo_bufcnt, rc, b->offset);
+ }
+
+ r->addr = (__u64)(unsigned long)page_address(page);
+ r->offset = b->offset;
+ r->page = page;
+ r->len = PAGE_SIZE;
+ }
+ }
+ return 0;
+}
+
+static int filter_commitrw(int cmd, struct obd_conn *conn,
+ int objcount, struct obd_ioobj *obj,
+ int niocount, struct niobuf *res)
+{
+ struct obd_ioobj *o = obj;
+ struct niobuf *r = res;
+ int i;
+ ENTRY;
+
+ for (i = 0; i < objcount; i++, obj++) {
+ int j;
+ for (j = 0 ; j < o->ioo_bufcnt ; j++, r++) {
+ struct page *page = r->page;
+
+ if (!r->page)
+ LBUG();
+
+ if (cmd == OBD_BRW_WRITE) {
+ int rc = lustre_commit_page(page, 0, PAGE_SIZE);
+
+ /* FIXME: still need to iput the other inodes */
+ if (rc)
+ RETURN(rc);
+ } else
+ lustre_put_page(page);
+
+ iput(page->mapping->host);
+ }
+ }
+ RETURN(0);