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 | |
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>
-rw-r--r-- | fs/jffs2/jffs2_fs_sb.h | 2 | ||||
-rw-r--r-- | fs/jffs2/malloc.c | 1 | ||||
-rw-r--r-- | fs/jffs2/nodelist.h | 2 | ||||
-rw-r--r-- | fs/jffs2/readinode.c | 1 | ||||
-rw-r--r-- | fs/jffs2/scan.c | 6 | ||||
-rw-r--r-- | fs/jffs2/summary.c | 3 | ||||
-rw-r--r-- | fs/jffs2/write.c | 1 | ||||
-rw-r--r-- | fs/jffs2/xattr.c | 75 | ||||
-rw-r--r-- | fs/jffs2/xattr.h | 7 |
9 files changed, 55 insertions, 43 deletions
diff --git a/fs/jffs2/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h index 3b4e0edd6dbb..272fbea55192 100644 --- a/fs/jffs2/jffs2_fs_sb.h +++ b/fs/jffs2/jffs2_fs_sb.h | |||
@@ -119,8 +119,8 @@ struct jffs2_sb_info { | |||
119 | #define XATTRINDEX_HASHSIZE (57) | 119 | #define XATTRINDEX_HASHSIZE (57) |
120 | uint32_t highest_xid; | 120 | uint32_t highest_xid; |
121 | struct list_head xattrindex[XATTRINDEX_HASHSIZE]; | 121 | struct list_head xattrindex[XATTRINDEX_HASHSIZE]; |
122 | struct list_head xattr_temp; | ||
123 | struct list_head xattr_unchecked; | 122 | struct list_head xattr_unchecked; |
123 | struct jffs2_xattr_ref *xref_temp; | ||
124 | struct rw_semaphore xattr_sem; | 124 | struct rw_semaphore xattr_sem; |
125 | uint32_t xdatum_mem_usage; | 125 | uint32_t xdatum_mem_usage; |
126 | uint32_t xdatum_mem_threshold; | 126 | uint32_t xdatum_mem_threshold; |
diff --git a/fs/jffs2/malloc.c b/fs/jffs2/malloc.c index 3d5b7ecfbf8d..f2473fa2fd16 100644 --- a/fs/jffs2/malloc.c +++ b/fs/jffs2/malloc.c | |||
@@ -259,7 +259,6 @@ struct jffs2_xattr_ref *jffs2_alloc_xattr_ref(void) | |||
259 | 259 | ||
260 | memset(ref, 0, sizeof(struct jffs2_xattr_ref)); | 260 | memset(ref, 0, sizeof(struct jffs2_xattr_ref)); |
261 | ref->class = RAWNODE_CLASS_XATTR_REF; | 261 | ref->class = RAWNODE_CLASS_XATTR_REF; |
262 | INIT_LIST_HEAD(&ref->ilist); | ||
263 | return ref; | 262 | return ref; |
264 | } | 263 | } |
265 | 264 | ||
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h index 6f6279cf4909..351d947c9375 100644 --- a/fs/jffs2/nodelist.h +++ b/fs/jffs2/nodelist.h | |||
@@ -117,7 +117,7 @@ struct jffs2_inode_cache { | |||
117 | uint32_t ino; | 117 | uint32_t ino; |
118 | int nlink; | 118 | int nlink; |
119 | #ifdef CONFIG_JFFS2_FS_XATTR | 119 | #ifdef CONFIG_JFFS2_FS_XATTR |
120 | struct list_head ilist; | 120 | struct jffs2_xattr_ref *xref; |
121 | #endif | 121 | #endif |
122 | }; | 122 | }; |
123 | 123 | ||
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 61ccdf4f1042..e1acce8fb2bf 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c | |||
@@ -902,7 +902,6 @@ int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, | |||
902 | f->inocache->ino = f->inocache->nlink = 1; | 902 | f->inocache->ino = f->inocache->nlink = 1; |
903 | f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; | 903 | f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; |
904 | f->inocache->state = INO_STATE_READING; | 904 | f->inocache->state = INO_STATE_READING; |
905 | init_xattr_inode_cache(f->inocache); | ||
906 | jffs2_add_ino_cache(c, f->inocache); | 905 | jffs2_add_ino_cache(c, f->inocache); |
907 | } | 906 | } |
908 | if (!f->inocache) { | 907 | if (!f->inocache) { |
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index f09689e320fe..0a79fc921e9f 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c | |||
@@ -408,14 +408,15 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock | |||
408 | * ref->xid is used to store 32bit xid, xd is not used | 408 | * ref->xid is used to store 32bit xid, xd is not used |
409 | * ref->ino is used to store 32bit inode-number, ic is not used | 409 | * ref->ino is used to store 32bit inode-number, ic is not used |
410 | * Thoes variables are declared as union, thus using those | 410 | * Thoes variables are declared as union, thus using those |
411 | * are exclusive. In a similar way, ref->ilist is temporarily | 411 | * are exclusive. In a similar way, ref->next is temporarily |
412 | * used to chain all xattr_ref object. It's re-chained to | 412 | * used to chain all xattr_ref object. It's re-chained to |
413 | * jffs2_inode_cache in jffs2_build_xattr_subsystem() correctly. | 413 | * jffs2_inode_cache in jffs2_build_xattr_subsystem() correctly. |
414 | */ | 414 | */ |
415 | ref->node = raw; | 415 | ref->node = raw; |
416 | ref->ino = je32_to_cpu(rr->ino); | 416 | ref->ino = je32_to_cpu(rr->ino); |
417 | ref->xid = je32_to_cpu(rr->xid); | 417 | ref->xid = je32_to_cpu(rr->xid); |
418 | list_add_tail(&ref->ilist, &c->xattr_temp); | 418 | ref->next = c->xref_temp; |
419 | c->xref_temp = ref; | ||
419 | 420 | ||
420 | raw->__totlen = PAD(je32_to_cpu(rr->totlen)); | 421 | raw->__totlen = PAD(je32_to_cpu(rr->totlen)); |
421 | raw->flash_offset = ofs | REF_PRISTINE; | 422 | raw->flash_offset = ofs | REF_PRISTINE; |
@@ -888,7 +889,6 @@ struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uin | |||
888 | 889 | ||
889 | ic->ino = ino; | 890 | ic->ino = ino; |
890 | ic->nodes = (void *)ic; | 891 | ic->nodes = (void *)ic; |
891 | init_xattr_inode_cache(ic); | ||
892 | jffs2_add_ino_cache(c, ic); | 892 | jffs2_add_ino_cache(c, ic); |
893 | if (ino == 1) | 893 | if (ino == 1) |
894 | ic->nlink = 1; | 894 | ic->nlink = 1; |
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c index 5d9ec8e36528..831a42c13059 100644 --- a/fs/jffs2/summary.c +++ b/fs/jffs2/summary.c | |||
@@ -556,7 +556,8 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras | |||
556 | ref->ino = 0xfffffffe; | 556 | ref->ino = 0xfffffffe; |
557 | ref->xid = 0xfffffffd; | 557 | ref->xid = 0xfffffffd; |
558 | ref->node = raw; | 558 | ref->node = raw; |
559 | list_add_tail(&ref->ilist, &c->xattr_temp); | 559 | ref->next = c->xref_temp; |
560 | c->xref_temp = ref; | ||
560 | 561 | ||
561 | raw->__totlen = PAD(sizeof(struct jffs2_raw_xref)); | 562 | raw->__totlen = PAD(sizeof(struct jffs2_raw_xref)); |
562 | raw->flash_offset = ofs | REF_UNCHECKED; | 563 | raw->flash_offset = ofs | REF_UNCHECKED; |
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c index d5c78195f3b8..ff2b00b604ec 100644 --- a/fs/jffs2/write.c +++ b/fs/jffs2/write.c | |||
@@ -36,7 +36,6 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint | |||
36 | f->inocache->nlink = 1; | 36 | f->inocache->nlink = 1; |
37 | f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; | 37 | f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; |
38 | f->inocache->state = INO_STATE_PRESENT; | 38 | f->inocache->state = INO_STATE_PRESENT; |
39 | init_xattr_inode_cache(f->inocache); | ||
40 | 39 | ||
41 | jffs2_add_ino_cache(c, f->inocache); | 40 | jffs2_add_ino_cache(c, f->inocache); |
42 | D1(printk(KERN_DEBUG "jffs2_do_new_inode(): Assigned ino# %d\n", f->inocache->ino)); | 41 | D1(printk(KERN_DEBUG "jffs2_do_new_inode(): Assigned ino# %d\n", f->inocache->ino)); |
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: |
diff --git a/fs/jffs2/xattr.h b/fs/jffs2/xattr.h index d157ad641ed4..0360097e5933 100644 --- a/fs/jffs2/xattr.h +++ b/fs/jffs2/xattr.h | |||
@@ -54,7 +54,7 @@ struct jffs2_xattr_ref | |||
54 | struct jffs2_xattr_datum *xd; /* reference to jffs2_xattr_datum */ | 54 | struct jffs2_xattr_datum *xd; /* reference to jffs2_xattr_datum */ |
55 | uint32_t xid; /* only used in sccanning/building */ | 55 | uint32_t xid; /* only used in sccanning/building */ |
56 | }; | 56 | }; |
57 | struct list_head ilist; /* chained from ic->ilist */ | 57 | struct jffs2_xattr_ref *next; /* chained from ic->xref_list */ |
58 | }; | 58 | }; |
59 | 59 | ||
60 | #ifdef CONFIG_JFFS2_FS_XATTR | 60 | #ifdef CONFIG_JFFS2_FS_XATTR |
@@ -86,9 +86,6 @@ extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t); | |||
86 | #define jffs2_setxattr generic_setxattr | 86 | #define jffs2_setxattr generic_setxattr |
87 | #define jffs2_removexattr generic_removexattr | 87 | #define jffs2_removexattr generic_removexattr |
88 | 88 | ||
89 | /*---- Any inline initialize functions ----*/ | ||
90 | #define init_xattr_inode_cache(x) INIT_LIST_HEAD(&((x)->ilist)) | ||
91 | |||
92 | #else | 89 | #else |
93 | 90 | ||
94 | #define jffs2_init_xattr_subsystem(c) | 91 | #define jffs2_init_xattr_subsystem(c) |
@@ -106,8 +103,6 @@ extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t); | |||
106 | #define jffs2_setxattr NULL | 103 | #define jffs2_setxattr NULL |
107 | #define jffs2_removexattr NULL | 104 | #define jffs2_removexattr NULL |
108 | 105 | ||
109 | #define init_xattr_inode_cache(x) | ||
110 | |||
111 | #endif /* CONFIG_JFFS2_FS_XATTR */ | 106 | #endif /* CONFIG_JFFS2_FS_XATTR */ |
112 | 107 | ||
113 | #ifdef CONFIG_JFFS2_FS_SECURITY | 108 | #ifdef CONFIG_JFFS2_FS_SECURITY |