From 566e97183179307444ba0793bc6e1452f71286f0 Mon Sep 17 00:00:00 2001 From: tappro Date: Thu, 5 Mar 2009 09:28:29 +0000 Subject: [PATCH] - use truncate instead of invalidate to drop pages if ROC is disabled b:18520 i:green,adilger --- lustre/autoconf/lustre-core.m4 | 10 ++++++++++ lustre/obdfilter/filter_io.c | 44 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index 86adfe8..1525eec 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -1105,6 +1105,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],[ @@ -1572,6 +1581,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 901e60e..fe91eaa 100644 --- a/lustre/obdfilter/filter_io.c +++ b/lustre/obdfilter/filter_io.c @@ -345,14 +345,40 @@ void filter_invalidate_cache(struct obd_device *obd, struct obd_ioobj *obj, int i; LASSERT(inode != NULL); - for (i = 0, rnb = nb; i < obj->ioo_bufcnt; i++, rnb++) { - invalidate_mapping_pages(inode->i_mapping, + invalidate_mapping_pages(inode->i_mapping, rnb->offset >> CFS_PAGE_SHIFT, (rnb->offset + rnb->len) >> CFS_PAGE_SHIFT); } - +} + +/* + * 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, @@ -894,15 +920,17 @@ static int filter_commitrw_read(struct obd_export *exp, struct obdo *oa, inode = res->dentry->d_inode; for (i = 0, lnb = res; i < pages; i++, lnb++) { - if (lnb->page != NULL) { + 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, pages, res, + inode); + + for (i = 0, lnb = res; i < pages; i++, lnb++) + lnb->page = NULL; if (res->dentry != NULL) f_dput(res->dentry); -- 1.8.3.1