aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_attr.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2008-06-22 23:23:48 -0400
committerNiv Sardi <xaiki@debian.org>2008-07-28 02:58:53 -0400
commitad9b463aa206b8c8f0bab378cf7c090c1a9a8e34 (patch)
treec427ffd218b9123ec5fc6d004d6bd25e65e8de1f /fs/xfs/xfs_attr.c
parentcaf8aabdbc6849de772850d26d3dbe35e8f63bff (diff)
[XFS] Switches xfs_vn_listxattr to set it's put_listent callback directly
and not go through xfs_attr_list. SGI-PV: 983395 SGI-Modid: xfs-linux-melb:xfs-kern:31324a Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Tim Shimmin <tes@sgi.com> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_attr.c')
-rw-r--r--fs/xfs/xfs_attr.c139
1 files changed, 45 insertions, 94 deletions
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);