])
])
+AC_DEFUN([LC_EXPORT_TRUNCATE_RANGE],
+[LB_CHECK_SYMBOL_EXPORT([truncate_inode_pages_range],
+[mm/truncate.c],[
+AC_DEFINE(HAVE_TRUNCATE_RANGE, 1,
+ [kernel export truncate_inode_pages_range])
+],[
+])
+])
+
AC_DEFUN([LC_EXPORT_D_REHASH_COND],
[LB_CHECK_SYMBOL_EXPORT([d_rehash_cond],
[fs/dcache.c],[
LC_TASK_PPTR
# RHEL4 patches
LC_EXPORT_TRUNCATE_COMPLETE
+ LC_EXPORT_TRUNCATE_RANGE
LC_EXPORT_D_REHASH_COND
LC_EXPORT___D_REHASH
LC_EXPORT_D_MOVE_LOCKED
}
}
+/*
+ * the invalidate above doesn't work during read because lnet pins pages.
+ * The truncate is used here instead to drop pages from cache
+ */
+void filter_truncate_cache(struct obd_device *obd, struct obd_ioobj *obj,
+ struct niobuf_remote *nb, int pages,
+ struct niobuf_local *res, struct inode *inode)
+{
+ struct niobuf_remote *rnb;
+ int i;
+
+ LASSERT(inode != NULL);
+#ifdef HAVE_TRUNCATE_RANGE
+ for (i = 0, rnb = nb; i < obj->ioo_bufcnt; i++, rnb++) {
+ /* remove pages in which range is fit */
+ truncate_inode_pages_range(inode->i_mapping,
+ rnb->offset & CFS_PAGE_MASK,
+ (rnb->offset + rnb->len - 1) |
+ ~CFS_PAGE_MASK);
+ }
+#elif (defined HAVE_TRUNCATE_COMPLETE)
+ for (i = 0, lnb = res; i < pages; i++, lnb++)
+ truncate_complete_page(inode->i_mapping, lnb->page);
+#else
+#error "Nor truncate_inode_pages_range or truncate_complete_page are supported"
+#endif
+}
+
static int filter_preprw_read(int cmd, struct obd_export *exp, struct obdo *oa,
int objcount, struct obd_ioobj *obj,
struct niobuf_remote *nb,
if (res->dentry != NULL)
inode = res->dentry->d_inode;
- for (i = 0, lnb = res; i < npages; i++, lnb++) {
- if (lnb->page != NULL) {
+ for (i = 0, lnb = res; i < npages; i++, lnb++)
+ if (lnb->page != NULL)
page_cache_release(lnb->page);
- lnb->page = NULL;
- }
- }
if (inode && (fo->fo_read_cache == 0 ||
- i_size_read(inode) > fo->fo_readcache_max_filesize))
- filter_invalidate_cache(exp->exp_obd, obj, rnb, inode);
+ i_size_read(inode) > fo->fo_readcache_max_filesize))
+ filter_truncate_cache(exp->exp_obd, obj, rnb, npages, res,
+ inode);
+
+ for (i = 0, lnb = res; i < npages; i++, lnb++)
+ lnb->page = NULL;
if (res->dentry != NULL)
f_dput(res->dentry);