Commit 542ce7a9bc6b3838832ae0f4f8de30c667af8ff3

Authored by Miklos Szeredi
Committed by Al Viro
1 parent 6d0b5456e1

cachefiles: use path_get instead of lone dget

Dentry references should not be acquired without a corresponding
vfsmount ref.

Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 1 changed file with 14 additions and 12 deletions Inline Diff

fs/cachefiles/daemon.c
1 /* Daemon interface 1 /* Daemon interface
2 * 2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence 7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version 8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version. 9 * 2 of the Licence, or (at your option) any later version.
10 */ 10 */
11 11
12 #include <linux/module.h> 12 #include <linux/module.h>
13 #include <linux/init.h> 13 #include <linux/init.h>
14 #include <linux/sched.h> 14 #include <linux/sched.h>
15 #include <linux/completion.h> 15 #include <linux/completion.h>
16 #include <linux/slab.h> 16 #include <linux/slab.h>
17 #include <linux/fs.h> 17 #include <linux/fs.h>
18 #include <linux/file.h> 18 #include <linux/file.h>
19 #include <linux/namei.h> 19 #include <linux/namei.h>
20 #include <linux/poll.h> 20 #include <linux/poll.h>
21 #include <linux/mount.h> 21 #include <linux/mount.h>
22 #include <linux/statfs.h> 22 #include <linux/statfs.h>
23 #include <linux/ctype.h> 23 #include <linux/ctype.h>
24 #include <linux/string.h> 24 #include <linux/string.h>
25 #include <linux/fs_struct.h> 25 #include <linux/fs_struct.h>
26 #include "internal.h" 26 #include "internal.h"
27 27
28 static int cachefiles_daemon_open(struct inode *, struct file *); 28 static int cachefiles_daemon_open(struct inode *, struct file *);
29 static int cachefiles_daemon_release(struct inode *, struct file *); 29 static int cachefiles_daemon_release(struct inode *, struct file *);
30 static ssize_t cachefiles_daemon_read(struct file *, char __user *, size_t, 30 static ssize_t cachefiles_daemon_read(struct file *, char __user *, size_t,
31 loff_t *); 31 loff_t *);
32 static ssize_t cachefiles_daemon_write(struct file *, const char __user *, 32 static ssize_t cachefiles_daemon_write(struct file *, const char __user *,
33 size_t, loff_t *); 33 size_t, loff_t *);
34 static unsigned int cachefiles_daemon_poll(struct file *, 34 static unsigned int cachefiles_daemon_poll(struct file *,
35 struct poll_table_struct *); 35 struct poll_table_struct *);
36 static int cachefiles_daemon_frun(struct cachefiles_cache *, char *); 36 static int cachefiles_daemon_frun(struct cachefiles_cache *, char *);
37 static int cachefiles_daemon_fcull(struct cachefiles_cache *, char *); 37 static int cachefiles_daemon_fcull(struct cachefiles_cache *, char *);
38 static int cachefiles_daemon_fstop(struct cachefiles_cache *, char *); 38 static int cachefiles_daemon_fstop(struct cachefiles_cache *, char *);
39 static int cachefiles_daemon_brun(struct cachefiles_cache *, char *); 39 static int cachefiles_daemon_brun(struct cachefiles_cache *, char *);
40 static int cachefiles_daemon_bcull(struct cachefiles_cache *, char *); 40 static int cachefiles_daemon_bcull(struct cachefiles_cache *, char *);
41 static int cachefiles_daemon_bstop(struct cachefiles_cache *, char *); 41 static int cachefiles_daemon_bstop(struct cachefiles_cache *, char *);
42 static int cachefiles_daemon_cull(struct cachefiles_cache *, char *); 42 static int cachefiles_daemon_cull(struct cachefiles_cache *, char *);
43 static int cachefiles_daemon_debug(struct cachefiles_cache *, char *); 43 static int cachefiles_daemon_debug(struct cachefiles_cache *, char *);
44 static int cachefiles_daemon_dir(struct cachefiles_cache *, char *); 44 static int cachefiles_daemon_dir(struct cachefiles_cache *, char *);
45 static int cachefiles_daemon_inuse(struct cachefiles_cache *, char *); 45 static int cachefiles_daemon_inuse(struct cachefiles_cache *, char *);
46 static int cachefiles_daemon_secctx(struct cachefiles_cache *, char *); 46 static int cachefiles_daemon_secctx(struct cachefiles_cache *, char *);
47 static int cachefiles_daemon_tag(struct cachefiles_cache *, char *); 47 static int cachefiles_daemon_tag(struct cachefiles_cache *, char *);
48 48
49 static unsigned long cachefiles_open; 49 static unsigned long cachefiles_open;
50 50
51 const struct file_operations cachefiles_daemon_fops = { 51 const struct file_operations cachefiles_daemon_fops = {
52 .owner = THIS_MODULE, 52 .owner = THIS_MODULE,
53 .open = cachefiles_daemon_open, 53 .open = cachefiles_daemon_open,
54 .release = cachefiles_daemon_release, 54 .release = cachefiles_daemon_release,
55 .read = cachefiles_daemon_read, 55 .read = cachefiles_daemon_read,
56 .write = cachefiles_daemon_write, 56 .write = cachefiles_daemon_write,
57 .poll = cachefiles_daemon_poll, 57 .poll = cachefiles_daemon_poll,
58 }; 58 };
59 59
60 struct cachefiles_daemon_cmd { 60 struct cachefiles_daemon_cmd {
61 char name[8]; 61 char name[8];
62 int (*handler)(struct cachefiles_cache *cache, char *args); 62 int (*handler)(struct cachefiles_cache *cache, char *args);
63 }; 63 };
64 64
65 static const struct cachefiles_daemon_cmd cachefiles_daemon_cmds[] = { 65 static const struct cachefiles_daemon_cmd cachefiles_daemon_cmds[] = {
66 { "bind", cachefiles_daemon_bind }, 66 { "bind", cachefiles_daemon_bind },
67 { "brun", cachefiles_daemon_brun }, 67 { "brun", cachefiles_daemon_brun },
68 { "bcull", cachefiles_daemon_bcull }, 68 { "bcull", cachefiles_daemon_bcull },
69 { "bstop", cachefiles_daemon_bstop }, 69 { "bstop", cachefiles_daemon_bstop },
70 { "cull", cachefiles_daemon_cull }, 70 { "cull", cachefiles_daemon_cull },
71 { "debug", cachefiles_daemon_debug }, 71 { "debug", cachefiles_daemon_debug },
72 { "dir", cachefiles_daemon_dir }, 72 { "dir", cachefiles_daemon_dir },
73 { "frun", cachefiles_daemon_frun }, 73 { "frun", cachefiles_daemon_frun },
74 { "fcull", cachefiles_daemon_fcull }, 74 { "fcull", cachefiles_daemon_fcull },
75 { "fstop", cachefiles_daemon_fstop }, 75 { "fstop", cachefiles_daemon_fstop },
76 { "inuse", cachefiles_daemon_inuse }, 76 { "inuse", cachefiles_daemon_inuse },
77 { "secctx", cachefiles_daemon_secctx }, 77 { "secctx", cachefiles_daemon_secctx },
78 { "tag", cachefiles_daemon_tag }, 78 { "tag", cachefiles_daemon_tag },
79 { "", NULL } 79 { "", NULL }
80 }; 80 };
81 81
82 82
83 /* 83 /*
84 * do various checks 84 * do various checks
85 */ 85 */
86 static int cachefiles_daemon_open(struct inode *inode, struct file *file) 86 static int cachefiles_daemon_open(struct inode *inode, struct file *file)
87 { 87 {
88 struct cachefiles_cache *cache; 88 struct cachefiles_cache *cache;
89 89
90 _enter(""); 90 _enter("");
91 91
92 /* only the superuser may do this */ 92 /* only the superuser may do this */
93 if (!capable(CAP_SYS_ADMIN)) 93 if (!capable(CAP_SYS_ADMIN))
94 return -EPERM; 94 return -EPERM;
95 95
96 /* the cachefiles device may only be open once at a time */ 96 /* the cachefiles device may only be open once at a time */
97 if (xchg(&cachefiles_open, 1) == 1) 97 if (xchg(&cachefiles_open, 1) == 1)
98 return -EBUSY; 98 return -EBUSY;
99 99
100 /* allocate a cache record */ 100 /* allocate a cache record */
101 cache = kzalloc(sizeof(struct cachefiles_cache), GFP_KERNEL); 101 cache = kzalloc(sizeof(struct cachefiles_cache), GFP_KERNEL);
102 if (!cache) { 102 if (!cache) {
103 cachefiles_open = 0; 103 cachefiles_open = 0;
104 return -ENOMEM; 104 return -ENOMEM;
105 } 105 }
106 106
107 mutex_init(&cache->daemon_mutex); 107 mutex_init(&cache->daemon_mutex);
108 cache->active_nodes = RB_ROOT; 108 cache->active_nodes = RB_ROOT;
109 rwlock_init(&cache->active_lock); 109 rwlock_init(&cache->active_lock);
110 init_waitqueue_head(&cache->daemon_pollwq); 110 init_waitqueue_head(&cache->daemon_pollwq);
111 111
112 /* set default caching limits 112 /* set default caching limits
113 * - limit at 1% free space and/or free files 113 * - limit at 1% free space and/or free files
114 * - cull below 5% free space and/or free files 114 * - cull below 5% free space and/or free files
115 * - cease culling above 7% free space and/or free files 115 * - cease culling above 7% free space and/or free files
116 */ 116 */
117 cache->frun_percent = 7; 117 cache->frun_percent = 7;
118 cache->fcull_percent = 5; 118 cache->fcull_percent = 5;
119 cache->fstop_percent = 1; 119 cache->fstop_percent = 1;
120 cache->brun_percent = 7; 120 cache->brun_percent = 7;
121 cache->bcull_percent = 5; 121 cache->bcull_percent = 5;
122 cache->bstop_percent = 1; 122 cache->bstop_percent = 1;
123 123
124 file->private_data = cache; 124 file->private_data = cache;
125 cache->cachefilesd = file; 125 cache->cachefilesd = file;
126 return 0; 126 return 0;
127 } 127 }
128 128
129 /* 129 /*
130 * release a cache 130 * release a cache
131 */ 131 */
132 static int cachefiles_daemon_release(struct inode *inode, struct file *file) 132 static int cachefiles_daemon_release(struct inode *inode, struct file *file)
133 { 133 {
134 struct cachefiles_cache *cache = file->private_data; 134 struct cachefiles_cache *cache = file->private_data;
135 135
136 _enter(""); 136 _enter("");
137 137
138 ASSERT(cache); 138 ASSERT(cache);
139 139
140 set_bit(CACHEFILES_DEAD, &cache->flags); 140 set_bit(CACHEFILES_DEAD, &cache->flags);
141 141
142 cachefiles_daemon_unbind(cache); 142 cachefiles_daemon_unbind(cache);
143 143
144 ASSERT(!cache->active_nodes.rb_node); 144 ASSERT(!cache->active_nodes.rb_node);
145 145
146 /* clean up the control file interface */ 146 /* clean up the control file interface */
147 cache->cachefilesd = NULL; 147 cache->cachefilesd = NULL;
148 file->private_data = NULL; 148 file->private_data = NULL;
149 cachefiles_open = 0; 149 cachefiles_open = 0;
150 150
151 kfree(cache); 151 kfree(cache);
152 152
153 _leave(""); 153 _leave("");
154 return 0; 154 return 0;
155 } 155 }
156 156
157 /* 157 /*
158 * read the cache state 158 * read the cache state
159 */ 159 */
160 static ssize_t cachefiles_daemon_read(struct file *file, char __user *_buffer, 160 static ssize_t cachefiles_daemon_read(struct file *file, char __user *_buffer,
161 size_t buflen, loff_t *pos) 161 size_t buflen, loff_t *pos)
162 { 162 {
163 struct cachefiles_cache *cache = file->private_data; 163 struct cachefiles_cache *cache = file->private_data;
164 char buffer[256]; 164 char buffer[256];
165 int n; 165 int n;
166 166
167 //_enter(",,%zu,", buflen); 167 //_enter(",,%zu,", buflen);
168 168
169 if (!test_bit(CACHEFILES_READY, &cache->flags)) 169 if (!test_bit(CACHEFILES_READY, &cache->flags))
170 return 0; 170 return 0;
171 171
172 /* check how much space the cache has */ 172 /* check how much space the cache has */
173 cachefiles_has_space(cache, 0, 0); 173 cachefiles_has_space(cache, 0, 0);
174 174
175 /* summarise */ 175 /* summarise */
176 clear_bit(CACHEFILES_STATE_CHANGED, &cache->flags); 176 clear_bit(CACHEFILES_STATE_CHANGED, &cache->flags);
177 177
178 n = snprintf(buffer, sizeof(buffer), 178 n = snprintf(buffer, sizeof(buffer),
179 "cull=%c" 179 "cull=%c"
180 " frun=%llx" 180 " frun=%llx"
181 " fcull=%llx" 181 " fcull=%llx"
182 " fstop=%llx" 182 " fstop=%llx"
183 " brun=%llx" 183 " brun=%llx"
184 " bcull=%llx" 184 " bcull=%llx"
185 " bstop=%llx", 185 " bstop=%llx",
186 test_bit(CACHEFILES_CULLING, &cache->flags) ? '1' : '0', 186 test_bit(CACHEFILES_CULLING, &cache->flags) ? '1' : '0',
187 (unsigned long long) cache->frun, 187 (unsigned long long) cache->frun,
188 (unsigned long long) cache->fcull, 188 (unsigned long long) cache->fcull,
189 (unsigned long long) cache->fstop, 189 (unsigned long long) cache->fstop,
190 (unsigned long long) cache->brun, 190 (unsigned long long) cache->brun,
191 (unsigned long long) cache->bcull, 191 (unsigned long long) cache->bcull,
192 (unsigned long long) cache->bstop 192 (unsigned long long) cache->bstop
193 ); 193 );
194 194
195 if (n > buflen) 195 if (n > buflen)
196 return -EMSGSIZE; 196 return -EMSGSIZE;
197 197
198 if (copy_to_user(_buffer, buffer, n) != 0) 198 if (copy_to_user(_buffer, buffer, n) != 0)
199 return -EFAULT; 199 return -EFAULT;
200 200
201 return n; 201 return n;
202 } 202 }
203 203
204 /* 204 /*
205 * command the cache 205 * command the cache
206 */ 206 */
207 static ssize_t cachefiles_daemon_write(struct file *file, 207 static ssize_t cachefiles_daemon_write(struct file *file,
208 const char __user *_data, 208 const char __user *_data,
209 size_t datalen, 209 size_t datalen,
210 loff_t *pos) 210 loff_t *pos)
211 { 211 {
212 const struct cachefiles_daemon_cmd *cmd; 212 const struct cachefiles_daemon_cmd *cmd;
213 struct cachefiles_cache *cache = file->private_data; 213 struct cachefiles_cache *cache = file->private_data;
214 ssize_t ret; 214 ssize_t ret;
215 char *data, *args, *cp; 215 char *data, *args, *cp;
216 216
217 //_enter(",,%zu,", datalen); 217 //_enter(",,%zu,", datalen);
218 218
219 ASSERT(cache); 219 ASSERT(cache);
220 220
221 if (test_bit(CACHEFILES_DEAD, &cache->flags)) 221 if (test_bit(CACHEFILES_DEAD, &cache->flags))
222 return -EIO; 222 return -EIO;
223 223
224 if (datalen < 0 || datalen > PAGE_SIZE - 1) 224 if (datalen < 0 || datalen > PAGE_SIZE - 1)
225 return -EOPNOTSUPP; 225 return -EOPNOTSUPP;
226 226
227 /* drag the command string into the kernel so we can parse it */ 227 /* drag the command string into the kernel so we can parse it */
228 data = kmalloc(datalen + 1, GFP_KERNEL); 228 data = kmalloc(datalen + 1, GFP_KERNEL);
229 if (!data) 229 if (!data)
230 return -ENOMEM; 230 return -ENOMEM;
231 231
232 ret = -EFAULT; 232 ret = -EFAULT;
233 if (copy_from_user(data, _data, datalen) != 0) 233 if (copy_from_user(data, _data, datalen) != 0)
234 goto error; 234 goto error;
235 235
236 data[datalen] = '\0'; 236 data[datalen] = '\0';
237 237
238 ret = -EINVAL; 238 ret = -EINVAL;
239 if (memchr(data, '\0', datalen)) 239 if (memchr(data, '\0', datalen))
240 goto error; 240 goto error;
241 241
242 /* strip any newline */ 242 /* strip any newline */
243 cp = memchr(data, '\n', datalen); 243 cp = memchr(data, '\n', datalen);
244 if (cp) { 244 if (cp) {
245 if (cp == data) 245 if (cp == data)
246 goto error; 246 goto error;
247 247
248 *cp = '\0'; 248 *cp = '\0';
249 } 249 }
250 250
251 /* parse the command */ 251 /* parse the command */
252 ret = -EOPNOTSUPP; 252 ret = -EOPNOTSUPP;
253 253
254 for (args = data; *args; args++) 254 for (args = data; *args; args++)
255 if (isspace(*args)) 255 if (isspace(*args))
256 break; 256 break;
257 if (*args) { 257 if (*args) {
258 if (args == data) 258 if (args == data)
259 goto error; 259 goto error;
260 *args = '\0'; 260 *args = '\0';
261 args = skip_spaces(++args); 261 args = skip_spaces(++args);
262 } 262 }
263 263
264 /* run the appropriate command handler */ 264 /* run the appropriate command handler */
265 for (cmd = cachefiles_daemon_cmds; cmd->name[0]; cmd++) 265 for (cmd = cachefiles_daemon_cmds; cmd->name[0]; cmd++)
266 if (strcmp(cmd->name, data) == 0) 266 if (strcmp(cmd->name, data) == 0)
267 goto found_command; 267 goto found_command;
268 268
269 error: 269 error:
270 kfree(data); 270 kfree(data);
271 //_leave(" = %zd", ret); 271 //_leave(" = %zd", ret);
272 return ret; 272 return ret;
273 273
274 found_command: 274 found_command:
275 mutex_lock(&cache->daemon_mutex); 275 mutex_lock(&cache->daemon_mutex);
276 276
277 ret = -EIO; 277 ret = -EIO;
278 if (!test_bit(CACHEFILES_DEAD, &cache->flags)) 278 if (!test_bit(CACHEFILES_DEAD, &cache->flags))
279 ret = cmd->handler(cache, args); 279 ret = cmd->handler(cache, args);
280 280
281 mutex_unlock(&cache->daemon_mutex); 281 mutex_unlock(&cache->daemon_mutex);
282 282
283 if (ret == 0) 283 if (ret == 0)
284 ret = datalen; 284 ret = datalen;
285 goto error; 285 goto error;
286 } 286 }
287 287
288 /* 288 /*
289 * poll for culling state 289 * poll for culling state
290 * - use POLLOUT to indicate culling state 290 * - use POLLOUT to indicate culling state
291 */ 291 */
292 static unsigned int cachefiles_daemon_poll(struct file *file, 292 static unsigned int cachefiles_daemon_poll(struct file *file,
293 struct poll_table_struct *poll) 293 struct poll_table_struct *poll)
294 { 294 {
295 struct cachefiles_cache *cache = file->private_data; 295 struct cachefiles_cache *cache = file->private_data;
296 unsigned int mask; 296 unsigned int mask;
297 297
298 poll_wait(file, &cache->daemon_pollwq, poll); 298 poll_wait(file, &cache->daemon_pollwq, poll);
299 mask = 0; 299 mask = 0;
300 300
301 if (test_bit(CACHEFILES_STATE_CHANGED, &cache->flags)) 301 if (test_bit(CACHEFILES_STATE_CHANGED, &cache->flags))
302 mask |= POLLIN; 302 mask |= POLLIN;
303 303
304 if (test_bit(CACHEFILES_CULLING, &cache->flags)) 304 if (test_bit(CACHEFILES_CULLING, &cache->flags))
305 mask |= POLLOUT; 305 mask |= POLLOUT;
306 306
307 return mask; 307 return mask;
308 } 308 }
309 309
310 /* 310 /*
311 * give a range error for cache space constraints 311 * give a range error for cache space constraints
312 * - can be tail-called 312 * - can be tail-called
313 */ 313 */
314 static int cachefiles_daemon_range_error(struct cachefiles_cache *cache, 314 static int cachefiles_daemon_range_error(struct cachefiles_cache *cache,
315 char *args) 315 char *args)
316 { 316 {
317 kerror("Free space limits must be in range" 317 kerror("Free space limits must be in range"
318 " 0%%<=stop<cull<run<100%%"); 318 " 0%%<=stop<cull<run<100%%");
319 319
320 return -EINVAL; 320 return -EINVAL;
321 } 321 }
322 322
323 /* 323 /*
324 * set the percentage of files at which to stop culling 324 * set the percentage of files at which to stop culling
325 * - command: "frun <N>%" 325 * - command: "frun <N>%"
326 */ 326 */
327 static int cachefiles_daemon_frun(struct cachefiles_cache *cache, char *args) 327 static int cachefiles_daemon_frun(struct cachefiles_cache *cache, char *args)
328 { 328 {
329 unsigned long frun; 329 unsigned long frun;
330 330
331 _enter(",%s", args); 331 _enter(",%s", args);
332 332
333 if (!*args) 333 if (!*args)
334 return -EINVAL; 334 return -EINVAL;
335 335
336 frun = simple_strtoul(args, &args, 10); 336 frun = simple_strtoul(args, &args, 10);
337 if (args[0] != '%' || args[1] != '\0') 337 if (args[0] != '%' || args[1] != '\0')
338 return -EINVAL; 338 return -EINVAL;
339 339
340 if (frun <= cache->fcull_percent || frun >= 100) 340 if (frun <= cache->fcull_percent || frun >= 100)
341 return cachefiles_daemon_range_error(cache, args); 341 return cachefiles_daemon_range_error(cache, args);
342 342
343 cache->frun_percent = frun; 343 cache->frun_percent = frun;
344 return 0; 344 return 0;
345 } 345 }
346 346
347 /* 347 /*
348 * set the percentage of files at which to start culling 348 * set the percentage of files at which to start culling
349 * - command: "fcull <N>%" 349 * - command: "fcull <N>%"
350 */ 350 */
351 static int cachefiles_daemon_fcull(struct cachefiles_cache *cache, char *args) 351 static int cachefiles_daemon_fcull(struct cachefiles_cache *cache, char *args)
352 { 352 {
353 unsigned long fcull; 353 unsigned long fcull;
354 354
355 _enter(",%s", args); 355 _enter(",%s", args);
356 356
357 if (!*args) 357 if (!*args)
358 return -EINVAL; 358 return -EINVAL;
359 359
360 fcull = simple_strtoul(args, &args, 10); 360 fcull = simple_strtoul(args, &args, 10);
361 if (args[0] != '%' || args[1] != '\0') 361 if (args[0] != '%' || args[1] != '\0')
362 return -EINVAL; 362 return -EINVAL;
363 363
364 if (fcull <= cache->fstop_percent || fcull >= cache->frun_percent) 364 if (fcull <= cache->fstop_percent || fcull >= cache->frun_percent)
365 return cachefiles_daemon_range_error(cache, args); 365 return cachefiles_daemon_range_error(cache, args);
366 366
367 cache->fcull_percent = fcull; 367 cache->fcull_percent = fcull;
368 return 0; 368 return 0;
369 } 369 }
370 370
371 /* 371 /*
372 * set the percentage of files at which to stop allocating 372 * set the percentage of files at which to stop allocating
373 * - command: "fstop <N>%" 373 * - command: "fstop <N>%"
374 */ 374 */
375 static int cachefiles_daemon_fstop(struct cachefiles_cache *cache, char *args) 375 static int cachefiles_daemon_fstop(struct cachefiles_cache *cache, char *args)
376 { 376 {
377 unsigned long fstop; 377 unsigned long fstop;
378 378
379 _enter(",%s", args); 379 _enter(",%s", args);
380 380
381 if (!*args) 381 if (!*args)
382 return -EINVAL; 382 return -EINVAL;
383 383
384 fstop = simple_strtoul(args, &args, 10); 384 fstop = simple_strtoul(args, &args, 10);
385 if (args[0] != '%' || args[1] != '\0') 385 if (args[0] != '%' || args[1] != '\0')
386 return -EINVAL; 386 return -EINVAL;
387 387
388 if (fstop < 0 || fstop >= cache->fcull_percent) 388 if (fstop < 0 || fstop >= cache->fcull_percent)
389 return cachefiles_daemon_range_error(cache, args); 389 return cachefiles_daemon_range_error(cache, args);
390 390
391 cache->fstop_percent = fstop; 391 cache->fstop_percent = fstop;
392 return 0; 392 return 0;
393 } 393 }
394 394
395 /* 395 /*
396 * set the percentage of blocks at which to stop culling 396 * set the percentage of blocks at which to stop culling
397 * - command: "brun <N>%" 397 * - command: "brun <N>%"
398 */ 398 */
399 static int cachefiles_daemon_brun(struct cachefiles_cache *cache, char *args) 399 static int cachefiles_daemon_brun(struct cachefiles_cache *cache, char *args)
400 { 400 {
401 unsigned long brun; 401 unsigned long brun;
402 402
403 _enter(",%s", args); 403 _enter(",%s", args);
404 404
405 if (!*args) 405 if (!*args)
406 return -EINVAL; 406 return -EINVAL;
407 407
408 brun = simple_strtoul(args, &args, 10); 408 brun = simple_strtoul(args, &args, 10);
409 if (args[0] != '%' || args[1] != '\0') 409 if (args[0] != '%' || args[1] != '\0')
410 return -EINVAL; 410 return -EINVAL;
411 411
412 if (brun <= cache->bcull_percent || brun >= 100) 412 if (brun <= cache->bcull_percent || brun >= 100)
413 return cachefiles_daemon_range_error(cache, args); 413 return cachefiles_daemon_range_error(cache, args);
414 414
415 cache->brun_percent = brun; 415 cache->brun_percent = brun;
416 return 0; 416 return 0;
417 } 417 }
418 418
419 /* 419 /*
420 * set the percentage of blocks at which to start culling 420 * set the percentage of blocks at which to start culling
421 * - command: "bcull <N>%" 421 * - command: "bcull <N>%"
422 */ 422 */
423 static int cachefiles_daemon_bcull(struct cachefiles_cache *cache, char *args) 423 static int cachefiles_daemon_bcull(struct cachefiles_cache *cache, char *args)
424 { 424 {
425 unsigned long bcull; 425 unsigned long bcull;
426 426
427 _enter(",%s", args); 427 _enter(",%s", args);
428 428
429 if (!*args) 429 if (!*args)
430 return -EINVAL; 430 return -EINVAL;
431 431
432 bcull = simple_strtoul(args, &args, 10); 432 bcull = simple_strtoul(args, &args, 10);
433 if (args[0] != '%' || args[1] != '\0') 433 if (args[0] != '%' || args[1] != '\0')
434 return -EINVAL; 434 return -EINVAL;
435 435
436 if (bcull <= cache->bstop_percent || bcull >= cache->brun_percent) 436 if (bcull <= cache->bstop_percent || bcull >= cache->brun_percent)
437 return cachefiles_daemon_range_error(cache, args); 437 return cachefiles_daemon_range_error(cache, args);
438 438
439 cache->bcull_percent = bcull; 439 cache->bcull_percent = bcull;
440 return 0; 440 return 0;
441 } 441 }
442 442
443 /* 443 /*
444 * set the percentage of blocks at which to stop allocating 444 * set the percentage of blocks at which to stop allocating
445 * - command: "bstop <N>%" 445 * - command: "bstop <N>%"
446 */ 446 */
447 static int cachefiles_daemon_bstop(struct cachefiles_cache *cache, char *args) 447 static int cachefiles_daemon_bstop(struct cachefiles_cache *cache, char *args)
448 { 448 {
449 unsigned long bstop; 449 unsigned long bstop;
450 450
451 _enter(",%s", args); 451 _enter(",%s", args);
452 452
453 if (!*args) 453 if (!*args)
454 return -EINVAL; 454 return -EINVAL;
455 455
456 bstop = simple_strtoul(args, &args, 10); 456 bstop = simple_strtoul(args, &args, 10);
457 if (args[0] != '%' || args[1] != '\0') 457 if (args[0] != '%' || args[1] != '\0')
458 return -EINVAL; 458 return -EINVAL;
459 459
460 if (bstop < 0 || bstop >= cache->bcull_percent) 460 if (bstop < 0 || bstop >= cache->bcull_percent)
461 return cachefiles_daemon_range_error(cache, args); 461 return cachefiles_daemon_range_error(cache, args);
462 462
463 cache->bstop_percent = bstop; 463 cache->bstop_percent = bstop;
464 return 0; 464 return 0;
465 } 465 }
466 466
467 /* 467 /*
468 * set the cache directory 468 * set the cache directory
469 * - command: "dir <name>" 469 * - command: "dir <name>"
470 */ 470 */
471 static int cachefiles_daemon_dir(struct cachefiles_cache *cache, char *args) 471 static int cachefiles_daemon_dir(struct cachefiles_cache *cache, char *args)
472 { 472 {
473 char *dir; 473 char *dir;
474 474
475 _enter(",%s", args); 475 _enter(",%s", args);
476 476
477 if (!*args) { 477 if (!*args) {
478 kerror("Empty directory specified"); 478 kerror("Empty directory specified");
479 return -EINVAL; 479 return -EINVAL;
480 } 480 }
481 481
482 if (cache->rootdirname) { 482 if (cache->rootdirname) {
483 kerror("Second cache directory specified"); 483 kerror("Second cache directory specified");
484 return -EEXIST; 484 return -EEXIST;
485 } 485 }
486 486
487 dir = kstrdup(args, GFP_KERNEL); 487 dir = kstrdup(args, GFP_KERNEL);
488 if (!dir) 488 if (!dir)
489 return -ENOMEM; 489 return -ENOMEM;
490 490
491 cache->rootdirname = dir; 491 cache->rootdirname = dir;
492 return 0; 492 return 0;
493 } 493 }
494 494
495 /* 495 /*
496 * set the cache security context 496 * set the cache security context
497 * - command: "secctx <ctx>" 497 * - command: "secctx <ctx>"
498 */ 498 */
499 static int cachefiles_daemon_secctx(struct cachefiles_cache *cache, char *args) 499 static int cachefiles_daemon_secctx(struct cachefiles_cache *cache, char *args)
500 { 500 {
501 char *secctx; 501 char *secctx;
502 502
503 _enter(",%s", args); 503 _enter(",%s", args);
504 504
505 if (!*args) { 505 if (!*args) {
506 kerror("Empty security context specified"); 506 kerror("Empty security context specified");
507 return -EINVAL; 507 return -EINVAL;
508 } 508 }
509 509
510 if (cache->secctx) { 510 if (cache->secctx) {
511 kerror("Second security context specified"); 511 kerror("Second security context specified");
512 return -EINVAL; 512 return -EINVAL;
513 } 513 }
514 514
515 secctx = kstrdup(args, GFP_KERNEL); 515 secctx = kstrdup(args, GFP_KERNEL);
516 if (!secctx) 516 if (!secctx)
517 return -ENOMEM; 517 return -ENOMEM;
518 518
519 cache->secctx = secctx; 519 cache->secctx = secctx;
520 return 0; 520 return 0;
521 } 521 }
522 522
523 /* 523 /*
524 * set the cache tag 524 * set the cache tag
525 * - command: "tag <name>" 525 * - command: "tag <name>"
526 */ 526 */
527 static int cachefiles_daemon_tag(struct cachefiles_cache *cache, char *args) 527 static int cachefiles_daemon_tag(struct cachefiles_cache *cache, char *args)
528 { 528 {
529 char *tag; 529 char *tag;
530 530
531 _enter(",%s", args); 531 _enter(",%s", args);
532 532
533 if (!*args) { 533 if (!*args) {
534 kerror("Empty tag specified"); 534 kerror("Empty tag specified");
535 return -EINVAL; 535 return -EINVAL;
536 } 536 }
537 537
538 if (cache->tag) 538 if (cache->tag)
539 return -EEXIST; 539 return -EEXIST;
540 540
541 tag = kstrdup(args, GFP_KERNEL); 541 tag = kstrdup(args, GFP_KERNEL);
542 if (!tag) 542 if (!tag)
543 return -ENOMEM; 543 return -ENOMEM;
544 544
545 cache->tag = tag; 545 cache->tag = tag;
546 return 0; 546 return 0;
547 } 547 }
548 548
549 /* 549 /*
550 * request a node in the cache be culled from the current working directory 550 * request a node in the cache be culled from the current working directory
551 * - command: "cull <name>" 551 * - command: "cull <name>"
552 */ 552 */
553 static int cachefiles_daemon_cull(struct cachefiles_cache *cache, char *args) 553 static int cachefiles_daemon_cull(struct cachefiles_cache *cache, char *args)
554 { 554 {
555 struct fs_struct *fs; 555 struct fs_struct *fs;
556 struct dentry *dir; 556 struct path path;
557 const struct cred *saved_cred; 557 const struct cred *saved_cred;
558 int ret; 558 int ret;
559 559
560 _enter(",%s", args); 560 _enter(",%s", args);
561 561
562 if (strchr(args, '/')) 562 if (strchr(args, '/'))
563 goto inval; 563 goto inval;
564 564
565 if (!test_bit(CACHEFILES_READY, &cache->flags)) { 565 if (!test_bit(CACHEFILES_READY, &cache->flags)) {
566 kerror("cull applied to unready cache"); 566 kerror("cull applied to unready cache");
567 return -EIO; 567 return -EIO;
568 } 568 }
569 569
570 if (test_bit(CACHEFILES_DEAD, &cache->flags)) { 570 if (test_bit(CACHEFILES_DEAD, &cache->flags)) {
571 kerror("cull applied to dead cache"); 571 kerror("cull applied to dead cache");
572 return -EIO; 572 return -EIO;
573 } 573 }
574 574
575 /* extract the directory dentry from the cwd */ 575 /* extract the directory dentry from the cwd */
576 fs = current->fs; 576 fs = current->fs;
577 read_lock(&fs->lock); 577 read_lock(&fs->lock);
578 dir = dget(fs->pwd.dentry); 578 path = fs->pwd;
579 path_get(&path);
579 read_unlock(&fs->lock); 580 read_unlock(&fs->lock);
580 581
581 if (!S_ISDIR(dir->d_inode->i_mode)) 582 if (!S_ISDIR(path.dentry->d_inode->i_mode))
582 goto notdir; 583 goto notdir;
583 584
584 cachefiles_begin_secure(cache, &saved_cred); 585 cachefiles_begin_secure(cache, &saved_cred);
585 ret = cachefiles_cull(cache, dir, args); 586 ret = cachefiles_cull(cache, path.dentry, args);
586 cachefiles_end_secure(cache, saved_cred); 587 cachefiles_end_secure(cache, saved_cred);
587 588
588 dput(dir); 589 path_put(&path);
589 _leave(" = %d", ret); 590 _leave(" = %d", ret);
590 return ret; 591 return ret;
591 592
592 notdir: 593 notdir:
593 dput(dir); 594 path_put(&path);
594 kerror("cull command requires dirfd to be a directory"); 595 kerror("cull command requires dirfd to be a directory");
595 return -ENOTDIR; 596 return -ENOTDIR;
596 597
597 inval: 598 inval:
598 kerror("cull command requires dirfd and filename"); 599 kerror("cull command requires dirfd and filename");
599 return -EINVAL; 600 return -EINVAL;
600 } 601 }
601 602
602 /* 603 /*
603 * set debugging mode 604 * set debugging mode
604 * - command: "debug <mask>" 605 * - command: "debug <mask>"
605 */ 606 */
606 static int cachefiles_daemon_debug(struct cachefiles_cache *cache, char *args) 607 static int cachefiles_daemon_debug(struct cachefiles_cache *cache, char *args)
607 { 608 {
608 unsigned long mask; 609 unsigned long mask;
609 610
610 _enter(",%s", args); 611 _enter(",%s", args);
611 612
612 mask = simple_strtoul(args, &args, 0); 613 mask = simple_strtoul(args, &args, 0);
613 if (args[0] != '\0') 614 if (args[0] != '\0')
614 goto inval; 615 goto inval;
615 616
616 cachefiles_debug = mask; 617 cachefiles_debug = mask;
617 _leave(" = 0"); 618 _leave(" = 0");
618 return 0; 619 return 0;
619 620
620 inval: 621 inval:
621 kerror("debug command requires mask"); 622 kerror("debug command requires mask");
622 return -EINVAL; 623 return -EINVAL;
623 } 624 }
624 625
625 /* 626 /*
626 * find out whether an object in the current working directory is in use or not 627 * find out whether an object in the current working directory is in use or not
627 * - command: "inuse <name>" 628 * - command: "inuse <name>"
628 */ 629 */
629 static int cachefiles_daemon_inuse(struct cachefiles_cache *cache, char *args) 630 static int cachefiles_daemon_inuse(struct cachefiles_cache *cache, char *args)
630 { 631 {
631 struct fs_struct *fs; 632 struct fs_struct *fs;
632 struct dentry *dir; 633 struct path path;
633 const struct cred *saved_cred; 634 const struct cred *saved_cred;
634 int ret; 635 int ret;
635 636
636 //_enter(",%s", args); 637 //_enter(",%s", args);
637 638
638 if (strchr(args, '/')) 639 if (strchr(args, '/'))
639 goto inval; 640 goto inval;
640 641
641 if (!test_bit(CACHEFILES_READY, &cache->flags)) { 642 if (!test_bit(CACHEFILES_READY, &cache->flags)) {
642 kerror("inuse applied to unready cache"); 643 kerror("inuse applied to unready cache");
643 return -EIO; 644 return -EIO;
644 } 645 }
645 646
646 if (test_bit(CACHEFILES_DEAD, &cache->flags)) { 647 if (test_bit(CACHEFILES_DEAD, &cache->flags)) {
647 kerror("inuse applied to dead cache"); 648 kerror("inuse applied to dead cache");
648 return -EIO; 649 return -EIO;
649 } 650 }
650 651
651 /* extract the directory dentry from the cwd */ 652 /* extract the directory dentry from the cwd */
652 fs = current->fs; 653 fs = current->fs;
653 read_lock(&fs->lock); 654 read_lock(&fs->lock);
654 dir = dget(fs->pwd.dentry); 655 path = fs->pwd;
656 path_get(&path);
655 read_unlock(&fs->lock); 657 read_unlock(&fs->lock);
656 658
657 if (!S_ISDIR(dir->d_inode->i_mode)) 659 if (!S_ISDIR(path.dentry->d_inode->i_mode))
658 goto notdir; 660 goto notdir;
659 661
660 cachefiles_begin_secure(cache, &saved_cred); 662 cachefiles_begin_secure(cache, &saved_cred);
661 ret = cachefiles_check_in_use(cache, dir, args); 663 ret = cachefiles_check_in_use(cache, path.dentry, args);
662 cachefiles_end_secure(cache, saved_cred); 664 cachefiles_end_secure(cache, saved_cred);
663 665
664 dput(dir); 666 path_put(&path);
665 //_leave(" = %d", ret); 667 //_leave(" = %d", ret);
666 return ret; 668 return ret;
667 669
668 notdir: 670 notdir:
669 dput(dir); 671 path_put(&path);
670 kerror("inuse command requires dirfd to be a directory"); 672 kerror("inuse command requires dirfd to be a directory");
671 return -ENOTDIR; 673 return -ENOTDIR;
672 674
673 inval: 675 inval:
674 kerror("inuse command requires dirfd and filename"); 676 kerror("inuse command requires dirfd and filename");
675 return -EINVAL; 677 return -EINVAL;
676 } 678 }
677 679
678 /* 680 /*
679 * see if we have space for a number of pages and/or a number of files in the 681 * see if we have space for a number of pages and/or a number of files in the
680 * cache 682 * cache
681 */ 683 */
682 int cachefiles_has_space(struct cachefiles_cache *cache, 684 int cachefiles_has_space(struct cachefiles_cache *cache,
683 unsigned fnr, unsigned bnr) 685 unsigned fnr, unsigned bnr)
684 { 686 {
685 struct kstatfs stats; 687 struct kstatfs stats;
686 struct path path = { 688 struct path path = {
687 .mnt = cache->mnt, 689 .mnt = cache->mnt,
688 .dentry = cache->mnt->mnt_root, 690 .dentry = cache->mnt->mnt_root,
689 }; 691 };
690 int ret; 692 int ret;
691 693
692 //_enter("{%llu,%llu,%llu,%llu,%llu,%llu},%u,%u", 694 //_enter("{%llu,%llu,%llu,%llu,%llu,%llu},%u,%u",
693 // (unsigned long long) cache->frun, 695 // (unsigned long long) cache->frun,
694 // (unsigned long long) cache->fcull, 696 // (unsigned long long) cache->fcull,
695 // (unsigned long long) cache->fstop, 697 // (unsigned long long) cache->fstop,
696 // (unsigned long long) cache->brun, 698 // (unsigned long long) cache->brun,
697 // (unsigned long long) cache->bcull, 699 // (unsigned long long) cache->bcull,
698 // (unsigned long long) cache->bstop, 700 // (unsigned long long) cache->bstop,
699 // fnr, bnr); 701 // fnr, bnr);
700 702
701 /* find out how many pages of blockdev are available */ 703 /* find out how many pages of blockdev are available */
702 memset(&stats, 0, sizeof(stats)); 704 memset(&stats, 0, sizeof(stats));
703 705
704 ret = vfs_statfs(&path, &stats); 706 ret = vfs_statfs(&path, &stats);
705 if (ret < 0) { 707 if (ret < 0) {
706 if (ret == -EIO) 708 if (ret == -EIO)
707 cachefiles_io_error(cache, "statfs failed"); 709 cachefiles_io_error(cache, "statfs failed");
708 _leave(" = %d", ret); 710 _leave(" = %d", ret);
709 return ret; 711 return ret;
710 } 712 }
711 713
712 stats.f_bavail >>= cache->bshift; 714 stats.f_bavail >>= cache->bshift;
713 715
714 //_debug("avail %llu,%llu", 716 //_debug("avail %llu,%llu",
715 // (unsigned long long) stats.f_ffree, 717 // (unsigned long long) stats.f_ffree,
716 // (unsigned long long) stats.f_bavail); 718 // (unsigned long long) stats.f_bavail);
717 719
718 /* see if there is sufficient space */ 720 /* see if there is sufficient space */
719 if (stats.f_ffree > fnr) 721 if (stats.f_ffree > fnr)
720 stats.f_ffree -= fnr; 722 stats.f_ffree -= fnr;
721 else 723 else
722 stats.f_ffree = 0; 724 stats.f_ffree = 0;
723 725
724 if (stats.f_bavail > bnr) 726 if (stats.f_bavail > bnr)
725 stats.f_bavail -= bnr; 727 stats.f_bavail -= bnr;
726 else 728 else
727 stats.f_bavail = 0; 729 stats.f_bavail = 0;
728 730
729 ret = -ENOBUFS; 731 ret = -ENOBUFS;
730 if (stats.f_ffree < cache->fstop || 732 if (stats.f_ffree < cache->fstop ||
731 stats.f_bavail < cache->bstop) 733 stats.f_bavail < cache->bstop)
732 goto begin_cull; 734 goto begin_cull;
733 735
734 ret = 0; 736 ret = 0;
735 if (stats.f_ffree < cache->fcull || 737 if (stats.f_ffree < cache->fcull ||
736 stats.f_bavail < cache->bcull) 738 stats.f_bavail < cache->bcull)
737 goto begin_cull; 739 goto begin_cull;
738 740
739 if (test_bit(CACHEFILES_CULLING, &cache->flags) && 741 if (test_bit(CACHEFILES_CULLING, &cache->flags) &&
740 stats.f_ffree >= cache->frun && 742 stats.f_ffree >= cache->frun &&
741 stats.f_bavail >= cache->brun && 743 stats.f_bavail >= cache->brun &&
742 test_and_clear_bit(CACHEFILES_CULLING, &cache->flags) 744 test_and_clear_bit(CACHEFILES_CULLING, &cache->flags)
743 ) { 745 ) {
744 _debug("cease culling"); 746 _debug("cease culling");
745 cachefiles_state_changed(cache); 747 cachefiles_state_changed(cache);
746 } 748 }
747 749
748 //_leave(" = 0"); 750 //_leave(" = 0");
749 return 0; 751 return 0;
750 752
751 begin_cull: 753 begin_cull:
752 if (!test_and_set_bit(CACHEFILES_CULLING, &cache->flags)) { 754 if (!test_and_set_bit(CACHEFILES_CULLING, &cache->flags)) {
753 _debug("### CULL CACHE ###"); 755 _debug("### CULL CACHE ###");
754 cachefiles_state_changed(cache); 756 cachefiles_state_changed(cache);
755 } 757 }
756 758
757 _leave(" = %d", ret); 759 _leave(" = %d", ret);
758 return ret; 760 return ret;
759 } 761 }
760 762