984616cca254f21dc8307e8432fd3f91926d8de7
[linux-2.6.git] / fs / btrfs / xattr.c
1 /*
2  * Copyright (C) 2007 Red Hat.  All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public
6  * License v2 as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public
14  * License along with this program; if not, write to the
15  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16  * Boston, MA 021110-1307, USA.
17  */
18
19 #include <linux/init.h>
20 #include <linux/fs.h>
21 #include <linux/slab.h>
22 #include <linux/rwsem.h>
23 #include <linux/xattr.h>
24 #include "ctree.h"
25 #include "btrfs_inode.h"
26 #include "transaction.h"
27 #include "xattr.h"
28 #include "disk-io.h"
29
30 static struct xattr_handler *btrfs_xattr_handler_map[] = {
31         [BTRFS_XATTR_INDEX_USER]                = &btrfs_xattr_user_handler,
32         [BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS]    = &btrfs_xattr_acl_access_handler,
33         [BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT]   = &btrfs_xattr_acl_default_handler,
34         [BTRFS_XATTR_INDEX_TRUSTED]             = &btrfs_xattr_trusted_handler,
35         [BTRFS_XATTR_INDEX_SECURITY]            = &btrfs_xattr_security_handler,
36         [BTRFS_XATTR_INDEX_SYSTEM]              = &btrfs_xattr_system_handler,
37 };
38
39 struct xattr_handler *btrfs_xattr_handlers[] = {
40         &btrfs_xattr_user_handler,
41         &btrfs_xattr_acl_access_handler,
42         &btrfs_xattr_acl_default_handler,
43         &btrfs_xattr_trusted_handler,
44         &btrfs_xattr_security_handler,
45         &btrfs_xattr_system_handler,
46         NULL,
47 };
48
49 /*
50  * @param name - the xattr name
51  * @return - the xattr_handler for the xattr, NULL if its not found
52  *
53  * use this with listxattr where we don't already know the type of xattr we
54  * have
55  */
56 static struct xattr_handler *find_btrfs_xattr_handler(struct extent_buffer *l,
57                                                       unsigned long name_ptr,
58                                                       u16 name_len)
59 {
60         struct xattr_handler *handler = NULL;
61         int i = 0;
62
63         for (handler = btrfs_xattr_handlers[i]; handler != NULL; i++,
64              handler = btrfs_xattr_handlers[i]) {
65                 u16 prefix_len = strlen(handler->prefix);
66
67                 if (name_len < prefix_len)
68                         continue;
69
70                 if (memcmp_extent_buffer(l, handler->prefix, name_ptr,
71                                          prefix_len) == 0)
72                         break;
73         }
74
75         return handler;
76 }
77
78 /*
79  * @param name_index - the index for the xattr handler
80  * @return the xattr_handler if we found it, NULL otherwise
81  *
82  * use this if we know the type of the xattr already
83  */
84 static struct xattr_handler *btrfs_xattr_handler(int name_index)
85 {
86         struct xattr_handler *handler = NULL;
87
88         if (name_index >= 0 &&
89             name_index < ARRAY_SIZE(btrfs_xattr_handler_map))
90                 handler = btrfs_xattr_handler_map[name_index];
91
92         return handler;
93 }
94
95 static inline char *get_name(const char *name, int name_index)
96 {
97         char *ret = NULL;
98         struct xattr_handler *handler = btrfs_xattr_handler(name_index);
99         int prefix_len;
100
101         if (!handler)
102                 return ret;
103
104         prefix_len = strlen(handler->prefix);
105
106         ret = kmalloc(strlen(name) + prefix_len + 1, GFP_KERNEL);
107         if (!ret)
108                 return ret;
109
110         memcpy(ret, handler->prefix, prefix_len);
111         memcpy(ret+prefix_len, name, strlen(name));
112         ret[prefix_len + strlen(name)] = '\0';
113
114         return ret;
115 }
116
117 size_t btrfs_xattr_generic_list(struct inode *inode, char *list,
118                                 size_t list_size, const char *name,
119                                 size_t name_len)
120 {
121         if (list && (name_len+1) <= list_size) {
122                 memcpy(list, name, name_len);
123                 list[name_len] = '\0';
124         } else
125                 return -ERANGE;
126
127         return name_len+1;
128 }
129
130 ssize_t btrfs_xattr_get(struct inode *inode, int name_index,
131                         const char *attr_name, void *buffer, size_t size)
132 {
133         struct btrfs_dir_item *di;
134         struct btrfs_root *root = BTRFS_I(inode)->root;
135         struct btrfs_path *path;
136         struct extent_buffer *leaf;
137         struct xattr_handler *handler = btrfs_xattr_handler(name_index);
138         int ret = 0;
139         unsigned long data_ptr;
140         char *name;
141
142         if (!handler)
143                 return -EOPNOTSUPP;
144
145         /* just in case... */
146         if (*attr_name == '\0')
147                 return -EINVAL;
148
149         name = get_name(attr_name, name_index);
150         if (!name)
151                 return -ENOMEM;
152
153         path = btrfs_alloc_path();
154         if (!path) {
155                 kfree(name);
156                 return -ENOMEM;
157         }
158
159         mutex_lock(&root->fs_info->fs_mutex);
160         /* lookup the xattr by name */
161         di = btrfs_lookup_xattr(NULL, root, path, inode->i_ino, name,
162                                 strlen(name), 0);
163         if (!di || IS_ERR(di)) {
164                 ret = -ENODATA;
165                 goto out;
166         }
167
168         leaf = path->nodes[0];
169         /* if size is 0, that means we want the size of the attr */
170         if (!size) {
171                 ret = btrfs_dir_data_len(leaf, di);
172                 goto out;
173         }
174
175         /* now get the data out of our dir_item */
176         if (btrfs_dir_data_len(leaf, di) > size) {
177                 ret = -ERANGE;
178                 goto out;
179         }
180         data_ptr = (unsigned long)((char *)(di + 1) +
181                                    btrfs_dir_name_len(leaf, di));
182         read_extent_buffer(leaf, buffer, data_ptr,
183                            btrfs_dir_name_len(leaf, di));
184         ret = btrfs_dir_data_len(leaf, di);
185
186 out:
187         mutex_unlock(&root->fs_info->fs_mutex);
188         kfree(name);
189         btrfs_free_path(path);
190         return ret;
191 }
192
193 int btrfs_xattr_set(struct inode *inode, int name_index,
194                     const char *attr_name, const void *value, size_t size,
195                     int flags)
196 {
197         struct btrfs_dir_item *di;
198         struct btrfs_root *root = BTRFS_I(inode)->root;
199         struct btrfs_trans_handle *trans;
200         struct btrfs_path *path;
201         struct xattr_handler *handler = btrfs_xattr_handler(name_index);
202         char *name;
203         int ret = 0, mod = 0;
204
205         if (!handler)
206                 return -EOPNOTSUPP;
207
208         /* just in case... */
209         if (*attr_name == '\0')
210                 return -EINVAL;
211
212         name = get_name(attr_name, name_index);
213         if (!name)
214                 return -ENOMEM;
215
216         path = btrfs_alloc_path();
217         if (!path) {
218                 kfree(name);
219                 return -ENOMEM;
220         }
221
222         mutex_lock(&root->fs_info->fs_mutex);
223         trans = btrfs_start_transaction(root, 1);
224         btrfs_set_trans_block_group(trans, inode);
225
226         /* first lets see if we already have this xattr */
227         di = btrfs_lookup_xattr(trans, root, path, inode->i_ino, name,
228                                 strlen(name), -1);
229         if (IS_ERR(di)) {
230                 ret = PTR_ERR(di);
231                 goto out;
232         }
233
234         /* ok we already have this xattr, lets remove it */
235         if (di) {
236                 /* if we want create only exit */
237                 if (flags & XATTR_CREATE) {
238                         ret = -EEXIST;
239                         goto out;
240                 }
241
242                 ret = btrfs_delete_one_dir_name(trans, root, path, di);
243                 if (ret)
244                         goto out;
245                 btrfs_release_path(root, path);
246
247                 /* if we don't have a value then we are removing the xattr */
248                 if (!value) {
249                         mod = 1;
250                         goto out;
251                 }
252         } else if (flags & XATTR_REPLACE) {
253                 /* we couldn't find the attr to replace, so error out */
254                 ret = -ENODATA;
255                 goto out;
256         }
257
258         /* ok we have to create a completely new xattr */
259         ret = btrfs_insert_xattr_item(trans, root, name, strlen(name),
260                                       value, size, inode->i_ino);
261         if (ret)
262                 goto out;
263         mod = 1;
264
265 out:
266         if (mod) {
267                 inode->i_ctime = CURRENT_TIME;
268                 ret = btrfs_update_inode(trans, root, inode);
269         }
270
271         btrfs_end_transaction(trans, root);
272         mutex_unlock(&root->fs_info->fs_mutex);
273         kfree(name);
274         btrfs_free_path(path);
275
276         return ret;
277 }
278
279 ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
280 {
281         struct btrfs_key key, found_key;
282         struct inode *inode = dentry->d_inode;
283         struct btrfs_root *root = BTRFS_I(inode)->root;
284         struct btrfs_path *path;
285         struct btrfs_item *item;
286         struct extent_buffer *leaf;
287         struct btrfs_dir_item *di;
288         struct xattr_handler *handler;
289         int ret = 0, slot, advance;
290         size_t total_size = 0, size_left = size, written;
291         unsigned long name_ptr;
292         char *name;
293         u32 nritems;
294
295         /*
296          * ok we want all objects associated with this id.
297          * NOTE: we set key.offset = 0; because we want to start with the
298          * first xattr that we find and walk forward
299          */
300         key.objectid = inode->i_ino;
301         btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY);
302         key.offset = 0;
303
304         path = btrfs_alloc_path();
305         if (!path)
306                 return -ENOMEM;
307         path->reada = 2;
308
309         mutex_lock(&root->fs_info->fs_mutex);
310
311         /* search for our xattrs */
312         ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
313         if (ret < 0)
314                 goto err;
315         ret = 0;
316         advance = 0;
317         while (1) {
318                 leaf = path->nodes[0];
319                 nritems = btrfs_header_nritems(leaf);
320                 slot = path->slots[0];
321
322                 /* this is where we start walking through the path */
323                 if (advance || slot >= nritems) {
324                         /*
325                          * if we've reached the last slot in this leaf we need
326                          * to go to the next leaf and reset everything
327                          */
328                         if (slot >= nritems-1) {
329                                 ret = btrfs_next_leaf(root, path);
330                                 if (ret)
331                                         break;
332                                 leaf = path->nodes[0];
333                                 nritems = btrfs_header_nritems(leaf);
334                                 slot = path->slots[0];
335                         } else {
336                                 /*
337                                  * just walking through the slots on this leaf
338                                  */
339                                 slot++;
340                                 path->slots[0]++;
341                         }
342                 }
343                 advance = 1;
344
345                 item = btrfs_item_nr(leaf, slot);
346                 btrfs_item_key_to_cpu(leaf, &found_key, slot);
347
348                 /* check to make sure this item is what we want */
349                 if (found_key.objectid != key.objectid)
350                         break;
351                 if (btrfs_key_type(&found_key) != BTRFS_XATTR_ITEM_KEY)
352                         break;
353
354                 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
355
356                 total_size += btrfs_dir_name_len(leaf, di)+1;
357
358                 /* we are just looking for how big our buffer needs to be */
359                 if (!size)
360                         continue;
361
362                 /* find our handler for this xattr */
363                 name_ptr = (unsigned long)(di + 1);
364                 handler = find_btrfs_xattr_handler(leaf, name_ptr,
365                                                    btrfs_dir_name_len(leaf, di));
366                 if (!handler) {
367                         printk(KERN_ERR "btrfs: unsupported xattr found\n");
368                         continue;
369                 }
370
371                 name = kmalloc(btrfs_dir_name_len(leaf, di), GFP_KERNEL);
372                 read_extent_buffer(leaf, name, name_ptr,
373                                    btrfs_dir_name_len(leaf, di));
374
375                 /* call the list function associated with this xattr */
376                 written = handler->list(inode, buffer, size_left, name,
377                                         btrfs_dir_name_len(leaf, di));
378                 kfree(name);
379
380                 if (written < 0) {
381                         ret = -ERANGE;
382                         break;
383                 }
384
385                 size_left -= written;
386                 buffer += written;
387         }
388         ret = total_size;
389
390 err:
391         mutex_unlock(&root->fs_info->fs_mutex);
392         btrfs_free_path(path);
393
394         return ret;
395 }
396
397 /*
398  * delete all the xattrs associated with the inode.  fs_mutex should be
399  * held when we come into here
400  */
401 int btrfs_delete_xattrs(struct btrfs_trans_handle *trans,
402                         struct btrfs_root *root, struct inode *inode)
403 {
404         struct btrfs_path *path;
405         struct btrfs_key key, found_key;
406         struct btrfs_item *item;
407         struct extent_buffer *leaf;
408         int ret;
409
410         path = btrfs_alloc_path();
411         if (!path)
412                 return -ENOMEM;
413         path->reada = -1;
414         key.objectid = inode->i_ino;
415         btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY);
416         key.offset = (u64)-1;
417
418         while(1) {
419                 /* look for our next xattr */
420                 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
421                 if (ret < 0)
422                         goto out;
423                 BUG_ON(ret == 0);
424
425                 if (path->slots[0] == 0)
426                         break;
427
428                 path->slots[0]--;
429                 leaf = path->nodes[0];
430                 item = btrfs_item_nr(leaf, path->slots[0]);
431                 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
432
433                 if (found_key.objectid != key.objectid)
434                         break;
435                 if (btrfs_key_type(&found_key) != BTRFS_XATTR_ITEM_KEY)
436                         break;
437
438                 ret = btrfs_del_item(trans, root, path);
439                 BUG_ON(ret);
440                 btrfs_release_path(root, path);
441         }
442         ret = 0;
443 out:
444         btrfs_free_path(path);
445
446         return ret;
447 }
448
449 /*
450  * Handler functions
451  */
452 #define BTRFS_XATTR_SETGET_FUNCS(name, index)                           \
453 static int btrfs_xattr_##name##_get(struct inode *inode,                \
454                                     const char *name, void *value,      \
455                                     size_t size)                        \
456 {                                                                       \
457         return btrfs_xattr_get(inode, index, name, value, size);        \
458 }                                                                       \
459 static int btrfs_xattr_##name##_set(struct inode *inode,                \
460                                     const char *name, const void *value,\
461                                     size_t size, int flags)             \
462 {                                                                       \
463         return btrfs_xattr_set(inode, index, name, value, size, flags); \
464 }                                                                       \
465
466 BTRFS_XATTR_SETGET_FUNCS(security, BTRFS_XATTR_INDEX_SECURITY);
467 BTRFS_XATTR_SETGET_FUNCS(system, BTRFS_XATTR_INDEX_SYSTEM);
468 BTRFS_XATTR_SETGET_FUNCS(user, BTRFS_XATTR_INDEX_USER);
469 BTRFS_XATTR_SETGET_FUNCS(trusted, BTRFS_XATTR_INDEX_TRUSTED);
470
471 struct xattr_handler btrfs_xattr_security_handler = {
472         .prefix = XATTR_SECURITY_PREFIX,
473         .list   = btrfs_xattr_generic_list,
474         .get    = btrfs_xattr_security_get,
475         .set    = btrfs_xattr_security_set,
476 };
477
478 struct xattr_handler btrfs_xattr_system_handler = {
479         .prefix = XATTR_SYSTEM_PREFIX,
480         .list   = btrfs_xattr_generic_list,
481         .get    = btrfs_xattr_system_get,
482         .set    = btrfs_xattr_system_set,
483 };
484
485 struct xattr_handler btrfs_xattr_user_handler = {
486         .prefix = XATTR_USER_PREFIX,
487         .list   = btrfs_xattr_generic_list,
488         .get    = btrfs_xattr_user_get,
489         .set    = btrfs_xattr_user_set,
490 };
491
492 struct xattr_handler btrfs_xattr_trusted_handler = {
493         .prefix = XATTR_USER_PREFIX,
494         .list   = btrfs_xattr_generic_list,
495         .get    = btrfs_xattr_trusted_get,
496         .set    = btrfs_xattr_trusted_set,
497 };