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
||
134 !root
->d_sb
->s_op
->statfs
||
135 !root
->d_sb
->s_op
->sync_fs
)
136 goto error_unsupported
;
139 if (root
->d_sb
->s_flags
& MS_RDONLY
)
140 goto error_unsupported
;
142 /* determine the security of the on-disk cache as this governs
143 * security ID of files we create */
144 ret
= cachefiles_determine_cache_security(cache
, root
, &saved_cred
);
146 goto error_unsupported
;
148 /* get the cache size and blocksize */
149 ret
= vfs_statfs(root
, &stats
);
151 goto error_unsupported
;
154 if (stats
.f_bsize
<= 0)
155 goto error_unsupported
;
158 if (stats
.f_bsize
> PAGE_SIZE
)
159 goto error_unsupported
;
161 cache
->bsize
= stats
.f_bsize
;
163 if (stats
.f_bsize
< PAGE_SIZE
)
164 cache
->bshift
= PAGE_SHIFT
- ilog2(stats
.f_bsize
);
166 _debug("blksize %u (shift %u)",
167 cache
->bsize
, cache
->bshift
);
169 _debug("size %llu, avail %llu",
170 (unsigned long long) stats
.f_blocks
,
171 (unsigned long long) stats
.f_bavail
);
173 /* set up caching limits */
174 do_div(stats
.f_files
, 100);
175 cache
->fstop
= stats
.f_files
* cache
->fstop_percent
;
176 cache
->fcull
= stats
.f_files
* cache
->fcull_percent
;
177 cache
->frun
= stats
.f_files
* cache
->frun_percent
;
179 _debug("limits {%llu,%llu,%llu} files",
180 (unsigned long long) cache
->frun
,
181 (unsigned long long) cache
->fcull
,
182 (unsigned long long) cache
->fstop
);
184 stats
.f_blocks
>>= cache
->bshift
;
185 do_div(stats
.f_blocks
, 100);
186 cache
->bstop
= stats
.f_blocks
* cache
->bstop_percent
;
187 cache
->bcull
= stats
.f_blocks
* cache
->bcull_percent
;
188 cache
->brun
= stats
.f_blocks
* cache
->brun_percent
;
190 _debug("limits {%llu,%llu,%llu} blocks",
191 (unsigned long long) cache
->brun
,
192 (unsigned long long) cache
->bcull
,
193 (unsigned long long) cache
->bstop
);
195 /* get the cache directory and check its type */
196 cachedir
= cachefiles_get_directory(cache
, root
, "cache");
197 if (IS_ERR(cachedir
)) {
198 ret
= PTR_ERR(cachedir
);
199 goto error_unsupported
;
202 fsdef
->dentry
= cachedir
;
203 fsdef
->fscache
.cookie
= NULL
;
205 ret
= cachefiles_check_object_type(fsdef
);
207 goto error_unsupported
;
209 /* get the graveyard directory */
210 graveyard
= cachefiles_get_directory(cache
, root
, "graveyard");
211 if (IS_ERR(graveyard
)) {
212 ret
= PTR_ERR(graveyard
);
213 goto error_unsupported
;
216 cache
->graveyard
= graveyard
;
218 /* publish the cache */
219 fscache_init_cache(&cache
->cache
,
220 &cachefiles_cache_ops
,
222 fsdef
->dentry
->d_sb
->s_id
);
224 fscache_object_init(&fsdef
->fscache
, NULL
, &cache
->cache
);
226 ret
= fscache_add_cache(&cache
->cache
, &fsdef
->fscache
, cache
->tag
);
228 goto error_add_cache
;
231 set_bit(CACHEFILES_READY
, &cache
->flags
);
234 printk(KERN_INFO
"CacheFiles:"
235 " File cache on %s registered\n",
236 cache
->cache
.identifier
);
238 /* check how much space the cache has */
239 cachefiles_has_space(cache
, 0, 0);
240 cachefiles_end_secure(cache
, saved_cred
);
244 dput(cache
->graveyard
);
245 cache
->graveyard
= NULL
;
250 fsdef
->dentry
= NULL
;
253 kmem_cache_free(cachefiles_object_jar
, fsdef
);
255 cachefiles_end_secure(cache
, saved_cred
);
256 kerror("Failed to register: %d", ret
);
261 * unbind a cache on fd release
263 void cachefiles_daemon_unbind(struct cachefiles_cache
*cache
)
267 if (test_bit(CACHEFILES_READY
, &cache
->flags
)) {
268 printk(KERN_INFO
"CacheFiles:"
269 " File cache on %s unregistering\n",
270 cache
->cache
.identifier
);
272 fscache_withdraw_cache(&cache
->cache
);
275 dput(cache
->graveyard
);
278 kfree(cache
->rootdirname
);
279 kfree(cache
->secctx
);