blob: 00a0cda8f47a39bcf984770c74cc8fd37ff1a826 [file] [log] [blame]
David Howells9ae326a2009-04-03 16:42:41 +01001/* CacheFiles path walking and related routines
2 *
3 * Copyright (C) 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 Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#include <linux/module.h>
13#include <linux/sched.h>
14#include <linux/file.h>
15#include <linux/fs.h>
16#include <linux/fsnotify.h>
17#include <linux/quotaops.h>
18#include <linux/xattr.h>
19#include <linux/mount.h>
20#include <linux/namei.h>
21#include <linux/security.h>
22#include "internal.h"
23
24static int cachefiles_wait_bit(void *flags)
25{
26 schedule();
27 return 0;
28}
29
David Howellsd0e27b72009-11-19 18:12:02 +000030#define CACHEFILES_KEYBUF_SIZE 512
31
32/*
33 * dump debugging info about an object
34 */
35static noinline
36void __cachefiles_printk_object(struct cachefiles_object *object,
37 const char *prefix,
38 u8 *keybuf)
39{
40 struct fscache_cookie *cookie;
41 unsigned keylen, loop;
42
43 printk(KERN_ERR "%sobject: OBJ%x\n",
44 prefix, object->fscache.debug_id);
45 printk(KERN_ERR "%sobjstate=%s fl=%lx swfl=%lx ev=%lx[%lx]\n",
46 prefix, fscache_object_states[object->fscache.state],
47 object->fscache.flags, object->fscache.work.flags,
48 object->fscache.events,
49 object->fscache.event_mask & FSCACHE_OBJECT_EVENTS_MASK);
50 printk(KERN_ERR "%sops=%u inp=%u exc=%u\n",
51 prefix, object->fscache.n_ops, object->fscache.n_in_progress,
52 object->fscache.n_exclusive);
53 printk(KERN_ERR "%sparent=%p\n",
54 prefix, object->fscache.parent);
55
56 spin_lock(&object->fscache.lock);
57 cookie = object->fscache.cookie;
58 if (cookie) {
59 printk(KERN_ERR "%scookie=%p [pr=%p nd=%p fl=%lx]\n",
60 prefix,
61 object->fscache.cookie,
62 object->fscache.cookie->parent,
63 object->fscache.cookie->netfs_data,
64 object->fscache.cookie->flags);
65 if (keybuf)
66 keylen = cookie->def->get_key(cookie->netfs_data, keybuf,
67 CACHEFILES_KEYBUF_SIZE);
68 else
69 keylen = 0;
70 } else {
71 printk(KERN_ERR "%scookie=NULL\n", prefix);
72 keylen = 0;
73 }
74 spin_unlock(&object->fscache.lock);
75
76 if (keylen) {
77 printk(KERN_ERR "%skey=[%u] '", prefix, keylen);
78 for (loop = 0; loop < keylen; loop++)
79 printk("%02x", keybuf[loop]);
80 printk("'\n");
81 }
82}
83
84/*
85 * dump debugging info about a pair of objects
86 */
87static noinline void cachefiles_printk_object(struct cachefiles_object *object,
88 struct cachefiles_object *xobject)
89{
90 u8 *keybuf;
91
92 keybuf = kmalloc(CACHEFILES_KEYBUF_SIZE, GFP_NOIO);
93 if (object)
94 __cachefiles_printk_object(object, "", keybuf);
95 if (xobject)
96 __cachefiles_printk_object(xobject, "x", keybuf);
97 kfree(keybuf);
98}
99
David Howells9ae326a2009-04-03 16:42:41 +0100100/*
101 * record the fact that an object is now active
102 */
103static void cachefiles_mark_object_active(struct cachefiles_cache *cache,
104 struct cachefiles_object *object)
105{
106 struct cachefiles_object *xobject;
107 struct rb_node **_p, *_parent = NULL;
108 struct dentry *dentry;
109
110 _enter(",%p", object);
111
112try_again:
113 write_lock(&cache->active_lock);
114
David Howellsd0e27b72009-11-19 18:12:02 +0000115 if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) {
116 printk(KERN_ERR "CacheFiles: Error: Object already active\n");
117 cachefiles_printk_object(object, NULL);
David Howells9ae326a2009-04-03 16:42:41 +0100118 BUG();
David Howellsd0e27b72009-11-19 18:12:02 +0000119 }
David Howells9ae326a2009-04-03 16:42:41 +0100120
121 dentry = object->dentry;
122 _p = &cache->active_nodes.rb_node;
123 while (*_p) {
124 _parent = *_p;
125 xobject = rb_entry(_parent,
126 struct cachefiles_object, active_node);
127
128 ASSERT(xobject != object);
129
130 if (xobject->dentry > dentry)
131 _p = &(*_p)->rb_left;
132 else if (xobject->dentry < dentry)
133 _p = &(*_p)->rb_right;
134 else
135 goto wait_for_old_object;
136 }
137
138 rb_link_node(&object->active_node, _parent, _p);
139 rb_insert_color(&object->active_node, &cache->active_nodes);
140
141 write_unlock(&cache->active_lock);
142 _leave("");
143 return;
144
145 /* an old object from a previous incarnation is hogging the slot - we
146 * need to wait for it to be destroyed */
147wait_for_old_object:
148 if (xobject->fscache.state < FSCACHE_OBJECT_DYING) {
149 printk(KERN_ERR "\n");
150 printk(KERN_ERR "CacheFiles: Error:"
151 " Unexpected object collision\n");
David Howellsd0e27b72009-11-19 18:12:02 +0000152 cachefiles_printk_object(object, xobject);
David Howells9ae326a2009-04-03 16:42:41 +0100153 BUG();
154 }
155 atomic_inc(&xobject->usage);
156 write_unlock(&cache->active_lock);
157
158 _debug(">>> wait");
159 wait_on_bit(&xobject->flags, CACHEFILES_OBJECT_ACTIVE,
160 cachefiles_wait_bit, TASK_UNINTERRUPTIBLE);
161 _debug("<<< waited");
162
163 cache->cache.ops->put_object(&xobject->fscache);
164 goto try_again;
165}
166
167/*
168 * delete an object representation from the cache
169 * - file backed objects are unlinked
170 * - directory backed objects are stuffed into the graveyard for userspace to
171 * delete
172 * - unlocks the directory mutex
173 */
174static int cachefiles_bury_object(struct cachefiles_cache *cache,
175 struct dentry *dir,
176 struct dentry *rep)
177{
178 struct dentry *grave, *trap;
179 char nbuffer[8 + 8 + 1];
180 int ret;
181
182 _enter(",'%*.*s','%*.*s'",
183 dir->d_name.len, dir->d_name.len, dir->d_name.name,
184 rep->d_name.len, rep->d_name.len, rep->d_name.name);
185
186 /* non-directories can just be unlinked */
187 if (!S_ISDIR(rep->d_inode->i_mode)) {
188 _debug("unlink stale object");
189 ret = vfs_unlink(dir->d_inode, rep);
190
191 mutex_unlock(&dir->d_inode->i_mutex);
192
193 if (ret == -EIO)
194 cachefiles_io_error(cache, "Unlink failed");
195
196 _leave(" = %d", ret);
197 return ret;
198 }
199
200 /* directories have to be moved to the graveyard */
201 _debug("move stale object to graveyard");
202 mutex_unlock(&dir->d_inode->i_mutex);
203
204try_again:
205 /* first step is to make up a grave dentry in the graveyard */
206 sprintf(nbuffer, "%08x%08x",
207 (uint32_t) get_seconds(),
208 (uint32_t) atomic_inc_return(&cache->gravecounter));
209
210 /* do the multiway lock magic */
211 trap = lock_rename(cache->graveyard, dir);
212
213 /* do some checks before getting the grave dentry */
214 if (rep->d_parent != dir) {
215 /* the entry was probably culled when we dropped the parent dir
216 * lock */
217 unlock_rename(cache->graveyard, dir);
218 _leave(" = 0 [culled?]");
219 return 0;
220 }
221
222 if (!S_ISDIR(cache->graveyard->d_inode->i_mode)) {
223 unlock_rename(cache->graveyard, dir);
224 cachefiles_io_error(cache, "Graveyard no longer a directory");
225 return -EIO;
226 }
227
228 if (trap == rep) {
229 unlock_rename(cache->graveyard, dir);
230 cachefiles_io_error(cache, "May not make directory loop");
231 return -EIO;
232 }
233
234 if (d_mountpoint(rep)) {
235 unlock_rename(cache->graveyard, dir);
236 cachefiles_io_error(cache, "Mountpoint in cache");
237 return -EIO;
238 }
239
240 grave = lookup_one_len(nbuffer, cache->graveyard, strlen(nbuffer));
241 if (IS_ERR(grave)) {
242 unlock_rename(cache->graveyard, dir);
243
244 if (PTR_ERR(grave) == -ENOMEM) {
245 _leave(" = -ENOMEM");
246 return -ENOMEM;
247 }
248
249 cachefiles_io_error(cache, "Lookup error %ld",
250 PTR_ERR(grave));
251 return -EIO;
252 }
253
254 if (grave->d_inode) {
255 unlock_rename(cache->graveyard, dir);
256 dput(grave);
257 grave = NULL;
258 cond_resched();
259 goto try_again;
260 }
261
262 if (d_mountpoint(grave)) {
263 unlock_rename(cache->graveyard, dir);
264 dput(grave);
265 cachefiles_io_error(cache, "Mountpoint in graveyard");
266 return -EIO;
267 }
268
269 /* target should not be an ancestor of source */
270 if (trap == grave) {
271 unlock_rename(cache->graveyard, dir);
272 dput(grave);
273 cachefiles_io_error(cache, "May not make directory loop");
274 return -EIO;
275 }
276
277 /* attempt the rename */
278 ret = vfs_rename(dir->d_inode, rep, cache->graveyard->d_inode, grave);
279 if (ret != 0 && ret != -ENOMEM)
280 cachefiles_io_error(cache, "Rename failed with error %d", ret);
281
282 unlock_rename(cache->graveyard, dir);
283 dput(grave);
284 _leave(" = 0");
285 return 0;
286}
287
288/*
289 * delete an object representation from the cache
290 */
291int cachefiles_delete_object(struct cachefiles_cache *cache,
292 struct cachefiles_object *object)
293{
294 struct dentry *dir;
295 int ret;
296
297 _enter(",{%p}", object->dentry);
298
299 ASSERT(object->dentry);
300 ASSERT(object->dentry->d_inode);
301 ASSERT(object->dentry->d_parent);
302
303 dir = dget_parent(object->dentry);
304
David Howells6511de32009-11-19 18:11:58 +0000305 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
David Howells9ae326a2009-04-03 16:42:41 +0100306 ret = cachefiles_bury_object(cache, dir, object->dentry);
307
308 dput(dir);
309 _leave(" = %d", ret);
310 return ret;
311}
312
313/*
314 * walk from the parent object to the child object through the backing
315 * filesystem, creating directories as we go
316 */
317int cachefiles_walk_to_object(struct cachefiles_object *parent,
318 struct cachefiles_object *object,
319 const char *key,
320 struct cachefiles_xattr *auxdata)
321{
322 struct cachefiles_cache *cache;
323 struct dentry *dir, *next = NULL;
324 unsigned long start;
325 const char *name;
326 int ret, nlen;
327
328 _enter("{%p},,%s,", parent->dentry, key);
329
330 cache = container_of(parent->fscache.cache,
331 struct cachefiles_cache, cache);
332
333 ASSERT(parent->dentry);
334 ASSERT(parent->dentry->d_inode);
335
336 if (!(S_ISDIR(parent->dentry->d_inode->i_mode))) {
337 // TODO: convert file to dir
338 _leave("looking up in none directory");
339 return -ENOBUFS;
340 }
341
342 dir = dget(parent->dentry);
343
344advance:
345 /* attempt to transit the first directory component */
346 name = key;
347 nlen = strlen(key);
348
349 /* key ends in a double NUL */
350 key = key + nlen + 1;
351 if (!*key)
352 key = NULL;
353
354lookup_again:
355 /* search the current directory for the element name */
356 _debug("lookup '%s'", name);
357
David Howells6511de32009-11-19 18:11:58 +0000358 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
David Howells9ae326a2009-04-03 16:42:41 +0100359
360 start = jiffies;
361 next = lookup_one_len(name, dir, nlen);
362 cachefiles_hist(cachefiles_lookup_histogram, start);
363 if (IS_ERR(next))
364 goto lookup_error;
365
366 _debug("next -> %p %s", next, next->d_inode ? "positive" : "negative");
367
368 if (!key)
369 object->new = !next->d_inode;
370
371 /* if this element of the path doesn't exist, then the lookup phase
372 * failed, and we can release any readers in the certain knowledge that
373 * there's nothing for them to actually read */
374 if (!next->d_inode)
375 fscache_object_lookup_negative(&object->fscache);
376
377 /* we need to create the object if it's negative */
378 if (key || object->type == FSCACHE_COOKIE_TYPE_INDEX) {
379 /* index objects and intervening tree levels must be subdirs */
380 if (!next->d_inode) {
381 ret = cachefiles_has_space(cache, 1, 0);
382 if (ret < 0)
383 goto create_error;
384
385 start = jiffies;
386 ret = vfs_mkdir(dir->d_inode, next, 0);
387 cachefiles_hist(cachefiles_mkdir_histogram, start);
388 if (ret < 0)
389 goto create_error;
390
391 ASSERT(next->d_inode);
392
393 _debug("mkdir -> %p{%p{ino=%lu}}",
394 next, next->d_inode, next->d_inode->i_ino);
395
396 } else if (!S_ISDIR(next->d_inode->i_mode)) {
397 kerror("inode %lu is not a directory",
398 next->d_inode->i_ino);
399 ret = -ENOBUFS;
400 goto error;
401 }
402
403 } else {
404 /* non-index objects start out life as files */
405 if (!next->d_inode) {
406 ret = cachefiles_has_space(cache, 1, 0);
407 if (ret < 0)
408 goto create_error;
409
410 start = jiffies;
411 ret = vfs_create(dir->d_inode, next, S_IFREG, NULL);
412 cachefiles_hist(cachefiles_create_histogram, start);
413 if (ret < 0)
414 goto create_error;
415
416 ASSERT(next->d_inode);
417
418 _debug("create -> %p{%p{ino=%lu}}",
419 next, next->d_inode, next->d_inode->i_ino);
420
421 } else if (!S_ISDIR(next->d_inode->i_mode) &&
422 !S_ISREG(next->d_inode->i_mode)
423 ) {
424 kerror("inode %lu is not a file or directory",
425 next->d_inode->i_ino);
426 ret = -ENOBUFS;
427 goto error;
428 }
429 }
430
431 /* process the next component */
432 if (key) {
433 _debug("advance");
434 mutex_unlock(&dir->d_inode->i_mutex);
435 dput(dir);
436 dir = next;
437 next = NULL;
438 goto advance;
439 }
440
441 /* we've found the object we were looking for */
442 object->dentry = next;
443
444 /* if we've found that the terminal object exists, then we need to
445 * check its attributes and delete it if it's out of date */
446 if (!object->new) {
447 _debug("validate '%*.*s'",
448 next->d_name.len, next->d_name.len, next->d_name.name);
449
450 ret = cachefiles_check_object_xattr(object, auxdata);
451 if (ret == -ESTALE) {
452 /* delete the object (the deleter drops the directory
453 * mutex) */
454 object->dentry = NULL;
455
456 ret = cachefiles_bury_object(cache, dir, next);
457 dput(next);
458 next = NULL;
459
460 if (ret < 0)
461 goto delete_error;
462
463 _debug("redo lookup");
464 goto lookup_again;
465 }
466 }
467
468 /* note that we're now using this object */
469 cachefiles_mark_object_active(cache, object);
470
471 mutex_unlock(&dir->d_inode->i_mutex);
472 dput(dir);
473 dir = NULL;
474
475 _debug("=== OBTAINED_OBJECT ===");
476
477 if (object->new) {
478 /* attach data to a newly constructed terminal object */
479 ret = cachefiles_set_object_xattr(object, auxdata);
480 if (ret < 0)
481 goto check_error;
482 } else {
483 /* always update the atime on an object we've just looked up
484 * (this is used to keep track of culling, and atimes are only
485 * updated by read, write and readdir but not lookup or
486 * open) */
487 touch_atime(cache->mnt, next);
488 }
489
490 /* open a file interface onto a data file */
491 if (object->type != FSCACHE_COOKIE_TYPE_INDEX) {
492 if (S_ISREG(object->dentry->d_inode->i_mode)) {
493 const struct address_space_operations *aops;
494
495 ret = -EPERM;
496 aops = object->dentry->d_inode->i_mapping->a_ops;
497 if (!aops->bmap)
498 goto check_error;
499
500 object->backer = object->dentry;
501 } else {
502 BUG(); // TODO: open file in data-class subdir
503 }
504 }
505
506 object->new = 0;
507 fscache_obtained_object(&object->fscache);
508
509 _leave(" = 0 [%lu]", object->dentry->d_inode->i_ino);
510 return 0;
511
512create_error:
513 _debug("create error %d", ret);
514 if (ret == -EIO)
515 cachefiles_io_error(cache, "Create/mkdir failed");
516 goto error;
517
518check_error:
519 _debug("check error %d", ret);
520 write_lock(&cache->active_lock);
521 rb_erase(&object->active_node, &cache->active_nodes);
522 clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
523 wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE);
524 write_unlock(&cache->active_lock);
525
526 dput(object->dentry);
527 object->dentry = NULL;
528 goto error_out;
529
530delete_error:
531 _debug("delete error %d", ret);
532 goto error_out2;
533
534lookup_error:
535 _debug("lookup error %ld", PTR_ERR(next));
536 ret = PTR_ERR(next);
537 if (ret == -EIO)
538 cachefiles_io_error(cache, "Lookup failed");
539 next = NULL;
540error:
541 mutex_unlock(&dir->d_inode->i_mutex);
542 dput(next);
543error_out2:
544 dput(dir);
545error_out:
546 if (ret == -ENOSPC)
547 ret = -ENOBUFS;
548
549 _leave(" = error %d", -ret);
550 return ret;
551}
552
553/*
554 * get a subdirectory
555 */
556struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
557 struct dentry *dir,
558 const char *dirname)
559{
560 struct dentry *subdir;
561 unsigned long start;
562 int ret;
563
564 _enter(",,%s", dirname);
565
566 /* search the current directory for the element name */
567 mutex_lock(&dir->d_inode->i_mutex);
568
569 start = jiffies;
570 subdir = lookup_one_len(dirname, dir, strlen(dirname));
571 cachefiles_hist(cachefiles_lookup_histogram, start);
572 if (IS_ERR(subdir)) {
573 if (PTR_ERR(subdir) == -ENOMEM)
574 goto nomem_d_alloc;
575 goto lookup_error;
576 }
577
578 _debug("subdir -> %p %s",
579 subdir, subdir->d_inode ? "positive" : "negative");
580
581 /* we need to create the subdir if it doesn't exist yet */
582 if (!subdir->d_inode) {
583 ret = cachefiles_has_space(cache, 1, 0);
584 if (ret < 0)
585 goto mkdir_error;
586
587 _debug("attempt mkdir");
588
589 ret = vfs_mkdir(dir->d_inode, subdir, 0700);
590 if (ret < 0)
591 goto mkdir_error;
592
593 ASSERT(subdir->d_inode);
594
595 _debug("mkdir -> %p{%p{ino=%lu}}",
596 subdir,
597 subdir->d_inode,
598 subdir->d_inode->i_ino);
599 }
600
601 mutex_unlock(&dir->d_inode->i_mutex);
602
603 /* we need to make sure the subdir is a directory */
604 ASSERT(subdir->d_inode);
605
606 if (!S_ISDIR(subdir->d_inode->i_mode)) {
607 kerror("%s is not a directory", dirname);
608 ret = -EIO;
609 goto check_error;
610 }
611
612 ret = -EPERM;
613 if (!subdir->d_inode->i_op ||
614 !subdir->d_inode->i_op->setxattr ||
615 !subdir->d_inode->i_op->getxattr ||
616 !subdir->d_inode->i_op->lookup ||
617 !subdir->d_inode->i_op->mkdir ||
618 !subdir->d_inode->i_op->create ||
619 !subdir->d_inode->i_op->rename ||
620 !subdir->d_inode->i_op->rmdir ||
621 !subdir->d_inode->i_op->unlink)
622 goto check_error;
623
624 _leave(" = [%lu]", subdir->d_inode->i_ino);
625 return subdir;
626
627check_error:
628 dput(subdir);
629 _leave(" = %d [check]", ret);
630 return ERR_PTR(ret);
631
632mkdir_error:
633 mutex_unlock(&dir->d_inode->i_mutex);
634 dput(subdir);
635 kerror("mkdir %s failed with error %d", dirname, ret);
636 return ERR_PTR(ret);
637
638lookup_error:
639 mutex_unlock(&dir->d_inode->i_mutex);
640 ret = PTR_ERR(subdir);
641 kerror("Lookup %s failed with error %d", dirname, ret);
642 return ERR_PTR(ret);
643
644nomem_d_alloc:
645 mutex_unlock(&dir->d_inode->i_mutex);
646 _leave(" = -ENOMEM");
647 return ERR_PTR(-ENOMEM);
648}
649
650/*
651 * find out if an object is in use or not
652 * - if finds object and it's not in use:
653 * - returns a pointer to the object and a reference on it
654 * - returns with the directory locked
655 */
656static struct dentry *cachefiles_check_active(struct cachefiles_cache *cache,
657 struct dentry *dir,
658 char *filename)
659{
660 struct cachefiles_object *object;
661 struct rb_node *_n;
662 struct dentry *victim;
663 unsigned long start;
664 int ret;
665
666 //_enter(",%*.*s/,%s",
667 // dir->d_name.len, dir->d_name.len, dir->d_name.name, filename);
668
669 /* look up the victim */
670 mutex_lock_nested(&dir->d_inode->i_mutex, 1);
671
672 start = jiffies;
673 victim = lookup_one_len(filename, dir, strlen(filename));
674 cachefiles_hist(cachefiles_lookup_histogram, start);
675 if (IS_ERR(victim))
676 goto lookup_error;
677
678 //_debug("victim -> %p %s",
679 // victim, victim->d_inode ? "positive" : "negative");
680
681 /* if the object is no longer there then we probably retired the object
682 * at the netfs's request whilst the cull was in progress
683 */
684 if (!victim->d_inode) {
685 mutex_unlock(&dir->d_inode->i_mutex);
686 dput(victim);
687 _leave(" = -ENOENT [absent]");
688 return ERR_PTR(-ENOENT);
689 }
690
691 /* check to see if we're using this object */
692 read_lock(&cache->active_lock);
693
694 _n = cache->active_nodes.rb_node;
695
696 while (_n) {
697 object = rb_entry(_n, struct cachefiles_object, active_node);
698
699 if (object->dentry > victim)
700 _n = _n->rb_left;
701 else if (object->dentry < victim)
702 _n = _n->rb_right;
703 else
704 goto object_in_use;
705 }
706
707 read_unlock(&cache->active_lock);
708
709 //_leave(" = %p", victim);
710 return victim;
711
712object_in_use:
713 read_unlock(&cache->active_lock);
714 mutex_unlock(&dir->d_inode->i_mutex);
715 dput(victim);
716 //_leave(" = -EBUSY [in use]");
717 return ERR_PTR(-EBUSY);
718
719lookup_error:
720 mutex_unlock(&dir->d_inode->i_mutex);
721 ret = PTR_ERR(victim);
722 if (ret == -ENOENT) {
723 /* file or dir now absent - probably retired by netfs */
724 _leave(" = -ESTALE [absent]");
725 return ERR_PTR(-ESTALE);
726 }
727
728 if (ret == -EIO) {
729 cachefiles_io_error(cache, "Lookup failed");
730 } else if (ret != -ENOMEM) {
731 kerror("Internal error: %d", ret);
732 ret = -EIO;
733 }
734
735 _leave(" = %d", ret);
736 return ERR_PTR(ret);
737}
738
739/*
740 * cull an object if it's not in use
741 * - called only by cache manager daemon
742 */
743int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
744 char *filename)
745{
746 struct dentry *victim;
747 int ret;
748
749 _enter(",%*.*s/,%s",
750 dir->d_name.len, dir->d_name.len, dir->d_name.name, filename);
751
752 victim = cachefiles_check_active(cache, dir, filename);
753 if (IS_ERR(victim))
754 return PTR_ERR(victim);
755
756 _debug("victim -> %p %s",
757 victim, victim->d_inode ? "positive" : "negative");
758
759 /* okay... the victim is not being used so we can cull it
760 * - start by marking it as stale
761 */
762 _debug("victim is cullable");
763
764 ret = cachefiles_remove_object_xattr(cache, victim);
765 if (ret < 0)
766 goto error_unlock;
767
768 /* actually remove the victim (drops the dir mutex) */
769 _debug("bury");
770
771 ret = cachefiles_bury_object(cache, dir, victim);
772 if (ret < 0)
773 goto error;
774
775 dput(victim);
776 _leave(" = 0");
777 return 0;
778
779error_unlock:
780 mutex_unlock(&dir->d_inode->i_mutex);
781error:
782 dput(victim);
783 if (ret == -ENOENT) {
784 /* file or dir now absent - probably retired by netfs */
785 _leave(" = -ESTALE [absent]");
786 return -ESTALE;
787 }
788
789 if (ret != -ENOMEM) {
790 kerror("Internal error: %d", ret);
791 ret = -EIO;
792 }
793
794 _leave(" = %d", ret);
795 return ret;
796}
797
798/*
799 * find out if an object is in use or not
800 * - called only by cache manager daemon
801 * - returns -EBUSY or 0 to indicate whether an object is in use or not
802 */
803int cachefiles_check_in_use(struct cachefiles_cache *cache, struct dentry *dir,
804 char *filename)
805{
806 struct dentry *victim;
807
808 //_enter(",%*.*s/,%s",
809 // dir->d_name.len, dir->d_name.len, dir->d_name.name, filename);
810
811 victim = cachefiles_check_active(cache, dir, filename);
812 if (IS_ERR(victim))
813 return PTR_ERR(victim);
814
815 mutex_unlock(&dir->d_inode->i_mutex);
816 dput(victim);
817 //_leave(" = 0");
818 return 0;
819}