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 ASSERT(dentry); 139 140 _enter("%p,#%d", object, auxdata->len); 141 142 /* attempt to install the cache metadata directly */ 143 _debug("SET #%u", auxdata->len); 144 145 clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags); 146 ret = vfs_setxattr(dentry, cachefiles_xattr_cache, 147 &auxdata->type, auxdata->len, 148 XATTR_REPLACE); 149 if (ret < 0 && ret != -ENOMEM) 150 cachefiles_io_error_obj( 151 object, 152 "Failed to update xattr with error %d", ret); 153 154 _leave(" = %d", ret); 155 return ret; 156 } 157 158 /* 159 * check the consistency between the backing cache and the FS-Cache cookie 160 */ 161 int cachefiles_check_auxdata(struct cachefiles_object *object) 162 { 163 struct cachefiles_xattr *auxbuf; 164 enum fscache_checkaux validity; 165 struct dentry *dentry = object->dentry; 166 ssize_t xlen; 167 int ret; 168 169 ASSERT(dentry); 170 ASSERT(d_backing_inode(dentry)); 171 ASSERT(object->fscache.cookie->def->check_aux); 172 173 auxbuf = kmalloc(sizeof(struct cachefiles_xattr) + 512, GFP_KERNEL); 174 if (!auxbuf) 175 return -ENOMEM; 176 177 xlen = vfs_getxattr(dentry, cachefiles_xattr_cache, 178 &auxbuf->type, 512 + 1); 179 ret = -ESTALE; 180 if (xlen < 1 || 181 auxbuf->type != object->fscache.cookie->def->type) 182 goto error; 183 184 xlen--; 185 validity = fscache_check_aux(&object->fscache, &auxbuf->data, xlen, 186 i_size_read(d_backing_inode(dentry))); 187 if (validity != FSCACHE_CHECKAUX_OKAY) 188 goto error; 189 190 ret = 0; 191 error: 192 kfree(auxbuf); 193 return ret; 194 } 195 196 /* 197 * check the state xattr on a cache file 198 * - return -ESTALE if the object should be deleted 199 */ 200 int cachefiles_check_object_xattr(struct cachefiles_object *object, 201 struct cachefiles_xattr *auxdata) 202 { 203 struct cachefiles_xattr *auxbuf; 204 struct dentry *dentry = object->dentry; 205 int ret; 206 207 _enter("%p,#%d", object, auxdata->len); 208 209 ASSERT(dentry); 210 ASSERT(d_backing_inode(dentry)); 211 212 auxbuf = kmalloc(sizeof(struct cachefiles_xattr) + 512, cachefiles_gfp); 213 if (!auxbuf) { 214 _leave(" = -ENOMEM"); 215 return -ENOMEM; 216 } 217 218 /* read the current type label */ 219 ret = vfs_getxattr(dentry, cachefiles_xattr_cache, 220 &auxbuf->type, 512 + 1); 221 if (ret < 0) { 222 if (ret == -ENODATA) 223 goto stale; /* no attribute - power went off 224 * mid-cull? */ 225 226 if (ret == -ERANGE) 227 goto bad_type_length; 228 229 cachefiles_io_error_obj(object, 230 "Can't read xattr on %lu (err %d)", 231 d_backing_inode(dentry)->i_ino, -ret); 232 goto error; 233 } 234 235 /* check the on-disk object */ 236 if (ret < 1) 237 goto bad_type_length; 238 239 if (auxbuf->type != auxdata->type) 240 goto stale; 241 242 auxbuf->len = ret; 243 244 /* consult the netfs */ 245 if (object->fscache.cookie->def->check_aux) { 246 enum fscache_checkaux result; 247 unsigned int dlen; 248 249 dlen = auxbuf->len - 1; 250 251 _debug("checkaux %s #%u", 252 object->fscache.cookie->def->name, dlen); 253 254 result = fscache_check_aux(&object->fscache, 255 &auxbuf->data, dlen, 256 i_size_read(d_backing_inode(dentry))); 257 258 switch (result) { 259 /* entry okay as is */ 260 case FSCACHE_CHECKAUX_OKAY: 261 goto okay; 262 263 /* entry requires update */ 264 case FSCACHE_CHECKAUX_NEEDS_UPDATE: 265 break; 266 267 /* entry requires deletion */ 268 case FSCACHE_CHECKAUX_OBSOLETE: 269 goto stale; 270 271 default: 272 BUG(); 273 } 274 275 /* update the current label */ 276 ret = vfs_setxattr(dentry, cachefiles_xattr_cache, 277 &auxdata->type, auxdata->len, 278 XATTR_REPLACE); 279 if (ret < 0) { 280 cachefiles_io_error_obj(object, 281 "Can't update xattr on %lu" 282 " (error %d)", 283 d_backing_inode(dentry)->i_ino, -ret); 284 goto error; 285 } 286 } 287 288 okay: 289 ret = 0; 290 291 error: 292 kfree(auxbuf); 293 _leave(" = %d", ret); 294 return ret; 295 296 bad_type_length: 297 pr_err("Cache object %lu xattr length incorrect\n", 298 d_backing_inode(dentry)->i_ino); 299 ret = -EIO; 300 goto error; 301 302 stale: 303 ret = -ESTALE; 304 goto error; 305 } 306 307 /* 308 * remove the object's xattr to mark it stale 309 */ 310 int cachefiles_remove_object_xattr(struct cachefiles_cache *cache, 311 struct dentry *dentry) 312 { 313 int ret; 314 315 ret = vfs_removexattr(dentry, cachefiles_xattr_cache); 316 if (ret < 0) { 317 if (ret == -ENOENT || ret == -ENODATA) 318 ret = 0; 319 else if (ret != -ENOMEM) 320 cachefiles_io_error(cache, 321 "Can't remove xattr from %lu" 322 " (error %d)", 323 d_backing_inode(dentry)->i_ino, -ret); 324 } 325 326 _leave(" = %d", ret); 327 return ret; 328 } 329