#define DEBUG_SUBSYSTEM S_OST
#include <linux/obd_class.h>
+#include <linux/lustre_net.h>
#include <linux/lustre_lib.h>
+#include <linux/lustre_ha.h>
+
+static int sync_io_timeout(void *data)
+{
+ struct io_cb_data *cbd = data;
+ struct ptlrpc_bulk_desc *desc = cbd->desc;
+
+ ENTRY;
+ desc->b_connection->c_level = LUSTRE_CONN_RECOVD;
+ desc->b_flags |= PTL_RPC_FL_TIMEOUT;
+ if (desc->b_client && desc->b_client->cli_recovd &&
+ class_signal_client_failure) {
+ /* XXXshaver Do we need a resend strategy, or do we just
+ * XXXshaver return -ERESTARTSYS and punt it?
+ */
+ CERROR("signalling failure of client %p\n", desc->b_client);
+ class_signal_client_failure(desc->b_client);
+
+ /* We go back to sleep, until we're resumed or interrupted. */
+ RETURN(0);
+ }
+
+ /* If we can't be recovered, just abort the syscall with -ETIMEDOUT. */
+ RETURN(1);
+}
+
+static int sync_io_intr(void *data)
+{
+ struct io_cb_data *cbd = data;
+ struct ptlrpc_bulk_desc *desc = cbd->desc;
+
+ ENTRY;
+ desc->b_flags |= PTL_RPC_FL_INTR;
+ RETURN(1); /* ignored, as of this writing */
+}
+
+int ll_sync_io_cb(struct io_cb_data *data, int err, int phase)
+{
+ int ret;
+ ENTRY;
+
+ if (phase == CB_PHASE_START) {
+ struct l_wait_info lwi;
+ lwi = LWI_TIMEOUT_INTR(obd_timeout * HZ, sync_io_timeout,
+ sync_io_intr, data);
+ ret = l_wait_event(data->waitq, data->complete, &lwi);
+ if (atomic_dec_and_test(&data->refcount))
+ OBD_FREE(data, sizeof(*data));
+ if (ret == -ERESTARTSYS)
+ return ret;
+ } else if (phase == CB_PHASE_FINISH) {
+ data->err = err;
+ data->complete = 1;
+ wake_up(&data->waitq);
+ if (atomic_dec_and_test(&data->refcount))
+ OBD_FREE(data, sizeof(*data));
+ return err;
+ } else
+ LBUG();
+ EXIT;
+ return 0;
+}
+
+struct io_cb_data *ll_init_cb(void)
+{
+ struct io_cb_data *d;
+
+
+ OBD_ALLOC(d, sizeof(*d));
+ if (d) {
+ init_waitqueue_head(&d->waitq);
+ atomic_set(&d->refcount, 2);
+ }
+ RETURN(d);
+}
/*
* Remove page from dirty list
CERROR("page index %lu has error\n", index);
GOTO(err_page, rc = -EIO);
}
- kmap(page);
}
return page;
page = grab_cache_page(mapping, index); /* locked page */
if (!IS_ERR(page)) {
+ kmap(page);
/* Note: Called with "O" and "PAGE_SIZE" this is essentially
* a no-op for most filesystems, because we write the whole
* page. For partial-page I/O this will read in the page.
LBUG();
GOTO(err_unlock, rc = -EIO);
}
-
- kmap(page);
}
return page;
return ERR_PTR(rc);
}
-int lustre_commit_page(struct page *page, unsigned from, unsigned to)
+int lustre_commit_write(struct page *page, unsigned from, unsigned to)
{
struct inode *inode = page->mapping->host;
- int err = 0;
-
- SetPageUptodate(page);
- set_page_clean(page);
+ int err;
- page->mapping->a_ops->commit_write(NULL, page, from, to);
- if (IS_SYNC(inode))
+ err = page->mapping->a_ops->commit_write(NULL, page, from, to);
+ if (!err && IS_SYNC(inode))
err = waitfor_one_page(page);
- UnlockPage(page);
+
+ //SetPageUptodate(page); // the client commit_write will do this
+
+ SetPageReferenced(page);
+ unlock_page(page);
lustre_put_page(page);
return err;
}