From d6475ffc4318590f1459e1def38e1dc23e64f31a Mon Sep 17 00:00:00 2001 From: tappro Date: Thu, 5 Mar 2009 12:36:43 +0000 Subject: [PATCH] - use truncate instead of invalidate to drop pages from cache if ROC is disabled b:18520 i:adilger, green --- lustre/autoconf/lustre-core.m4 | 10 ++++++++++ lustre/obdfilter/filter_io.c | 43 +++++++++++++++++++++++++++++++++++------- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index 19051bc..2088f90 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -1170,6 +1170,15 @@ AC_DEFINE(HAVE_TRUNCATE_COMPLETE_PAGE, 1, ]) ]) +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],[ @@ -1495,6 +1504,7 @@ AC_DEFUN([LC_PROG_LINUX], 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 diff --git a/lustre/obdfilter/filter_io.c b/lustre/obdfilter/filter_io.c index 7e75c80..bfd7092 100644 --- a/lustre/obdfilter/filter_io.c +++ b/lustre/obdfilter/filter_io.c @@ -359,6 +359,34 @@ void filter_invalidate_cache(struct obd_device *obd, struct obd_ioobj *obj, } } +/* + * 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, @@ -891,16 +919,17 @@ static int filter_commitrw_read(struct obd_export *exp, struct obdo *oa, 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); -- 1.8.3.1