Whamcloud - gitweb
- fixes to osc_brw path to address fsx failures. We in fact uncovered
authorbraam <braam>
Mon, 21 Oct 2002 23:37:39 +0000 (23:37 +0000)
committerbraam <braam>
Mon, 21 Oct 2002 23:37:39 +0000 (23:37 +0000)
  serious problems with writes of less than one page.
- minor fixes for 2.5

lustre/include/linux/obd_support.h
lustre/llite/Makefile.am
lustre/llite/file.c
lustre/llite/rw.c
lustre/obdfilter/filter.c

index 724a8e2..0df7a46 100644 (file)
@@ -126,7 +126,9 @@ do {                                                                         \
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
 #define ll_bdevname(a) __bdevname((a))
+#define ll_lock_kernel lock_kernel()
 #else 
+#define ll_lock_kernel 
 #define ll_bdevname(a) bdevname((a))
 #endif
 
index 03612fc..74e2710 100644 (file)
@@ -9,11 +9,15 @@ MODULE = llite
 modulefs_DATA = llite.o
 EXTRA_PROGRAMS = llite
 
+LINX= ll_pack.c
+
 llite_SOURCES = dcache.c commit_callback.c super.c rw.c super25.c
-llite_SOURCES += file.c dir.c sysctl.c symlink.c
+llite_SOURCES += file.c dir.c sysctl.c symlink.c $(LINX)
 llite_SOURCES += lov_pack.c recover.c namei.c
 
 lov_pack.c: 
        test -e lov_pack.c || ln -sf $(top_srcdir)/lib/lov_pack.c .
+ll_pack.c:
+       test -e ll_pack.c || ln -sf $(top_srcdir)/lib/ll_pack.c .
 
 include $(top_srcdir)/Rules
index bae0711..29d1d35 100644 (file)
@@ -728,8 +728,8 @@ struct file_operations ll_file_operations = {
 };
 
 struct inode_operations ll_file_inode_operations = {
-        truncate:   ll_truncate,
         setattr:    ll_setattr,
+        truncate:   ll_truncate,
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
         getattr: ll_getattr,
 #else
index be36447..3742f05 100644 (file)
@@ -33,8 +33,6 @@
 #include <linux/lustre_lite.h>
 #include <linux/lustre_lib.h>
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-
 /*
  * Remove page from dirty list
  */
@@ -46,7 +44,7 @@ static void __set_page_clean(struct page *page)
         if (!mapping)
                 return;
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,9))
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0))
         spin_lock(&pagecache_lock);
 #endif
 
@@ -58,7 +56,7 @@ static void __set_page_clean(struct page *page)
                 CDEBUG(D_INODE, "inode clean\n");
                 inode->i_state &= ~I_DIRTY_PAGES;
         }
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,10))
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0))
         spin_unlock(&pagecache_lock);
 #endif
         EXIT;
@@ -88,8 +86,13 @@ static int ll_brw(int cmd, struct inode *inode, struct page *page, int create)
                 RETURN(-ENOMEM);
 
         pg.pg = page;
-        pg.count = PAGE_SIZE;
         pg.off = ((obd_off)page->index) << PAGE_SHIFT;
+
+        if (cmd == OBD_BRW_WRITE && (pg.off + PAGE_SIZE > inode->i_size))
+                pg.count = inode->i_size % PAGE_SIZE; 
+        else
+                pg.count = PAGE_SIZE;
+
         pg.flag = create ? OBD_BRW_CREATE : 0;
 
         err = obd_brw(cmd, ll_i2obdconn(inode),lsm, 1, &pg, ll_sync_io_cb, cbd);
@@ -114,7 +117,7 @@ static int ll_readpage(struct file *file, struct page *page)
                 GOTO(readpage_out, rc);
         }
 
-        if (Page_Uptodate(page)) {
+        if (PageUptodate(page)) {
                 CERROR("Explain this please?\n");
                 GOTO(readpage_out, rc);
         }
@@ -129,6 +132,51 @@ static int ll_readpage(struct file *file, struct page *page)
         return 0;
 } /* ll_readpage */
 
