aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2008-08-28 06:21:16 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:07 -0400
commiteaa47d8612783807ef9703ebc9bf0d0f0455bf62 (patch)
treeaae589fac6573e2974935b357bfa687dbab2e718 /fs/btrfs
parenteab922ec8907b8c506e799785e7e2d16eabe50e4 (diff)
btrfs: optmize listxattr
The ->list handler is really not useful at all, because we always call btrfs_xattr_generic_list anyway. After this is done find_btrfs_xattr_handler becomes unused, and it becomes obvious that the temporary name buffer allocation isn't needed but we can directly copy into the supplied buffer. Tested with various getfattr -d calls on varying xattr lists. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/acl.c2
-rw-r--r--fs/btrfs/xattr.c82
-rw-r--r--fs/btrfs/xattr.h8
3 files changed, 11 insertions, 81 deletions
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c
index b95147ef1c77..2f865311460c 100644
--- a/fs/btrfs/acl.c
+++ b/fs/btrfs/acl.c
@@ -320,14 +320,12 @@ int btrfs_acl_chmod(struct inode *inode)
320 320
321struct xattr_handler btrfs_xattr_acl_default_handler = { 321struct xattr_handler btrfs_xattr_acl_default_handler = {
322 .prefix = POSIX_ACL_XATTR_DEFAULT, 322 .prefix = POSIX_ACL_XATTR_DEFAULT,
323 .list = btrfs_xattr_generic_list,
324 .get = btrfs_xattr_acl_default_get, 323 .get = btrfs_xattr_acl_default_get,
325 .set = btrfs_xattr_acl_default_set, 324 .set = btrfs_xattr_acl_default_set,
326}; 325};
327 326
328struct xattr_handler btrfs_xattr_acl_access_handler = { 327struct xattr_handler btrfs_xattr_acl_access_handler = {
329 .prefix = POSIX_ACL_XATTR_ACCESS, 328 .prefix = POSIX_ACL_XATTR_ACCESS,
330 .list = btrfs_xattr_generic_list,
331 .get = btrfs_xattr_acl_access_get, 329 .get = btrfs_xattr_acl_access_get,
332 .set = btrfs_xattr_acl_access_set, 330 .set = btrfs_xattr_acl_access_set,
333}; 331};
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index 121c9550314f..fdfece41dd16 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -51,35 +51,6 @@ struct xattr_handler *btrfs_xattr_handlers[] = {
51}; 51};
52 52
53/* 53/*
54 * @param name - the xattr name
55 * @return - the xattr_handler for the xattr, NULL if its not found
56 *
57 * use this with listxattr where we don't already know the type of xattr we
58 * have
59 */
60static struct xattr_handler *find_btrfs_xattr_handler(struct extent_buffer *l,
61 unsigned long name_ptr,
62 u16 name_len)
63{
64 struct xattr_handler *handler = NULL;
65 int i = 0;
66
67 for (handler = btrfs_xattr_handlers[i]; handler != NULL; i++,
68 handler = btrfs_xattr_handlers[i]) {
69 u16 prefix_len = strlen(handler->prefix);
70
71 if (name_len < prefix_len)
72 continue;
73
74 if (memcmp_extent_buffer(l, handler->prefix, name_ptr,
75 prefix_len) == 0)
76 break;
77 }
78
79 return handler;
80}
81
82/*
83 * @param name_index - the index for the xattr handler 54 * @param name_index - the index for the xattr handler
84 * @return the xattr_handler if we found it, NULL otherwise 55 * @return the xattr_handler if we found it, NULL otherwise
85 * 56 *
@@ -118,19 +89,6 @@ static inline char *get_name(const char *name, int name_index)
118 return ret; 89 return ret;
119} 90}
120 91
121size_t btrfs_xattr_generic_list(struct inode *inode, char *list,
122 size_t list_size, const char *name,
123 size_t name_len)
124{
125 if (list && (name_len+1) <= list_size) {
126 memcpy(list, name, name_len);
127 list[name_len] = '\0';
128 } else
129 return -ERANGE;
130
131 return name_len+1;
132}
133
134ssize_t btrfs_xattr_get(struct inode *inode, int name_index, 92ssize_t btrfs_xattr_get(struct inode *inode, int name_index,
135 const char *attr_name, void *buffer, size_t size) 93 const char *attr_name, void *buffer, size_t size)
136{ 94{
@@ -278,11 +236,10 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
278 struct btrfs_item *item; 236 struct btrfs_item *item;
279 struct extent_buffer *leaf; 237 struct extent_buffer *leaf;
280 struct btrfs_dir_item *di; 238 struct btrfs_dir_item *di;
281 struct xattr_handler *handler;
282 int ret = 0, slot, advance; 239 int ret = 0, slot, advance;
283 size_t total_size = 0, size_left = size, written; 240 size_t total_size = 0, size_left = size;
284 unsigned long name_ptr; 241 unsigned long name_ptr;
285 char *name; 242 size_t name_len;
286 u32 nritems; 243 u32 nritems;
287 244
288 /* 245 /*
@@ -344,37 +301,24 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
344 301
345 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); 302 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
346 303
347 total_size += btrfs_dir_name_len(leaf, di)+1; 304 name_len = btrfs_dir_name_len(leaf, di);
305 total_size += name_len + 1;
348 306
349 /* we are just looking for how big our buffer needs to be */ 307 /* we are just looking for how big our buffer needs to be */
350 if (!size) 308 if (!size)
351 continue; 309 continue;
352 310
353 /* find our handler for this xattr */ 311 if (!buffer || (name_len + 1) > size_left) {
354 name_ptr = (unsigned long)(di + 1);
355 handler = find_btrfs_xattr_handler(leaf, name_ptr,
356 btrfs_dir_name_len(leaf, di));
357 if (!handler) {
358 printk(KERN_ERR "btrfs: unsupported xattr found\n");
359 continue;
360 }
361
362 name = kmalloc(btrfs_dir_name_len(leaf, di), GFP_KERNEL);
363 read_extent_buffer(leaf, name, name_ptr,
364 btrfs_dir_name_len(leaf, di));
365
366 /* call the list function associated with this xattr */
367 written = handler->list(inode, buffer, size_left, name,
368 btrfs_dir_name_len(leaf, di));
369 kfree(name);
370
371 if (written < 0) {
372 ret = -ERANGE; 312 ret = -ERANGE;
373 break; 313 break;
374 } 314 }
375 315
376 size_left -= written; 316 name_ptr = (unsigned long)(di + 1);
377 buffer += written; 317 read_extent_buffer(leaf, buffer, name_ptr, name_len);
318 buffer[name_len] = '\0';
319
320 size_left -= name_len + 1;
321 buffer += name_len + 1;
378 } 322 }
379 ret = total_size; 323 ret = total_size;
380 324
@@ -412,28 +356,24 @@ BTRFS_XATTR_SETGET_FUNCS(trusted, BTRFS_XATTR_INDEX_TRUSTED);
412 356
413struct xattr_handler btrfs_xattr_security_handler = { 357struct xattr_handler btrfs_xattr_security_handler = {
414 .prefix = XATTR_SECURITY_PREFIX, 358 .prefix = XATTR_SECURITY_PREFIX,
415 .list = btrfs_xattr_generic_list,
416 .get = btrfs_xattr_security_get, 359 .get = btrfs_xattr_security_get,
417 .set = btrfs_xattr_security_set, 360 .set = btrfs_xattr_security_set,
418}; 361};
419 362
420struct xattr_handler btrfs_xattr_system_handler = { 363struct xattr_handler btrfs_xattr_system_handler = {
421 .prefix = XATTR_SYSTEM_PREFIX, 364 .prefix = XATTR_SYSTEM_PREFIX,
422 .list = btrfs_xattr_generic_list,
423 .get = btrfs_xattr_system_get, 365 .get = btrfs_xattr_system_get,
424 .set = btrfs_xattr_system_set, 366 .set = btrfs_xattr_system_set,
425}; 367};
426 368
427struct xattr_handler btrfs_xattr_user_handler = { 369struct xattr_handler btrfs_xattr_user_handler = {
428 .prefix = XATTR_USER_PREFIX, 370 .prefix = XATTR_USER_PREFIX,
429 .list = btrfs_xattr_generic_list,
430 .get = btrfs_xattr_user_get, 371 .get = btrfs_xattr_user_get,
431 .set = btrfs_xattr_user_set, 372 .set = btrfs_xattr_user_set,
432}; 373};
433 374
434struct xattr_handler btrfs_xattr_trusted_handler = { 375struct xattr_handler btrfs_xattr_trusted_handler = {
435 .prefix = XATTR_TRUSTED_PREFIX, 376 .prefix = XATTR_TRUSTED_PREFIX,
436 .list = btrfs_xattr_generic_list,
437 .get = btrfs_xattr_trusted_get, 377 .get = btrfs_xattr_trusted_get,
438 .set = btrfs_xattr_trusted_set, 378 .set = btrfs_xattr_trusted_set,
439}; 379};
diff --git a/fs/btrfs/xattr.h b/fs/btrfs/xattr.h
index b2e47e3f2442..825e55bd4960 100644
--- a/fs/btrfs/xattr.h
+++ b/fs/btrfs/xattr.h
@@ -47,12 +47,4 @@ ssize_t btrfs_xattr_get(struct inode *inode, int name_index, const char *name,
47int btrfs_xattr_set(struct inode *inode, int name_index, const char *name, 47int btrfs_xattr_set(struct inode *inode, int name_index, const char *name,
48 const void *value, size_t size, int flags); 48 const void *value, size_t size, int flags);
49 49
50/*
51 * the only reason this is public is for acl.c. There may be a point where
52 * acl.c doesn't need it, and if thats the case we need to remove it and make
53 * it static in xattr.c
54 */
55size_t btrfs_xattr_generic_list(struct inode *inode, char *list,
56 size_t list_size, const char *name,
57 size_t name_len);
58#endif /* __XATTR__ */ 50#endif /* __XATTR__ */