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 state xattr on a cache file 161 * - return -ESTALE if the object should be deleted 162 */ 163 int cachefiles_check_object_xattr(struct cachefiles_object *object, 164 struct cachefiles_xattr *auxdata) 165 { 166 struct cachefiles_xattr *auxbuf; 167 struct dentry *dentry = object->dentry; 168 int ret; 169 170 _enter("%p,#%d", object, auxdata->len); 171 172 ASSERT(dentry); 173 ASSERT(dentry->d_inode); 174 175 auxbuf = kmalloc(sizeof(struct cachefiles_xattr) + 512, cachefiles_gfp); 176 if (!auxbuf) { 177 _leave(" = -ENOMEM"); 178 return -ENOMEM; 179 } 180 181 /* read the current type label */ 182 ret = vfs_getxattr(dentry, cachefiles_xattr_cache, 183 &auxbuf->type, 512 + 1); 184 if (ret < 0) { 185 if (ret == -ENODATA) 186 goto stale; /* no attribute - power went off 187 * mid-cull? */ 188 189 if (ret == -ERANGE) 190 goto bad_type_length; 191 192 cachefiles_io_error_obj(object, 193 "Can't read xattr on %lu (err %d)", 194 dentry->d_inode->i_ino, -ret); 195 goto error; 196 } 197 198 /* check the on-disk object */ 199 if (ret < 1) 200 goto bad_type_length; 201 202 if (auxbuf->type != auxdata->type) 203 goto stale; 204 205 auxbuf->len = ret; 206 207 /* consult the netfs */ 208 if (object->fscache.cookie->def->check_aux) { 209 enum fscache_checkaux result; 210 unsigned int dlen; 211 212 dlen = auxbuf->len - 1; 213 214 _debug("checkaux %s #%u", 215 object->fscache.cookie->def->name, dlen); 216 217 result = fscache_check_aux(&object->fscache, 218 &auxbuf->data, dlen); 219 220 switch (result) { 221 /* entry okay as is */ 222 case FSCACHE_CHECKAUX_OKAY: 223 goto okay; 224 225 /* entry requires update */ 226 case FSCACHE_CHECKAUX_NEEDS_UPDATE: 227 break; 228 229 /* entry requires deletion */ 230 case FSCACHE_CHECKAUX_OBSOLETE: 231 goto stale; 232 233 default: 234 BUG(); 235 } 236 237 /* update the current label */ 238 ret = vfs_setxattr(dentry, cachefiles_xattr_cache, 239 &auxdata->type, auxdata->len, 240 XATTR_REPLACE); 241 if (ret < 0) { 242 cachefiles_io_error_obj(object, 243 "Can't update xattr on %lu" 244 " (error %d)", 245 dentry->d_inode->i_ino, -ret); 246 goto error; 247 } 248 } 249 250 okay: 251 ret = 0; 252 253 error: 254 kfree(auxbuf); 255 _leave(" = %d", ret); 256 return ret; 257 258 bad_type_length: 259 kerror("Cache object %lu xattr length incorrect", 260 dentry->d_inode->i_ino); 261 ret = -EIO; 262 goto error; 263 264 stale: 265 ret = -ESTALE; 266 goto error; 267 } 268 269 /* 270 * remove the object's xattr to mark it stale 271 */ 272 int cachefiles_remove_object_xattr(struct cachefiles_cache *cache, 273 struct dentry *dentry) 274 { 275 int ret; 276 277 ret = vfs_removexattr(dentry, cachefiles_xattr_cache); 278 if (ret < 0) { 279 if (ret == -ENOENT || ret == -ENODATA) 280 ret = 0; 281 else if (ret != -ENOMEM) 282 cachefiles_io_error(cache, 283 "Can't remove xattr from %lu" 284 " (error %d)", 285 dentry->d_inode->i_ino, -ret); 286 } 287 288 _leave(" = %d", ret); 289 return ret; 290 } 291