aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 22:52:47 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 22:52:47 -0400
commitaab008db8063364dc3c8ccf4981c21124866b395 (patch)
tree72914203f4decb023efdaabd0301a62d742dfa8c
parent4f5b1affdda3e0c48cac674182f52004137b0ffc (diff)
parent16c0cfa425b8e1488f7a1873bd112a7a099325f0 (diff)
Merge tag 'stable/for-linus-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/mm
Pull cleancache changes from Konrad Rzeszutek Wilk: "This has some patches for the cleancache API that should have been submitted a _long_ time ago. They are basically cleanups: - rename of flush to invalidate - moving reporting of statistics into debugfs - use __read_mostly as necessary. Oh, and also the MAINTAINERS file change. The files (except the MAINTAINERS file) have been in #linux-next for months now. The late addition of MAINTAINERS file is a brain-fart on my side - didn't realize I needed that just until I was typing this up - and I based that patch on v3.3 - so the tree is on top of v3.3." * tag 'stable/for-linus-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/mm: MAINTAINERS: Adding cleancache API to the list. mm: cleancache: Use __read_mostly as appropiate. mm: cleancache: report statistics via debugfs instead of sysfs. mm: zcache/tmem/cleancache: s/flush/invalidate/ mm: cleancache: s/flush/invalidate/
-rw-r--r--Documentation/ABI/testing/sysfs-kernel-mm-cleancache11
-rw-r--r--Documentation/vm/cleancache.txt41
-rw-r--r--MAINTAINERS7
-rw-r--r--drivers/staging/zcache/zcache-main.c10
-rw-r--r--drivers/xen/tmem.c10
-rw-r--r--fs/block_dev.c2
-rw-r--r--fs/super.c2
-rw-r--r--include/linux/cleancache.h24
-rw-r--r--mm/cleancache.c98
-rw-r--r--mm/filemap.c2
-rw-r--r--mm/truncate.c10
11 files changed, 96 insertions, 121 deletions
diff --git a/Documentation/ABI/testing/sysfs-kernel-mm-cleancache b/Documentation/ABI/testing/sysfs-kernel-mm-cleancache
deleted file mode 100644
index 662ae646ea12..000000000000
--- a/Documentation/ABI/testing/sysfs-kernel-mm-cleancache
+++ /dev/null
@@ -1,11 +0,0 @@
1What: /sys/kernel/mm/cleancache/
2Date: April 2011
3Contact: Dan Magenheimer <dan.magenheimer@oracle.com>
4Description:
5 /sys/kernel/mm/cleancache/ contains a number of files which
6 record a count of various cleancache operations
7 (sum across all filesystems):
8 succ_gets
9 failed_gets
10 puts
11 flushes
diff --git a/Documentation/vm/cleancache.txt b/Documentation/vm/cleancache.txt
index d5c615af10ba..142fbb0f325a 100644
--- a/Documentation/vm/cleancache.txt
+++ b/Documentation/vm/cleancache.txt
@@ -46,10 +46,11 @@ a negative return value indicates failure. A "put_page" will copy a
46the pool id, a file key, and a page index into the file. (The combination 46the pool id, a file key, and a page index into the file. (The combination
47of a pool id, a file key, and an index is sometimes called a "handle".) 47of a pool id, a file key, and an index is sometimes called a "handle".)
48A "get_page" will copy the page, if found, from cleancache into kernel memory. 48A "get_page" will copy the page, if found, from cleancache into kernel memory.
49A "flush_page" will ensure the page no longer is present in cleancache; 49An "invalidate_page" will ensure the page no longer is present in cleancache;
50a "flush_inode" will flush all pages associated with the specified file; 50an "invalidate_inode" will invalidate all pages associated with the specified
51and, when a filesystem is unmounted, a "flush_fs" will flush all pages in 51file; and, when a filesystem is unmounted, an "invalidate_fs" will invalidate
52all files specified by the given pool id and also surrender the pool id. 52all pages in all files specified by the given pool id and also surrender
53the pool id.
53 54
54An "init_shared_fs", like init_fs, obtains a pool id but tells cleancache 55An "init_shared_fs", like init_fs, obtains a pool id but tells cleancache
55to treat the pool as shared using a 128-bit UUID as a key. On systems 56to treat the pool as shared using a 128-bit UUID as a key. On systems
@@ -62,12 +63,12 @@ of the kernel (e.g. by "tools" that control cleancache). Or a
62cleancache implementation can simply disable shared_init by always 63cleancache implementation can simply disable shared_init by always
63returning a negative value. 64returning a negative value.
64 65
65If a get_page is successful on a non-shared pool, the page is flushed (thus 66If a get_page is successful on a non-shared pool, the page is invalidated
66making cleancache an "exclusive" cache). On a shared pool, the page 67(thus making cleancache an "exclusive" cache). On a shared pool, the page
67is NOT flushed on a successful get_page so that it remains accessible to 68is NOT invalidated on a successful get_page so that it remains accessible to
68other sharers. The kernel is responsible for ensuring coherency between 69other sharers. The kernel is responsible for ensuring coherency between
69cleancache (shared or not), the page cache, and the filesystem, using 70cleancache (shared or not), the page cache, and the filesystem, using
70cleancache flush operations as required. 71cleancache invalidate operations as required.
71 72
72Note that cleancache must enforce put-put-get coherency and get-get 73Note that cleancache must enforce put-put-get coherency and get-get
73coherency. For the former, if two puts are made to the same handle but 74coherency. For the former, if two puts are made to the same handle but
@@ -77,20 +78,20 @@ if a get for a given handle fails, subsequent gets for that handle will
77never succeed unless preceded by a successful put with that handle. 78never succeed unless preceded by a successful put with that handle.
78 79
79Last, cleancache provides no SMP serialization guarantees; if two 80Last, cleancache provides no SMP serialization guarantees; if two
80different Linux threads are simultaneously putting and flushing a page 81different Linux threads are simultaneously putting and invalidating a page
81with the same handle, the results are indeterminate. Callers must 82with the same handle, the results are indeterminate. Callers must
82lock the page to ensure serial behavior. 83lock the page to ensure serial behavior.
83 84
84CLEANCACHE PERFORMANCE METRICS 85CLEANCACHE PERFORMANCE METRICS
85 86
86Cleancache monitoring is done by sysfs files in the 87If properly configured, monitoring of cleancache is done via debugfs in
87/sys/kernel/mm/cleancache directory. The effectiveness of cleancache 88the /sys/kernel/debug/mm/cleancache directory. The effectiveness of cleancache
88can be measured (across all filesystems) with: 89can be measured (across all filesystems) with:
89 90
90succ_gets - number of gets that were successful 91succ_gets - number of gets that were successful
91failed_gets - number of gets that failed 92failed_gets - number of gets that failed
92puts - number of puts attempted (all "succeed") 93puts - number of puts attempted (all "succeed")
93flushes - number of flushes attempted 94invalidates - number of invalidates attempted
94 95
95A backend implementation may provide additional metrics. 96A backend implementation may provide additional metrics.
96 97
@@ -143,7 +144,7 @@ systems.
143 144
144The core hooks for cleancache in VFS are in most cases a single line 145The core hooks for cleancache in VFS are in most cases a single line
145and the minimum set are placed precisely where needed to maintain 146and the minimum set are placed precisely where needed to maintain
146coherency (via cleancache_flush operations) between cleancache, 147coherency (via cleancache_invalidate operations) between cleancache,
147the page cache, and disk. All hooks compile into nothingness if 148the page cache, and disk. All hooks compile into nothingness if
148cleancache is config'ed off and turn into a function-pointer- 149cleancache is config'ed off and turn into a function-pointer-
149compare-to-NULL if config'ed on but no backend claims the ops 150compare-to-NULL if config'ed on but no backend claims the ops
@@ -184,15 +185,15 @@ or for real kernel-addressable RAM, it makes perfect sense for
184transcendent memory. 185transcendent memory.
185 186
1864) Why is non-shared cleancache "exclusive"? And where is the 1874) Why is non-shared cleancache "exclusive"? And where is the
187 page "flushed" after a "get"? (Minchan Kim) 188 page "invalidated" after a "get"? (Minchan Kim)
188 189
189The main reason is to free up space in transcendent memory and 190The main reason is to free up space in transcendent memory and
190to avoid unnecessary cleancache_flush calls. If you want inclusive, 191to avoid unnecessary cleancache_invalidate calls. If you want inclusive,
191the page can be "put" immediately following the "get". If 192the page can be "put" immediately following the "get". If
192put-after-get for inclusive becomes common, the interface could 193put-after-get for inclusive becomes common, the interface could
193be easily extended to add a "get_no_flush" call. 194be easily extended to add a "get_no_invalidate" call.
194 195
195The flush is done by the cleancache backend implementation. 196The invalidate is done by the cleancache backend implementation.
196 197
1975) What's the performance impact? 1985) What's the performance impact?
198 199
@@ -222,7 +223,7 @@ Some points for a filesystem to consider:
222 as tmpfs should not enable cleancache) 223 as tmpfs should not enable cleancache)
223- To ensure coherency/correctness, the FS must ensure that all 224- To ensure coherency/correctness, the FS must ensure that all
224 file removal or truncation operations either go through VFS or 225 file removal or truncation operations either go through VFS or
225 add hooks to do the equivalent cleancache "flush" operations 226 add hooks to do the equivalent cleancache "invalidate" operations
226- To ensure coherency/correctness, either inode numbers must 227- To ensure coherency/correctness, either inode numbers must
227 be unique across the lifetime of the on-disk file OR the 228 be unique across the lifetime of the on-disk file OR the
228 FS must provide an "encode_fh" function. 229 FS must provide an "encode_fh" function.
@@ -243,11 +244,11 @@ If cleancache would use the inode virtual address instead of
243inode/filehandle, the pool id could be eliminated. But, this 244inode/filehandle, the pool id could be eliminated. But, this
244won't work because cleancache retains pagecache data pages 245won't work because cleancache retains pagecache data pages
245persistently even when the inode has been pruned from the 246persistently even when the inode has been pruned from the
246inode unused list, and only flushes the data page if the file 247inode unused list, and only invalidates the data page if the file
247gets removed/truncated. So if cleancache used the inode kva, 248gets removed/truncated. So if cleancache used the inode kva,
248there would be potential coherency issues if/when the inode 249there would be potential coherency issues if/when the inode
249kva is reused for a different file. Alternately, if cleancache 250kva is reused for a different file. Alternately, if cleancache
250flushed the pages when the inode kva was freed, much of the value 251invalidated the pages when the inode kva was freed, much of the value
251of cleancache would be lost because the cache of pages in cleanache 252of cleancache would be lost because the cache of pages in cleanache
252is potentially much larger than the kernel pagecache and is most 253is potentially much larger than the kernel pagecache and is most
253useful if the pages survive inode cache removal. 254useful if the pages survive inode cache removal.
diff --git a/MAINTAINERS b/MAINTAINERS
index 58f60356f071..922a674974a9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1832,6 +1832,13 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers)
1832S: Supported 1832S: Supported
1833F: sound/soc/codecs/cs4270* 1833F: sound/soc/codecs/cs4270*
1834 1834
1835CLEANCACHE API
1836M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
1837L: linux-kernel@vger.kernel.org
1838S: Maintained
1839F: mm/cleancache.c
1840F: include/linux/cleancache.h
1841
1835CLK API 1842CLK API
1836M: Russell King <linux@arm.linux.org.uk> 1843M: Russell King <linux@arm.linux.org.uk>
1837F: include/linux/clk.h 1844F: include/linux/clk.h
diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c
index ed2c800b3a7e..2734dacacbaf 100644
--- a/drivers/staging/zcache/zcache-main.c
+++ b/drivers/staging/zcache/zcache-main.c
@@ -1811,9 +1811,9 @@ static int zcache_cleancache_init_shared_fs(char *uuid, size_t pagesize)
1811static struct cleancache_ops zcache_cleancache_ops = { 1811static struct cleancache_ops zcache_cleancache_ops = {
1812 .put_page = zcache_cleancache_put_page, 1812 .put_page = zcache_cleancache_put_page,
1813 .get_page = zcache_cleancache_get_page, 1813 .get_page = zcache_cleancache_get_page,
1814 .flush_page = zcache_cleancache_flush_page, 1814 .invalidate_page = zcache_cleancache_flush_page,
1815 .flush_inode = zcache_cleancache_flush_inode, 1815 .invalidate_inode = zcache_cleancache_flush_inode,
1816 .flush_fs = zcache_cleancache_flush_fs, 1816 .invalidate_fs = zcache_cleancache_flush_fs,
1817 .init_shared_fs = zcache_cleancache_init_shared_fs, 1817 .init_shared_fs = zcache_cleancache_init_shared_fs,
1818 .init_fs = zcache_cleancache_init_fs 1818 .init_fs = zcache_cleancache_init_fs
1819}; 1819};
@@ -1921,8 +1921,8 @@ static void zcache_frontswap_init(unsigned ignored)
1921static struct frontswap_ops zcache_frontswap_ops = { 1921static struct frontswap_ops zcache_frontswap_ops = {
1922 .put_page = zcache_frontswap_put_page, 1922 .put_page = zcache_frontswap_put_page,
1923 .get_page = zcache_frontswap_get_page, 1923 .get_page = zcache_frontswap_get_page,
1924 .flush_page = zcache_frontswap_flush_page, 1924 .invalidate_page = zcache_frontswap_flush_page,
1925 .flush_area = zcache_frontswap_flush_area, 1925 .invalidate_area = zcache_frontswap_flush_area,
1926 .init = zcache_frontswap_init 1926 .init = zcache_frontswap_init
1927}; 1927};
1928 1928
diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c
index d369965e8f8a..17d9e37beba4 100644
--- a/drivers/xen/tmem.c
+++ b/drivers/xen/tmem.c
@@ -242,9 +242,9 @@ __setup("nocleancache", no_cleancache);
242static struct cleancache_ops tmem_cleancache_ops = { 242static struct cleancache_ops tmem_cleancache_ops = {
243 .put_page = tmem_cleancache_put_page, 243 .put_page = tmem_cleancache_put_page,
244 .get_page = tmem_cleancache_get_page, 244 .get_page = tmem_cleancache_get_page,
245 .flush_page = tmem_cleancache_flush_page, 245 .invalidate_page = tmem_cleancache_flush_page,
246 .flush_inode = tmem_cleancache_flush_inode, 246 .invalidate_inode = tmem_cleancache_flush_inode,
247 .flush_fs = tmem_cleancache_flush_fs, 247 .invalidate_fs = tmem_cleancache_flush_fs,
248 .init_shared_fs = tmem_cleancache_init_shared_fs, 248 .init_shared_fs = tmem_cleancache_init_shared_fs,
249 .init_fs = tmem_cleancache_init_fs 249 .init_fs = tmem_cleancache_init_fs
250}; 250};
@@ -369,8 +369,8 @@ __setup("nofrontswap", no_frontswap);
369static struct frontswap_ops tmem_frontswap_ops = { 369static struct frontswap_ops tmem_frontswap_ops = {
370 .put_page = tmem_frontswap_put_page, 370 .put_page = tmem_frontswap_put_page,
371 .get_page = tmem_frontswap_get_page, 371 .get_page = tmem_frontswap_get_page,
372 .flush_page = tmem_frontswap_flush_page, 372 .invalidate_page = tmem_frontswap_flush_page,
373 .flush_area = tmem_frontswap_flush_area, 373 .invalidate_area = tmem_frontswap_flush_area,
374 .init = tmem_frontswap_init 374 .init = tmem_frontswap_init
375}; 375};
376#endif 376#endif
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 5e9f198f7712..a9ff3000b83d 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -109,7 +109,7 @@ void invalidate_bdev(struct block_device *bdev)
109 /* 99% of the time, we don't need to flush the cleancache on the bdev. 109 /* 99% of the time, we don't need to flush the cleancache on the bdev.
110 * But, for the strange corners, lets be cautious 110 * But, for the strange corners, lets be cautious
111 */ 111 */
112 cleancache_flush_inode(mapping); 112 cleancache_invalidate_inode(mapping);
113} 113}
114EXPORT_SYMBOL(invalidate_bdev); 114EXPORT_SYMBOL(invalidate_bdev);
115 115
diff --git a/fs/super.c b/fs/super.c
index d90e900a8a0e..7fcb1354c554 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -251,7 +251,7 @@ void deactivate_locked_super(struct super_block *s)
251{ 251{
252 struct file_system_type *fs = s->s_type; 252 struct file_system_type *fs = s->s_type;
253 if (atomic_dec_and_test(&s->s_active)) { 253 if (atomic_dec_and_test(&s->s_active)) {
254 cleancache_flush_fs(s); 254 cleancache_invalidate_fs(s);
255 fs->kill_sb(s); 255 fs->kill_sb(s);
256 256
257 /* caches are now gone, we can safely kill the shrinker now */ 257 /* caches are now gone, we can safely kill the shrinker now */
diff --git a/include/linux/cleancache.h b/include/linux/cleancache.h
index 04ffb2e6c9d0..42e55deee757 100644
--- a/include/linux/cleancache.h
+++ b/include/linux/cleancache.h
@@ -28,9 +28,9 @@ struct cleancache_ops {
28 pgoff_t, struct page *); 28 pgoff_t, struct page *);
29 void (*put_page)(int, struct cleancache_filekey, 29 void (*put_page)(int, struct cleancache_filekey,
30 pgoff_t, struct page *); 30 pgoff_t, struct page *);
31 void (*flush_page)(int, struct cleancache_filekey, pgoff_t); 31 void (*invalidate_page)(int, struct cleancache_filekey, pgoff_t);
32 void (*flush_inode)(int, struct cleancache_filekey); 32 void (*invalidate_inode)(int, struct cleancache_filekey);
33 void (*flush_fs)(int); 33 void (*invalidate_fs)(int);
34}; 34};
35 35
36extern struct cleancache_ops 36extern struct cleancache_ops
@@ -39,9 +39,9 @@ extern void __cleancache_init_fs(struct super_block *);
39extern void __cleancache_init_shared_fs(char *, struct super_block *); 39extern void __cleancache_init_shared_fs(char *, struct super_block *);
40extern int __cleancache_get_page(struct page *); 40extern int __cleancache_get_page(struct page *);
41extern void __cleancache_put_page(struct page *); 41extern void __cleancache_put_page(struct page *);
42extern void __cleancache_flush_page(struct address_space *, struct page *); 42extern void __cleancache_invalidate_page(struct address_space *, struct page *);
43extern void __cleancache_flush_inode(struct address_space *); 43extern void __cleancache_invalidate_inode(struct address_space *);
44extern void __cleancache_flush_fs(struct super_block *); 44extern void __cleancache_invalidate_fs(struct super_block *);
45extern int cleancache_enabled; 45extern int cleancache_enabled;
46 46
47#ifdef CONFIG_CLEANCACHE 47#ifdef CONFIG_CLEANCACHE
@@ -99,24 +99,24 @@ static inline void cleancache_put_page(struct page *page)
99 __cleancache_put_page(page); 99 __cleancache_put_page(page);
100} 100}
101 101
102static inline void cleancache_flush_page(struct address_space *mapping, 102static inline void cleancache_invalidate_page(struct address_space *mapping,
103 struct page *page) 103 struct page *page)
104{ 104{
105 /* careful... page->mapping is NULL sometimes when this is called */ 105 /* careful... page->mapping is NULL sometimes when this is called */
106 if (cleancache_enabled && cleancache_fs_enabled_mapping(mapping)) 106 if (cleancache_enabled && cleancache_fs_enabled_mapping(mapping))
107 __cleancache_flush_page(mapping, page); 107 __cleancache_invalidate_page(mapping, page);
108} 108}
109 109
110static inline void cleancache_flush_inode(struct address_space *mapping) 110static inline void cleancache_invalidate_inode(struct address_space *mapping)
111{ 111{
112 if (cleancache_enabled && cleancache_fs_enabled_mapping(mapping)) 112 if (cleancache_enabled && cleancache_fs_enabled_mapping(mapping))
113 __cleancache_flush_inode(mapping); 113 __cleancache_invalidate_inode(mapping);
114} 114}
115 115
116static inline void cleancache_flush_fs(struct super_block *sb) 116static inline void cleancache_invalidate_fs(struct super_block *sb)
117{ 117{
118 if (cleancache_enabled) 118 if (cleancache_enabled)
119 __cleancache_flush_fs(sb); 119 __cleancache_invalidate_fs(sb);
120} 120}
121 121
122#endif /* _LINUX_CLEANCACHE_H */ 122#endif /* _LINUX_CLEANCACHE_H */
diff --git a/mm/cleancache.c b/mm/cleancache.c
index bcaae4c2a770..5646c740f613 100644
--- a/mm/cleancache.c
+++ b/mm/cleancache.c
@@ -15,29 +15,34 @@
15#include <linux/fs.h> 15#include <linux/fs.h>
16#include <linux/exportfs.h> 16#include <linux/exportfs.h>
17#include <linux/mm.h> 17#include <linux/mm.h>
18#include <linux/debugfs.h>
18#include <linux/cleancache.h> 19#include <linux/cleancache.h>
19 20
20/* 21/*
21 * This global enablement flag may be read thousands of times per second 22 * This global enablement flag may be read thousands of times per second
22 * by cleancache_get/put/flush even on systems where cleancache_ops 23 * by cleancache_get/put/invalidate even on systems where cleancache_ops
23 * is not claimed (e.g. cleancache is config'ed on but remains 24 * is not claimed (e.g. cleancache is config'ed on but remains
24 * disabled), so is preferred to the slower alternative: a function 25 * disabled), so is preferred to the slower alternative: a function
25 * call that checks a non-global. 26 * call that checks a non-global.
26 */ 27 */
27int cleancache_enabled; 28int cleancache_enabled __read_mostly;
28EXPORT_SYMBOL(cleancache_enabled); 29EXPORT_SYMBOL(cleancache_enabled);
29 30
30/* 31/*
31 * cleancache_ops is set by cleancache_ops_register to contain the pointers 32 * cleancache_ops is set by cleancache_ops_register to contain the pointers
32 * to the cleancache "backend" implementation functions. 33 * to the cleancache "backend" implementation functions.
33 */ 34 */
34static struct cleancache_ops cleancache_ops; 35static struct cleancache_ops cleancache_ops __read_mostly;
35 36
36/* useful stats available in /sys/kernel/mm/cleancache */ 37/*
37static unsigned long cleancache_succ_gets; 38 * Counters available via /sys/kernel/debug/frontswap (if debugfs is
38static unsigned long cleancache_failed_gets; 39 * properly configured. These are for information only so are not protected
39static unsigned long cleancache_puts; 40 * against increment races.
40static unsigned long cleancache_flushes; 41 */
42static u64 cleancache_succ_gets;
43static u64 cleancache_failed_gets;
44static u64 cleancache_puts;
45static u64 cleancache_invalidates;
41 46
42/* 47/*
43 * register operations for cleancache, returning previous thus allowing 48 * register operations for cleancache, returning previous thus allowing
@@ -148,10 +153,11 @@ void __cleancache_put_page(struct page *page)
148EXPORT_SYMBOL(__cleancache_put_page); 153EXPORT_SYMBOL(__cleancache_put_page);
149 154
150/* 155/*
151 * Flush any data from cleancache associated with the poolid and the 156 * Invalidate any data from cleancache associated with the poolid and the
152 * page's inode and page index so that a subsequent "get" will fail. 157 * page's inode and page index so that a subsequent "get" will fail.
153 */ 158 */
154void __cleancache_flush_page(struct address_space *mapping, struct page *page) 159void __cleancache_invalidate_page(struct address_space *mapping,
160 struct page *page)
155{ 161{
156 /* careful... page->mapping is NULL sometimes when this is called */ 162 /* careful... page->mapping is NULL sometimes when this is called */
157 int pool_id = mapping->host->i_sb->cleancache_poolid; 163 int pool_id = mapping->host->i_sb->cleancache_poolid;
@@ -160,85 +166,57 @@ void __cleancache_flush_page(struct address_space *mapping, struct page *page)
160 if (pool_id >= 0) { 166 if (pool_id >= 0) {
161 VM_BUG_ON(!PageLocked(page)); 167 VM_BUG_ON(!PageLocked(page));
162 if (cleancache_get_key(mapping->host, &key) >= 0) { 168 if (cleancache_get_key(mapping->host, &key) >= 0) {
163 (*cleancache_ops.flush_page)(pool_id, key, page->index); 169 (*cleancache_ops.invalidate_page)(pool_id,
164 cleancache_flushes++; 170 key, page->index);
171 cleancache_invalidates++;
165 } 172 }
166 } 173 }
167} 174}
168EXPORT_SYMBOL(__cleancache_flush_page); 175EXPORT_SYMBOL(__cleancache_invalidate_page);
169 176
170/* 177/*
171 * Flush all data from cleancache associated with the poolid and the 178 * Invalidate all data from cleancache associated with the poolid and the
172 * mappings's inode so that all subsequent gets to this poolid/inode 179 * mappings's inode so that all subsequent gets to this poolid/inode
173 * will fail. 180 * will fail.
174 */ 181 */
175void __cleancache_flush_inode(struct address_space *mapping) 182void __cleancache_invalidate_inode(struct address_space *mapping)
176{ 183{
177 int pool_id = mapping->host->i_sb->cleancache_poolid; 184 int pool_id = mapping->host->i_sb->cleancache_poolid;
178 struct cleancache_filekey key = { .u.key = { 0 } }; 185 struct cleancache_filekey key = { .u.key = { 0 } };
179 186
180 if (pool_id >= 0 && cleancache_get_key(mapping->host, &key) >= 0) 187 if (pool_id >= 0 && cleancache_get_key(mapping->host, &key) >= 0)
181 (*cleancache_ops.flush_inode)(pool_id, key); 188 (*cleancache_ops.invalidate_inode)(pool_id, key);
182} 189}
183EXPORT_SYMBOL(__cleancache_flush_inode); 190EXPORT_SYMBOL(__cleancache_invalidate_inode);
184 191
185/* 192/*
186 * Called by any cleancache-enabled filesystem at time of unmount; 193 * Called by any cleancache-enabled filesystem at time of unmount;
187 * note that pool_id is surrendered and may be reutrned by a subsequent 194 * note that pool_id is surrendered and may be reutrned by a subsequent
188 * cleancache_init_fs or cleancache_init_shared_fs 195 * cleancache_init_fs or cleancache_init_shared_fs
189 */ 196 */
190void __cleancache_flush_fs(struct super_block *sb) 197void __cleancache_invalidate_fs(struct super_block *sb)
191{ 198{
192 if (sb->cleancache_poolid >= 0) { 199 if (sb->cleancache_poolid >= 0) {
193 int old_poolid = sb->cleancache_poolid; 200 int old_poolid = sb->cleancache_poolid;
194 sb->cleancache_poolid = -1; 201 sb->cleancache_poolid = -1;
195 (*cleancache_ops.flush_fs)(old_poolid); 202 (*cleancache_ops.invalidate_fs)(old_poolid);
196 } 203 }
197} 204}
198EXPORT_SYMBOL(__cleancache_flush_fs); 205EXPORT_SYMBOL(__cleancache_invalidate_fs);
199
200#ifdef CONFIG_SYSFS
201
202/* see Documentation/ABI/xxx/sysfs-kernel-mm-cleancache */
203
204#define CLEANCACHE_SYSFS_RO(_name) \
205 static ssize_t cleancache_##_name##_show(struct kobject *kobj, \
206 struct kobj_attribute *attr, char *buf) \
207 { \
208 return sprintf(buf, "%lu\n", cleancache_##_name); \
209 } \
210 static struct kobj_attribute cleancache_##_name##_attr = { \
211 .attr = { .name = __stringify(_name), .mode = 0444 }, \
212 .show = cleancache_##_name##_show, \
213 }
214
215CLEANCACHE_SYSFS_RO(succ_gets);
216CLEANCACHE_SYSFS_RO(failed_gets);
217CLEANCACHE_SYSFS_RO(puts);
218CLEANCACHE_SYSFS_RO(flushes);
219
220static struct attribute *cleancache_attrs[] = {
221 &cleancache_succ_gets_attr.attr,
222 &cleancache_failed_gets_attr.attr,
223 &cleancache_puts_attr.attr,
224 &cleancache_flushes_attr.attr,
225 NULL,
226};
227
228static struct attribute_group cleancache_attr_group = {
229 .attrs = cleancache_attrs,
230 .name = "cleancache",
231};
232
233#endif /* CONFIG_SYSFS */
234 206
235static int __init init_cleancache(void) 207static int __init init_cleancache(void)
236{ 208{
237#ifdef CONFIG_SYSFS 209#ifdef CONFIG_DEBUG_FS
238 int err; 210 struct dentry *root = debugfs_create_dir("cleancache", NULL);
239 211 if (root == NULL)
240 err = sysfs_create_group(mm_kobj, &cleancache_attr_group); 212 return -ENXIO;
241#endif /* CONFIG_SYSFS */ 213 debugfs_create_u64("succ_gets", S_IRUGO, root, &cleancache_succ_gets);
214 debugfs_create_u64("failed_gets", S_IRUGO,
215 root, &cleancache_failed_gets);
216 debugfs_create_u64("puts", S_IRUGO, root, &cleancache_puts);
217 debugfs_create_u64("invalidates", S_IRUGO,
218 root, &cleancache_invalidates);
219#endif
242 return 0; 220 return 0;
243} 221}
244module_init(init_cleancache) 222module_init(init_cleancache)
diff --git a/mm/filemap.c b/mm/filemap.c
index 843042045dc9..c3811bc6b9e3 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -122,7 +122,7 @@ void __delete_from_page_cache(struct page *page)
122 if (PageUptodate(page) && PageMappedToDisk(page)) 122 if (PageUptodate(page) && PageMappedToDisk(page))
123 cleancache_put_page(page); 123 cleancache_put_page(page);
124 else 124 else
125 cleancache_flush_page(mapping, page); 125 cleancache_invalidate_page(mapping, page);
126 126
127 radix_tree_delete(&mapping->page_tree, page->index); 127 radix_tree_delete(&mapping->page_tree, page->index);
128 page->mapping = NULL; 128 page->mapping = NULL;
diff --git a/mm/truncate.c b/mm/truncate.c
index a188058582e0..18aded3a89fc 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -52,7 +52,7 @@ void do_invalidatepage(struct page *page, unsigned long offset)
52static inline void truncate_partial_page(struct page *page, unsigned partial) 52static inline void truncate_partial_page(struct page *page, unsigned partial)
53{ 53{
54 zero_user_segment(page, partial, PAGE_CACHE_SIZE); 54 zero_user_segment(page, partial, PAGE_CACHE_SIZE);
55 cleancache_flush_page(page->mapping, page); 55 cleancache_invalidate_page(page->mapping, page);
56 if (page_has_private(page)) 56 if (page_has_private(page))
57 do_invalidatepage(page, partial); 57 do_invalidatepage(page, partial);
58} 58}
@@ -213,7 +213,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
213 pgoff_t end; 213 pgoff_t end;
214 int i; 214 int i;
215 215
216 cleancache_flush_inode(mapping); 216 cleancache_invalidate_inode(mapping);
217 if (mapping->nrpages == 0) 217 if (mapping->nrpages == 0)
218 return; 218 return;
219 219
@@ -292,7 +292,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
292 mem_cgroup_uncharge_end(); 292 mem_cgroup_uncharge_end();
293 index++; 293 index++;
294 } 294 }
295 cleancache_flush_inode(mapping); 295 cleancache_invalidate_inode(mapping);
296} 296}
297EXPORT_SYMBOL(truncate_inode_pages_range); 297EXPORT_SYMBOL(truncate_inode_pages_range);
298 298
@@ -444,7 +444,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
444 int ret2 = 0; 444 int ret2 = 0;
445 int did_range_unmap = 0; 445 int did_range_unmap = 0;
446 446
447 cleancache_flush_inode(mapping); 447 cleancache_invalidate_inode(mapping);
448 pagevec_init(&pvec, 0); 448 pagevec_init(&pvec, 0);
449 index = start; 449 index = start;
450 while (index <= end && pagevec_lookup(&pvec, mapping, index, 450 while (index <= end && pagevec_lookup(&pvec, mapping, index,
@@ -500,7 +500,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
500 cond_resched(); 500 cond_resched();
501 index++; 501 index++;
502 } 502 }
503 cleancache_flush_inode(mapping); 503 cleancache_invalidate_inode(mapping);
504 return ret; 504 return ret;
505} 505}
506EXPORT_SYMBOL_GPL(invalidate_inode_pages2_range); 506EXPORT_SYMBOL_GPL(invalidate_inode_pages2_range);