diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/xfs_acl.c | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_attr.c | 139 | ||||
-rw-r--r-- | fs/xfs/xfs_attr.h | 55 | ||||
-rw-r--r-- | fs/xfs/xfs_attr_leaf.c | 61 | ||||
-rw-r--r-- | fs/xfs/xfs_attr_leaf.h | 29 |
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 | ||
610 | STATIC int | 608 | int |
611 | xfs_attr_list_int(xfs_attr_list_context_t *context) | 609 | xfs_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*/ |
643 | STATIC int | 653 | STATIC int |
644 | xfs_attr_put_listent(xfs_attr_list_context_t *context, attrnames_t *namesp, | 654 | xfs_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 | ||
677 | STATIC int | ||
678 | xfs_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*/ | ||
703 | STATIC int | ||
704 | xfs_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 | ||
21 | struct xfs_inode; | ||
22 | struct xfs_da_args; | ||
23 | struct 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 | ||
38 | struct cred; | ||
39 | struct xfs_attr_list_context; | ||
40 | |||
41 | typedef struct attrnames { | ||
42 | char * attr_name; | ||
43 | unsigned int attr_namelen; | ||
44 | } attrnames_t; | ||
45 | |||
46 | extern struct attrnames attr_user; | ||
47 | extern struct attrnames attr_secure; | ||
48 | extern 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 | ||
135 | struct xfs_inode; | 120 | |
136 | struct attrlist_cursor_kern; | 121 | typedef int (*put_listent_func_t)(struct xfs_attr_list_context *, int, |
137 | struct xfs_da_args; | 122 | char *, int, int, char *); |
123 | |||
124 | typedef 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 | */ |
142 | int xfs_attr_inactive(struct xfs_inode *dp); | 148 | int xfs_attr_inactive(struct xfs_inode *dp); |
143 | |||
144 | int xfs_attr_shortform_getvalue(struct xfs_da_args *); | ||
145 | int xfs_attr_fetch(struct xfs_inode *, struct xfs_name *, char *, int *, int); | 149 | int xfs_attr_fetch(struct xfs_inode *, struct xfs_name *, char *, int *, int); |
146 | int xfs_attr_rmtval_get(struct xfs_da_args *args); | 150 | int xfs_attr_rmtval_get(struct xfs_da_args *args); |
151 | int 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 | ||
97 | STATIC_INLINE attrnames_t * | ||
98 | xfs_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 | */ | ||
119 | STATIC_INLINE int | ||
120 | xfs_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 | ||
31 | struct attrlist; | 31 | struct attrlist; |
32 | struct attrlist_cursor_kern; | 32 | struct attrlist_cursor_kern; |
33 | struct attrnames; | 33 | struct xfs_attr_list_context; |
34 | struct xfs_dabuf; | 34 | struct xfs_dabuf; |
35 | struct xfs_da_args; | 35 | struct xfs_da_args; |
36 | struct xfs_da_state; | 36 | struct 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 | |||
213 | struct xfs_attr_list_context; | ||
214 | |||
215 | typedef int (*put_listent_func_t)(struct xfs_attr_list_context *, struct attrnames *, | ||
216 | char *, int, int, char *); | ||
217 | |||
218 | typedef 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 | */ |