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 "internal.h" 20 21 static const char cachefiles_xattr_cache[] = 22 XATTR_USER_PREFIX "CacheFiles.cache"; 23 24 /* 25 * check the type label on an object 26 * - done using xattrs 27 */ 28 int cachefiles_check_object_type(struct cachefiles_object *object) 29 { 30 struct dentry *dentry = object->dentry; 31 char type[3], xtype[3]; 32 int ret; 33 34 ASSERT(dentry); 35 ASSERT(dentry->d_inode); 36 37 if (!object->fscache.cookie) 38 strcpy(type, "C3"); 39 else 40 snprintf(type, 3, "%02x", object->fscache.cookie->def->type); 41 42 _enter("%p{%s}", object, type); 43 44 /* attempt to install a type label directly */ 45 ret = vfs_setxattr(dentry, cachefiles_xattr_cache, type, 2, 46 XATTR_CREATE); 47 if (ret == 0) { 48 _debug("SET"); /* we succeeded */ 49 goto error; 50 } 51 52 if (ret != -EEXIST) { 53 kerror("Can't set xattr on %*.*s [%lu] (err %d)", 54 dentry->d_name.len, dentry->d_name.len, 55 dentry->d_name.name, dentry->d_inode->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 kerror("Can't read xattr on %*.*s [%lu] (err %d)", 67 dentry->d_name.len, dentry->d_name.len, 68 dentry->d_name.name, dentry->d_inode->i_ino, 69 -ret); 70 goto error; 71 } 72 73 /* check the type is what we're expecting */ 74 if (ret != 2) 75 goto bad_type_length; 76 77 if (xtype[0] != type[0] || xtype[1] != type[1]) 78 goto bad_type; 79 80 ret = 0; 81 82 error: 83 _leave(" = %d", ret); 84 return ret; 85 86 bad_type_length: 87 kerror("Cache object %lu type xattr length incorrect", 88 dentry->d_inode->i_ino); 89 ret = -EIO; 90 goto error; 91 92 bad_type: 93 xtype[2] = 0; 94 kerror("Cache object %*.*s [%lu] type %s not %s", 95 dentry->d_name.len, dentry->d_name.len, 96 dentry->d_name.name, dentry->d_inode->i_ino, 97 xtype, type); 98 ret = -EIO; 99 goto error; 100 } 101 102 /* 103 * set the state xattr on a cache file 104 */ 105 int cachefiles_set_object_xattr(struct cachefiles_object *object, 106 struct cachefiles_xattr *auxdata) 107 { 108 struct dentry *dentry = object->dentry; 109 int ret; 110 111 ASSERT(object->fscache.cookie); 112 ASSERT(dentry); 113 114 _enter("%p,#%d", object, auxdata->len); 115 116 /* attempt to install the cache metadata directly */ 117 _debug("SET %s #%u", object->fscache.cookie->def->name, 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(object->fscache.cookie); 141 ASSERT(dentry); 142 143 _enter("%p,#%d", object, auxdata->len); 144 145 /* attempt to install the cache metadata directly */ 146 _debug("SET %s #%u", object->fscache.cookie->def->name, auxdata->len); 147 148 ret = vfs_setxattr(dentry, cachefiles_xattr_cache, 149 &auxdata->type, auxdata->len, 150 XATTR_REPLACE); 151 if (ret < 0 && ret != -ENOMEM) 152 cachefiles_io_error_obj( 153 object, 154 "Failed to update xattr with error %d", ret); 155 156 _leave(" = %d", ret); 157 return ret; 158 } 159 160 /* 161 * check the state xattr on a cache file 162 * - return -ESTALE if the object should be deleted 163 */ 164 int cachefiles_check_object_xattr(struct cachefiles_object *object, 165 struct cachefiles_xattr *auxdata) 166 { 167 struct cachefiles_xattr *auxbuf; 168 struct dentry *dentry = object->dentry; 169 int ret; 170 171 _enter("%p,#%d", object, auxdata->len); 172 173 ASSERT(dentry); 174 ASSERT(dentry->d_inode); 175 176 auxbuf = kmalloc(sizeof(struct cachefiles_xattr) + 512, GFP_KERNEL); 177 if (!auxbuf) { 178 _leave(" = -ENOMEM"); 179 return -ENOMEM; 180 } 181 182 /* read the current type label */ 183 ret = vfs_getxattr(dentry, cachefiles_xattr_cache, 184 &auxbuf->type, 512 + 1); 185 if (ret < 0) { 186 if (ret == -ENODATA) 187 goto stale; /* no attribute - power went off 188 * mid-cull? */ 189 190 if (ret == -ERANGE) 191 goto bad_type_length; 192 193 cachefiles_io_error_obj(object, 194 "Can't read xattr on %lu (err %d)", 195 dentry->d_inode->i_ino, -ret); 196 goto error; 197 } 198 199 /* check the on-disk object */ 200 if (ret < 1) 201 goto bad_type_length; 202 203 if (auxbuf->type != auxdata->type) 204 goto stale; 205 206 auxbuf->len = ret; 207 208 /* consult the netfs */ 209 if (object->fscache.cookie->def->check_aux) { 210 enum fscache_checkaux result; 211 unsigned int dlen; 212 213 dlen = auxbuf->len - 1; 214 215 _debug("checkaux %s #%u", 216 object->fscache.cookie->def->name, dlen); 217 218 result = fscache_check_aux(&object->fscache, 219 &auxbuf->data, dlen); 220 221 switch (result) { 222 /* entry okay as is */ 223 case FSCACHE_CHECKAUX_OKAY: 224 goto okay; 225 226 /* entry requires update */ 227 case FSCACHE_CHECKAUX_NEEDS_UPDATE: 228 break; 229 230 /* entry requires deletion */ 231 case FSCACHE_CHECKAUX_OBSOLETE: 232 goto stale; 233 234 default: 235 BUG(); 236 } 237 238 /* update the current label */ 239 ret = vfs_setxattr(dentry, cachefiles_xattr_cache, 240 &auxdata->type, auxdata->len, 241 XATTR_REPLACE); 242 if (ret < 0) { 243 cachefiles_io_error_obj(object, 244 "Can't update xattr on %lu" 245 " (error %d)", 246 dentry->d_inode->i_ino, -ret); 247 goto error; 248 } 249 } 250 251 okay: 252 ret = 0; 253 254 error: 255 kfree(auxbuf); 256 _leave(" = %d", ret); 257 return ret; 258 259 bad_type_length: 260 kerror("Cache object %lu xattr length incorrect", 261 dentry->d_inode->i_ino); 262 ret = -EIO; 263 goto error; 264 265 stale: 266 ret = -ESTALE; 267 goto error; 268 } 269 270 /* 271 * remove the object's xattr to mark it stale 272 */ 273 int cachefiles_remove_object_xattr(struct cachefiles_cache *cache, 274 struct dentry *dentry) 275 { 276 int ret; 277 278 ret = vfs_removexattr(dentry, cachefiles_xattr_cache); 279 if (ret < 0) { 280 if (ret == -ENOENT || ret == -ENODATA) 281 ret = 0; 282 else if (ret != -ENOMEM) 283 cachefiles_io_error(cache, 284 "Can't remove xattr from %lu" 285 " (error %d)", 286 dentry->d_inode->i_ino, -ret); 287 } 288 289 _leave(" = %d", ret); 290 return ret; 291 } 292