Root/
1 | /* General filesystem local caching manager |
2 | * |
3 | * Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved. |
4 | * Written by David Howells (dhowells@redhat.com) |
5 | * |
6 | * This program is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU General Public License |
8 | * as published by the Free Software Foundation; either version |
9 | * 2 of the License, or (at your option) any later version. |
10 | */ |
11 | |
12 | #define FSCACHE_DEBUG_LEVEL CACHE |
13 | #include <linux/module.h> |
14 | #include <linux/init.h> |
15 | #include <linux/sched.h> |
16 | #include <linux/completion.h> |
17 | #include <linux/slab.h> |
18 | #include <linux/seq_file.h> |
19 | #include "internal.h" |
20 | |
21 | MODULE_DESCRIPTION("FS Cache Manager"); |
22 | MODULE_AUTHOR("Red Hat, Inc."); |
23 | MODULE_LICENSE("GPL"); |
24 | |
25 | unsigned fscache_defer_lookup = 1; |
26 | module_param_named(defer_lookup, fscache_defer_lookup, uint, |
27 | S_IWUSR | S_IRUGO); |
28 | MODULE_PARM_DESC(fscache_defer_lookup, |
29 | "Defer cookie lookup to background thread"); |
30 | |
31 | unsigned fscache_defer_create = 1; |
32 | module_param_named(defer_create, fscache_defer_create, uint, |
33 | S_IWUSR | S_IRUGO); |
34 | MODULE_PARM_DESC(fscache_defer_create, |
35 | "Defer cookie creation to background thread"); |
36 | |
37 | unsigned fscache_debug; |
38 | module_param_named(debug, fscache_debug, uint, |
39 | S_IWUSR | S_IRUGO); |
40 | MODULE_PARM_DESC(fscache_debug, |
41 | "FS-Cache debugging mask"); |
42 | |
43 | struct kobject *fscache_root; |
44 | struct workqueue_struct *fscache_object_wq; |
45 | struct workqueue_struct *fscache_op_wq; |
46 | |
47 | DEFINE_PER_CPU(wait_queue_head_t, fscache_object_cong_wait); |
48 | |
49 | /* these values serve as lower bounds, will be adjusted in fscache_init() */ |
50 | static unsigned fscache_object_max_active = 4; |
51 | static unsigned fscache_op_max_active = 2; |
52 | |
53 | #ifdef CONFIG_SYSCTL |
54 | static struct ctl_table_header *fscache_sysctl_header; |
55 | |
56 | static int fscache_max_active_sysctl(struct ctl_table *table, int write, |
57 | void __user *buffer, |
58 | size_t *lenp, loff_t *ppos) |
59 | { |
60 | struct workqueue_struct **wqp = table->extra1; |
61 | unsigned int *datap = table->data; |
62 | int ret; |
63 | |
64 | ret = proc_dointvec(table, write, buffer, lenp, ppos); |
65 | if (ret == 0) |
66 | workqueue_set_max_active(*wqp, *datap); |
67 | return ret; |
68 | } |
69 | |
70 | ctl_table fscache_sysctls[] = { |
71 | { |
72 | .procname = "object_max_active", |
73 | .data = &fscache_object_max_active, |
74 | .maxlen = sizeof(unsigned), |
75 | .mode = 0644, |
76 | .proc_handler = fscache_max_active_sysctl, |
77 | .extra1 = &fscache_object_wq, |
78 | }, |
79 | { |
80 | .procname = "operation_max_active", |
81 | .data = &fscache_op_max_active, |
82 | .maxlen = sizeof(unsigned), |
83 | .mode = 0644, |
84 | .proc_handler = fscache_max_active_sysctl, |
85 | .extra1 = &fscache_op_wq, |
86 | }, |
87 | {} |
88 | }; |
89 | |
90 | ctl_table fscache_sysctls_root[] = { |
91 | { |
92 | .procname = "fscache", |
93 | .mode = 0555, |
94 | .child = fscache_sysctls, |
95 | }, |
96 | {} |
97 | }; |
98 | #endif |
99 | |
100 | /* |
101 | * initialise the fs caching module |
102 | */ |
103 | static int __init fscache_init(void) |
104 | { |
105 | unsigned int nr_cpus = num_possible_cpus(); |
106 | unsigned int cpu; |
107 | int ret; |
108 | |
109 | fscache_object_max_active = |
110 | clamp_val(nr_cpus, |
111 | fscache_object_max_active, WQ_UNBOUND_MAX_ACTIVE); |
112 | |
113 | ret = -ENOMEM; |
114 | fscache_object_wq = alloc_workqueue("fscache_object", WQ_UNBOUND, |
115 | fscache_object_max_active); |
116 | if (!fscache_object_wq) |
117 | goto error_object_wq; |
118 | |
119 | fscache_op_max_active = |
120 | clamp_val(fscache_object_max_active / 2, |
121 | fscache_op_max_active, WQ_UNBOUND_MAX_ACTIVE); |
122 | |
123 | ret = -ENOMEM; |
124 | fscache_op_wq = alloc_workqueue("fscache_operation", WQ_UNBOUND, |
125 | fscache_op_max_active); |
126 | if (!fscache_op_wq) |
127 | goto error_op_wq; |
128 | |
129 | for_each_possible_cpu(cpu) |
130 | init_waitqueue_head(&per_cpu(fscache_object_cong_wait, cpu)); |
131 | |
132 | ret = fscache_proc_init(); |
133 | if (ret < 0) |
134 | goto error_proc; |
135 | |
136 | #ifdef CONFIG_SYSCTL |
137 | ret = -ENOMEM; |
138 | fscache_sysctl_header = register_sysctl_table(fscache_sysctls_root); |
139 | if (!fscache_sysctl_header) |
140 | goto error_sysctl; |
141 | #endif |
142 | |
143 | fscache_cookie_jar = kmem_cache_create("fscache_cookie_jar", |
144 | sizeof(struct fscache_cookie), |
145 | 0, |
146 | 0, |
147 | fscache_cookie_init_once); |
148 | if (!fscache_cookie_jar) { |
149 | printk(KERN_NOTICE |
150 | "FS-Cache: Failed to allocate a cookie jar\n"); |
151 | ret = -ENOMEM; |
152 | goto error_cookie_jar; |
153 | } |
154 | |
155 | fscache_root = kobject_create_and_add("fscache", kernel_kobj); |
156 | if (!fscache_root) |
157 | goto error_kobj; |
158 | |
159 | printk(KERN_NOTICE "FS-Cache: Loaded\n"); |
160 | return 0; |
161 | |
162 | error_kobj: |
163 | kmem_cache_destroy(fscache_cookie_jar); |
164 | error_cookie_jar: |
165 | #ifdef CONFIG_SYSCTL |
166 | unregister_sysctl_table(fscache_sysctl_header); |
167 | error_sysctl: |
168 | #endif |
169 | fscache_proc_cleanup(); |
170 | error_proc: |
171 | destroy_workqueue(fscache_op_wq); |
172 | error_op_wq: |
173 | destroy_workqueue(fscache_object_wq); |
174 | error_object_wq: |
175 | return ret; |
176 | } |
177 | |
178 | fs_initcall(fscache_init); |
179 | |
180 | /* |
181 | * clean up on module removal |
182 | */ |
183 | static void __exit fscache_exit(void) |
184 | { |
185 | _enter(""); |
186 | |
187 | kobject_put(fscache_root); |
188 | kmem_cache_destroy(fscache_cookie_jar); |
189 | #ifdef CONFIG_SYSCTL |
190 | unregister_sysctl_table(fscache_sysctl_header); |
191 | #endif |
192 | fscache_proc_cleanup(); |
193 | destroy_workqueue(fscache_op_wq); |
194 | destroy_workqueue(fscache_object_wq); |
195 | printk(KERN_NOTICE "FS-Cache: Unloaded\n"); |
196 | } |
197 | |
198 | module_exit(fscache_exit); |
199 | |
200 | /* |
201 | * wait_on_bit() sleep function for uninterruptible waiting |
202 | */ |
203 | int fscache_wait_bit(void *flags) |
204 | { |
205 | schedule(); |
206 | return 0; |
207 | } |
208 | EXPORT_SYMBOL(fscache_wait_bit); |
209 | |
210 | /* |
211 | * wait_on_bit() sleep function for interruptible waiting |
212 | */ |
213 | int fscache_wait_bit_interruptible(void *flags) |
214 | { |
215 | schedule(); |
216 | return signal_pending(current); |
217 | } |
218 | EXPORT_SYMBOL(fscache_wait_bit_interruptible); |
219 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9