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(dentry->d_inode); 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 kerror("Can't set xattr on %*.*s [%lu] (err %d)", 55 dentry->d_name.len, dentry->d_name.len, 56 dentry->d_name.name, dentry->d_inode->i_ino, 57 -ret); 58 goto error; 59 } 60 61 /* read the current type label */ 62 ret = vfs_getxattr(dentry, cachefiles_xattr_cache, xtype, 3); 63 if (ret < 0) { 64 if (ret == -ERANGE) 65 goto bad_type_length; 66 67 kerror("Can't read xattr on %*.*s [%lu] (err %d)", 68 dentry->d_name.len, dentry->d_name.len, 69 dentry->d_name.name, dentry->d_inode->i_ino, 70 -ret); 71 goto error; 72 } 73 74 /* check the type is what we're expecting */ 75 if (ret != 2) 76 goto bad_type_length; 77 78 if (xtype[0] != type[0] || xtype[1] != type[1]) 79 goto bad_type; 80 81 ret = 0; 82 83 error: 84 _leave(" = %d", ret); 85 return ret; 86 87 bad_type_length: 88 kerror("Cache object %lu type xattr length incorrect", 89 dentry->d_inode->i_ino); 90 ret = -EIO; 91 goto error; 92 93 bad_type: 94 xtype[2] = 0; 95 kerror("Cache object %*.*s [%lu] type %s not %s", 96 dentry->d_name.len, dentry->d_name.len, 97 dentry->d_name.name, dentry->d_inode->i_ino, 98 xtype, type); 99 ret = -EIO; 100 goto error; 101 } 102 103 /* 104 * set the state xattr on a cache file 105 */ 106 int cachefiles_set_object_xattr(struct cachefiles_object *object, 107 struct cachefiles_xattr *auxdata) 108 { 109 struct dentry *dentry = object->dentry; 110 int ret; 111 112 ASSERT(dentry); 113 114 _enter("%p,#%d", object, auxdata->len); 115 116 /* attempt to install the cache metadata directly */ 117 _debug("SET #%u", auxdata->len); 118 119 ret = vfs_setxattr(dentry, cachefiles_xattr_cache, 120 &auxdata->type, auxdata->len, 121 XATTR_CREATE); 122 if (ret < 0 && ret != -ENOMEM) 123 cachefiles_io_error_obj( 124 object, 125 "Failed to set xattr with error %d", ret); 126 127 _leave(" = %d", ret); 128 return ret; 129 } 130 131 /* 132 * update the state xattr on a cache file 133 */ 134 int cachefiles_update_object_xattr(struct cachefiles_object *object, 135 struct cachefiles_xattr *auxdata) 136 { 137 struct dentry *dentry = object->dentry; 138 int ret; 139 140 ASSERT(dentry); 141 142 _enter("%p,#%d", object, auxdata->len); 143 144 /* attempt to install the cache metadata directly */ 145 _debug("SET #%u", auxdata->len); 146 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 struct dentry *dentry = object->dentry; 166 unsigned int dlen; 167 int ret; 168 169 ASSERT(dentry); 170 ASSERT(dentry->d_inode); 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 auxbuf->len = vfs_getxattr(dentry, cachefiles_xattr_cache, 178 &auxbuf->type, 512 + 1); 179 if (auxbuf->len < 1) 180 return -ESTALE; 181 182 if (auxbuf->type != object->fscache.cookie->def->type) 183 return -ESTALE; 184 185 dlen = auxbuf->len - 1; 186 ret = fscache_check_aux(&object->fscache, &auxbuf->data, dlen); 187 188 kfree(auxbuf); 189 if (ret != FSCACHE_CHECKAUX_OKAY) 190 return -ESTALE; 191 192 return 0; 193 } 194 195 /* 196 * check the state xattr on a cache file 197 * - return -ESTALE if the object should be deleted 198 */ 199 int cachefiles_check_object_xattr(struct cachefiles_object *object, 200 struct cachefiles_xattr *auxdata) 201 { 202 struct cachefiles_xattr *auxbuf; 203 struct dentry *dentry = object->dentry; 204 int ret; 205 206 _enter("%p,#%d", object, auxdata->len); 207 208 ASSERT(dentry); 209 ASSERT(dentry->d_inode); 210 211 auxbuf = kmalloc(sizeof(struct cachefiles_xattr) + 512, cachefiles_gfp); 212 if (!auxbuf) { 213 _leave(" = -ENOMEM"); 214 return -ENOMEM; 215 } 216 217 /* read the current type label */ 218 ret = vfs_getxattr(dentry, cachefiles_xattr_cache, 219 &auxbuf->type, 512 + 1); 220 if (ret < 0) { 221 if (ret == -ENODATA) 222 goto stale; /* no attribute - power went off 223 * mid-cull? */ 224 225 if (ret == -ERANGE) 226 goto bad_type_length; 227 228 cachefiles_io_error_obj(object, 229 "Can't read xattr on %lu (err %d)", 230 dentry->d_inode->i_ino, -ret); 231 goto error; 232 } 233 234 /* check the on-disk object */ 235 if (ret < 1) 236 goto bad_type_length; 237 238 if (auxbuf->type != auxdata->type) 239 goto stale; 240 241 auxbuf->len = ret; 242 243 /* consult the netfs */ 244 if (object->fscache.cookie->def->check_aux) { 245 enum fscache_checkaux result; 246 unsigned int dlen; 247 248 dlen = auxbuf->len - 1; 249 250 _debug("checkaux %s #%u", 251 object->fscache.cookie->def->name, dlen); 252 253 result = fscache_check_aux(&object->fscache, 254 &auxbuf->data, dlen); 255 256 switch (result) { 257 /* entry okay as is */ 258 case FSCACHE_CHECKAUX_OKAY: 259 goto okay; 260 261 /* entry requires update */ 262 case FSCACHE_CHECKAUX_NEEDS_UPDATE: 263 break; 264 265 /* entry requires deletion */ 266 case FSCACHE_CHECKAUX_OBSOLETE: 267 goto stale; 268 269 default: 270 BUG(); 271 } 272 273 /* update the current label */ 274 ret = vfs_setxattr(dentry, cachefiles_xattr_cache, 275 &auxdata->type, auxdata->len, 276 XATTR_REPLACE); 277 if (ret < 0) { 278 cachefiles_io_error_obj(object, 279 "Can't update xattr on %lu" 280 " (error %d)", 281 dentry->d_inode->i_ino, -ret); 282 goto error; 283 } 284 } 285 286 okay: 287 ret = 0; 288 289 error: 290 kfree(auxbuf); 291 _leave(" = %d", ret); 292 return ret; 293 294 bad_type_length: 295 kerror("Cache object %lu xattr length incorrect", 296 dentry->d_inode->i_ino); 297 ret = -EIO; 298 goto error; 299 300 stale: 301 ret = -ESTALE; 302 goto error; 303 } 304 305 /* 306 * remove the object's xattr to mark it stale 307 */ 308 int cachefiles_remove_object_xattr(struct cachefiles_cache *cache, 309 struct dentry *dentry) 310 { 311 int ret; 312 313 ret = vfs_removexattr(dentry, cachefiles_xattr_cache); 314 if (ret < 0) { 315 if (ret == -ENOENT || ret == -ENODATA) 316 ret = 0; 317 else if (ret != -ENOMEM) 318 cachefiles_io_error(cache, 319 "Can't remove xattr from %lu" 320 " (error %d)", 321 dentry->d_inode->i_ino, -ret); 322 } 323 324 _leave(" = %d", ret); 325 return ret; 326 } 327