1 /* cf-xattr.c: CacheFiles extended attribute management
3 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
12 #include <linux/module.h>
13 #include <linux/sched.h>
14 #include <linux/file.h>
16 #include <linux/fsnotify.h>
17 #include <linux/quotaops.h>
18 #include <linux/xattr.h>
21 static const char cachefiles_xattr_cache[] = XATTR_USER_PREFIX "CacheFiles.cache";
23 /*****************************************************************************/
25 * check the type label on an object
28 int cachefiles_check_object_type(struct cachefiles_object *object)
30 struct dentry *dentry = object->dentry;
31 char type[3], xtype[3];
35 ASSERT(dentry->d_inode);
36 ASSERT(dentry->d_inode->i_op);
37 ASSERT(dentry->d_inode->i_op->setxattr);
38 ASSERT(dentry->d_inode->i_op->getxattr);
40 if (!object->fscache.cookie)
43 snprintf(type, 3, "%02x", object->fscache.cookie->def->type);
45 _enter("%p{%s}", object, type);
47 mutex_lock(&dentry->d_inode->i_mutex);
49 /* attempt to install a type label directly */
50 ret = dentry->d_inode->i_op->setxattr(dentry, cachefiles_xattr_cache,
51 type, 2, XATTR_CREATE);
54 fsnotify_xattr(dentry);
55 mutex_unlock(&dentry->d_inode->i_mutex);
60 kerror("Can't set xattr on %*.*s [%lu] (err %d)",
61 dentry->d_name.len, dentry->d_name.len,
62 dentry->d_name.name, dentry->d_inode->i_ino,
67 /* read the current type label */
68 ret = dentry->d_inode->i_op->getxattr(dentry, cachefiles_xattr_cache,
74 kerror("Can't read xattr on %*.*s [%lu] (err %d)",
75 dentry->d_name.len, dentry->d_name.len,
76 dentry->d_name.name, dentry->d_inode->i_ino,
81 /* check the type is what we're expecting */
85 if (xtype[0] != type[0] || xtype[1] != type[1])
91 mutex_unlock(&dentry->d_inode->i_mutex);
96 kerror("Cache object %lu type xattr length incorrect",
97 dentry->d_inode->i_ino);
103 kerror("Cache object %*.*s [%lu] type %s not %s",
104 dentry->d_name.len, dentry->d_name.len,
105 dentry->d_name.name, dentry->d_inode->i_ino,
111 /*****************************************************************************/
113 * set the state xattr on a cache file
115 int cachefiles_set_object_xattr(struct cachefiles_object *object,
116 struct cachefiles_xattr *auxdata)
118 struct dentry *dentry = object->dentry;
121 ASSERT(object->fscache.cookie);
123 ASSERT(dentry->d_inode->i_op->setxattr);
125 _enter("%p,#%d", object, auxdata->len);
127 /* attempt to install the cache metadata directly */
128 mutex_lock(&dentry->d_inode->i_mutex);
131 object->fscache.cookie->def->name, auxdata->len);
133 ret = dentry->d_inode->i_op->setxattr(dentry, cachefiles_xattr_cache,
134 &auxdata->type, auxdata->len,
137 fsnotify_xattr(dentry);
138 else if (ret != -ENOMEM)
139 cachefiles_io_error_obj(object,
140 "Failed to set xattr with error %d",
143 mutex_unlock(&dentry->d_inode->i_mutex);
144 _leave(" = %d", ret);
148 /*****************************************************************************/
150 * check the state xattr on a cache file
151 * - return -ESTALE if the object should be deleted
153 int cachefiles_check_object_xattr(struct cachefiles_object *object,
154 struct cachefiles_xattr *auxdata)
156 struct cachefiles_xattr *auxbuf;
157 struct dentry *dentry = object->dentry;
160 _enter("%p,#%d", object, auxdata->len);
163 ASSERT(dentry->d_inode);
164 ASSERT(dentry->d_inode->i_op->setxattr);
165 ASSERT(dentry->d_inode->i_op->getxattr);
167 auxbuf = kmalloc(sizeof(struct cachefiles_xattr) + 512, GFP_KERNEL);
169 _leave(" = -ENOMEM");
173 mutex_lock(&dentry->d_inode->i_mutex);
175 /* read the current type label */
176 ret = dentry->d_inode->i_op->getxattr(dentry, cachefiles_xattr_cache,
177 &auxbuf->type, 512 + 1);
180 goto stale; /* no attribute - power went off
184 goto bad_type_length;
186 cachefiles_io_error_obj(object,
187 "can't read xattr on %lu (err %d)",
188 dentry->d_inode->i_ino, -ret);
192 /* check the on-disk object */
194 goto bad_type_length;
196 if (auxbuf->type != auxdata->type)
201 /* consult the netfs */
202 if (object->fscache.cookie->def->check_aux) {
203 fscache_checkaux_t result;
206 dlen = auxbuf->len - 1;
208 _debug("checkaux %s #%u",
209 object->fscache.cookie->def->name, dlen);
211 result = object->fscache.cookie->def->check_aux(
212 object->fscache.cookie->netfs_data,
213 &auxbuf->data, dlen);
216 /* entry okay as is */
217 case FSCACHE_CHECKAUX_OKAY:
220 /* entry requires update */
221 case FSCACHE_CHECKAUX_NEEDS_UPDATE:
224 /* entry requires deletion */
225 case FSCACHE_CHECKAUX_OBSOLETE:
232 /* update the current label */
233 ret = dentry->d_inode->i_op->setxattr(dentry,
234 cachefiles_xattr_cache,
239 cachefiles_io_error_obj(object,
240 "Can't update xattr on %lu"
242 dentry->d_inode->i_ino, -ret);
251 mutex_unlock(&dentry->d_inode->i_mutex);
253 _leave(" = %d", ret);
257 kerror("Cache object %lu xattr length incorrect",
258 dentry->d_inode->i_ino);
267 /*****************************************************************************/
269 * remove the object's xattr to mark it stale
271 int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
272 struct dentry *dentry)
276 mutex_lock(&dentry->d_inode->i_mutex);
278 ret = dentry->d_inode->i_op->removexattr(dentry,
279 cachefiles_xattr_cache);
281 mutex_unlock(&dentry->d_inode->i_mutex);
284 if (ret == -ENOENT || ret == -ENODATA)
286 else if (ret != -ENOMEM)
287 cachefiles_io_error(cache,
288 "Can't remove xattr from %lu"
290 dentry->d_inode->i_ino, -ret);
293 _leave(" = %d", ret);