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 enum fscache_checkaux validity; 166 struct dentry *dentry = object->dentry; 167 ssize_t xlen; 168 int ret; 169 170 ASSERT(dentry); 171 ASSERT(dentry->d_inode); 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 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(dentry->d_inode); 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 dentry->d_inode->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 257 switch (result) { 258 /* entry okay as is */ 259 case FSCACHE_CHECKAUX_OKAY: 260 goto okay; 261 262 /* entry requires update */ 263 case FSCACHE_CHECKAUX_NEEDS_UPDATE: 264 break; 265 266 /* entry requires deletion */ 267 case FSCACHE_CHECKAUX_OBSOLETE: 268 goto stale; 269 270 default: 271 BUG(); 272 } 273 274 /* update the current label */ 275 ret = vfs_setxattr(dentry, cachefiles_xattr_cache, 276 &auxdata->type, auxdata->len, 277 XATTR_REPLACE); 278 if (ret < 0) { 279 cachefiles_io_error_obj(object, 280 "Can't update xattr on %lu" 281 " (error %d)", 282 dentry->d_inode->i_ino, -ret); 283 goto error; 284 } 285 } 286 287 okay: 288 ret = 0; 289 290 error: 291 kfree(auxbuf); 292 _leave(" = %d", ret); 293 return ret; 294 295 bad_type_length: 296 kerror("Cache object %lu xattr length incorrect", 297 dentry->d_inode->i_ino); 298 ret = -EIO; 299 goto error; 300 301 stale: 302 ret = -ESTALE; 303 goto error; 304 } 305 306 /* 307 * remove the object's xattr to mark it stale 308 */ 309 int cachefiles_remove_object_xattr(struct cachefiles_cache *cache, 310 struct dentry *dentry) 311 { 312 int ret; 313 314 ret = vfs_removexattr(dentry, cachefiles_xattr_cache); 315 if (ret < 0) { 316 if (ret == -ENOENT || ret == -ENODATA) 317 ret = 0; 318 else if (ret != -ENOMEM) 319 cachefiles_io_error(cache, 320 "Can't remove xattr from %lu" 321 " (error %d)", 322 dentry->d_inode->i_ino, -ret); 323 } 324 325 _leave(" = %d", ret); 326 return ret; 327 } 328