Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
xattr.c
Go to the documentation of this file.
1 /* CacheFiles extended attribute management
2  *
3  * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells ([email protected])
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  */
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  */
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)
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  */
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)
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  */
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 
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) {
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 */
225  goto okay;
226 
227  /* entry requires update */
229  break;
230 
231  /* entry requires deletion */
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) {
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  */
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 }