diff options
author | KaiGai Kohei <kaigai@ak.jp.nec.com> | 2006-05-13 02:15:07 -0400 |
---|---|---|
committer | KaiGai Kohei <kaigai@ak.jp.nec.com> | 2006-05-13 02:15:07 -0400 |
commit | 8f2b6f49c656dd4597904f8c20661d6b73cdbbeb (patch) | |
tree | 7452e7d2fb9070181a943c104c409cac79abc991 /fs/jffs2/xattr.c | |
parent | 8b0b339d46ca0105a9936e3caa3bac80b72de7a3 (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.c | 75 |
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 | * -------------------------------------------------- */ |
462 | static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) | 462 | static 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 | ||
672 | static int check_xattr_ref_ilist(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) | 676 | static 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: |