diff options
-rw-r--r-- | Documentation/vm/cleancache.txt | 4 | ||||
-rw-r--r-- | drivers/xen/tmem.c | 16 | ||||
-rw-r--r-- | include/linux/cleancache.h | 3 | ||||
-rw-r--r-- | mm/cleancache.c | 12 |
4 files changed, 18 insertions, 17 deletions
diff --git a/Documentation/vm/cleancache.txt b/Documentation/vm/cleancache.txt index 01d76282444e..e4b49df7a048 100644 --- a/Documentation/vm/cleancache.txt +++ b/Documentation/vm/cleancache.txt | |||
@@ -28,9 +28,7 @@ IMPLEMENTATION OVERVIEW | |||
28 | A cleancache "backend" that provides transcendent memory registers itself | 28 | A cleancache "backend" that provides transcendent memory registers itself |
29 | to the kernel's cleancache "frontend" by calling cleancache_register_ops, | 29 | to the kernel's cleancache "frontend" by calling cleancache_register_ops, |
30 | passing a pointer to a cleancache_ops structure with funcs set appropriately. | 30 | passing a pointer to a cleancache_ops structure with funcs set appropriately. |
31 | Note that cleancache_register_ops returns the previous settings so that | 31 | The functions provided must conform to certain semantics as follows: |
32 | chaining can be performed if desired. The functions provided must conform to | ||
33 | certain semantics as follows: | ||
34 | 32 | ||
35 | Most important, cleancache is "ephemeral". Pages which are copied into | 33 | Most important, cleancache is "ephemeral". Pages which are copied into |
36 | cleancache have an indefinite lifetime which is completely unknowable | 34 | cleancache have an indefinite lifetime which is completely unknowable |
diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c index 8a65423bc696..c4211a31612d 100644 --- a/drivers/xen/tmem.c +++ b/drivers/xen/tmem.c | |||
@@ -397,13 +397,15 @@ static int __init xen_tmem_init(void) | |||
397 | #ifdef CONFIG_CLEANCACHE | 397 | #ifdef CONFIG_CLEANCACHE |
398 | BUG_ON(sizeof(struct cleancache_filekey) != sizeof(struct tmem_oid)); | 398 | BUG_ON(sizeof(struct cleancache_filekey) != sizeof(struct tmem_oid)); |
399 | if (tmem_enabled && cleancache) { | 399 | if (tmem_enabled && cleancache) { |
400 | char *s = ""; | 400 | int err; |
401 | struct cleancache_ops *old_ops = | 401 | |
402 | cleancache_register_ops(&tmem_cleancache_ops); | 402 | err = cleancache_register_ops(&tmem_cleancache_ops); |
403 | if (old_ops) | 403 | if (err) |
404 | s = " (WARNING: cleancache_ops overridden)"; | 404 | pr_warn("xen-tmem: failed to enable cleancache: %d\n", |
405 | pr_info("cleancache enabled, RAM provided by Xen Transcendent Memory%s\n", | 405 | err); |
406 | s); | 406 | else |
407 | pr_info("cleancache enabled, RAM provided by " | ||
408 | "Xen Transcendent Memory\n"); | ||
407 | } | 409 | } |
408 | #endif | 410 | #endif |
409 | #ifdef CONFIG_XEN_SELFBALLOONING | 411 | #ifdef CONFIG_XEN_SELFBALLOONING |
diff --git a/include/linux/cleancache.h b/include/linux/cleancache.h index 29657d1c83fb..b23611f43cfb 100644 --- a/include/linux/cleancache.h +++ b/include/linux/cleancache.h | |||
@@ -33,8 +33,7 @@ struct cleancache_ops { | |||
33 | void (*invalidate_fs)(int); | 33 | void (*invalidate_fs)(int); |
34 | }; | 34 | }; |
35 | 35 | ||
36 | extern struct cleancache_ops * | 36 | extern int cleancache_register_ops(struct cleancache_ops *ops); |
37 | cleancache_register_ops(struct cleancache_ops *ops); | ||
38 | extern void __cleancache_init_fs(struct super_block *); | 37 | extern void __cleancache_init_fs(struct super_block *); |
39 | extern void __cleancache_init_shared_fs(struct super_block *); | 38 | extern void __cleancache_init_shared_fs(struct super_block *); |
40 | extern int __cleancache_get_page(struct page *); | 39 | extern int __cleancache_get_page(struct page *); |
diff --git a/mm/cleancache.c b/mm/cleancache.c index 532495f2e4f4..aa10f9a3bc88 100644 --- a/mm/cleancache.c +++ b/mm/cleancache.c | |||
@@ -106,15 +106,17 @@ static DEFINE_MUTEX(poolid_mutex); | |||
106 | */ | 106 | */ |
107 | 107 | ||
108 | /* | 108 | /* |
109 | * Register operations for cleancache, returning previous thus allowing | 109 | * Register operations for cleancache. Returns 0 on success. |
110 | * detection of multiple backends and possible nesting. | ||
111 | */ | 110 | */ |
112 | struct cleancache_ops *cleancache_register_ops(struct cleancache_ops *ops) | 111 | int cleancache_register_ops(struct cleancache_ops *ops) |
113 | { | 112 | { |
114 | struct cleancache_ops *old = cleancache_ops; | ||
115 | int i; | 113 | int i; |
116 | 114 | ||
117 | mutex_lock(&poolid_mutex); | 115 | mutex_lock(&poolid_mutex); |
116 | if (cleancache_ops) { | ||
117 | mutex_unlock(&poolid_mutex); | ||
118 | return -EBUSY; | ||
119 | } | ||
118 | for (i = 0; i < MAX_INITIALIZABLE_FS; i++) { | 120 | for (i = 0; i < MAX_INITIALIZABLE_FS; i++) { |
119 | if (fs_poolid_map[i] == FS_NO_BACKEND) | 121 | if (fs_poolid_map[i] == FS_NO_BACKEND) |
120 | fs_poolid_map[i] = ops->init_fs(PAGE_SIZE); | 122 | fs_poolid_map[i] = ops->init_fs(PAGE_SIZE); |
@@ -130,7 +132,7 @@ struct cleancache_ops *cleancache_register_ops(struct cleancache_ops *ops) | |||
130 | barrier(); | 132 | barrier(); |
131 | cleancache_ops = ops; | 133 | cleancache_ops = ops; |
132 | mutex_unlock(&poolid_mutex); | 134 | mutex_unlock(&poolid_mutex); |
133 | return old; | 135 | return 0; |
134 | } | 136 | } |
135 | EXPORT_SYMBOL(cleancache_register_ops); | 137 | EXPORT_SYMBOL(cleancache_register_ops); |
136 | 138 | ||