1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* CacheFiles extended attribute management 3 * 4 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.com) 6 */ 7 8 #include <linux/module.h> 9 #include <linux/sched.h> 10 #include <linux/file.h> 11 #include <linux/fs.h> 12 #include <linux/fsnotify.h> 13 #include <linux/quotaops.h> 14 #include <linux/xattr.h> 15 #include <linux/slab.h> 16 #include "internal.h" 17 18 static const char cachefiles_xattr_cache[] = 19 XATTR_USER_PREFIX "CacheFiles.cache"; 20 21 /* 22 * check the type label on an object 23 * - done using xattrs 24 */ 25 int cachefiles_check_object_type(struct cachefiles_object *object) 26 { 27 struct dentry *dentry = object->dentry; 28 char type[3], xtype[3]; 29 int ret; 30 31 ASSERT(dentry); 32 ASSERT(d_backing_inode(dentry)); 33 34 if (!object->fscache.cookie) 35 strcpy(type, "C3"); 36 else 37 snprintf(type, 3, "%02x", object->fscache.cookie->def->type); 38 39 _enter("%p{%s}", object, type); 40 41 /* attempt to install a type label directly */ 42 ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache, type, 43 2, XATTR_CREATE); 44 if (ret == 0) { 45 _debug("SET"); /* we succeeded */ 46 goto error; 47 } 48 49 if (ret != -EEXIST) { 50 pr_err("Can't set xattr on %pd [%lu] (err %d)\n", 51 dentry, d_backing_inode(dentry)->i_ino, 52 -ret); 53 goto error; 54 } 55 56 /* read the current type label */ 57 ret = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache, xtype, 58 3); 59 if (ret < 0) { 60 if (ret == -ERANGE) 61 goto bad_type_length; 62 63 pr_err("Can't read xattr on %pd [%lu] (err %d)\n", 64 dentry, d_backing_inode(dentry)->i_ino, 65 -ret); 66 goto error; 67 } 68 69 /* check the type is what we're expecting */ 70 if (ret != 2) 71 goto bad_type_length; 72 73 if (xtype[0] != type[0] || xtype[1] != type[1]) 74 goto bad_type; 75 76 ret = 0; 77 78 error: 79 _leave(" = %d", ret); 80 return ret; 81 82 bad_type_length: 83 pr_err("Cache object %lu type xattr length incorrect\n", 84 d_backing_inode(dentry)->i_ino); 85 ret = -EIO; 86 goto error; 87 88 bad_type: 89 xtype[2] = 0; 90 pr_err("Cache object %pd [%lu] type %s not %s\n", 91 dentry, d_backing_inode(dentry)->i_ino, 92 xtype, type); 93 ret = -EIO; 94 goto error; 95 } 96 97 /* 98 * set the state xattr on a cache file 99 */ 100 int cachefiles_set_object_xattr(struct cachefiles_object *object, 101 struct cachefiles_xattr *auxdata) 102 { 103 struct dentry *dentry = object->dentry; 104 int ret; 105 106 ASSERT(dentry); 107 108 _enter("%p,#%d", object, auxdata->len); 109 110 /* attempt to install the cache metadata directly */ 111 _debug("SET #%u", auxdata->len); 112 113 clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags); 114 ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache, 115 &auxdata->type, auxdata->len, XATTR_CREATE); 116 if (ret < 0 && ret != -ENOMEM) 117 cachefiles_io_error_obj( 118 object, 119 "Failed to set xattr with error %d", ret); 120 121 _leave(" = %d", ret); 122 return ret; 123 } 124 125 /* 126 * update the state xattr on a cache file 127 */ 128 int cachefiles_update_object_xattr(struct cachefiles_object *object, 129 struct cachefiles_xattr *auxdata) 130 { 131 struct dentry *dentry = object->dentry; 132 int ret; 133 134 if (!dentry) 135 return -ESTALE; 136 137 _enter("%p,#%d", object, auxdata->len); 138 139 /* attempt to install the cache metadata directly */ 140 _debug("SET #%u", auxdata->len); 141 142 clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags); 143 ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache, 144 &auxdata->type, auxdata->len, XATTR_REPLACE); 145 if (ret < 0 && ret != -ENOMEM) 146 cachefiles_io_error_obj( 147 object, 148 "Failed to update xattr with error %d", ret); 149 150 _leave(" = %d", ret); 151 return ret; 152 } 153 154 /* 155 * check the consistency between the backing cache and the FS-Cache cookie 156 */ 157 int cachefiles_check_auxdata(struct cachefiles_object *object) 158 { 159 struct cachefiles_xattr *auxbuf; 160 enum fscache_checkaux validity; 161 struct dentry *dentry = object->dentry; 162 ssize_t xlen; 163 int ret; 164 165 ASSERT(dentry); 166 ASSERT(d_backing_inode(dentry)); 167 ASSERT(object->fscache.cookie->def->check_aux); 168 169 auxbuf = kmalloc(sizeof(struct cachefiles_xattr) + 512, GFP_KERNEL); 170 if (!auxbuf) 171 return -ENOMEM; 172 173 xlen = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache, 174 &auxbuf->type, 512 + 1); 175 ret = -ESTALE; 176 if (xlen < 1 || 177 auxbuf->type != object->fscache.cookie->def->type) 178 goto error; 179 180 xlen--; 181 validity = fscache_check_aux(&object->fscache, &auxbuf->data, xlen, 182 i_size_read(d_backing_inode(dentry))); 183 if (validity != FSCACHE_CHECKAUX_OKAY) 184 goto error; 185 186 ret = 0; 187 error: 188 kfree(auxbuf); 189 return ret; 190 } 191 192 /* 193 * check the state xattr on a cache file 194 * - return -ESTALE if the object should be deleted 195 */ 196 int cachefiles_check_object_xattr(struct cachefiles_object *object, 197 struct cachefiles_xattr *auxdata) 198 { 199 struct cachefiles_xattr *auxbuf; 200 struct dentry *dentry = object->dentry; 201 int ret; 202 203 _enter("%p,#%d", object, auxdata->len); 204 205 ASSERT(dentry); 206 ASSERT(d_backing_inode(dentry)); 207 208 auxbuf = kmalloc(sizeof(struct cachefiles_xattr) + 512, cachefiles_gfp); 209 if (!auxbuf) { 210 _leave(" = -ENOMEM"); 211 return -ENOMEM; 212 } 213 214 /* read the current type label */ 215 ret = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache, 216 &auxbuf->type, 512 + 1); 217 if (ret < 0) { 218 if (ret == -ENODATA) 219 goto stale; /* no attribute - power went off 220 * mid-cull? */ 221 222 if (ret == -ERANGE) 223 goto bad_type_length; 224 225 cachefiles_io_error_obj(object, 226 "Can't read xattr on %lu (err %d)", 227 d_backing_inode(dentry)->i_ino, -ret); 228 goto error; 229 } 230 231 /* check the on-disk object */ 232 if (ret < 1) 233 goto bad_type_length; 234 235 if (auxbuf->type != auxdata->type) 236 goto stale; 237 238 auxbuf->len = ret; 239 240 /* consult the netfs */ 241 if (object->fscache.cookie->def->check_aux) { 242 enum fscache_checkaux result; 243 unsigned int dlen; 244 245 dlen = auxbuf->len - 1; 246 247 _debug("checkaux %s #%u", 248 object->fscache.cookie->def->name, dlen); 249 250 result = fscache_check_aux(&object->fscache, 251 &auxbuf->data, dlen, 252 i_size_read(d_backing_inode(dentry))); 253 254 switch (result) { 255 /* entry okay as is */ 256 case FSCACHE_CHECKAUX_OKAY: 257 goto okay; 258 259 /* entry requires update */ 260 case FSCACHE_CHECKAUX_NEEDS_UPDATE: 261 break; 262 263 /* entry requires deletion */ 264 case FSCACHE_CHECKAUX_OBSOLETE: 265 goto stale; 266 267 default: 268 BUG(); 269 } 270 271 /* update the current label */ 272 ret = vfs_setxattr(&init_user_ns, dentry, 273 cachefiles_xattr_cache, &auxdata->type, 274 auxdata->len, XATTR_REPLACE); 275 if (ret < 0) { 276 cachefiles_io_error_obj(object, 277 "Can't update xattr on %lu" 278 " (error %d)", 279 d_backing_inode(dentry)->i_ino, -ret); 280 goto error; 281 } 282 } 283 284 okay: 285 ret = 0; 286 287 error: 288 kfree(auxbuf); 289 _leave(" = %d", ret); 290 return ret; 291 292 bad_type_length: 293 pr_err("Cache object %lu xattr length incorrect\n", 294 d_backing_inode(dentry)->i_ino); 295 ret = -EIO; 296 goto error; 297 298 stale: 299 ret = -ESTALE; 300 goto error; 301 } 302 303 /* 304 * remove the object's xattr to mark it stale 305 */ 306 int cachefiles_remove_object_xattr(struct cachefiles_cache *cache, 307 struct dentry *dentry) 308 { 309 int ret; 310 311 ret = vfs_removexattr(&init_user_ns, dentry, cachefiles_xattr_cache); 312 if (ret < 0) { 313 if (ret == -ENOENT || ret == -ENODATA) 314 ret = 0; 315 else if (ret != -ENOMEM) 316 cachefiles_io_error(cache, 317 "Can't remove xattr from %lu" 318 " (error %d)", 319 d_backing_inode(dentry)->i_ino, -ret); 320 } 321 322 _leave(" = %d", ret); 323 return ret; 324 } 325