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