0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/sched.h>
0010 #include <linux/file.h>
0011 #include <linux/fs.h>
0012 #include <linux/fsnotify.h>
0013 #include <linux/quotaops.h>
0014 #include <linux/xattr.h>
0015 #include <linux/slab.h>
0016 #include "internal.h"
0017
0018 #define CACHEFILES_COOKIE_TYPE_DATA 1
0019
0020 struct cachefiles_xattr {
0021 __be64 object_size;
0022 __be64 zero_point;
0023 __u8 type;
0024 __u8 content;
0025 __u8 data[];
0026 } __packed;
0027
0028 static const char cachefiles_xattr_cache[] =
0029 XATTR_USER_PREFIX "CacheFiles.cache";
0030
0031 struct cachefiles_vol_xattr {
0032 __be32 reserved;
0033 __u8 data[];
0034 } __packed;
0035
0036
0037
0038
0039 int cachefiles_set_object_xattr(struct cachefiles_object *object)
0040 {
0041 struct cachefiles_xattr *buf;
0042 struct dentry *dentry;
0043 struct file *file = object->file;
0044 unsigned int len = object->cookie->aux_len;
0045 int ret;
0046
0047 if (!file)
0048 return -ESTALE;
0049 dentry = file->f_path.dentry;
0050
0051 _enter("%x,#%d", object->debug_id, len);
0052
0053 buf = kmalloc(sizeof(struct cachefiles_xattr) + len, GFP_KERNEL);
0054 if (!buf)
0055 return -ENOMEM;
0056
0057 buf->object_size = cpu_to_be64(object->cookie->object_size);
0058 buf->zero_point = 0;
0059 buf->type = CACHEFILES_COOKIE_TYPE_DATA;
0060 buf->content = object->content_info;
0061 if (test_bit(FSCACHE_COOKIE_LOCAL_WRITE, &object->cookie->flags))
0062 buf->content = CACHEFILES_CONTENT_DIRTY;
0063 if (len > 0)
0064 memcpy(buf->data, fscache_get_aux(object->cookie), len);
0065
0066 ret = cachefiles_inject_write_error();
0067 if (ret == 0)
0068 ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache,
0069 buf, sizeof(struct cachefiles_xattr) + len, 0);
0070 if (ret < 0) {
0071 trace_cachefiles_vfs_error(object, file_inode(file), ret,
0072 cachefiles_trace_setxattr_error);
0073 trace_cachefiles_coherency(object, file_inode(file)->i_ino,
0074 buf->content,
0075 cachefiles_coherency_set_fail);
0076 if (ret != -ENOMEM)
0077 cachefiles_io_error_obj(
0078 object,
0079 "Failed to set xattr with error %d", ret);
0080 } else {
0081 trace_cachefiles_coherency(object, file_inode(file)->i_ino,
0082 buf->content,
0083 cachefiles_coherency_set_ok);
0084 }
0085
0086 kfree(buf);
0087 _leave(" = %d", ret);
0088 return ret;
0089 }
0090
0091
0092
0093
0094 int cachefiles_check_auxdata(struct cachefiles_object *object, struct file *file)
0095 {
0096 struct cachefiles_xattr *buf;
0097 struct dentry *dentry = file->f_path.dentry;
0098 unsigned int len = object->cookie->aux_len, tlen;
0099 const void *p = fscache_get_aux(object->cookie);
0100 enum cachefiles_coherency_trace why;
0101 ssize_t xlen;
0102 int ret = -ESTALE;
0103
0104 tlen = sizeof(struct cachefiles_xattr) + len;
0105 buf = kmalloc(tlen, GFP_KERNEL);
0106 if (!buf)
0107 return -ENOMEM;
0108
0109 xlen = cachefiles_inject_read_error();
0110 if (xlen == 0)
0111 xlen = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache, buf, tlen);
0112 if (xlen != tlen) {
0113 if (xlen < 0)
0114 trace_cachefiles_vfs_error(object, file_inode(file), xlen,
0115 cachefiles_trace_getxattr_error);
0116 if (xlen == -EIO)
0117 cachefiles_io_error_obj(
0118 object,
0119 "Failed to read aux with error %zd", xlen);
0120 why = cachefiles_coherency_check_xattr;
0121 } else if (buf->type != CACHEFILES_COOKIE_TYPE_DATA) {
0122 why = cachefiles_coherency_check_type;
0123 } else if (memcmp(buf->data, p, len) != 0) {
0124 why = cachefiles_coherency_check_aux;
0125 } else if (be64_to_cpu(buf->object_size) != object->cookie->object_size) {
0126 why = cachefiles_coherency_check_objsize;
0127 } else if (buf->content == CACHEFILES_CONTENT_DIRTY) {
0128
0129 pr_warn("Dirty object in cache\n");
0130 why = cachefiles_coherency_check_dirty;
0131 } else {
0132 why = cachefiles_coherency_check_ok;
0133 ret = 0;
0134 }
0135
0136 trace_cachefiles_coherency(object, file_inode(file)->i_ino,
0137 buf->content, why);
0138 kfree(buf);
0139 return ret;
0140 }
0141
0142
0143
0144
0145 int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
0146 struct cachefiles_object *object,
0147 struct dentry *dentry)
0148 {
0149 int ret;
0150
0151 ret = cachefiles_inject_remove_error();
0152 if (ret == 0)
0153 ret = vfs_removexattr(&init_user_ns, dentry, cachefiles_xattr_cache);
0154 if (ret < 0) {
0155 trace_cachefiles_vfs_error(object, d_inode(dentry), ret,
0156 cachefiles_trace_remxattr_error);
0157 if (ret == -ENOENT || ret == -ENODATA)
0158 ret = 0;
0159 else if (ret != -ENOMEM)
0160 cachefiles_io_error(cache,
0161 "Can't remove xattr from %lu"
0162 " (error %d)",
0163 d_backing_inode(dentry)->i_ino, -ret);
0164 }
0165
0166 _leave(" = %d", ret);
0167 return ret;
0168 }
0169
0170
0171
0172
0173 void cachefiles_prepare_to_write(struct fscache_cookie *cookie)
0174 {
0175 const struct cred *saved_cred;
0176 struct cachefiles_object *object = cookie->cache_priv;
0177 struct cachefiles_cache *cache = object->volume->cache;
0178
0179 _enter("c=%08x", object->cookie->debug_id);
0180
0181 if (!test_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags)) {
0182 cachefiles_begin_secure(cache, &saved_cred);
0183 cachefiles_set_object_xattr(object);
0184 cachefiles_end_secure(cache, saved_cred);
0185 }
0186 }
0187
0188
0189
0190
0191 bool cachefiles_set_volume_xattr(struct cachefiles_volume *volume)
0192 {
0193 struct cachefiles_vol_xattr *buf;
0194 unsigned int len = volume->vcookie->coherency_len;
0195 const void *p = volume->vcookie->coherency;
0196 struct dentry *dentry = volume->dentry;
0197 int ret;
0198
0199 _enter("%x,#%d", volume->vcookie->debug_id, len);
0200
0201 len += sizeof(*buf);
0202 buf = kmalloc(len, GFP_KERNEL);
0203 if (!buf)
0204 return false;
0205 buf->reserved = cpu_to_be32(0);
0206 memcpy(buf->data, p, volume->vcookie->coherency_len);
0207
0208 ret = cachefiles_inject_write_error();
0209 if (ret == 0)
0210 ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache,
0211 buf, len, 0);
0212 if (ret < 0) {
0213 trace_cachefiles_vfs_error(NULL, d_inode(dentry), ret,
0214 cachefiles_trace_setxattr_error);
0215 trace_cachefiles_vol_coherency(volume, d_inode(dentry)->i_ino,
0216 cachefiles_coherency_vol_set_fail);
0217 if (ret != -ENOMEM)
0218 cachefiles_io_error(
0219 volume->cache, "Failed to set xattr with error %d", ret);
0220 } else {
0221 trace_cachefiles_vol_coherency(volume, d_inode(dentry)->i_ino,
0222 cachefiles_coherency_vol_set_ok);
0223 }
0224
0225 kfree(buf);
0226 _leave(" = %d", ret);
0227 return ret == 0;
0228 }
0229
0230
0231
0232
0233 int cachefiles_check_volume_xattr(struct cachefiles_volume *volume)
0234 {
0235 struct cachefiles_vol_xattr *buf;
0236 struct dentry *dentry = volume->dentry;
0237 unsigned int len = volume->vcookie->coherency_len;
0238 const void *p = volume->vcookie->coherency;
0239 enum cachefiles_coherency_trace why;
0240 ssize_t xlen;
0241 int ret = -ESTALE;
0242
0243 _enter("");
0244
0245 len += sizeof(*buf);
0246 buf = kmalloc(len, GFP_KERNEL);
0247 if (!buf)
0248 return -ENOMEM;
0249
0250 xlen = cachefiles_inject_read_error();
0251 if (xlen == 0)
0252 xlen = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache, buf, len);
0253 if (xlen != len) {
0254 if (xlen < 0) {
0255 trace_cachefiles_vfs_error(NULL, d_inode(dentry), xlen,
0256 cachefiles_trace_getxattr_error);
0257 if (xlen == -EIO)
0258 cachefiles_io_error(
0259 volume->cache,
0260 "Failed to read xattr with error %zd", xlen);
0261 }
0262 why = cachefiles_coherency_vol_check_xattr;
0263 } else if (buf->reserved != cpu_to_be32(0)) {
0264 why = cachefiles_coherency_vol_check_resv;
0265 } else if (memcmp(buf->data, p, len - sizeof(*buf)) != 0) {
0266 why = cachefiles_coherency_vol_check_cmp;
0267 } else {
0268 why = cachefiles_coherency_vol_check_ok;
0269 ret = 0;
0270 }
0271
0272 trace_cachefiles_vol_coherency(volume, d_inode(dentry)->i_ino, why);
0273 kfree(buf);
0274 _leave(" = %d", ret);
0275 return ret;
0276 }