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 memset(&nd
, 0, sizeof(nd
));
119 ret
= path_lookup(cache
->rootdirname
, LOOKUP_DIRECTORY
, &nd
);
121 goto error_open_root
;
123 cache
->mnt
= mntget(nd
.path
.mnt
);
124 root
= dget(nd
.path
.dentry
);
127 /* check parameters */
129 if (!root
->d_inode
||
130 !root
->d_inode
->i_op
||
131 !root
->d_inode
->i_op
->lookup
||
132 !root
->d_inode
->i_op
->mkdir
||
133 !root
->d_inode
->i_op
->setxattr
||
134 !root
->d_inode
->i_op
->getxattr
||
137 !root
->d_sb
->s_op
->statfs
||
138 !root
->d_sb
->s_op
->sync_fs
)
139 goto error_unsupported
;
142 if (root
->d_sb
->s_flags
& MS_RDONLY
)
143 goto error_unsupported
;
145 /* determine the security of the on-disk cache as this governs
146 * security ID of files we create */
147 ret
= cachefiles_determine_cache_security(cache
, root
, &saved_cred
);
149 goto error_unsupported
;
151 /* get the cache size and blocksize */
152 ret
= vfs_statfs(root
, &stats
);
154 goto error_unsupported
;
157 if (stats
.f_bsize
<= 0)
158 goto error_unsupported
;
161 if (stats
.f_bsize
> PAGE_SIZE
)
162 goto error_unsupported
;
164 cache
->bsize
= stats
.f_bsize
;
166 if (stats
.f_bsize
< PAGE_SIZE
)
167 cache
->bshift
= PAGE_SHIFT
- ilog2(stats
.f_bsize
);
169 _debug("blksize %u (shift %u)",
170 cache
->bsize
, cache
->bshift
);
172 _debug("size %llu, avail %llu",
173 (unsigned long long) stats
.f_blocks
,
174 (unsigned long long) stats
.f_bavail
);
176 /* set up caching limits */
177 do_div(stats
.f_files
, 100);
178 cache
->fstop
= stats
.f_files
* cache
->fstop_percent
;
179 cache
->fcull
= stats
.f_files
* cache
->fcull_percent
;
180 cache
->frun
= stats
.f_files
* cache
->frun_percent
;
182 _debug("limits {%llu,%llu,%llu} files",
183 (unsigned long long) cache
->frun
,
184 (unsigned long long) cache
->fcull
,
185 (unsigned long long) cache
->fstop
);
187 stats
.f_blocks
>>= cache
->bshift
;
188 do_div(stats
.f_blocks
, 100);
189 cache
->bstop
= stats
.f_blocks
* cache
->bstop_percent
;
190 cache
->bcull
= stats
.f_blocks
* cache
->bcull_percent
;
191 cache
->brun
= stats
.f_blocks
* cache
->brun_percent
;
193 _debug("limits {%llu,%llu,%llu} blocks",
194 (unsigned long long) cache
->brun
,
195 (unsigned long long) cache
->bcull
,
196 (unsigned long long) cache
->bstop
);
198 /* get the cache directory and check its type */
199 cachedir
= cachefiles_get_directory(cache
, root
, "cache");
200 if (IS_ERR(cachedir
)) {
201 ret
= PTR_ERR(cachedir
);
202 goto error_unsupported
;
205 fsdef
->dentry
= cachedir
;
206 fsdef
->fscache
.cookie
= NULL
;
208 ret
= cachefiles_check_object_type(fsdef
);
210 goto error_unsupported
;
212 /* get the graveyard directory */
213 graveyard
= cachefiles_get_directory(cache
, root
, "graveyard");
214 if (IS_ERR(graveyard
)) {
215 ret
= PTR_ERR(graveyard
);
216 goto error_unsupported
;
219 cache
->graveyard
= graveyard
;
221 /* publish the cache */
222 fscache_init_cache(&cache
->cache
,
223 &cachefiles_cache_ops
,
225 fsdef
->dentry
->d_sb
->s_id
);
227 fscache_object_init(&fsdef
->fscache
, NULL
, &cache
->cache
);
229 ret
= fscache_add_cache(&cache
->cache
, &fsdef
->fscache
, cache
->tag
);
231 goto error_add_cache
;
234 set_bit(CACHEFILES_READY
, &cache
->flags
);
237 printk(KERN_INFO
"CacheFiles:"
238 " File cache on %s registered\n",
239 cache
->cache
.identifier
);
241 /* check how much space the cache has */
242 cachefiles_has_space(cache
, 0, 0);
243 cachefiles_end_secure(cache
, saved_cred
);
247 dput(cache
->graveyard
);
248 cache
->graveyard
= NULL
;
253 fsdef
->dentry
= NULL
;
256 kmem_cache_free(cachefiles_object_jar
, fsdef
);
258 cachefiles_end_secure(cache
, saved_cred
);
259 kerror("Failed to register: %d", ret
);
264 * unbind a cache on fd release
266 void cachefiles_daemon_unbind(struct cachefiles_cache
*cache
)
270 if (test_bit(CACHEFILES_READY
, &cache
->flags
)) {
271 printk(KERN_INFO
"CacheFiles:"
272 " File cache on %s unregistering\n",
273 cache
->cache
.identifier
);
275 fscache_withdraw_cache(&cache
->cache
);
278 dput(cache
->graveyard
);
281 kfree(cache
->rootdirname
);
282 kfree(cache
->secctx
);