#include <linux/lustre_lite.h>
#include <linux/lustre_lib.h>
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-
/*
* Remove page from dirty list
*/
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
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;
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);
GOTO(readpage_out, rc);
}
- if (Page_Uptodate(page)) {
+ if (PageUptodate(page)) {
CERROR("Explain this please?\n");
GOTO(readpage_out, rc);
}
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)
/* 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);
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)
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
+};
#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;
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;
LBUG();
GOTO(err, rc = -ENOMEM);
}
+ /* XXX debugging */
+ memset((void *)addr, 0xBA, PAGE_SIZE);
page = virt_to_page(addr);
kmap(page);
page->index = 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)
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;
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;
}
}
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;
}