From: tappro Date: Thu, 5 Mar 2009 06:54:15 +0000 (+0000) Subject: - use truncate instead of invalidate to drop referenced pages from cache. This X-Git-Tag: 1.8.0~83 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=2c1af87090c8db281d3e6bb77e9e21ed768f5b42;p=fs%2Flustre-release.git - use truncate instead of invalidate to drop referenced pages from cache. This is needed to disable ROC correctly b:18520 i:adilger,green --- diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index dbf064d..60c2bc5 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -1178,6 +1178,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],[ @@ -1394,6 +1403,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 eeb8c7c..bd0ad34 100644 --- a/lustre/obdfilter/filter_io.c +++ b/lustre/obdfilter/filter_io.c @@ -325,14 +325,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, @@ -874,15 +900,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);