1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Bind and unbind a cache from the filesystem backing it
4 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
5 * Written by David Howells (dhowells@redhat.com)
8 #include <linux/module.h>
9 #include <linux/init.h>
10 #include <linux/sched.h>
11 #include <linux/completion.h>
12 #include <linux/slab.h>
14 #include <linux/file.h>
15 #include <linux/namei.h>
16 #include <linux/mount.h>
17 #include <linux/statfs.h>
18 #include <linux/ctype.h>
19 #include <linux/xattr.h>
22 static int cachefiles_daemon_add_cache(struct cachefiles_cache
*caches
);
25 * bind a directory as a cache
27 int cachefiles_daemon_bind(struct cachefiles_cache
*cache
, char *args
)
29 _enter("{%u,%u,%u,%u,%u,%u},%s",
38 /* start by checking things over */
39 ASSERT(cache
->fstop_percent
>= 0 &&
40 cache
->fstop_percent
< cache
->fcull_percent
&&
41 cache
->fcull_percent
< cache
->frun_percent
&&
42 cache
->frun_percent
< 100);
44 ASSERT(cache
->bstop_percent
>= 0 &&
45 cache
->bstop_percent
< cache
->bcull_percent
&&
46 cache
->bcull_percent
< cache
->brun_percent
&&
47 cache
->brun_percent
< 100);
50 pr_err("'bind' command doesn't take an argument\n");
54 if (!cache
->rootdirname
) {
55 pr_err("No cache directory specified\n");
59 /* don't permit already bound caches to be re-bound */
60 if (test_bit(CACHEFILES_READY
, &cache
->flags
)) {
61 pr_err("Cache already bound\n");
65 /* make sure we have copies of the tag and dirname strings */
67 /* the tag string is released by the fops->release()
68 * function, so we don't release it on error here */
69 cache
->tag
= kstrdup("CacheFiles", GFP_KERNEL
);
75 return cachefiles_daemon_add_cache(cache
);
81 static int cachefiles_daemon_add_cache(struct cachefiles_cache
*cache
)
83 struct cachefiles_object
*fsdef
;
86 struct dentry
*graveyard
, *cachedir
, *root
;
87 const struct cred
*saved_cred
;
92 /* we want to work under the module's security ID */
93 ret
= cachefiles_get_security_ID(cache
);
97 cachefiles_begin_secure(cache
, &saved_cred
);
99 /* allocate the root index object */
102 fsdef
= kmem_cache_alloc(cachefiles_object_jar
, GFP_KERNEL
);
104 goto error_root_object
;
106 ASSERTCMP(fsdef
->backer
, ==, NULL
);
108 atomic_set(&fsdef
->usage
, 1);
109 fsdef
->type
= FSCACHE_COOKIE_TYPE_INDEX
;
111 _debug("- fsdef %p", fsdef
);
113 /* look up the directory at the root of the cache */
114 ret
= kern_path(cache
->rootdirname
, LOOKUP_DIRECTORY
, &path
);
116 goto error_open_root
;
118 cache
->mnt
= path
.mnt
;
121 /* check parameters */
123 if (d_is_negative(root
) ||
124 !d_backing_inode(root
)->i_op
->lookup
||
125 !d_backing_inode(root
)->i_op
->mkdir
||
126 !(d_backing_inode(root
)->i_opflags
& IOP_XATTR
) ||
127 !root
->d_sb
->s_op
->statfs
||
128 !root
->d_sb
->s_op
->sync_fs
)
129 goto error_unsupported
;
132 if (sb_rdonly(root
->d_sb
))
133 goto error_unsupported
;
135 /* determine the security of the on-disk cache as this governs
136 * security ID of files we create */
137 ret
= cachefiles_determine_cache_security(cache
, root
, &saved_cred
);
139 goto error_unsupported
;
141 /* get the cache size and blocksize */
142 ret
= vfs_statfs(&path
, &stats
);
144 goto error_unsupported
;
147 if (stats
.f_bsize
<= 0)
148 goto error_unsupported
;
151 if (stats
.f_bsize
> PAGE_SIZE
)
152 goto error_unsupported
;
154 cache
->bsize
= stats
.f_bsize
;
156 if (stats
.f_bsize
< PAGE_SIZE
)
157 cache
->bshift
= PAGE_SHIFT
- ilog2(stats
.f_bsize
);
159 _debug("blksize %u (shift %u)",
160 cache
->bsize
, cache
->bshift
);
162 _debug("size %llu, avail %llu",
163 (unsigned long long) stats
.f_blocks
,
164 (unsigned long long) stats
.f_bavail
);
166 /* set up caching limits */
167 do_div(stats
.f_files
, 100);
168 cache
->fstop
= stats
.f_files
* cache
->fstop_percent
;
169 cache
->fcull
= stats
.f_files
* cache
->fcull_percent
;
170 cache
->frun
= stats
.f_files
* cache
->frun_percent
;
172 _debug("limits {%llu,%llu,%llu} files",
173 (unsigned long long) cache
->frun
,
174 (unsigned long long) cache
->fcull
,
175 (unsigned long long) cache
->fstop
);
177 stats
.f_blocks
>>= cache
->bshift
;
178 do_div(stats
.f_blocks
, 100);
179 cache
->bstop
= stats
.f_blocks
* cache
->bstop_percent
;
180 cache
->bcull
= stats
.f_blocks
* cache
->bcull_percent
;
181 cache
->brun
= stats
.f_blocks
* cache
->brun_percent
;
183 _debug("limits {%llu,%llu,%llu} blocks",
184 (unsigned long long) cache
->brun
,
185 (unsigned long long) cache
->bcull
,
186 (unsigned long long) cache
->bstop
);
188 /* get the cache directory and check its type */
189 cachedir
= cachefiles_get_directory(cache
, root
, "cache");
190 if (IS_ERR(cachedir
)) {
191 ret
= PTR_ERR(cachedir
);
192 goto error_unsupported
;
195 fsdef
->dentry
= cachedir
;
196 fsdef
->fscache
.cookie
= NULL
;
198 ret
= cachefiles_check_object_type(fsdef
);
200 goto error_unsupported
;
202 /* get the graveyard directory */
203 graveyard
= cachefiles_get_directory(cache
, root
, "graveyard");
204 if (IS_ERR(graveyard
)) {
205 ret
= PTR_ERR(graveyard
);
206 goto error_unsupported
;
209 cache
->graveyard
= graveyard
;
211 /* publish the cache */
212 fscache_init_cache(&cache
->cache
,
213 &cachefiles_cache_ops
,
215 fsdef
->dentry
->d_sb
->s_id
);
217 fscache_object_init(&fsdef
->fscache
, &fscache_fsdef_index
,
220 ret
= fscache_add_cache(&cache
->cache
, &fsdef
->fscache
, cache
->tag
);
222 goto error_add_cache
;
225 set_bit(CACHEFILES_READY
, &cache
->flags
);
228 pr_info("File cache on %s registered\n", cache
->cache
.identifier
);
230 /* check how much space the cache has */
231 cachefiles_has_space(cache
, 0, 0);
232 cachefiles_end_secure(cache
, saved_cred
);
236 dput(cache
->graveyard
);
237 cache
->graveyard
= NULL
;
242 fsdef
->dentry
= NULL
;
245 kmem_cache_free(cachefiles_object_jar
, fsdef
);
247 cachefiles_end_secure(cache
, saved_cred
);
248 pr_err("Failed to register: %d\n", ret
);
253 * unbind a cache on fd release
255 void cachefiles_daemon_unbind(struct cachefiles_cache
*cache
)
259 if (test_bit(CACHEFILES_READY
, &cache
->flags
)) {
260 pr_info("File cache on %s unregistering\n",
261 cache
->cache
.identifier
);
263 fscache_withdraw_cache(&cache
->cache
);
266 dput(cache
->graveyard
);
269 kfree(cache
->rootdirname
);
270 kfree(cache
->secctx
);