Whamcloud - gitweb
LU-848 clio: page writeback support
[fs/lustre-release.git] / lustre / llite / rw.c
index 25f45fb..2243aab 100644 (file)
@@ -38,7 +38,6 @@
  * Lustre Lite I/O page cache routines shared by different kernel revs
  */
 
-#include <linux/autoconf.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/string.h>
@@ -61,7 +60,6 @@
 
 #define DEBUG_SUBSYSTEM S_LLITE
 
-//#include <lustre_mdc.h>
 #include <lustre_lite.h>
 #include <obd_cksum.h>
 #include "llite_internal.h"
@@ -78,7 +76,7 @@ void ll_truncate(struct inode *inode)
         struct ll_inode_info *lli = ll_i2info(inode);
         ENTRY;
 
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) to %Lu\n",inode->i_ino,
+        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) to %llu\n", inode->i_ino,
                inode->i_generation, inode, i_size_read(inode));
 
         ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_TRUNC, 1);
@@ -294,7 +292,7 @@ int ll_commit_write(struct file *file, struct page *vmpage, unsigned from,
         struct lu_env    *env;
         struct cl_io     *io;
         struct cl_page   *page;
-        int result;
+        int result = 0;
         ENTRY;
 
         lcc  = ll_cl_get();
@@ -303,11 +301,14 @@ int ll_commit_write(struct file *file, struct page *vmpage, unsigned from,
         io   = lcc->lcc_io;
 
         LASSERT(cl_page_is_owned(page, io));
-        result = cl_io_commit_write(env, io, page, from, to);
+        LASSERT(from <= to);
+        if (from != to) /* handle short write case. */
+                result = cl_io_commit_write(env, io, page, from, to);
         if (cl_page_is_owned(page, io))
                 cl_page_unassume(env, io, page);
+
         /*
-         * Release reference acquired by cl_io_prepare_write().
+         * Release reference acquired by ll_prepare_write().
          */
         lu_ref_del(&page->cp_reference, "prepare_write", cfs_current());
         cl_page_put(env, page);
@@ -335,7 +336,8 @@ static void ll_ra_stats_inc_sbi(struct ll_sb_info *sbi, enum ra_stat which);
  * ll_ra_count_get at the exactly same time. All of them will get a zero ra
  * window, although the global window is 100M. -jay
  */
-static unsigned long ll_ra_count_get(struct ll_sb_info *sbi, unsigned long len)
+static unsigned long ll_ra_count_get(struct ll_sb_info *sbi, struct ra_io_arg *ria,
+                                     unsigned long len)
 {
         struct ll_ra_info *ra = &sbi->ll_ra_info;
         unsigned long ret;
@@ -346,14 +348,23 @@ static unsigned long ll_ra_count_get(struct ll_sb_info *sbi, unsigned long len)
          * otherwise it will form small read RPC(< 1M), which hurt server
          * performance a lot.
          */
+        if (ra->ra_max_pages < atomic_read(&ra->ra_cur_pages))
+                GOTO(out, ret = 0);
+
         ret = min(ra->ra_max_pages - cfs_atomic_read(&ra->ra_cur_pages), len);
         if ((int)ret < 0 || ret < min((unsigned long)PTLRPC_MAX_BRW_PAGES, len))
                 GOTO(out, ret = 0);
 
+        if (ria->ria_pages == 0)
+                /* it needs 1M align again after trimed by ra_max_pages*/
+                if (ret >= ((ria->ria_start + ret) % PTLRPC_MAX_BRW_PAGES))
+                        ret -= (ria->ria_start + ret) % PTLRPC_MAX_BRW_PAGES;
+
         if (cfs_atomic_add_return(ret, &ra->ra_cur_pages) > ra->ra_max_pages) {
                 cfs_atomic_sub(ret, &ra->ra_cur_pages);
                 ret = 0;
         }
+
 out:
         RETURN(ret);
 }
@@ -784,8 +795,7 @@ int ll_readahead(const struct lu_env *env, struct cl_io *io,
         if (len == 0)
                 RETURN(0);
 
-        reserved = ll_ra_count_get(ll_i2sbi(inode), len);
-
+        reserved = ll_ra_count_get(ll_i2sbi(inode), ria, len);
         if (reserved < len)
                 ll_ra_stats_inc(mapping, RA_STAT_MAX_IN_FLIGHT);
 
@@ -1120,7 +1130,7 @@ out_unlock:
         return;
 }
 
-int ll_writepage(struct page *vmpage, struct writeback_control *unused)
+int ll_writepage(struct page *vmpage, struct writeback_control *wbc)
 {
         struct inode           *inode = vmpage->mapping->host;
         struct lu_env          *env;
@@ -1167,21 +1177,18 @@ int ll_writepage(struct page *vmpage, struct writeback_control *unused)
                         cl_2queue_init_page(queue, page);
                         result = cl_io_submit_rw(env, io, CRT_WRITE,
                                                  queue, CRP_NORMAL);
-                        cl_page_list_disown(env, io, &queue->c2_qin);
                         if (result != 0) {
                                 /*
-                                 * There is no need to clear PG_writeback, as
-                                 * cl_io_submit_rw() calls completion callback
-                                 * on failure.
-                                 */
-                                /*
                                  * Re-dirty page on error so it retries write,
                                  * but not in case when IO has actually
                                  * occurred and completed with an error.
                                  */
-                                if (!PageError(vmpage))
-                                        set_page_dirty(vmpage);
+                                if (!PageError(vmpage)) {
+                                        redirty_page_for_writepage(wbc, vmpage);
+                                        result = 0;
+                                }
                         }
+                        cl_page_list_disown(env, io, &queue->c2_qin);
                         LASSERT(!cl_page_is_owned(page, io));
                         lu_ref_del(&page->cp_reference,
                                    "writepage", cfs_current());