aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_acl.c3
-rw-r--r--fs/xfs/xfs_attr.c139
-rw-r--r--fs/xfs/xfs_attr.h55
-rw-r--r--fs/xfs/xfs_attr_leaf.c61
-rw-r--r--fs/xfs/xfs_attr_leaf.h29
5 files changed, 84 insertions, 203 deletions
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index ebee3a4f703a..93057af2fe3d 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -341,8 +341,7 @@ xfs_acl_iaccess(
341 341
342 /* If the file has no ACL return -1. */ 342 /* If the file has no ACL return -1. */
343 rval = sizeof(xfs_acl_t); 343 rval = sizeof(xfs_acl_t);
344 if (xfs_attr_fetch(ip, &acl_name, (char *)acl, &rval, 344 if (xfs_attr_fetch(ip, &acl_name, (char *)acl, &rval, ATTR_ROOT)) {
345 ATTR_ROOT | ATTR_KERNACCESS)) {
346 _ACL_FREE(acl); 345 _ACL_FREE(acl);
347 return -1; 346 return -1;
348 } 347 }
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index 49fac8d6db12..78de80e3caa2 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -16,8 +16,6 @@
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18 18
19#include <linux/capability.h>
20
21#include "xfs.h" 19#include "xfs.h"
22#include "xfs_fs.h" 20#include "xfs_fs.h"
23#include "xfs_types.h" 21#include "xfs_types.h"
@@ -607,12 +605,20 @@ xfs_attr_remove(
607 return xfs_attr_remove_int(dp, &xname, flags); 605 return xfs_attr_remove_int(dp, &xname, flags);
608} 606}
609 607
610STATIC int 608int
611xfs_attr_list_int(xfs_attr_list_context_t *context) 609xfs_attr_list_int(xfs_attr_list_context_t *context)
612{ 610{
613 int error; 611 int error;
614 xfs_inode_t *dp = context->dp; 612 xfs_inode_t *dp = context->dp;
615 613
614 XFS_STATS_INC(xs_attr_list);
615
616 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
617 return EIO;
618
619 xfs_ilock(dp, XFS_ILOCK_SHARED);
620 xfs_attr_trace_l_c("syscall start", context);
621
616 /* 622 /*
617 * Decide on what work routines to call based on the inode size. 623 * Decide on what work routines to call based on the inode size.
618 */ 624 */
@@ -625,6 +631,10 @@ xfs_attr_list_int(xfs_attr_list_context_t *context)
625 } else { 631 } else {
626 error = xfs_attr_node_list(context); 632 error = xfs_attr_node_list(context);
627 } 633 }
634
635 xfs_iunlock(dp, XFS_ILOCK_SHARED);
636 xfs_attr_trace_l_c("syscall end", context);
637
628 return error; 638 return error;
629} 639}
630 640
@@ -641,74 +651,50 @@ xfs_attr_list_int(xfs_attr_list_context_t *context)
641 */ 651 */
642/*ARGSUSED*/ 652/*ARGSUSED*/
643STATIC int 653STATIC int
644xfs_attr_put_listent(xfs_attr_list_context_t *context, attrnames_t *namesp, 654xfs_attr_put_listent(xfs_attr_list_context_t *context, int flags,
645 char *name, int namelen, 655 char *name, int namelen,
646 int valuelen, char *value) 656 int valuelen, char *value)
647{ 657{
658 struct attrlist *alist = (struct attrlist *)context->alist;
648 attrlist_ent_t *aep; 659 attrlist_ent_t *aep;
649 int arraytop; 660 int arraytop;
650 661
651 ASSERT(!(context->flags & ATTR_KERNOVAL)); 662 ASSERT(!(context->flags & ATTR_KERNOVAL));
652 ASSERT(context->count >= 0); 663 ASSERT(context->count >= 0);
653 ASSERT(context->count < (ATTR_MAX_VALUELEN/8)); 664 ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
654 ASSERT(context->firstu >= sizeof(*context->alist)); 665 ASSERT(context->firstu >= sizeof(*alist));
655 ASSERT(context->firstu <= context->bufsize); 666 ASSERT(context->firstu <= context->bufsize);
656 667
657 arraytop = sizeof(*context->alist) + 668 /*
658 context->count * sizeof(context->alist->al_offset[0]); 669 * Only list entries in the right namespace.
670 */
671 if (((context->flags & ATTR_SECURE) == 0) !=
672 ((flags & XFS_ATTR_SECURE) == 0))
673 return 0;
674 if (((context->flags & ATTR_ROOT) == 0) !=
675 ((flags & XFS_ATTR_ROOT) == 0))
676 return 0;
677
678 arraytop = sizeof(*alist) +
679 context->count * sizeof(alist->al_offset[0]);
659 context->firstu -= ATTR_ENTSIZE(namelen); 680 context->firstu -= ATTR_ENTSIZE(namelen);
660 if (context->firstu < arraytop) { 681 if (context->firstu < arraytop) {
661 xfs_attr_trace_l_c("buffer full", context); 682 xfs_attr_trace_l_c("buffer full", context);
662 context->alist->al_more = 1; 683 alist->al_more = 1;
663 context->seen_enough = 1; 684 context->seen_enough = 1;
664 return 1; 685 return 1;
665 } 686 }
666 687
667 aep = (attrlist_ent_t *)&(((char *)context->alist)[ context->firstu ]); 688 aep = (attrlist_ent_t *)&context->alist[context->firstu];
668 aep->a_valuelen = valuelen; 689 aep->a_valuelen = valuelen;
669 memcpy(aep->a_name, name, namelen); 690 memcpy(aep->a_name, name, namelen);
670 aep->a_name[ namelen ] = 0; 691 aep->a_name[namelen] = 0;
671 context->alist->al_offset[ context->count++ ] = context->firstu; 692 alist->al_offset[context->count++] = context->firstu;
672 context->alist->al_count = context->count; 693 alist->al_count = context->count;
673 xfs_attr_trace_l_c("add", context); 694 xfs_attr_trace_l_c("add", context);
674 return 0; 695 return 0;
675} 696}
676 697
677STATIC int
678xfs_attr_kern_list(xfs_attr_list_context_t *context, attrnames_t *namesp,
679 char *name, int namelen,
680 int valuelen, char *value)
681{
682 char *offset;
683 int arraytop;
684
685 ASSERT(context->count >= 0);
686
687 arraytop = context->count + namesp->attr_namelen + namelen + 1;
688 if (arraytop > context->firstu) {
689 context->count = -1; /* insufficient space */
690 return 1;
691 }
692 offset = (char *)context->alist + context->count;
693 strncpy(offset, namesp->attr_name, namesp->attr_namelen);
694 offset += namesp->attr_namelen;
695 strncpy(offset, name, namelen); /* real name */
696 offset += namelen;
697 *offset = '\0';
698 context->count += namesp->attr_namelen + namelen + 1;
699 return 0;
700}
701
702/*ARGSUSED*/
703STATIC int
704xfs_attr_kern_list_sizes(xfs_attr_list_context_t *context, attrnames_t *namesp,
705 char *name, int namelen,
706 int valuelen, char *value)
707{
708 context->count += namesp->attr_namelen + namelen + 1;
709 return 0;
710}
711
712/* 698/*
713 * Generate a list of extended attribute names and optionally 699 * Generate a list of extended attribute names and optionally
714 * also value lengths. Positive return value follows the XFS 700 * also value lengths. Positive return value follows the XFS
@@ -725,10 +711,9 @@ xfs_attr_list(
725 attrlist_cursor_kern_t *cursor) 711 attrlist_cursor_kern_t *cursor)
726{ 712{
727 xfs_attr_list_context_t context; 713 xfs_attr_list_context_t context;
714 struct attrlist *alist;
728 int error; 715 int error;
729 716
730 XFS_STATS_INC(xs_attr_list);
731
732 /* 717 /*
733 * Validate the cursor. 718 * Validate the cursor.
734 */ 719 */
@@ -749,52 +734,23 @@ xfs_attr_list(
749 /* 734 /*
750 * Initialize the output buffer. 735 * Initialize the output buffer.
751 */ 736 */
737 memset(&context, 0, sizeof(context));
752 context.dp = dp; 738 context.dp = dp;
753 context.cursor = cursor; 739 context.cursor = cursor;
754 context.count = 0;
755 context.dupcnt = 0;
756 context.resynch = 1; 740 context.resynch = 1;
757 context.flags = flags; 741 context.flags = flags;
758 context.seen_enough = 0; 742 context.alist = buffer;
759 context.alist = (attrlist_t *)buffer; 743 context.bufsize = (bufsize & ~(sizeof(int)-1)); /* align */
760 context.put_value = 0; 744 context.firstu = context.bufsize;
761 745 context.put_listent = xfs_attr_put_listent;
762 if (flags & ATTR_KERNAMELS) {
763 context.bufsize = bufsize;
764 context.firstu = context.bufsize;
765 if (flags & ATTR_KERNOVAL)
766 context.put_listent = xfs_attr_kern_list_sizes;
767 else
768 context.put_listent = xfs_attr_kern_list;
769 } else {
770 context.bufsize = (bufsize & ~(sizeof(int)-1)); /* align */
771 context.firstu = context.bufsize;
772 context.alist->al_count = 0;
773 context.alist->al_more = 0;
774 context.alist->al_offset[0] = context.bufsize;
775 context.put_listent = xfs_attr_put_listent;
776 }
777
778 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
779 return EIO;
780 746
781 xfs_ilock(dp, XFS_ILOCK_SHARED); 747 alist = (struct attrlist *)context.alist;
782 xfs_attr_trace_l_c("syscall start", &context); 748 alist->al_count = 0;
749 alist->al_more = 0;
750 alist->al_offset[0] = context.bufsize;
783 751
784 error = xfs_attr_list_int(&context); 752 error = xfs_attr_list_int(&context);
785 753 ASSERT(error >= 0);
786 xfs_iunlock(dp, XFS_ILOCK_SHARED);
787 xfs_attr_trace_l_c("syscall end", &context);
788
789 if (context.flags & (ATTR_KERNOVAL|ATTR_KERNAMELS)) {
790 /* must return negated buffer size or the error */
791 if (context.count < 0)
792 error = XFS_ERROR(ERANGE);
793 else
794 error = -context.count;
795 } else
796 ASSERT(error >= 0);
797
798 return error; 754 return error;
799} 755}
800 756
@@ -2357,12 +2313,7 @@ xfs_attr_trace_enter(int type, char *where,
2357 (void *)((__psunsigned_t)context->bufsize), 2313 (void *)((__psunsigned_t)context->bufsize),
2358 (void *)((__psunsigned_t)context->count), 2314 (void *)((__psunsigned_t)context->count),
2359 (void *)((__psunsigned_t)context->firstu), 2315 (void *)((__psunsigned_t)context->firstu),
2360 (void *)((__psunsigned_t) 2316 NULL,
2361 (((context->count > 0) &&
2362 !(context->flags & (ATTR_KERNAMELS|ATTR_KERNOVAL)))
2363 ? (ATTR_ENTRY(context->alist,
2364 context->count-1)->a_valuelen)
2365 : 0)),
2366 (void *)((__psunsigned_t)context->dupcnt), 2317 (void *)((__psunsigned_t)context->dupcnt),
2367 (void *)((__psunsigned_t)context->flags), 2318 (void *)((__psunsigned_t)context->flags),
2368 (void *)a13, (void *)a14, (void *)a15); 2319 (void *)a13, (void *)a14, (void *)a15);
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h
index c1f7d43e5ecf..41469434f413 100644
--- a/fs/xfs/xfs_attr.h
+++ b/fs/xfs/xfs_attr.h
@@ -18,9 +18,11 @@
18#ifndef __XFS_ATTR_H__ 18#ifndef __XFS_ATTR_H__
19#define __XFS_ATTR_H__ 19#define __XFS_ATTR_H__
20 20
21struct xfs_inode;
22struct xfs_da_args;
23struct xfs_attr_list_context;
24
21/* 25/*
22 * xfs_attr.h
23 *
24 * Large attribute lists are structured around Btrees where all the data 26 * Large attribute lists are structured around Btrees where all the data
25 * elements are in the leaf nodes. Attribute names are hashed into an int, 27 * elements are in the leaf nodes. Attribute names are hashed into an int,
26 * then that int is used as the index into the Btree. Since the hashval 28 * then that int is used as the index into the Btree. Since the hashval
@@ -35,17 +37,6 @@
35 * External interfaces 37 * External interfaces
36 *========================================================================*/ 38 *========================================================================*/
37 39
38struct cred;
39struct xfs_attr_list_context;
40
41typedef struct attrnames {
42 char * attr_name;
43 unsigned int attr_namelen;
44} attrnames_t;
45
46extern struct attrnames attr_user;
47extern struct attrnames attr_secure;
48extern struct attrnames attr_trusted;
49 40
50#define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */ 41#define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */
51#define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */ 42#define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */
@@ -54,14 +45,8 @@ extern struct attrnames attr_trusted;
54#define ATTR_CREATE 0x0010 /* pure create: fail if attr already exists */ 45#define ATTR_CREATE 0x0010 /* pure create: fail if attr already exists */
55#define ATTR_REPLACE 0x0020 /* pure set: fail if attr does not exist */ 46#define ATTR_REPLACE 0x0020 /* pure set: fail if attr does not exist */
56 47
57#define ATTR_KERNACCESS 0x0400 /* [kernel] iaccess, inode held io-locked */
58#define ATTR_KERNOTIME 0x1000 /* [kernel] don't update inode timestamps */ 48#define ATTR_KERNOTIME 0x1000 /* [kernel] don't update inode timestamps */
59#define ATTR_KERNOVAL 0x2000 /* [kernel] get attr size only, not value */ 49#define ATTR_KERNOVAL 0x2000 /* [kernel] get attr size only, not value */
60#define ATTR_KERNAMELS 0x4000 /* [kernel] list attr names (simple list) */
61
62#define ATTR_KERNORMALS 0x0800 /* [kernel] normal attr list: user+secure */
63#define ATTR_KERNROOTLS 0x8000 /* [kernel] include root in the attr list */
64#define ATTR_KERNFULLS (ATTR_KERNORMALS|ATTR_KERNROOTLS)
65 50
66/* 51/*
67 * The maximum size (into the kernel or returned from the kernel) of an 52 * The maximum size (into the kernel or returned from the kernel) of an
@@ -129,20 +114,40 @@ typedef struct attrlist_cursor_kern {
129 114
130 115
131/*======================================================================== 116/*========================================================================
132 * Function prototypes for the kernel. 117 * Structure used to pass context around among the routines.
133 *========================================================================*/ 118 *========================================================================*/
134 119
135struct xfs_inode; 120
136struct attrlist_cursor_kern; 121typedef int (*put_listent_func_t)(struct xfs_attr_list_context *, int,
137struct xfs_da_args; 122 char *, int, int, char *);
123
124typedef struct xfs_attr_list_context {
125 struct xfs_inode *dp; /* inode */
126 struct attrlist_cursor_kern *cursor; /* position in list */
127 char *alist; /* output buffer */
128 int seen_enough; /* T/F: seen enough of list? */
129 int count; /* num used entries */
130 int dupcnt; /* count dup hashvals seen */
131 int bufsize; /* total buffer size */
132 int firstu; /* first used byte in buffer */
133 int flags; /* from VOP call */
134 int resynch; /* T/F: resynch with cursor */
135 int put_value; /* T/F: need value for listent */
136 put_listent_func_t put_listent; /* list output fmt function */
137 int index; /* index into output buffer */
138} xfs_attr_list_context_t;
139
140
141/*========================================================================
142 * Function prototypes for the kernel.
143 *========================================================================*/
138 144
139/* 145/*
140 * Overall external interface routines. 146 * Overall external interface routines.
141 */ 147 */
142int xfs_attr_inactive(struct xfs_inode *dp); 148int xfs_attr_inactive(struct xfs_inode *dp);
143
144int xfs_attr_shortform_getvalue(struct xfs_da_args *);
145int xfs_attr_fetch(struct xfs_inode *, struct xfs_name *, char *, int *, int); 149int xfs_attr_fetch(struct xfs_inode *, struct xfs_name *, char *, int *, int);
146int xfs_attr_rmtval_get(struct xfs_da_args *args); 150int xfs_attr_rmtval_get(struct xfs_da_args *args);
151int xfs_attr_list_int(struct xfs_attr_list_context *);
147 152
148#endif /* __XFS_ATTR_H__ */ 153#endif /* __XFS_ATTR_H__ */
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index cb345e6e4850..23ef5d7c87e1 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -94,13 +94,6 @@ STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
94 * Namespace helper routines 94 * Namespace helper routines
95 *========================================================================*/ 95 *========================================================================*/
96 96
97STATIC_INLINE attrnames_t *
98xfs_attr_flags_namesp(int flags)
99{
100 return ((flags & XFS_ATTR_SECURE) ? &attr_secure:
101 ((flags & XFS_ATTR_ROOT) ? &attr_trusted : &attr_user));
102}
103
104/* 97/*
105 * If namespace bits don't match return 0. 98 * If namespace bits don't match return 0.
106 * If all match then return 1. 99 * If all match then return 1.
@@ -111,25 +104,6 @@ xfs_attr_namesp_match(int arg_flags, int ondisk_flags)
111 return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags); 104 return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags);
112} 105}
113 106
114/*
115 * If namespace bits don't match and we don't have an override for it
116 * then return 0.
117 * If all match or are overridable then return 1.
118 */
119STATIC_INLINE int
120xfs_attr_namesp_match_overrides(int arg_flags, int ondisk_flags)
121{
122 if (((arg_flags & ATTR_SECURE) == 0) !=
123 ((ondisk_flags & XFS_ATTR_SECURE) == 0) &&
124 !(arg_flags & ATTR_KERNORMALS))
125 return 0;
126 if (((arg_flags & ATTR_ROOT) == 0) !=
127 ((ondisk_flags & XFS_ATTR_ROOT) == 0) &&
128 !(arg_flags & ATTR_KERNROOTLS))
129 return 0;
130 return 1;
131}
132
133 107
134/*======================================================================== 108/*========================================================================
135 * External routines when attribute fork size < XFS_LITINO(mp). 109 * External routines when attribute fork size < XFS_LITINO(mp).
@@ -626,15 +600,8 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
626 (XFS_ISRESET_CURSOR(cursor) && 600 (XFS_ISRESET_CURSOR(cursor) &&
627 (dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) { 601 (dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) {
628 for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { 602 for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
629 attrnames_t *namesp;
630
631 if (!xfs_attr_namesp_match_overrides(context->flags, sfe->flags)) {
632 sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
633 continue;
634 }
635 namesp = xfs_attr_flags_namesp(sfe->flags);
636 error = context->put_listent(context, 603 error = context->put_listent(context,
637 namesp, 604 sfe->flags,
638 (char *)sfe->nameval, 605 (char *)sfe->nameval,
639 (int)sfe->namelen, 606 (int)sfe->namelen,
640 (int)sfe->valuelen, 607 (int)sfe->valuelen,
@@ -681,10 +648,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
681 kmem_free(sbuf); 648 kmem_free(sbuf);
682 return XFS_ERROR(EFSCORRUPTED); 649 return XFS_ERROR(EFSCORRUPTED);
683 } 650 }
684 if (!xfs_attr_namesp_match_overrides(context->flags, sfe->flags)) { 651
685 sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
686 continue;
687 }
688 sbp->entno = i; 652 sbp->entno = i;
689 sbp->hash = xfs_da_hashname((char *)sfe->nameval, sfe->namelen); 653 sbp->hash = xfs_da_hashname((char *)sfe->nameval, sfe->namelen);
690 sbp->name = (char *)sfe->nameval; 654 sbp->name = (char *)sfe->nameval;
@@ -728,16 +692,12 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
728 * Loop putting entries into the user buffer. 692 * Loop putting entries into the user buffer.
729 */ 693 */
730 for ( ; i < nsbuf; i++, sbp++) { 694 for ( ; i < nsbuf; i++, sbp++) {
731 attrnames_t *namesp;
732
733 namesp = xfs_attr_flags_namesp(sbp->flags);
734
735 if (cursor->hashval != sbp->hash) { 695 if (cursor->hashval != sbp->hash) {
736 cursor->hashval = sbp->hash; 696 cursor->hashval = sbp->hash;
737 cursor->offset = 0; 697 cursor->offset = 0;
738 } 698 }
739 error = context->put_listent(context, 699 error = context->put_listent(context,
740 namesp, 700 sbp->flags,
741 sbp->name, 701 sbp->name,
742 sbp->namelen, 702 sbp->namelen,
743 sbp->valuelen, 703 sbp->valuelen,
@@ -2402,8 +2362,6 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
2402 */ 2362 */
2403 retval = 0; 2363 retval = 0;
2404 for ( ; (i < be16_to_cpu(leaf->hdr.count)); entry++, i++) { 2364 for ( ; (i < be16_to_cpu(leaf->hdr.count)); entry++, i++) {
2405 attrnames_t *namesp;
2406
2407 if (be32_to_cpu(entry->hashval) != cursor->hashval) { 2365 if (be32_to_cpu(entry->hashval) != cursor->hashval) {
2408 cursor->hashval = be32_to_cpu(entry->hashval); 2366 cursor->hashval = be32_to_cpu(entry->hashval);
2409 cursor->offset = 0; 2367 cursor->offset = 0;
@@ -2411,17 +2369,13 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
2411 2369
2412 if (entry->flags & XFS_ATTR_INCOMPLETE) 2370 if (entry->flags & XFS_ATTR_INCOMPLETE)
2413 continue; /* skip incomplete entries */ 2371 continue; /* skip incomplete entries */
2414 if (!xfs_attr_namesp_match_overrides(context->flags, entry->flags))
2415 continue;
2416
2417 namesp = xfs_attr_flags_namesp(entry->flags);
2418 2372
2419 if (entry->flags & XFS_ATTR_LOCAL) { 2373 if (entry->flags & XFS_ATTR_LOCAL) {
2420 xfs_attr_leaf_name_local_t *name_loc = 2374 xfs_attr_leaf_name_local_t *name_loc =
2421 XFS_ATTR_LEAF_NAME_LOCAL(leaf, i); 2375 XFS_ATTR_LEAF_NAME_LOCAL(leaf, i);
2422 2376
2423 retval = context->put_listent(context, 2377 retval = context->put_listent(context,
2424 namesp, 2378 entry->flags,
2425 (char *)name_loc->nameval, 2379 (char *)name_loc->nameval,
2426 (int)name_loc->namelen, 2380 (int)name_loc->namelen,
2427 be16_to_cpu(name_loc->valuelen), 2381 be16_to_cpu(name_loc->valuelen),
@@ -2448,16 +2402,15 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
2448 if (retval) 2402 if (retval)
2449 return retval; 2403 return retval;
2450 retval = context->put_listent(context, 2404 retval = context->put_listent(context,
2451 namesp, 2405 entry->flags,
2452 (char *)name_rmt->name, 2406 (char *)name_rmt->name,
2453 (int)name_rmt->namelen, 2407 (int)name_rmt->namelen,
2454 valuelen, 2408 valuelen,
2455 (char*)args.value); 2409 (char*)args.value);
2456 kmem_free(args.value); 2410 kmem_free(args.value);
2457 } 2411 } else {
2458 else {
2459 retval = context->put_listent(context, 2412 retval = context->put_listent(context,
2460 namesp, 2413 entry->flags,
2461 (char *)name_rmt->name, 2414 (char *)name_rmt->name,
2462 (int)name_rmt->namelen, 2415 (int)name_rmt->namelen,
2463 valuelen, 2416 valuelen,
diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h
index 040f732ce1e2..5ecf437b7825 100644
--- a/fs/xfs/xfs_attr_leaf.h
+++ b/fs/xfs/xfs_attr_leaf.h
@@ -30,7 +30,7 @@
30 30
31struct attrlist; 31struct attrlist;
32struct attrlist_cursor_kern; 32struct attrlist_cursor_kern;
33struct attrnames; 33struct xfs_attr_list_context;
34struct xfs_dabuf; 34struct xfs_dabuf;
35struct xfs_da_args; 35struct xfs_da_args;
36struct xfs_da_state; 36struct xfs_da_state;
@@ -204,33 +204,6 @@ static inline int xfs_attr_leaf_entsize_local_max(int bsize)
204 return (((bsize) >> 1) + ((bsize) >> 2)); 204 return (((bsize) >> 1) + ((bsize) >> 2));
205} 205}
206 206
207
208/*========================================================================
209 * Structure used to pass context around among the routines.
210 *========================================================================*/
211
212
213struct xfs_attr_list_context;
214
215typedef int (*put_listent_func_t)(struct xfs_attr_list_context *, struct attrnames *,
216 char *, int, int, char *);
217
218typedef struct xfs_attr_list_context {
219 struct xfs_inode *dp; /* inode */
220 struct attrlist_cursor_kern *cursor; /* position in list */
221 struct attrlist *alist; /* output buffer */
222 int seen_enough; /* T/F: seen enough of list? */
223 int count; /* num used entries */
224 int dupcnt; /* count dup hashvals seen */
225 int bufsize; /* total buffer size */
226 int firstu; /* first used byte in buffer */
227 int flags; /* from VOP call */
228 int resynch; /* T/F: resynch with cursor */
229 int put_value; /* T/F: need value for listent */
230 put_listent_func_t put_listent; /* list output fmt function */
231 int index; /* index into output buffer */
232} xfs_attr_list_context_t;
233
234/* 207/*
235 * Used to keep a list of "remote value" extents when unlinking an inode. 208 * Used to keep a list of "remote value" extents when unlinking an inode.
236 */ 209 */