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