From 3ad012e11fafefe3fdc52393153d0c819dc0030b Mon Sep 17 00:00:00 2001 From: braam Date: Mon, 21 Oct 2002 23:37:39 +0000 Subject: [PATCH] - fixes to osc_brw path to address fsx failures. We in fact uncovered serious problems with writes of less than one page. - minor fixes for 2.5 --- lustre/include/linux/obd_support.h | 2 + lustre/llite/Makefile.am | 6 +- lustre/llite/file.c | 2 +- lustre/llite/rw.c | 115 ++++++++++++++++++++----------------- lustre/obdfilter/filter.c | 50 ++++++++-------- 5 files changed, 96 insertions(+), 79 deletions(-) diff --git a/lustre/include/linux/obd_support.h b/lustre/include/linux/obd_support.h index 724a8e2..0df7a46 100644 --- a/lustre/include/linux/obd_support.h +++ b/lustre/include/linux/obd_support.h @@ -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 diff --git a/lustre/llite/Makefile.am b/lustre/llite/Makefile.am index 03612fc..74e2710 100644 --- a/lustre/llite/Makefile.am +++ b/lustre/llite/Makefile.am @@ -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 diff --git a/lustre/llite/file.c b/lustre/llite/file.c index bae0711..29d1d35 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -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 diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index be36447..3742f05 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -33,8 +33,6 @@ #include #include -#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 +}; diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index 7a12023..70ea821 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -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; } -- 1.8.3.1