0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/slab.h>
0009 #include <linux/statfs.h>
0010 #include <linux/namei.h>
0011 #include "internal.h"
0012
0013
0014
0015
0016 int cachefiles_add_cache(struct cachefiles_cache *cache)
0017 {
0018 struct fscache_cache *cache_cookie;
0019 struct path path;
0020 struct kstatfs stats;
0021 struct dentry *graveyard, *cachedir, *root;
0022 const struct cred *saved_cred;
0023 int ret;
0024
0025 _enter("");
0026
0027 cache_cookie = fscache_acquire_cache(cache->tag);
0028 if (IS_ERR(cache_cookie))
0029 return PTR_ERR(cache_cookie);
0030
0031
0032 ret = cachefiles_get_security_ID(cache);
0033 if (ret < 0)
0034 goto error_getsec;
0035
0036 cachefiles_begin_secure(cache, &saved_cred);
0037
0038
0039 ret = kern_path(cache->rootdirname, LOOKUP_DIRECTORY, &path);
0040 if (ret < 0)
0041 goto error_open_root;
0042
0043 cache->mnt = path.mnt;
0044 root = path.dentry;
0045
0046 ret = -EINVAL;
0047 if (is_idmapped_mnt(path.mnt)) {
0048 pr_warn("File cache on idmapped mounts not supported");
0049 goto error_unsupported;
0050 }
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060 ret = -EOPNOTSUPP;
0061 if (d_is_negative(root) ||
0062 !d_backing_inode(root)->i_op->lookup ||
0063 !d_backing_inode(root)->i_op->mkdir ||
0064 !d_backing_inode(root)->i_op->tmpfile ||
0065 !(d_backing_inode(root)->i_opflags & IOP_XATTR) ||
0066 !root->d_sb->s_op->statfs ||
0067 !root->d_sb->s_op->sync_fs ||
0068 root->d_sb->s_blocksize > PAGE_SIZE)
0069 goto error_unsupported;
0070
0071 ret = -EROFS;
0072 if (sb_rdonly(root->d_sb))
0073 goto error_unsupported;
0074
0075
0076
0077 ret = cachefiles_determine_cache_security(cache, root, &saved_cred);
0078 if (ret < 0)
0079 goto error_unsupported;
0080
0081
0082 ret = vfs_statfs(&path, &stats);
0083 if (ret < 0)
0084 goto error_unsupported;
0085
0086 ret = -ERANGE;
0087 if (stats.f_bsize <= 0)
0088 goto error_unsupported;
0089
0090 ret = -EOPNOTSUPP;
0091 if (stats.f_bsize > PAGE_SIZE)
0092 goto error_unsupported;
0093
0094 cache->bsize = stats.f_bsize;
0095 cache->bshift = ilog2(stats.f_bsize);
0096
0097 _debug("blksize %u (shift %u)",
0098 cache->bsize, cache->bshift);
0099
0100 _debug("size %llu, avail %llu",
0101 (unsigned long long) stats.f_blocks,
0102 (unsigned long long) stats.f_bavail);
0103
0104
0105 do_div(stats.f_files, 100);
0106 cache->fstop = stats.f_files * cache->fstop_percent;
0107 cache->fcull = stats.f_files * cache->fcull_percent;
0108 cache->frun = stats.f_files * cache->frun_percent;
0109
0110 _debug("limits {%llu,%llu,%llu} files",
0111 (unsigned long long) cache->frun,
0112 (unsigned long long) cache->fcull,
0113 (unsigned long long) cache->fstop);
0114
0115 do_div(stats.f_blocks, 100);
0116 cache->bstop = stats.f_blocks * cache->bstop_percent;
0117 cache->bcull = stats.f_blocks * cache->bcull_percent;
0118 cache->brun = stats.f_blocks * cache->brun_percent;
0119
0120 _debug("limits {%llu,%llu,%llu} blocks",
0121 (unsigned long long) cache->brun,
0122 (unsigned long long) cache->bcull,
0123 (unsigned long long) cache->bstop);
0124
0125
0126 cachedir = cachefiles_get_directory(cache, root, "cache", NULL);
0127 if (IS_ERR(cachedir)) {
0128 ret = PTR_ERR(cachedir);
0129 goto error_unsupported;
0130 }
0131
0132 cache->store = cachedir;
0133
0134
0135 graveyard = cachefiles_get_directory(cache, root, "graveyard", NULL);
0136 if (IS_ERR(graveyard)) {
0137 ret = PTR_ERR(graveyard);
0138 goto error_unsupported;
0139 }
0140
0141 cache->graveyard = graveyard;
0142 cache->cache = cache_cookie;
0143
0144 ret = fscache_add_cache(cache_cookie, &cachefiles_cache_ops, cache);
0145 if (ret < 0)
0146 goto error_add_cache;
0147
0148
0149 set_bit(CACHEFILES_READY, &cache->flags);
0150 dput(root);
0151
0152 pr_info("File cache on %s registered\n", cache_cookie->name);
0153
0154
0155 cachefiles_has_space(cache, 0, 0, cachefiles_has_space_check);
0156 cachefiles_end_secure(cache, saved_cred);
0157 _leave(" = 0 [%px]", cache->cache);
0158 return 0;
0159
0160 error_add_cache:
0161 cachefiles_put_directory(cache->graveyard);
0162 cache->graveyard = NULL;
0163 error_unsupported:
0164 cachefiles_put_directory(cache->store);
0165 cache->store = NULL;
0166 mntput(cache->mnt);
0167 cache->mnt = NULL;
0168 dput(root);
0169 error_open_root:
0170 cachefiles_end_secure(cache, saved_cred);
0171 error_getsec:
0172 fscache_relinquish_cache(cache_cookie);
0173 cache->cache = NULL;
0174 pr_err("Failed to register: %d\n", ret);
0175 return ret;
0176 }
0177
0178
0179
0180
0181
0182 int cachefiles_has_space(struct cachefiles_cache *cache,
0183 unsigned fnr, unsigned bnr,
0184 enum cachefiles_has_space_for reason)
0185 {
0186 struct kstatfs stats;
0187 u64 b_avail, b_writing;
0188 int ret;
0189
0190 struct path path = {
0191 .mnt = cache->mnt,
0192 .dentry = cache->mnt->mnt_root,
0193 };
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205 memset(&stats, 0, sizeof(stats));
0206
0207 ret = vfs_statfs(&path, &stats);
0208 if (ret < 0) {
0209 trace_cachefiles_vfs_error(NULL, d_inode(path.dentry), ret,
0210 cachefiles_trace_statfs_error);
0211 if (ret == -EIO)
0212 cachefiles_io_error(cache, "statfs failed");
0213 _leave(" = %d", ret);
0214 return ret;
0215 }
0216
0217 b_avail = stats.f_bavail;
0218 b_writing = atomic_long_read(&cache->b_writing);
0219 if (b_avail > b_writing)
0220 b_avail -= b_writing;
0221 else
0222 b_avail = 0;
0223
0224
0225
0226
0227
0228
0229 if (stats.f_ffree > fnr)
0230 stats.f_ffree -= fnr;
0231 else
0232 stats.f_ffree = 0;
0233
0234 if (b_avail > bnr)
0235 b_avail -= bnr;
0236 else
0237 b_avail = 0;
0238
0239 ret = -ENOBUFS;
0240 if (stats.f_ffree < cache->fstop ||
0241 b_avail < cache->bstop)
0242 goto stop_and_begin_cull;
0243
0244 ret = 0;
0245 if (stats.f_ffree < cache->fcull ||
0246 b_avail < cache->bcull)
0247 goto begin_cull;
0248
0249 if (test_bit(CACHEFILES_CULLING, &cache->flags) &&
0250 stats.f_ffree >= cache->frun &&
0251 b_avail >= cache->brun &&
0252 test_and_clear_bit(CACHEFILES_CULLING, &cache->flags)
0253 ) {
0254 _debug("cease culling");
0255 cachefiles_state_changed(cache);
0256 }
0257
0258
0259 return 0;
0260
0261 stop_and_begin_cull:
0262 switch (reason) {
0263 case cachefiles_has_space_for_write:
0264 fscache_count_no_write_space();
0265 break;
0266 case cachefiles_has_space_for_create:
0267 fscache_count_no_create_space();
0268 break;
0269 default:
0270 break;
0271 }
0272 begin_cull:
0273 if (!test_and_set_bit(CACHEFILES_CULLING, &cache->flags)) {
0274 _debug("### CULL CACHE ###");
0275 cachefiles_state_changed(cache);
0276 }
0277
0278 _leave(" = %d", ret);
0279 return ret;
0280 }
0281
0282
0283
0284
0285 static void cachefiles_withdraw_objects(struct cachefiles_cache *cache)
0286 {
0287 struct cachefiles_object *object;
0288 unsigned int count = 0;
0289
0290 _enter("");
0291
0292 spin_lock(&cache->object_list_lock);
0293
0294 while (!list_empty(&cache->object_list)) {
0295 object = list_first_entry(&cache->object_list,
0296 struct cachefiles_object, cache_link);
0297 cachefiles_see_object(object, cachefiles_obj_see_withdrawal);
0298 list_del_init(&object->cache_link);
0299 fscache_withdraw_cookie(object->cookie);
0300 count++;
0301 if ((count & 63) == 0) {
0302 spin_unlock(&cache->object_list_lock);
0303 cond_resched();
0304 spin_lock(&cache->object_list_lock);
0305 }
0306 }
0307
0308 spin_unlock(&cache->object_list_lock);
0309 _leave(" [%u objs]", count);
0310 }
0311
0312
0313
0314
0315 static void cachefiles_withdraw_volumes(struct cachefiles_cache *cache)
0316 {
0317 _enter("");
0318
0319 for (;;) {
0320 struct cachefiles_volume *volume = NULL;
0321
0322 spin_lock(&cache->object_list_lock);
0323 if (!list_empty(&cache->volumes)) {
0324 volume = list_first_entry(&cache->volumes,
0325 struct cachefiles_volume, cache_link);
0326 list_del_init(&volume->cache_link);
0327 }
0328 spin_unlock(&cache->object_list_lock);
0329 if (!volume)
0330 break;
0331
0332 cachefiles_withdraw_volume(volume);
0333 }
0334
0335 _leave("");
0336 }
0337
0338
0339
0340
0341 static void cachefiles_sync_cache(struct cachefiles_cache *cache)
0342 {
0343 const struct cred *saved_cred;
0344 int ret;
0345
0346 _enter("%s", cache->cache->name);
0347
0348
0349
0350 cachefiles_begin_secure(cache, &saved_cred);
0351 down_read(&cache->mnt->mnt_sb->s_umount);
0352 ret = sync_filesystem(cache->mnt->mnt_sb);
0353 up_read(&cache->mnt->mnt_sb->s_umount);
0354 cachefiles_end_secure(cache, saved_cred);
0355
0356 if (ret == -EIO)
0357 cachefiles_io_error(cache,
0358 "Attempt to sync backing fs superblock returned error %d",
0359 ret);
0360 }
0361
0362
0363
0364
0365 void cachefiles_withdraw_cache(struct cachefiles_cache *cache)
0366 {
0367 struct fscache_cache *fscache = cache->cache;
0368
0369 pr_info("File cache on %s unregistering\n", fscache->name);
0370
0371 fscache_withdraw_cache(fscache);
0372
0373
0374
0375
0376 cachefiles_withdraw_objects(cache);
0377 fscache_wait_for_objects(fscache);
0378
0379 cachefiles_withdraw_volumes(cache);
0380 cachefiles_sync_cache(cache);
0381 cache->cache = NULL;
0382 fscache_relinquish_cache(fscache);
0383 }