From 99282868825f5d9ecec0c854ae61ea7f7342f6a1 Mon Sep 17 00:00:00 2001
From: adilger <adilger>
Date: Wed, 28 Jan 2004 22:47:19 +0000
Subject: [PATCH] Allow OST read cache to be disabled (already on b1_0). b=2591
 r=zab,shaver

---
 lustre/include/linux/lprocfs_status.h |  6 ++++--
 lustre/include/linux/obd.h            |  2 ++
 lustre/obdclass/lprocfs_status.c      | 23 +++++++++++++++++++-
 lustre/obdfilter/filter.c             |  1 +
 lustre/obdfilter/filter_internal.h    |  2 ++
 lustre/obdfilter/filter_io.c          | 17 ++++++++++++---
 lustre/obdfilter/lproc_obdfilter.c    | 31 ++++++++++++++++++++++++++-
 7 files changed, 75 insertions(+), 7 deletions(-)

diff --git a/lustre/include/linux/lprocfs_status.h b/lustre/include/linux/lprocfs_status.h
index 8fbbe6199a..3f4d52fefc 100644
--- a/lustre/include/linux/lprocfs_status.h
+++ b/lustre/include/linux/lprocfs_status.h
@@ -256,9 +256,11 @@ extern int lprocfs_rd_filesfree(char *page, char **start, off_t off,
 extern int lprocfs_rd_filegroups(char *page, char **start, off_t off,
                                  int count, int *eof, void *data);
 
-extern int lprocfs_write_helper(const char *buffer, unsigned long count, 
+extern int lprocfs_write_helper(const char *buffer, unsigned long count,
                                 int *val);
-int lprocfs_obd_seq_create(struct obd_device *dev, char *name, mode_t mode, 
+extern int lprocfs_write_u64_helper(const char *buffer, unsigned long count,
+                                    __u64 *val);
+int lprocfs_obd_seq_create(struct obd_device *dev, char *name, mode_t mode,
                            struct file_operations *seq_fops, void *data);
 struct obd_histogram;
 void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value);
diff --git a/lustre/include/linux/obd.h b/lustre/include/linux/obd.h
index 3982a4ce4b..d946942b40 100644
--- a/lustre/include/linux/obd.h
+++ b/lustre/include/linux/obd.h
@@ -168,6 +168,8 @@ struct filter_obd {
         obd_size             fo_tot_granted;
         obd_size             fo_tot_cached;
 
+        obd_size             fo_readcache_max_filesize;
+
         struct obd_import   *fo_mdc_imp;
         struct obd_uuid      fo_mdc_uuid;
         struct lustre_handle fo_mdc_conn;
diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c
index a5ad77c669..eb98251633 100644
--- a/lustre/obdclass/lprocfs_status.c
+++ b/lustre/obdclass/lprocfs_status.c
@@ -684,7 +684,27 @@ int lprocfs_write_helper(const char *buffer, unsigned long count,
         return 0;
 }
 
-int lprocfs_obd_seq_create(struct obd_device *dev, char *name, mode_t mode, 
+int lprocfs_write_u64_helper(const char *buffer, unsigned long count,
+                             __u64 *val)
+{
+        char kernbuf[22], *end;
+
+        if (count > (sizeof(kernbuf) - 1))
+                return -EINVAL;
+
+        if (copy_from_user(kernbuf, buffer, count))
+                return -EFAULT;
+
+        kernbuf[count] = '\0';
+
+        *val = simple_strtoull(kernbuf, &end, 0);
+        if (kernbuf == end)
+                return -EINVAL;
+
+        return 0;
+}
+
+int lprocfs_obd_seq_create(struct obd_device *dev, char *name, mode_t mode,
                            struct file_operations *seq_fops, void *data)
 {
         struct proc_dir_entry *entry;
@@ -774,3 +794,4 @@ EXPORT_SYMBOL(lprocfs_rd_filesfree);
 EXPORT_SYMBOL(lprocfs_rd_filegroups);
 
 EXPORT_SYMBOL(lprocfs_write_helper);
+EXPORT_SYMBOL(lprocfs_write_u64_helper);
diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c
index 86eda2d1ca..93d363ed1d 100644
--- a/lustre/obdfilter/filter.c
+++ b/lustre/obdfilter/filter.c
@@ -1123,6 +1123,7 @@ int filter_common_setup(struct obd_device *obd, obd_count len, void *buf,
         spin_lock_init(&filter->fo_w_discont_pages.oh_lock);
         spin_lock_init(&filter->fo_r_discont_blocks.oh_lock);
         spin_lock_init(&filter->fo_w_discont_blocks.oh_lock);
+        filter->fo_readcache_max_filesize = FILTER_MAX_CACHE_SIZE;
 
         obd->obd_namespace = ldlm_namespace_new("filter-tgt",
                                                 LDLM_NAMESPACE_SERVER);
diff --git a/lustre/obdfilter/filter_internal.h b/lustre/obdfilter/filter_internal.h
index 610d969c0b..ce7b4a372b 100644
--- a/lustre/obdfilter/filter_internal.h
+++ b/lustre/obdfilter/filter_internal.h
@@ -90,6 +90,8 @@ enum {
         LPROC_FILTER_LAST,
 };
 
+#define FILTER_MAX_CACHE_SIZE OBD_OBJECT_EOF
+
 /* filter.c */
 struct dentry *filter_parent(struct obd_device *, obd_gr group, obd_id objid);
 struct dentry *filter_parent_lock(struct obd_device *, obd_gr, obd_id,
diff --git a/lustre/obdfilter/filter_io.c b/lustre/obdfilter/filter_io.c
index 774e669200..afb49dbb20 100644
--- a/lustre/obdfilter/filter_io.c
+++ b/lustre/obdfilter/filter_io.c
@@ -360,13 +360,24 @@ static int filter_commitrw_read(struct obd_export *exp, struct obdo *oa,
 {
         struct obd_ioobj *o;
         struct niobuf_local *lnb;
-        int i, j;
+        int i, j, drop = 0;
         ENTRY;
 
+        if (res->dentry != NULL)
+                drop = (res->dentry->d_inode->i_size >
+                        exp->exp_obd->u.filter.fo_readcache_max_filesize);
+
         for (i = 0, o = obj, lnb = res; i < objcount; i++, o++) {
                 for (j = 0 ; j < o->ioo_bufcnt ; j++, lnb++) {
-                        if (lnb->page != NULL)
-                                page_cache_release(lnb->page);
+                        if (lnb->page == NULL)
+                                continue;
+                        /* drop from cache like truncate_list_pages() */
+                        if (drop && !TryLockPage(lnb->page)) {
+                                if (lnb->page->mapping)
+                                        truncate_complete_page(lnb->page);
+                                unlock_page(lnb->page);
+                        }
+                        page_cache_release(lnb->page);
                 }
         }
         if (res->dentry != NULL)
diff --git a/lustre/obdfilter/lproc_obdfilter.c b/lustre/obdfilter/lproc_obdfilter.c
index 77f085276c..51458c0a8b 100644
--- a/lustre/obdfilter/lproc_obdfilter.c
+++ b/lustre/obdfilter/lproc_obdfilter.c
@@ -58,6 +58,32 @@ static int lprocfs_filter_rd_last_id(char *page, char **start, off_t off,
                         filter_last_id(&obd->u.filter, 0));
 }
 
+int lprocfs_filter_rd_readcache(char *page, char **start, off_t off, int count,
+                                int *eof, void *data)
+{
+        struct obd_device *obd = data;
+        int rc;
+
+        rc = snprintf(page, count, LPU64"\n",
+                      obd->u.filter.fo_readcache_max_filesize);
+        return rc;
+}
+
+int lprocfs_filter_wr_readcache(struct file *file, const char *buffer,
+                                unsigned long count, void *data)
+{
+        struct obd_device *obd = data;
+        __u64 val;
+        int rc;
+
+        rc = lprocfs_write_u64_helper(buffer, count, &val);
+        if (rc)
+                return rc;
+
+        obd->u.filter.fo_readcache_max_filesize = val;
+        return count;
+}
+
 static struct lprocfs_vars lprocfs_obd_vars[] = {
         { "uuid",         lprocfs_rd_uuid,          0, 0 },
         { "blocksize",    lprocfs_rd_blksize,       0, 0 },
@@ -68,7 +94,10 @@ static struct lprocfs_vars lprocfs_obd_vars[] = {
         //{ "filegroups",   lprocfs_rd_filegroups,    0, 0 },
         { "fstype",       lprocfs_rd_fstype,        0, 0 },
         { "mntdev",       lprocfs_filter_rd_mntdev, 0, 0 },
-        { "last_id",      lprocfs_filter_rd_last_id, 0, 0 },
+        { "last_id",      lprocfs_filter_rd_last_id,0, 0 },
+        { "readcache_max_filesize",
+                          lprocfs_filter_rd_readcache,
+                          lprocfs_filter_wr_readcache, 0 },
         { 0 }
 };
 
-- 
GitLab