Whamcloud - gitweb
Optimize write-full-page so that we don't read in a page full of data we
authoradilger <adilger>
Mon, 15 Apr 2002 19:51:09 +0000 (19:51 +0000)
committeradilger <adilger>
Mon, 15 Apr 2002 19:51:09 +0000 (19:51 +0000)
are not going to use.  This should speed up the rewrite tests in iozone.

Split the lustre_get_page() into two functions - lustre_get_page_read()
and lustre_get_page_write().  The first one reads in the page, and the
second one just gets the page locked but without any data.

lustre/include/linux/lustre_lib.h
lustre/lib/page.c
lustre/obdfilter/filter.c

index 0a03f2b..6b109e8 100644 (file)
@@ -34,8 +34,8 @@
 #ifdef __KERNEL__
 /* page.c */
 inline void lustre_put_page(struct page *page);
-struct page * lustre_get_page(struct inode *dir, unsigned long n);
-int lustre_prepare_page(unsigned from, unsigned to, struct page *page);
+struct page *lustre_get_page_read(struct inode *dir, unsigned long index);
+struct page *lustre_get_page_write(struct inode *dir, unsigned long index);
 int lustre_commit_page(struct page *page, unsigned from, unsigned to);
 
 /* simple.c */
index 1b1b995..0e401d8 100644 (file)
@@ -91,18 +91,19 @@ inline void lustre_put_page(struct page *page)
         page_cache_release(page);
 }
 
-struct page * lustre_get_page(struct inode *inode, unsigned long n)
+struct page *lustre_get_page_read(struct inode *inode, unsigned long index)
 {
         struct address_space *mapping = inode->i_mapping;
-        struct page *page = read_cache_page(mapping, n,
+        struct page *page = read_cache_page(mapping, index,
                                 (filler_t*)mapping->a_ops->readpage, NULL);
+
         if (!IS_ERR(page)) {
                 wait_on_page(page);
                 kmap(page);
                 if (!Page_Uptodate(page))
-                        goto fail;
+                        GOTO(fail, -EIO);
                 if (PageError(page))
-                        goto fail;
+                        GOTO(fail, -EIO);
         }
         return page;
 
@@ -111,19 +112,35 @@ fail:
         return ERR_PTR(-EIO);
 }
 
-int lustre_prepare_page(unsigned from, unsigned to, struct page *page)
+struct page *lustre_get_page_write(struct inode *inode, unsigned long index)
 {
+        struct address_space *mapping = inode->i_mapping;
+        struct page *page = grab_cache_page(mapping, index); /* locked page */
         int err;
 
-        lock_page(page);
-        err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
-        if (err) {
-                UnlockPage(page);
-                CERROR("page index %ld from %d to %d err %d\n",
-                                page->index, from, to, err);
-                LBUG();
+        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.
+                 */
+                err = mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE);
+                if (err) {
+                        CERROR("page index %ld, err %d\n", index, err);
+                        LBUG();
+                        GOTO(fail, err);
+                }
+                /* XXX not sure if we need this if we are overwriting page */
+                if (PageError(page))
+                        GOTO(fail, err = -EIO);
         }
-        return err;
+        return page;
+
+fail:
+        UnlockPage(page);
+        lustre_put_page(page);
+        return ERR_PTR(-EIO);
 }
 
 int lustre_commit_page(struct page *page, unsigned from, unsigned to)
index ec8c0cb..104e4da 100644 (file)
@@ -782,6 +782,7 @@ static int filter_preprw(int cmd, struct obd_conn *conn,
         for (i = 0; i < objcount; i++, o++) {
                 int j;
                 for (j = 0; j < o->ioo_bufcnt; j++, b++, r++) {
+                        unsigned long index = b->offset >> PAGE_SHIFT;
                         struct inode *inode = ioobj_to_inode(conn, o);
                         struct page *page;
 
@@ -789,16 +790,13 @@ static int filter_preprw(int cmd, struct obd_conn *conn,
                         if (!inode)
                                 RETURN(-EINVAL);
 
-                        page = lustre_get_page(inode, b->offset >> PAGE_SHIFT);
+                        if (cmd == OBD_BRW_WRITE)
+                                page = lustre_get_page_write(inode, index);
+                        else
+                                page = lustre_get_page_read(inode, index);
                         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;