+void ll_truncate(struct inode *inode)
+{
+        struct obdo oa = {0};
+        struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
+        struct lustre_handle *lockhs = NULL;
+        int err;
+        ENTRY;
+
+        if (!lsm) {
+                /* object not yet allocated */
+                inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+                return;
+        }
+
+        oa.o_id = lsm->lsm_object_id;
+        oa.o_mode = inode->i_mode;
+        oa.o_valid = OBD_MD_FLID | OBD_MD_FLMODE | OBD_MD_FLTYPE;
+
+        CDEBUG(D_INFO, "calling punch for "LPX64" (all bytes after "LPD64")\n",
+               oa.o_id, inode->i_size);
+
+        err = ll_size_lock(inode, lsm, inode->i_size, LCK_PW, &lockhs);
+        if (err) {
+                CERROR("ll_size_lock failed: %d\n", err);
+                /* FIXME: What to do here?  It's too late to back out... */
+                LBUG();
+        }
+
+        /* truncate == punch from new size to absolute end of file */
+        err = obd_punch(ll_i2obdconn(inode), &oa, lsm, inode->i_size,
+                        OBD_OBJECT_EOF);
+        if (err)
+                CERROR("obd_truncate fails (%d)\n", err);
+        else
+                obdo_to_inode(inode, &oa, oa.o_valid);
+
+        err = ll_size_unlock(inode, lsm, LCK_PW, lockhs);
+        if (err)
+                CERROR("ll_size_unlock failed: %d\n", err);
+
+        EXIT;
+        return;
+} /* ll_truncate */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
 
 static int ll_prepare_write(struct file *file, struct page *page, unsigned from,
                             unsigned to)
@@ -154,7 +202,7 @@ static int ll_prepare_write(struct file *file, struct page *page, unsigned from,
         /* We are writing to a new page, no need to read old data */
         if (inode->i_size <= offset) {
                 memset(addr, 0, PAGE_SIZE);
-                goto prepare_done;
+                GOTO(prepare_done, rc=0);
         }
 
         rc = ll_brw(OBD_BRW_READ, inode, page, 0);
@@ -234,49 +282,6 @@ static int ll_commit_write(struct file *file, struct page *page,
         RETURN(err);
 } /* ll_commit_write */
 
-void ll_truncate(struct inode *inode)
-{
-        struct obdo oa = {0};
-        struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
-        struct lustre_handle *lockhs = NULL;
-        int err;
-        ENTRY;
-
-        if (!lsm) {
-                /* object not yet allocated */
-                inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-                return;
-        }
-
-        oa.o_id = lsm->lsm_object_id;
-        oa.o_mode = inode->i_mode;
-        oa.o_valid = OBD_MD_FLID | OBD_MD_FLMODE | OBD_MD_FLTYPE;
-
-        CDEBUG(D_INFO, "calling punch for "LPX64" (all bytes after "LPD64")\n",
-               oa.o_id, inode->i_size);
-
-        err = ll_size_lock(inode, lsm, inode->i_size, LCK_PW, &lockhs);
-        if (err) {
-                CERROR("ll_size_lock failed: %d\n", err);
-                /* FIXME: What to do here?  It's too late to back out... */
-                LBUG();
-        }
-
-        /* truncate == punch from new size to absolute end of file */
-        err = obd_punch(ll_i2obdconn(inode), &oa, lsm, inode->i_size,
-                        OBD_OBJECT_EOF);
-        if (err)
-                CERROR("obd_truncate fails (%d)\n", err);
-        else
-                obdo_to_inode(inode, &oa, oa.o_valid);
-
-        err = ll_size_unlock(inode, lsm, LCK_PW, lockhs);
-        if (err)
-                CERROR("ll_size_unlock failed: %d\n", err);
-
-        EXIT;
-        return;
-} /* ll_truncate */
 
 static int ll_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf,
                         unsigned long blocknr, int blocksize)
@@ -370,15 +375,17 @@ int ll_flush_inode_pages(struct inode * inode)
         RETURN(err);
 }
 
+#endif
+
+
 struct address_space_operations ll_aops = {
         readpage: ll_readpage,
-        writepage: ll_writepage,
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,17))
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0))
         direct_IO: ll_direct_IO,
-#endif
+        writepage: ll_writepage,
         sync_page: block_sync_page,
         prepare_write: ll_prepare_write,
         commit_write: ll_commit_write,
         bmap: NULL
-};
 #endif
+};
index 7a12023..70ea821 100644 (file)
@@ -1010,8 +1010,10 @@ static inline void lustre_put_page(struct page *page)
 #define PageUptodate(page) Page_Uptodate(page)
 #endif
 static struct page *
