1 /* Bind and unbind a cache from the filesystem backing it
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
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.
12 #include <linux/module.h>
13 #include <linux/init.h>
14 #include <linux/sched.h>
15 #include <linux/completion.h>
16 #include <linux/slab.h>
18 #include <linux/file.h>
19 #include <linux/namei.h>
20 #include <linux/mount.h>
21 #include <linux/statfs.h>
22 #include <linux/ctype.h>
25 static int cachefiles_daemon_add_cache(struct cachefiles_cache
*caches
);
28 * bind a directory as a cache
30 int cachefiles_daemon_bind(struct cachefiles_cache
*cache
, char *args
)
32 _enter("{%u,%u,%u,%u,%u,%u},%s",
41 /* start by checking things over */
42 ASSERT(cache
->fstop_percent
>= 0 &&
43 cache
->fstop_percent
< cache
->fcull_percent
&&
44 cache
->fcull_percent
< cache
->frun_percent
&&
45 cache
->frun_percent
< 100);
47 ASSERT(cache
->bstop_percent
>= 0 &&
48 cache
->bstop_percent
< cache
->bcull_percent
&&
49 cache
->bcull_percent
< cache
->brun_percent
&&
50 cache
->brun_percent
< 100);
53 kerror("'bind' command doesn't take an argument");
57 if (!cache
->rootdirname
) {
58 kerror("No cache directory specified");
62 /* don't permit already bound caches to be re-bound */
63 if (test_bit(CACHEFILES_READY
, &cache
->flags
)) {
64 kerror("Cache already bound");
68 /* make sure we have copies of the tag and dirname strings */
70 /* the tag string is released by the fops->release()
71 * function, so we don't release it on error here */
72 cache
->tag
= kstrdup("CacheFiles", GFP_KERNEL
);
78 return cachefiles_daemon_add_cache(cache
);
84 static int cachefiles_daemon_add_cache(struct cachefiles_cache
*cache
)
86 struct cachefiles_object
*fsdef
;
89 struct dentry
*graveyard
, *cachedir
, *root
;
90 const struct cred
*saved_cred
;
95 /* we want to work under the module's security ID */
96 ret
= cachefiles_get_security_ID(cache
);
100 cachefiles_begin_secure(cache
, &saved_cred
);
102 /* allocate the root index object */
105 fsdef
= kmem_cache_alloc(cachefiles_object_jar
, GFP_KERNEL
);
107 goto error_root_object
;
109 ASSERTCMP(fsdef
->backer
, ==, NULL
);
111 atomic_set(&fsdef
->usage
, 1);
112 fsdef
->type
= FSCACHE_COOKIE_TYPE_INDEX
;
114 _debug("- fsdef %p", fsdef
);
116 /* look up the directory at the root of the cache */
117 ret
= kern_path(cache
->rootdirname
, LOOKUP_DIRECTORY
, &path
);
119 goto error_open_root
;
121 cache
->mnt
= path
.mnt
;
124 /* check parameters */
126 if (!root
->d_inode
||
127 !root
->d_inode
->i_op
||
128 !root
->d_inode
->i_op
->lookup
||
129 !root
->d_inode
->i_op
->mkdir
||
130 !root
->d_inode
->i_op
->setxattr
||
131 !root
->d_inode
->i_op
->getxattr
||
132 !root
->d_sb
->s_op
->statfs
||
133 !root
->d_sb
->s_op
->sync_fs
)
134 goto error_unsupported
;
137 if (root
->d_sb
->s_flags
& MS_RDONLY
)
138 goto error_unsupported
;
140 /* determine the security of the on-disk cache as this governs
141 * security ID of files we create */
142 ret
= cachefiles_determine_cache_security(cache
, root
, &saved_cred
);
144 goto error_unsupported
;
146 /* get the cache size and blocksize */
147 ret
= vfs_statfs(&path
, &stats
);
149 goto error_unsupported
;
152 if (stats
.f_bsize
<= 0)
153 goto error_unsupported
;
156 if (stats
.f_bsize
> PAGE_SIZE
)
157 goto error_unsupported
;
159 cache
->bsize
= stats
.f_bsize
;
161 if (stats
.f_bsize
< PAGE_SIZE
)
162 cache
->bshift
= PAGE_SHIFT
- ilog2(stats
.f_bsize
);
164 _debug("blksize %u (shift %u)",
165 cache
->bsize
, cache
->bshift
);
167 _debug("size %llu, avail %llu",
168 (unsigned long long) stats
.f_blocks
,
169 (unsigned long long) stats
.f_bavail
);
171 /* set up caching limits */
172 do_div(stats
.f_files
, 100);
173 cache
->fstop
= stats
.f_files
* cache
->fstop_percent
;
174 cache
->fcull
= stats
.f_files
* cache
->fcull_percent
;
175 cache
->frun
= stats
.f_files
* cache
->frun_percent
;
177 _debug("limits {%llu,%llu,%llu} files",
178 (unsigned long long) cache
->frun
,
179 (unsigned long long) cache
->fcull
,
180 (unsigned long long) cache
->fstop
);
182 stats
.f_blocks
>>= cache
->bshift
;
183 do_div(stats
.f_blocks
, 100);
184 cache
->bstop
= stats
.f_blocks
* cache
->bstop_percent
;
185 cache
->bcull
= stats
.f_blocks
* cache
->bcull_percent
;
186 cache
->brun
= stats
.f_blocks
* cache
->brun_percent
;
188 _debug("limits {%llu,%llu,%llu} blocks",
189 (unsigned long long) cache
->brun
,
190 (unsigned long long) cache
->bcull
,
191 (unsigned long long) cache
->bstop
);
193 /* get the cache directory and check its type */
194 cachedir
= cachefiles_get_directory(cache
, root
, "cache");
195 if (IS_ERR(cachedir
)) {
196 ret
= PTR_ERR(cachedir
);
197 goto error_unsupported
;
200 fsdef
->dentry
= cachedir
;
201 fsdef
->fscache
.cookie
= NULL
;
203 ret
= cachefiles_check_object_type(fsdef
);
205 goto error_unsupported
;
207 /* get the graveyard directory */
208 graveyard
= cachefiles_get_directory(cache
, root
, "graveyard");
209 if (IS_ERR(graveyard
)) {
210 ret
= PTR_ERR(graveyard
);
211 goto error_unsupported
;
214 cache
->graveyard
= graveyard
;
216 /* publish the cache */
217 fscache_init_cache(&cache
->cache
,
218 &cachefiles_cache_ops
,
220 fsdef
->dentry
->d_sb
->s_id
);
222 fscache_object_init(&fsdef
->fscache
, NULL
, &cache
->cache
);
224 ret
= fscache_add_cache(&cache
->cache
, &fsdef
->fscache
, cache
->tag
);
226 goto error_add_cache
;
229 set_bit(CACHEFILES_READY
, &cache
->flags
);
232 printk(KERN_INFO
"CacheFiles:"
233 " File cache on %s registered\n",
234 cache
->cache
.identifier
);
236 /* check how much space the cache has */
237 cachefiles_has_space(cache
, 0, 0);
238 cachefiles_end_secure(cache
, saved_cred
);
242 dput(cache
->graveyard
);
243 cache
->graveyard
= NULL
;
248 fsdef
->dentry
= NULL
;
251 kmem_cache_free(cachefiles_object_jar
, fsdef
);
253 cachefiles_end_secure(cache
, saved_cred
);
254 kerror("Failed to register: %d", ret
);
259 * unbind a cache on fd release
261 void cachefiles_daemon_unbind(struct cachefiles_cache
*cache
)
265 if (test_bit(CACHEFILES_READY
, &cache
->flags
)) {
266 printk(KERN_INFO
"CacheFiles:"
267 " File cache on %s unregistering\n",
268 cache
->cache
.identifier
);
270 fscache_withdraw_cache(&cache
->cache
);
273 dput(cache
->graveyard
);
276 kfree(cache
->rootdirname
);
277 kfree(cache
->secctx
);