Whamcloud - gitweb
Simplify adding manual test results to Tinderbox.
[fs/lustre-release.git] / lustre / lib / page.c
index a1e477c..7e9968b 100644 (file)
 #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
@@ -156,7 +232,6 @@ struct page *lustre_get_page_read(struct inode *inode, unsigned long index)
                         CERROR("page index %lu has error\n", index);
                         GOTO(err_page, rc = -EIO);
                 }
-                kmap(page);
         }
         return page;
 
@@ -174,6 +249,7 @@ struct page *lustre_get_page_write(struct inode *inode, unsigned long index)
         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.
@@ -191,8 +267,6 @@ struct page *lustre_get_page_write(struct inode *inode, unsigned long index)
                         LBUG();
                         GOTO(err_unlock, rc = -EIO);
                 }
-
-                kmap(page);
         }
         return page;
 
@@ -202,18 +276,19 @@ err_unlock:
         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;
 }