-lustre_get_page_read(struct inode *inode, unsigned long index)
+lustre_get_page_read(struct inode *inode, 
+                     struct niobuf_remote *rnb)
 {
+        unsigned long index = rnb->offset >> PAGE_SHIFT;
         struct address_space *mapping = inode->i_mapping;
         struct page *page;
         int rc;
@@ -1094,10 +1096,13 @@ static int lustre_commit_write(struct page *page, unsigned from, unsigned to)
         return err;
 }
 
-struct page *filter_get_page_write(struct inode *inode, unsigned long index,
+struct page *filter_get_page_write(struct inode *inode, 
+                                   struct niobuf_remote *rnb,
                                    struct niobuf_local *lnb, int *pglocked)
 {
+        unsigned long index = rnb->offset >> PAGE_SHIFT;
         struct address_space *mapping = inode->i_mapping;
+        
         struct page *page;
         int rc;
 
@@ -1126,6 +1131,8 @@ struct page *filter_get_page_write(struct inode *inode, unsigned long index,
                         LBUG();
                         GOTO(err, rc = -ENOMEM);
                 }
+                /* XXX debugging */
+                memset((void *)addr, 0xBA, PAGE_SIZE);
                 page = virt_to_page(addr);
                 kmap(page);
                 page->index = index;
@@ -1134,11 +1141,9 @@ struct page *filter_get_page_write(struct inode *inode, unsigned long index,
                 (*pglocked)++;
                 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.
-                 */
-                rc = mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE);
+                rc = mapping->a_ops->prepare_write(NULL, page, 
+                                                   rnb->offset % PAGE_SIZE, 
+                                                   rnb->len);
                 if (rc) {
                         CERROR("page index %lu, rc = %d\n", index, rc);
                         if (rc != -ENOSPC)
@@ -1206,8 +1211,8 @@ static int filter_preprw(int cmd, struct lustre_handle *conn,
         struct obd_run_ctxt saved;
         struct obd_device *obd;
         struct obd_ioobj *o = obj;
-        struct niobuf_remote *b = nb;
-        struct niobuf_local *r = res;
+        struct niobuf_remote *rnb = nb;
+        struct niobuf_local *lnb = res;
         void *journal_save = NULL;
         int pglocked = 0;
         int rc = 0;
@@ -1249,30 +1254,29 @@ static int filter_preprw(int cmd, struct lustre_handle *conn,
                         GOTO(out_clean, rc = -ENOENT);
                 }
 
-                for (j = 0; j < o->ioo_bufcnt; j++, b++, r++) {
-                        unsigned long index = b->offset >> PAGE_SHIFT;
+                for (j = 0; j < o->ioo_bufcnt; j++, rnb++, lnb++) {
                         struct page *page;
 
                         if (j == 0)
-                                r->dentry = dentry;
+                                lnb->dentry = dentry;
                         else
-                                r->dentry = dget(dentry);
+                                lnb->dentry = dget(dentry);
 
                         if (cmd & OBD_BRW_WRITE)
-                                page = filter_get_page_write(inode, index, r,
+                                page = filter_get_page_write(inode, rnb, lnb,
                                                              &pglocked);
                         else
-                                page = lustre_get_page_read(inode, index);
+                                page = lustre_get_page_read(inode, rnb);
 
                         if (IS_ERR(page)) {
                                 f_dput(dentry);
                                 GOTO(out_clean, rc = PTR_ERR(page));
                         }
 
-                        r->addr = page_address(page);
-                        r->offset = b->offset;
-                        r->page = page;
-                        r->len = b->len;
+                        lnb->addr = page_address(page);
+                        lnb->offset = rnb->offset;
+                        lnb->page = page;
+                        lnb->len = rnb->len;
                 }
         }
 
@@ -1287,13 +1291,13 @@ out_ctxt:
         pop_ctxt(&saved);
         RETURN(rc);
 out_clean:
-        while (r-- > res) {
+        while (lnb-- > res) {
                 CERROR("error cleanup on brw\n");
-                f_dput(r->dentry);
+                f_dput(lnb->dentry);
                 if (cmd & OBD_BRW_WRITE)
-                        filter_commit_write(r->page, 0, PAGE_SIZE, rc);
+                        filter_commit_write(lnb->page, 0, PAGE_SIZE, rc);
                 else
-                        lustre_put_page(r->page);
+                        lustre_put_page(lnb->page);
         }
         goto out_stop;
 }