aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/xattr.c
diff options
context:
space:
mode:
authorKaiGai Kohei <kaigai@ak.jp.nec.com>2006-05-13 02:15:07 -0400
committerKaiGai Kohei <kaigai@ak.jp.nec.com>2006-05-13 02:15:07 -0400
commit8f2b6f49c656dd4597904f8c20661d6b73cdbbeb (patch)
tree7452e7d2fb9070181a943c104c409cac79abc991 /fs/jffs2/xattr.c
parent8b0b339d46ca0105a9936e3caa3bac80b72de7a3 (diff)
[JFFS2][XATTR] Remove 'struct list_head ilist' from jffs2_inode_cache.
This patch can reduce 4-byte of memory usage per inode_cache. [4/10] jffs2-xattr-v5.1-04-remove_ilist_from_ic.patch Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Diffstat (limited to 'fs/jffs2/xattr.c')
-rw-r--r--fs/jffs2/xattr.c75
1 files changed, 47 insertions, 28 deletions
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c
index c9a185c54ce7..b16bc71c9cd2 100644
--- a/fs/jffs2/xattr.c
+++ b/fs/jffs2/xattr.c
@@ -456,7 +456,7 @@ static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c,
456 * is called to remove xrefs related to obsolete inode when inode is unlinked. 456 * is called to remove xrefs related to obsolete inode when inode is unlinked.
457 * jffs2_xattr_free_inode(c, ic) 457 * jffs2_xattr_free_inode(c, ic)
458 * is called to release xattr related objects when unmounting. 458 * is called to release xattr related objects when unmounting.
459 * check_xattr_ref_ilist(c, ic) 459 * check_xattr_ref_inode(c, ic)
460 * is used to confirm inode does not have duplicate xattr name/value pair. 460 * is used to confirm inode does not have duplicate xattr name/value pair.
461 * -------------------------------------------------- */ 461 * -------------------------------------------------- */
462static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) 462static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
@@ -549,7 +549,6 @@ static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *re
549 BUG_ON(!ref->node); 549 BUG_ON(!ref->node);
550 delete_xattr_ref_node(c, ref); 550 delete_xattr_ref_node(c, ref);
551 551
552 list_del(&ref->ilist);
553 xd = ref->xd; 552 xd = ref->xd;
554 xd->refcnt--; 553 xd->refcnt--;
555 if (!xd->refcnt) 554 if (!xd->refcnt)
@@ -629,7 +628,8 @@ static struct jffs2_xattr_ref *create_xattr_ref(struct jffs2_sb_info *c, struct
629 } 628 }
630 629
631 /* Chain to inode */ 630 /* Chain to inode */
632 list_add(&ref->ilist, &ic->ilist); 631 ref->next = ic->xref;
632 ic->xref = ref;
633 633
634 return ref; /* success */ 634 return ref; /* success */
635} 635}
@@ -644,8 +644,11 @@ void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache
644 return; 644 return;
645 645
646 down_write(&c->xattr_sem); 646 down_write(&c->xattr_sem);
647 list_for_each_entry_safe(ref, _ref, &ic->ilist, ilist) 647 for (ref = ic->xref; ref; ref = _ref) {
648 _ref = ref->next;
648 delete_xattr_ref(c, ref); 649 delete_xattr_ref(c, ref);
650 }
651 ic->xref = NULL;
649 up_write(&c->xattr_sem); 652 up_write(&c->xattr_sem);
650} 653}
651 654
@@ -656,8 +659,8 @@ void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *i
656 struct jffs2_xattr_ref *ref, *_ref; 659 struct jffs2_xattr_ref *ref, *_ref;
657 660
658 down_write(&c->xattr_sem); 661 down_write(&c->xattr_sem);
659 list_for_each_entry_safe(ref, _ref, &ic->ilist, ilist) { 662 for (ref = ic->xref; ref; ref = _ref) {
660 list_del(&ref->ilist); 663 _ref = ref->next;
661 xd = ref->xd; 664 xd = ref->xd;
662 xd->refcnt--; 665 xd->refcnt--;
663 if (!xd->refcnt) { 666 if (!xd->refcnt) {
@@ -666,16 +669,17 @@ void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *i
666 } 669 }
667 jffs2_free_xattr_ref(ref); 670 jffs2_free_xattr_ref(ref);
668 } 671 }
672 ic->xref = NULL;
669 up_write(&c->xattr_sem); 673 up_write(&c->xattr_sem);
670} 674}
671 675
672static int check_xattr_ref_ilist(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) 676static int check_xattr_ref_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
673{ 677{
674 /* success of check_xattr_ref_ilist() means taht inode (ic) dose not have 678 /* success of check_xattr_ref_inode() means taht inode (ic) dose not have
675 * duplicate name/value pairs. If duplicate name/value pair would be found, 679 * duplicate name/value pairs. If duplicate name/value pair would be found,
676 * one will be removed. 680 * one will be removed.
677 */ 681 */
678 struct jffs2_xattr_ref *ref, *cmp; 682 struct jffs2_xattr_ref *ref, *cmp, **pref;
679 int rc = 0; 683 int rc = 0;
680 684
681 if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED)) 685 if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED))
@@ -683,22 +687,23 @@ static int check_xattr_ref_ilist(struct jffs2_sb_info *c, struct jffs2_inode_cac
683 down_write(&c->xattr_sem); 687 down_write(&c->xattr_sem);
684 retry: 688 retry:
685 rc = 0; 689 rc = 0;
686 list_for_each_entry(ref, &ic->ilist, ilist) { 690 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
687 if (!ref->xd->xname) { 691 if (!ref->xd->xname) {
688 rc = load_xattr_datum(c, ref->xd); 692 rc = load_xattr_datum(c, ref->xd);
689 if (unlikely(rc > 0)) { 693 if (unlikely(rc > 0)) {
694 *pref = ref->next;
690 delete_xattr_ref(c, ref); 695 delete_xattr_ref(c, ref);
691 goto retry; 696 goto retry;
692 } else if (unlikely(rc < 0)) 697 } else if (unlikely(rc < 0))
693 goto out; 698 goto out;
694 } 699 }
695 cmp = ref; 700 for (cmp=ref->next, pref=&ref->next; cmp; pref=&cmp->next, cmp=cmp->next) {
696 list_for_each_entry_continue(cmp, &ic->ilist, ilist) {
697 if (!cmp->xd->xname) { 701 if (!cmp->xd->xname) {
698 ref->xd->flags |= JFFS2_XFLAGS_BIND; 702 ref->xd->flags |= JFFS2_XFLAGS_BIND;
699 rc = load_xattr_datum(c, cmp->xd); 703 rc = load_xattr_datum(c, cmp->xd);
700 ref->xd->flags &= ~JFFS2_XFLAGS_BIND; 704 ref->xd->flags &= ~JFFS2_XFLAGS_BIND;
701 if (unlikely(rc > 0)) { 705 if (unlikely(rc > 0)) {
706 *pref = cmp->next;
702 delete_xattr_ref(c, cmp); 707 delete_xattr_ref(c, cmp);
703 goto retry; 708 goto retry;
704 } else if (unlikely(rc < 0)) 709 } else if (unlikely(rc < 0))
@@ -706,6 +711,7 @@ static int check_xattr_ref_ilist(struct jffs2_sb_info *c, struct jffs2_inode_cac
706 } 711 }
707 if (ref->xd->xprefix == cmp->xd->xprefix 712 if (ref->xd->xprefix == cmp->xd->xprefix
708 && !strcmp(ref->xd->xname, cmp->xd->xname)) { 713 && !strcmp(ref->xd->xname, cmp->xd->xname)) {
714 *pref = cmp->next;
709 delete_xattr_ref(c, cmp); 715 delete_xattr_ref(c, cmp);
710 goto retry; 716 goto retry;
711 } 717 }
@@ -736,8 +742,8 @@ void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c)
736 742
737 for (i=0; i < XATTRINDEX_HASHSIZE; i++) 743 for (i=0; i < XATTRINDEX_HASHSIZE; i++)
738 INIT_LIST_HEAD(&c->xattrindex[i]); 744 INIT_LIST_HEAD(&c->xattrindex[i]);
739 INIT_LIST_HEAD(&c->xattr_temp);
740 INIT_LIST_HEAD(&c->xattr_unchecked); 745 INIT_LIST_HEAD(&c->xattr_unchecked);
746 c->xref_temp = NULL;
741 747
742 init_rwsem(&c->xattr_sem); 748 init_rwsem(&c->xattr_sem);
743 c->xdatum_mem_usage = 0; 749 c->xdatum_mem_usage = 0;
@@ -765,8 +771,11 @@ void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c)
765 struct jffs2_xattr_ref *ref, *_ref; 771 struct jffs2_xattr_ref *ref, *_ref;
766 int i; 772 int i;
767 773
768 list_for_each_entry_safe(ref, _ref, &c->xattr_temp, ilist) 774 for (ref=c->xref_temp; ref; ref = _ref) {
775 _ref = ref->next;
769 jffs2_free_xattr_ref(ref); 776 jffs2_free_xattr_ref(ref);
777 }
778 c->xref_temp = NULL;
770 779
771 for (i=0; i < XATTRINDEX_HASHSIZE; i++) { 780 for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
772 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) { 781 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
@@ -788,8 +797,8 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
788 BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING)); 797 BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING));
789 798
790 /* Phase.1 */ 799 /* Phase.1 */
791 list_for_each_entry_safe(ref, _ref, &c->xattr_temp, ilist) { 800 for (ref=c->xref_temp; ref; ref=_ref) {
792 list_del_init(&ref->ilist); 801 _ref = ref->next;
793 /* checking REF_UNCHECKED nodes */ 802 /* checking REF_UNCHECKED nodes */
794 if (ref_flags(ref->node) != REF_PRISTINE) { 803 if (ref_flags(ref->node) != REF_PRISTINE) {
795 if (verify_xattr_ref(c, ref)) { 804 if (verify_xattr_ref(c, ref)) {
@@ -813,9 +822,11 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
813 ref->xd = xd; 822 ref->xd = xd;
814 ref->ic = ic; 823 ref->ic = ic;
815 xd->refcnt++; 824 xd->refcnt++;
816 list_add_tail(&ref->ilist, &ic->ilist); 825 ref->next = ic->xref;
826 ic->xref = ref;
817 xref_count++; 827 xref_count++;
818 } 828 }
829 c->xref_temp = NULL;
819 /* After this, ref->xid/ino are NEVER used. */ 830 /* After this, ref->xid/ino are NEVER used. */
820 831
821 /* Phase.2 */ 832 /* Phase.2 */
@@ -931,20 +942,20 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
931 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); 942 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
932 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); 943 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
933 struct jffs2_inode_cache *ic = f->inocache; 944 struct jffs2_inode_cache *ic = f->inocache;
934 struct jffs2_xattr_ref *ref; 945 struct jffs2_xattr_ref *ref, **pref;
935 struct jffs2_xattr_datum *xd; 946 struct jffs2_xattr_datum *xd;
936 struct xattr_handler *xhandle; 947 struct xattr_handler *xhandle;
937 ssize_t len, rc; 948 ssize_t len, rc;
938 int retry = 0; 949 int retry = 0;
939 950
940 rc = check_xattr_ref_ilist(c, ic); 951 rc = check_xattr_ref_inode(c, ic);
941 if (unlikely(rc)) 952 if (unlikely(rc))
942 return rc; 953 return rc;
943 954
944 down_read(&c->xattr_sem); 955 down_read(&c->xattr_sem);
945 retry: 956 retry:
946 len = 0; 957 len = 0;
947 list_for_each_entry(ref, &ic->ilist, ilist) { 958 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
948 BUG_ON(ref->ic != ic); 959 BUG_ON(ref->ic != ic);
949 xd = ref->xd; 960 xd = ref->xd;
950 if (!xd->xname) { 961 if (!xd->xname) {
@@ -957,6 +968,7 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
957 } else { 968 } else {
958 rc = load_xattr_datum(c, xd); 969 rc = load_xattr_datum(c, xd);
959 if (unlikely(rc > 0)) { 970 if (unlikely(rc > 0)) {
971 *pref = ref->next;
960 delete_xattr_ref(c, ref); 972 delete_xattr_ref(c, ref);
961 goto retry; 973 goto retry;
962 } else if (unlikely(rc < 0)) 974 } else if (unlikely(rc < 0))
@@ -992,16 +1004,16 @@ int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname,
992 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); 1004 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
993 struct jffs2_inode_cache *ic = f->inocache; 1005 struct jffs2_inode_cache *ic = f->inocache;
994 struct jffs2_xattr_datum *xd; 1006 struct jffs2_xattr_datum *xd;
995 struct jffs2_xattr_ref *ref; 1007 struct jffs2_xattr_ref *ref, **pref;
996 int rc, retry = 0; 1008 int rc, retry = 0;
997 1009
998 rc = check_xattr_ref_ilist(c, ic); 1010 rc = check_xattr_ref_inode(c, ic);
999 if (unlikely(rc)) 1011 if (unlikely(rc))
1000 return rc; 1012 return rc;
1001 1013
1002 down_read(&c->xattr_sem); 1014 down_read(&c->xattr_sem);
1003 retry: 1015 retry:
1004 list_for_each_entry(ref, &ic->ilist, ilist) { 1016 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
1005 BUG_ON(ref->ic!=ic); 1017 BUG_ON(ref->ic!=ic);
1006 1018
1007 xd = ref->xd; 1019 xd = ref->xd;
@@ -1017,6 +1029,7 @@ int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname,
1017 } else { 1029 } else {
1018 rc = load_xattr_datum(c, xd); 1030 rc = load_xattr_datum(c, xd);
1019 if (unlikely(rc > 0)) { 1031 if (unlikely(rc > 0)) {
1032 *pref = ref->next;
1020 delete_xattr_ref(c, ref); 1033 delete_xattr_ref(c, ref);
1021 goto retry; 1034 goto retry;
1022 } else if (unlikely(rc < 0)) { 1035 } else if (unlikely(rc < 0)) {
@@ -1053,11 +1066,11 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1053 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); 1066 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
1054 struct jffs2_inode_cache *ic = f->inocache; 1067 struct jffs2_inode_cache *ic = f->inocache;
1055 struct jffs2_xattr_datum *xd; 1068 struct jffs2_xattr_datum *xd;
1056 struct jffs2_xattr_ref *ref, *newref; 1069 struct jffs2_xattr_ref *ref, *newref, **pref;
1057 uint32_t phys_ofs, length, request; 1070 uint32_t phys_ofs, length, request;
1058 int rc; 1071 int rc;
1059 1072
1060 rc = check_xattr_ref_ilist(c, ic); 1073 rc = check_xattr_ref_inode(c, ic);
1061 if (unlikely(rc)) 1074 if (unlikely(rc))
1062 return rc; 1075 return rc;
1063 1076
@@ -1072,13 +1085,14 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1072 /* Find existing xattr */ 1085 /* Find existing xattr */
1073 down_write(&c->xattr_sem); 1086 down_write(&c->xattr_sem);
1074 retry: 1087 retry:
1075 list_for_each_entry(ref, &ic->ilist, ilist) { 1088 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
1076 xd = ref->xd; 1089 xd = ref->xd;
1077 if (xd->xprefix != xprefix) 1090 if (xd->xprefix != xprefix)
1078 continue; 1091 continue;
1079 if (!xd->xname) { 1092 if (!xd->xname) {
1080 rc = load_xattr_datum(c, xd); 1093 rc = load_xattr_datum(c, xd);
1081 if (unlikely(rc > 0)) { 1094 if (unlikely(rc > 0)) {
1095 *pref = ref->next;
1082 delete_xattr_ref(c, ref); 1096 delete_xattr_ref(c, ref);
1083 goto retry; 1097 goto retry;
1084 } else if (unlikely(rc < 0)) 1098 } else if (unlikely(rc < 0))
@@ -1090,6 +1104,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1090 goto out; 1104 goto out;
1091 } 1105 }
1092 if (!buffer) { 1106 if (!buffer) {
1107 *pref = ref->next;
1093 delete_xattr_ref(c, ref); 1108 delete_xattr_ref(c, ref);
1094 rc = 0; 1109 rc = 0;
1095 goto out; 1110 goto out;
@@ -1098,7 +1113,6 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1098 } 1113 }
1099 } 1114 }
1100 /* not found */ 1115 /* not found */
1101 ref = NULL;
1102 if (flags & XATTR_REPLACE) { 1116 if (flags & XATTR_REPLACE) {
1103 rc = -ENODATA; 1117 rc = -ENODATA;
1104 goto out; 1118 goto out;
@@ -1130,14 +1144,19 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1130 return rc; 1144 return rc;
1131 } 1145 }
1132 down_write(&c->xattr_sem); 1146 down_write(&c->xattr_sem);
1147 if (ref)
1148 *pref = ref->next;
1133 newref = create_xattr_ref(c, ic, xd, phys_ofs); 1149 newref = create_xattr_ref(c, ic, xd, phys_ofs);
1134 if (IS_ERR(newref)) { 1150 if (IS_ERR(newref)) {
1151 if (ref) {
1152 ref->next = ic->xref;
1153 ic->xref = ref;
1154 }
1135 rc = PTR_ERR(newref); 1155 rc = PTR_ERR(newref);
1136 xd->refcnt--; 1156 xd->refcnt--;
1137 if (!xd->refcnt) 1157 if (!xd->refcnt)
1138 delete_xattr_datum(c, xd); 1158 delete_xattr_datum(c, xd);
1139 } else if (ref) { 1159 } else if (ref) {
1140 /* If replaced xattr_ref exists */
1141 delete_xattr_ref(c, ref); 1160 delete_xattr_ref(c, ref);
1142 } 1161 }
1143 out: 1162 out: