0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/fs.h>
0009 #include <linux/slab.h>
0010 #include "internal.h"
0011 #include <trace/events/fscache.h>
0012
0013
0014
0015
0016
0017 void cachefiles_acquire_volume(struct fscache_volume *vcookie)
0018 {
0019 struct cachefiles_volume *volume;
0020 struct cachefiles_cache *cache = vcookie->cache->cache_priv;
0021 const struct cred *saved_cred;
0022 struct dentry *vdentry, *fan;
0023 size_t len;
0024 char *name;
0025 bool is_new = false;
0026 int ret, n_accesses, i;
0027
0028 _enter("");
0029
0030 volume = kzalloc(sizeof(struct cachefiles_volume), GFP_KERNEL);
0031 if (!volume)
0032 return;
0033 volume->vcookie = vcookie;
0034 volume->cache = cache;
0035 INIT_LIST_HEAD(&volume->cache_link);
0036
0037 cachefiles_begin_secure(cache, &saved_cred);
0038
0039 len = vcookie->key[0];
0040 name = kmalloc(len + 3, GFP_NOFS);
0041 if (!name)
0042 goto error_vol;
0043 name[0] = 'I';
0044 memcpy(name + 1, vcookie->key + 1, len);
0045 name[len + 1] = 0;
0046
0047 retry:
0048 vdentry = cachefiles_get_directory(cache, cache->store, name, &is_new);
0049 if (IS_ERR(vdentry))
0050 goto error_name;
0051 volume->dentry = vdentry;
0052
0053 if (is_new) {
0054 if (!cachefiles_set_volume_xattr(volume))
0055 goto error_dir;
0056 } else {
0057 ret = cachefiles_check_volume_xattr(volume);
0058 if (ret < 0) {
0059 if (ret != -ESTALE)
0060 goto error_dir;
0061 inode_lock_nested(d_inode(cache->store), I_MUTEX_PARENT);
0062 cachefiles_bury_object(cache, NULL, cache->store, vdentry,
0063 FSCACHE_VOLUME_IS_WEIRD);
0064 cachefiles_put_directory(volume->dentry);
0065 cond_resched();
0066 goto retry;
0067 }
0068 }
0069
0070 for (i = 0; i < 256; i++) {
0071 sprintf(name, "@%02x", i);
0072 fan = cachefiles_get_directory(cache, vdentry, name, NULL);
0073 if (IS_ERR(fan))
0074 goto error_fan;
0075 volume->fanout[i] = fan;
0076 }
0077
0078 cachefiles_end_secure(cache, saved_cred);
0079
0080 vcookie->cache_priv = volume;
0081 n_accesses = atomic_inc_return(&vcookie->n_accesses);
0082 trace_fscache_access_volume(vcookie->debug_id, 0,
0083 refcount_read(&vcookie->ref),
0084 n_accesses, fscache_access_cache_pin);
0085
0086 spin_lock(&cache->object_list_lock);
0087 list_add(&volume->cache_link, &volume->cache->volumes);
0088 spin_unlock(&cache->object_list_lock);
0089
0090 kfree(name);
0091 return;
0092
0093 error_fan:
0094 for (i = 0; i < 256; i++)
0095 cachefiles_put_directory(volume->fanout[i]);
0096 error_dir:
0097 cachefiles_put_directory(volume->dentry);
0098 error_name:
0099 kfree(name);
0100 error_vol:
0101 kfree(volume);
0102 cachefiles_end_secure(cache, saved_cred);
0103 }
0104
0105
0106
0107
0108 static void __cachefiles_free_volume(struct cachefiles_volume *volume)
0109 {
0110 int i;
0111
0112 _enter("");
0113
0114 volume->vcookie->cache_priv = NULL;
0115
0116 for (i = 0; i < 256; i++)
0117 cachefiles_put_directory(volume->fanout[i]);
0118 cachefiles_put_directory(volume->dentry);
0119 kfree(volume);
0120 }
0121
0122 void cachefiles_free_volume(struct fscache_volume *vcookie)
0123 {
0124 struct cachefiles_volume *volume = vcookie->cache_priv;
0125
0126 if (volume) {
0127 spin_lock(&volume->cache->object_list_lock);
0128 list_del_init(&volume->cache_link);
0129 spin_unlock(&volume->cache->object_list_lock);
0130 __cachefiles_free_volume(volume);
0131 }
0132 }
0133
0134 void cachefiles_withdraw_volume(struct cachefiles_volume *volume)
0135 {
0136 fscache_withdraw_volume(volume->vcookie);
0137 cachefiles_set_volume_xattr(volume);
0138 __cachefiles_free_volume(volume);
0139 }