Lines Matching +full:ref +full:- +full:pad

2  * JFFS2 -- Journalling Flash File System, Version 2.
28 /* -------- xdatum related functions ----------------
31 * the index of the xattr name/value pair cache (c->xattrindex).
36 * is used to release xattr name/value pair and detach from c->xattrindex.
39 * memory usage by cache is over c->xdatum_mem_threshold. Currently, this threshold
56 * is used to write xdatum to medium. xd->version will be incremented.
61 * is set on xd->flags and chained xattr_dead_list or release it immediately.
63 * -------------------------------------------------- */
76 spin_lock(&c->erase_completion_lock); in is_xattr_datum_unchecked()
77 for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) { in is_xattr_datum_unchecked()
83 spin_unlock(&c->erase_completion_lock); in is_xattr_datum_unchecked()
90 D1(dbg_xattr("%s: xid=%u, version=%u\n", __func__, xd->xid, xd->version)); in unload_xattr_datum()
91 if (xd->xname) { in unload_xattr_datum()
92 c->xdatum_mem_usage -= (xd->name_len + 1 + xd->value_len); in unload_xattr_datum()
93 kfree(xd->xname); in unload_xattr_datum()
96 list_del_init(&xd->xindex); in unload_xattr_datum()
97 xd->hashkey = 0; in unload_xattr_datum()
98 xd->xname = NULL; in unload_xattr_datum()
99 xd->xvalue = NULL; in unload_xattr_datum()
110 if (c->xdatum_mem_threshold > c->xdatum_mem_usage) in reclaim_xattr_datum()
113 before = c->xdatum_mem_usage; in reclaim_xattr_datum()
114 target = c->xdatum_mem_usage * 4 / 5; /* 20% reduction */ in reclaim_xattr_datum()
116 list_for_each_entry_safe(xd, _xd, &c->xattrindex[index], xindex) { in reclaim_xattr_datum()
117 if (xd->flags & JFFS2_XFLAGS_HOT) { in reclaim_xattr_datum()
118 xd->flags &= ~JFFS2_XFLAGS_HOT; in reclaim_xattr_datum()
119 } else if (!(xd->flags & JFFS2_XFLAGS_BIND)) { in reclaim_xattr_datum()
122 if (c->xdatum_mem_usage <= target) in reclaim_xattr_datum()
129 before, c->xdatum_mem_usage, before - c->xdatum_mem_usage); in reclaim_xattr_datum()
142 spin_lock(&c->erase_completion_lock); in do_verify_xattr_datum()
143 offset = ref_offset(xd->node); in do_verify_xattr_datum()
144 if (ref_flags(xd->node) == REF_PRISTINE) in do_verify_xattr_datum()
146 spin_unlock(&c->erase_completion_lock); in do_verify_xattr_datum()
152 return rc ? rc : -EIO; in do_verify_xattr_datum()
154 crc = crc32(0, &rx, sizeof(rx) - 4); in do_verify_xattr_datum()
158 xd->flags |= JFFS2_XFLAGS_INVALID; in do_verify_xattr_datum()
161 totlen = PAD(sizeof(rx) + rx.name_len + 1 + je16_to_cpu(rx.value_len)); in do_verify_xattr_datum()
165 || je32_to_cpu(rx.xid) != xd->xid in do_verify_xattr_datum()
166 || je32_to_cpu(rx.version) != xd->version) { in do_verify_xattr_datum()
172 je32_to_cpu(rx.xid), xd->xid, in do_verify_xattr_datum()
173 je32_to_cpu(rx.version), xd->version); in do_verify_xattr_datum()
174 xd->flags |= JFFS2_XFLAGS_INVALID; in do_verify_xattr_datum()
177 xd->xprefix = rx.xprefix; in do_verify_xattr_datum()
178 xd->name_len = rx.name_len; in do_verify_xattr_datum()
179 xd->value_len = je16_to_cpu(rx.value_len); in do_verify_xattr_datum()
180 xd->data_crc = je32_to_cpu(rx.data_crc); in do_verify_xattr_datum()
182 spin_lock(&c->erase_completion_lock); in do_verify_xattr_datum()
184 for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) { in do_verify_xattr_datum()
185 jeb = &c->blocks[ref_offset(raw) / c->sector_size]; in do_verify_xattr_datum()
186 totlen = PAD(ref_totlen(c, jeb, raw)); in do_verify_xattr_datum()
188 c->unchecked_size -= totlen; c->used_size += totlen; in do_verify_xattr_datum()
189 jeb->unchecked_size -= totlen; jeb->used_size += totlen; in do_verify_xattr_datum()
191 raw->flash_offset = ref_offset(raw) | ((xd->node==raw) ? REF_PRISTINE : REF_NORMAL); in do_verify_xattr_datum()
193 spin_unlock(&c->erase_completion_lock); in do_verify_xattr_datum()
195 /* unchecked xdatum is chained with c->xattr_unchecked */ in do_verify_xattr_datum()
196 list_del_init(&xd->xindex); in do_verify_xattr_datum()
199 xd->xid, xd->version); in do_verify_xattr_datum()
212 BUG_ON(ref_flags(xd->node) != REF_PRISTINE); in do_load_xattr_datum()
213 BUG_ON(!list_empty(&xd->xindex)); in do_load_xattr_datum()
215 length = xd->name_len + 1 + xd->value_len; in do_load_xattr_datum()
218 return -ENOMEM; in do_load_xattr_datum()
220 ret = jffs2_flash_read(c, ref_offset(xd->node)+sizeof(struct jffs2_raw_xattr), in do_load_xattr_datum()
225 ret, length, readlen, ref_offset(xd->node)); in do_load_xattr_datum()
227 return ret ? ret : -EIO; in do_load_xattr_datum()
230 data[xd->name_len] = '\0'; in do_load_xattr_datum()
232 if (crc != xd->data_crc) { in do_load_xattr_datum()
235 ref_offset(xd->node), xd->data_crc, crc); in do_load_xattr_datum()
237 xd->flags |= JFFS2_XFLAGS_INVALID; in do_load_xattr_datum()
241 xd->flags |= JFFS2_XFLAGS_HOT; in do_load_xattr_datum()
242 xd->xname = data; in do_load_xattr_datum()
243 xd->xvalue = data + xd->name_len+1; in do_load_xattr_datum()
245 c->xdatum_mem_usage += length; in do_load_xattr_datum()
247 xd->hashkey = xattr_datum_hashkey(xd->xprefix, xd->xname, xd->xvalue, xd->value_len); in do_load_xattr_datum()
248 i = xd->hashkey % XATTRINDEX_HASHSIZE; in do_load_xattr_datum()
249 list_add(&xd->xindex, &c->xattrindex[i]); in do_load_xattr_datum()
253 if (!xd->xname) in do_load_xattr_datum()
258 xd->xid, xd->xprefix, xd->xname); in do_load_xattr_datum()
272 BUG_ON(xd->flags & JFFS2_XFLAGS_DEAD); in load_xattr_datum()
273 if (xd->xname) in load_xattr_datum()
275 if (xd->flags & JFFS2_XFLAGS_INVALID) in load_xattr_datum()
293 BUG_ON(!xd->xname); in save_xattr_datum()
294 BUG_ON(xd->flags & (JFFS2_XFLAGS_DEAD|JFFS2_XFLAGS_INVALID)); in save_xattr_datum()
298 vecs[1].iov_base = xd->xname; in save_xattr_datum()
299 vecs[1].iov_len = xd->name_len + 1 + xd->value_len; in save_xattr_datum()
302 /* Setup raw-xattr */ in save_xattr_datum()
306 rx.totlen = cpu_to_je32(PAD(totlen)); in save_xattr_datum()
307 rx.hdr_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_unknown_node) - 4)); in save_xattr_datum()
309 rx.xid = cpu_to_je32(xd->xid); in save_xattr_datum()
310 rx.version = cpu_to_je32(++xd->version); in save_xattr_datum()
311 rx.xprefix = xd->xprefix; in save_xattr_datum()
312 rx.name_len = xd->name_len; in save_xattr_datum()
313 rx.value_len = cpu_to_je16(xd->value_len); in save_xattr_datum()
315 rx.node_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_raw_xattr) - 4)); in save_xattr_datum()
321 rc = rc ? rc : -EIO; in save_xattr_datum()
323 jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, PAD(totlen), NULL); in save_xattr_datum()
328 jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(totlen), (void *)xd); in save_xattr_datum()
331 xd->xid, xd->version, xd->xprefix, xd->xname); in save_xattr_datum()
349 list_for_each_entry(xd, &c->xattrindex[i], xindex) { in create_xattr_datum()
350 if (xd->hashkey==hashkey in create_xattr_datum()
351 && xd->xprefix==xprefix in create_xattr_datum()
352 && xd->value_len==xsize in create_xattr_datum()
353 && !strcmp(xd->xname, xname) in create_xattr_datum()
354 && !memcmp(xd->xvalue, xvalue, xsize)) { in create_xattr_datum()
355 atomic_inc(&xd->refcnt); in create_xattr_datum()
360 /* Not found, Create NEW XATTR-Cache */ in create_xattr_datum()
365 return ERR_PTR(-ENOMEM); in create_xattr_datum()
370 return ERR_PTR(-ENOMEM); in create_xattr_datum()
375 atomic_set(&xd->refcnt, 1); in create_xattr_datum()
376 xd->xid = ++c->highest_xid; in create_xattr_datum()
377 xd->flags |= JFFS2_XFLAGS_HOT; in create_xattr_datum()
378 xd->xprefix = xprefix; in create_xattr_datum()
380 xd->hashkey = hashkey; in create_xattr_datum()
381 xd->xname = data; in create_xattr_datum()
382 xd->xvalue = data + name_len + 1; in create_xattr_datum()
383 xd->name_len = name_len; in create_xattr_datum()
384 xd->value_len = xsize; in create_xattr_datum()
385 xd->data_crc = crc32(0, data, xd->name_len + 1 + xd->value_len); in create_xattr_datum()
389 kfree(xd->xname); in create_xattr_datum()
396 list_add(&xd->xindex, &c->xattrindex[i]); in create_xattr_datum()
398 c->xdatum_mem_usage += (xd->name_len + 1 + xd->value_len); in create_xattr_datum()
407 if (atomic_dec_and_lock(&xd->refcnt, &c->erase_completion_lock)) { in unrefer_xattr_datum()
409 xd->flags |= JFFS2_XFLAGS_DEAD; in unrefer_xattr_datum()
410 if (xd->node == (void *)xd) { in unrefer_xattr_datum()
411 BUG_ON(!(xd->flags & JFFS2_XFLAGS_INVALID)); in unrefer_xattr_datum()
414 list_add(&xd->xindex, &c->xattr_dead_list); in unrefer_xattr_datum()
416 spin_unlock(&c->erase_completion_lock); in unrefer_xattr_datum()
419 xd->xid, xd->version); in unrefer_xattr_datum()
423 /* -------- xref related functions ------------------
424 * verify_xattr_ref(c, ref)
427 * save_xattr_ref(c, ref)
432 * delete_xattr_ref(c, ref)
443 * -------------------------------------------------- */
444 static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) in verify_xattr_ref() argument
453 spin_lock(&c->erase_completion_lock); in verify_xattr_ref()
454 if (ref_flags(ref->node) != REF_UNCHECKED) in verify_xattr_ref()
456 offset = ref_offset(ref->node); in verify_xattr_ref()
457 spin_unlock(&c->erase_completion_lock); in verify_xattr_ref()
463 return rc ? rc : -EIO; in verify_xattr_ref()
466 crc = crc32(0, &rr, sizeof(rr) - 4); in verify_xattr_ref()
474 || je32_to_cpu(rr.totlen) != PAD(sizeof(rr))) { in verify_xattr_ref()
479 je32_to_cpu(rr.totlen), PAD(sizeof(rr))); in verify_xattr_ref()
482 ref->ino = je32_to_cpu(rr.ino); in verify_xattr_ref()
483 ref->xid = je32_to_cpu(rr.xid); in verify_xattr_ref()
484 ref->xseqno = je32_to_cpu(rr.xseqno); in verify_xattr_ref()
485 if (ref->xseqno > c->highest_xseqno) in verify_xattr_ref()
486 c->highest_xseqno = (ref->xseqno & ~XREF_DELETE_MARKER); in verify_xattr_ref()
488 spin_lock(&c->erase_completion_lock); in verify_xattr_ref()
490 for (raw=ref->node; raw != (void *)ref; raw=raw->next_in_ino) { in verify_xattr_ref()
491 jeb = &c->blocks[ref_offset(raw) / c->sector_size]; in verify_xattr_ref()
492 totlen = PAD(ref_totlen(c, jeb, raw)); in verify_xattr_ref()
494 c->unchecked_size -= totlen; c->used_size += totlen; in verify_xattr_ref()
495 jeb->unchecked_size -= totlen; jeb->used_size += totlen; in verify_xattr_ref()
497 raw->flash_offset = ref_offset(raw) | ((ref->node==raw) ? REF_PRISTINE : REF_NORMAL); in verify_xattr_ref()
499 spin_unlock(&c->erase_completion_lock); in verify_xattr_ref()
502 ref->ino, ref->xid, ref_offset(ref->node)); in verify_xattr_ref()
506 static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) in save_xattr_ref() argument
516 rr.totlen = cpu_to_je32(PAD(sizeof(rr))); in save_xattr_ref()
517 rr.hdr_crc = cpu_to_je32(crc32(0, &rr, sizeof(struct jffs2_unknown_node) - 4)); in save_xattr_ref()
519 xseqno = (c->highest_xseqno += 2); in save_xattr_ref()
520 if (is_xattr_ref_dead(ref)) { in save_xattr_ref()
522 rr.ino = cpu_to_je32(ref->ino); in save_xattr_ref()
523 rr.xid = cpu_to_je32(ref->xid); in save_xattr_ref()
525 rr.ino = cpu_to_je32(ref->ic->ino); in save_xattr_ref()
526 rr.xid = cpu_to_je32(ref->xd->xid); in save_xattr_ref()
529 rr.node_crc = cpu_to_je32(crc32(0, &rr, sizeof(rr) - 4)); in save_xattr_ref()
535 ret = ret ? ret : -EIO; in save_xattr_ref()
537 jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, PAD(sizeof(rr)), NULL); in save_xattr_ref()
542 ref->xseqno = xseqno; in save_xattr_ref()
543 jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(sizeof(rr)), (void *)ref); in save_xattr_ref()
545 dbg_xattr("success on saving xref (ino=%u, xid=%u)\n", ref->ic->ino, ref->xd->xid); in save_xattr_ref()
554 struct jffs2_xattr_ref *ref; in create_xattr_ref() local
557 ref = jffs2_alloc_xattr_ref(); in create_xattr_ref()
558 if (!ref) in create_xattr_ref()
559 return ERR_PTR(-ENOMEM); in create_xattr_ref()
560 ref->ic = ic; in create_xattr_ref()
561 ref->xd = xd; in create_xattr_ref()
563 ret = save_xattr_ref(c, ref); in create_xattr_ref()
565 jffs2_free_xattr_ref(ref); in create_xattr_ref()
570 ref->next = ic->xref; in create_xattr_ref()
571 ic->xref = ref; in create_xattr_ref()
573 return ref; /* success */ in create_xattr_ref()
576 static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) in delete_xattr_ref() argument
581 xd = ref->xd; in delete_xattr_ref()
582 ref->xseqno |= XREF_DELETE_MARKER; in delete_xattr_ref()
583 ref->ino = ref->ic->ino; in delete_xattr_ref()
584 ref->xid = ref->xd->xid; in delete_xattr_ref()
585 spin_lock(&c->erase_completion_lock); in delete_xattr_ref()
586 ref->next = c->xref_dead_list; in delete_xattr_ref()
587 c->xref_dead_list = ref; in delete_xattr_ref()
588 spin_unlock(&c->erase_completion_lock); in delete_xattr_ref()
591 ref->ino, ref->xid, ref->xseqno); in delete_xattr_ref()
600 struct jffs2_xattr_ref *ref, *_ref; in jffs2_xattr_delete_inode() local
602 if (!ic || ic->pino_nlink > 0) in jffs2_xattr_delete_inode()
605 down_write(&c->xattr_sem); in jffs2_xattr_delete_inode()
606 for (ref = ic->xref; ref; ref = _ref) { in jffs2_xattr_delete_inode()
607 _ref = ref->next; in jffs2_xattr_delete_inode()
608 delete_xattr_ref(c, ref); in jffs2_xattr_delete_inode()
610 ic->xref = NULL; in jffs2_xattr_delete_inode()
611 up_write(&c->xattr_sem); in jffs2_xattr_delete_inode()
618 struct jffs2_xattr_ref *ref, *_ref; in jffs2_xattr_free_inode() local
620 down_write(&c->xattr_sem); in jffs2_xattr_free_inode()
621 for (ref = ic->xref; ref; ref = _ref) { in jffs2_xattr_free_inode()
622 _ref = ref->next; in jffs2_xattr_free_inode()
623 xd = ref->xd; in jffs2_xattr_free_inode()
624 if (atomic_dec_and_test(&xd->refcnt)) { in jffs2_xattr_free_inode()
628 jffs2_free_xattr_ref(ref); in jffs2_xattr_free_inode()
630 ic->xref = NULL; in jffs2_xattr_free_inode()
631 up_write(&c->xattr_sem); in jffs2_xattr_free_inode()
640 struct jffs2_xattr_ref *ref, *cmp, **pref, **pcmp; in check_xattr_ref_inode() local
643 if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED)) in check_xattr_ref_inode()
645 down_write(&c->xattr_sem); in check_xattr_ref_inode()
648 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) { in check_xattr_ref_inode()
649 if (!ref->xd->xname) { in check_xattr_ref_inode()
650 rc = load_xattr_datum(c, ref->xd); in check_xattr_ref_inode()
652 *pref = ref->next; in check_xattr_ref_inode()
653 delete_xattr_ref(c, ref); in check_xattr_ref_inode()
658 for (cmp=ref->next, pcmp=&ref->next; cmp; pcmp=&cmp->next, cmp=cmp->next) { in check_xattr_ref_inode()
659 if (!cmp->xd->xname) { in check_xattr_ref_inode()
660 ref->xd->flags |= JFFS2_XFLAGS_BIND; in check_xattr_ref_inode()
661 rc = load_xattr_datum(c, cmp->xd); in check_xattr_ref_inode()
662 ref->xd->flags &= ~JFFS2_XFLAGS_BIND; in check_xattr_ref_inode()
664 *pcmp = cmp->next; in check_xattr_ref_inode()
670 if (ref->xd->xprefix == cmp->xd->xprefix in check_xattr_ref_inode()
671 && !strcmp(ref->xd->xname, cmp->xd->xname)) { in check_xattr_ref_inode()
672 if (ref->xseqno > cmp->xseqno) { in check_xattr_ref_inode()
673 *pcmp = cmp->next; in check_xattr_ref_inode()
676 *pref = ref->next; in check_xattr_ref_inode()
677 delete_xattr_ref(c, ref); in check_xattr_ref_inode()
683 ic->flags |= INO_FLAGS_XATTR_CHECKED; in check_xattr_ref_inode()
685 up_write(&c->xattr_sem); in check_xattr_ref_inode()
695 /* -------- xattr subsystem functions ---------------
706 * -------------------------------------------------- */
712 INIT_LIST_HEAD(&c->xattrindex[i]); in jffs2_init_xattr_subsystem()
713 INIT_LIST_HEAD(&c->xattr_unchecked); in jffs2_init_xattr_subsystem()
714 INIT_LIST_HEAD(&c->xattr_dead_list); in jffs2_init_xattr_subsystem()
715 c->xref_dead_list = NULL; in jffs2_init_xattr_subsystem()
716 c->xref_temp = NULL; in jffs2_init_xattr_subsystem()
718 init_rwsem(&c->xattr_sem); in jffs2_init_xattr_subsystem()
719 c->highest_xid = 0; in jffs2_init_xattr_subsystem()
720 c->highest_xseqno = 0; in jffs2_init_xattr_subsystem()
721 c->xdatum_mem_usage = 0; in jffs2_init_xattr_subsystem()
722 c->xdatum_mem_threshold = 32 * 1024; /* Default 32KB */ in jffs2_init_xattr_subsystem()
731 BUG_ON(!(c->flags & (JFFS2_SB_FLAG_SCANNING|JFFS2_SB_FLAG_BUILDING))); in jffs2_find_xattr_datum()
733 list_for_each_entry(xd, &c->xattrindex[i], xindex) { in jffs2_find_xattr_datum()
734 if (xd->xid==xid) in jffs2_find_xattr_datum()
743 struct jffs2_xattr_ref *ref, *_ref; in jffs2_clear_xattr_subsystem() local
746 for (ref=c->xref_temp; ref; ref = _ref) { in jffs2_clear_xattr_subsystem()
747 _ref = ref->next; in jffs2_clear_xattr_subsystem()
748 jffs2_free_xattr_ref(ref); in jffs2_clear_xattr_subsystem()
751 for (ref=c->xref_dead_list; ref; ref = _ref) { in jffs2_clear_xattr_subsystem()
752 _ref = ref->next; in jffs2_clear_xattr_subsystem()
753 jffs2_free_xattr_ref(ref); in jffs2_clear_xattr_subsystem()
757 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) { in jffs2_clear_xattr_subsystem()
758 list_del(&xd->xindex); in jffs2_clear_xattr_subsystem()
759 kfree(xd->xname); in jffs2_clear_xattr_subsystem()
764 list_for_each_entry_safe(xd, _xd, &c->xattr_dead_list, xindex) { in jffs2_clear_xattr_subsystem()
765 list_del(&xd->xindex); in jffs2_clear_xattr_subsystem()
768 list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) { in jffs2_clear_xattr_subsystem()
769 list_del(&xd->xindex); in jffs2_clear_xattr_subsystem()
777 struct jffs2_xattr_ref *ref, *_ref; in jffs2_build_xattr_subsystem() local
785 BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING)); in jffs2_build_xattr_subsystem()
790 return -ENOMEM; in jffs2_build_xattr_subsystem()
793 for (ref=c->xref_temp; ref; ref=_ref) { in jffs2_build_xattr_subsystem()
796 _ref = ref->next; in jffs2_build_xattr_subsystem()
797 if (ref_flags(ref->node) != REF_PRISTINE) { in jffs2_build_xattr_subsystem()
798 if (verify_xattr_ref(c, ref)) { in jffs2_build_xattr_subsystem()
799 BUG_ON(ref->node->next_in_ino != (void *)ref); in jffs2_build_xattr_subsystem()
800 ref->node->next_in_ino = NULL; in jffs2_build_xattr_subsystem()
801 jffs2_mark_node_obsolete(c, ref->node); in jffs2_build_xattr_subsystem()
802 jffs2_free_xattr_ref(ref); in jffs2_build_xattr_subsystem()
807 i = (ref->ino ^ ref->xid) % XREF_TMPHASH_SIZE; in jffs2_build_xattr_subsystem()
808 for (tmp=xref_tmphash[i]; tmp; tmp=tmp->next) { in jffs2_build_xattr_subsystem()
809 if (tmp->ino == ref->ino && tmp->xid == ref->xid) in jffs2_build_xattr_subsystem()
813 raw = ref->node; in jffs2_build_xattr_subsystem()
814 if (ref->xseqno > tmp->xseqno) { in jffs2_build_xattr_subsystem()
815 tmp->xseqno = ref->xseqno; in jffs2_build_xattr_subsystem()
816 raw->next_in_ino = tmp->node; in jffs2_build_xattr_subsystem()
817 tmp->node = raw; in jffs2_build_xattr_subsystem()
819 raw->next_in_ino = tmp->node->next_in_ino; in jffs2_build_xattr_subsystem()
820 tmp->node->next_in_ino = raw; in jffs2_build_xattr_subsystem()
822 jffs2_free_xattr_ref(ref); in jffs2_build_xattr_subsystem()
825 ref->next = xref_tmphash[i]; in jffs2_build_xattr_subsystem()
826 xref_tmphash[i] = ref; in jffs2_build_xattr_subsystem()
829 c->xref_temp = NULL; in jffs2_build_xattr_subsystem()
833 for (ref=xref_tmphash[i]; ref; ref=_ref) { in jffs2_build_xattr_subsystem()
835 _ref = ref->next; in jffs2_build_xattr_subsystem()
836 if (is_xattr_ref_dead(ref)) { in jffs2_build_xattr_subsystem()
837 ref->next = c->xref_dead_list; in jffs2_build_xattr_subsystem()
838 c->xref_dead_list = ref; in jffs2_build_xattr_subsystem()
842 /* At this point, ref->xid and ref->ino contain XID and inode number. in jffs2_build_xattr_subsystem()
843 ref->xd and ref->ic are not valid yet. */ in jffs2_build_xattr_subsystem()
844 xd = jffs2_find_xattr_datum(c, ref->xid); in jffs2_build_xattr_subsystem()
845 ic = jffs2_get_ino_cache(c, ref->ino); in jffs2_build_xattr_subsystem()
846 if (!xd || !ic || !ic->pino_nlink) { in jffs2_build_xattr_subsystem()
848 ref->ino, ref->xid, ref->xseqno); in jffs2_build_xattr_subsystem()
849 ref->xseqno |= XREF_DELETE_MARKER; in jffs2_build_xattr_subsystem()
850 ref->next = c->xref_dead_list; in jffs2_build_xattr_subsystem()
851 c->xref_dead_list = ref; in jffs2_build_xattr_subsystem()
855 ref->xd = xd; in jffs2_build_xattr_subsystem()
856 ref->ic = ic; in jffs2_build_xattr_subsystem()
857 atomic_inc(&xd->refcnt); in jffs2_build_xattr_subsystem()
858 ref->next = ic->xref; in jffs2_build_xattr_subsystem()
859 ic->xref = ref; in jffs2_build_xattr_subsystem()
865 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) { in jffs2_build_xattr_subsystem()
867 list_del_init(&xd->xindex); in jffs2_build_xattr_subsystem()
868 if (!atomic_read(&xd->refcnt)) { in jffs2_build_xattr_subsystem()
870 xd->xid, xd->version); in jffs2_build_xattr_subsystem()
871 xd->flags |= JFFS2_XFLAGS_DEAD; in jffs2_build_xattr_subsystem()
872 list_add(&xd->xindex, &c->xattr_unchecked); in jffs2_build_xattr_subsystem()
878 xd->xid, xd->version); in jffs2_build_xattr_subsystem()
879 list_add(&xd->xindex, &c->xattr_unchecked); in jffs2_build_xattr_subsystem()
903 return ERR_PTR(-ENOMEM); in jffs2_setup_xattr_datum()
904 xd->xid = xid; in jffs2_setup_xattr_datum()
905 xd->version = version; in jffs2_setup_xattr_datum()
906 if (xd->xid > c->highest_xid) in jffs2_setup_xattr_datum()
907 c->highest_xid = xd->xid; in jffs2_setup_xattr_datum()
908 list_add_tail(&xd->xindex, &c->xattrindex[xid % XATTRINDEX_HASHSIZE]); in jffs2_setup_xattr_datum()
913 /* -------- xattr subsystem functions ---------------
922 * -------------------------------------------------- */
970 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); in jffs2_listxattr()
971 struct jffs2_inode_cache *ic = f->inocache; in jffs2_listxattr()
972 struct jffs2_xattr_ref *ref, **pref; in jffs2_listxattr() local
982 down_read(&c->xattr_sem); in jffs2_listxattr()
985 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) { in jffs2_listxattr()
986 BUG_ON(ref->ic != ic); in jffs2_listxattr()
987 xd = ref->xd; in jffs2_listxattr()
988 if (!xd->xname) { in jffs2_listxattr()
992 up_read(&c->xattr_sem); in jffs2_listxattr()
993 down_write(&c->xattr_sem); in jffs2_listxattr()
998 *pref = ref->next; in jffs2_listxattr()
999 delete_xattr_ref(c, ref); in jffs2_listxattr()
1006 prefix = jffs2_xattr_prefix(xd->xprefix, dentry); in jffs2_listxattr()
1010 rc = prefix_len + xd->name_len + 1; in jffs2_listxattr()
1013 if (rc > size - len) { in jffs2_listxattr()
1014 rc = -ERANGE; in jffs2_listxattr()
1019 memcpy(buffer, xd->xname, xd->name_len); in jffs2_listxattr()
1020 buffer += xd->name_len; in jffs2_listxattr()
1028 up_read(&c->xattr_sem); in jffs2_listxattr()
1030 up_write(&c->xattr_sem); in jffs2_listxattr()
1039 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); in do_jffs2_getxattr()
1040 struct jffs2_inode_cache *ic = f->inocache; in do_jffs2_getxattr()
1042 struct jffs2_xattr_ref *ref, **pref; in do_jffs2_getxattr() local
1049 down_read(&c->xattr_sem); in do_jffs2_getxattr()
1051 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) { in do_jffs2_getxattr()
1052 BUG_ON(ref->ic!=ic); in do_jffs2_getxattr()
1054 xd = ref->xd; in do_jffs2_getxattr()
1055 if (xd->xprefix != xprefix) in do_jffs2_getxattr()
1057 if (!xd->xname) { in do_jffs2_getxattr()
1061 up_read(&c->xattr_sem); in do_jffs2_getxattr()
1062 down_write(&c->xattr_sem); in do_jffs2_getxattr()
1067 *pref = ref->next; in do_jffs2_getxattr()
1068 delete_xattr_ref(c, ref); in do_jffs2_getxattr()
1075 if (!strcmp(xname, xd->xname)) { in do_jffs2_getxattr()
1076 rc = xd->value_len; in do_jffs2_getxattr()
1079 rc = -ERANGE; in do_jffs2_getxattr()
1081 memcpy(buffer, xd->xvalue, rc); in do_jffs2_getxattr()
1087 rc = -ENODATA; in do_jffs2_getxattr()
1090 up_read(&c->xattr_sem); in do_jffs2_getxattr()
1092 up_write(&c->xattr_sem); in do_jffs2_getxattr()
1101 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); in do_jffs2_setxattr()
1102 struct jffs2_inode_cache *ic = f->inocache; in do_jffs2_setxattr()
1104 struct jffs2_xattr_ref *ref, *newref, **pref; in do_jffs2_setxattr() local
1112 request = PAD(sizeof(struct jffs2_raw_xattr) + strlen(xname) + 1 + size); in do_jffs2_setxattr()
1113 if (request > c->sector_size - c->cleanmarker_size) in do_jffs2_setxattr()
1114 return -ERANGE; in do_jffs2_setxattr()
1124 down_write(&c->xattr_sem); in do_jffs2_setxattr()
1126 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) { in do_jffs2_setxattr()
1127 xd = ref->xd; in do_jffs2_setxattr()
1128 if (xd->xprefix != xprefix) in do_jffs2_setxattr()
1130 if (!xd->xname) { in do_jffs2_setxattr()
1133 *pref = ref->next; in do_jffs2_setxattr()
1134 delete_xattr_ref(c, ref); in do_jffs2_setxattr()
1139 if (!strcmp(xd->xname, xname)) { in do_jffs2_setxattr()
1141 rc = -EEXIST; in do_jffs2_setxattr()
1145 ref->ino = ic->ino; in do_jffs2_setxattr()
1146 ref->xid = xd->xid; in do_jffs2_setxattr()
1147 ref->xseqno |= XREF_DELETE_MARKER; in do_jffs2_setxattr()
1148 rc = save_xattr_ref(c, ref); in do_jffs2_setxattr()
1150 *pref = ref->next; in do_jffs2_setxattr()
1151 spin_lock(&c->erase_completion_lock); in do_jffs2_setxattr()
1152 ref->next = c->xref_dead_list; in do_jffs2_setxattr()
1153 c->xref_dead_list = ref; in do_jffs2_setxattr()
1154 spin_unlock(&c->erase_completion_lock); in do_jffs2_setxattr()
1157 ref->ic = ic; in do_jffs2_setxattr()
1158 ref->xd = xd; in do_jffs2_setxattr()
1159 ref->xseqno &= ~XREF_DELETE_MARKER; in do_jffs2_setxattr()
1168 rc = -ENODATA; in do_jffs2_setxattr()
1172 rc = -ENODATA; in do_jffs2_setxattr()
1181 up_write(&c->xattr_sem); in do_jffs2_setxattr()
1185 request = PAD(sizeof(struct jffs2_raw_xref)); in do_jffs2_setxattr()
1188 down_write(&c->xattr_sem); in do_jffs2_setxattr()
1192 up_write(&c->xattr_sem); in do_jffs2_setxattr()
1195 if (ref) in do_jffs2_setxattr()
1196 *pref = ref->next; in do_jffs2_setxattr()
1199 if (ref) { in do_jffs2_setxattr()
1200 ref->next = ic->xref; in do_jffs2_setxattr()
1201 ic->xref = ref; in do_jffs2_setxattr()
1205 } else if (ref) { in do_jffs2_setxattr()
1206 delete_xattr_ref(c, ref); in do_jffs2_setxattr()
1209 up_write(&c->xattr_sem); in do_jffs2_setxattr()
1214 /* -------- garbage collector functions -------------
1217 * jffs2_garbage_collect_xattr_ref(c, ref, raw)
1222 * is used to release an in-memory object of xdatum.
1223 * jffs2_release_xattr_ref(c, ref)
1224 * is used to release an in-memory object of xref.
1225 * -------------------------------------------------- */
1232 down_write(&c->xattr_sem); in jffs2_garbage_collect_xattr_datum()
1233 if (xd->node != raw) in jffs2_garbage_collect_xattr_datum()
1235 if (xd->flags & (JFFS2_XFLAGS_DEAD|JFFS2_XFLAGS_INVALID)) in jffs2_garbage_collect_xattr_datum()
1243 old_ofs = ref_offset(xd->node); in jffs2_garbage_collect_xattr_datum()
1244 totlen = PAD(sizeof(struct jffs2_raw_xattr) in jffs2_garbage_collect_xattr_datum()
1245 + xd->name_len + 1 + xd->value_len); in jffs2_garbage_collect_xattr_datum()
1254 xd->xid, xd->version, old_ofs, ref_offset(xd->node)); in jffs2_garbage_collect_xattr_datum()
1258 up_write(&c->xattr_sem); in jffs2_garbage_collect_xattr_datum()
1262 int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref, in jffs2_garbage_collect_xattr_ref() argument
1268 down_write(&c->xattr_sem); in jffs2_garbage_collect_xattr_ref()
1269 BUG_ON(!ref->node); in jffs2_garbage_collect_xattr_ref()
1271 if (ref->node != raw) in jffs2_garbage_collect_xattr_ref()
1273 if (is_xattr_ref_dead(ref) && (raw->next_in_ino == (void *)ref)) in jffs2_garbage_collect_xattr_ref()
1276 old_ofs = ref_offset(ref->node); in jffs2_garbage_collect_xattr_ref()
1277 totlen = ref_totlen(c, c->gcblock, ref->node); in jffs2_garbage_collect_xattr_ref()
1285 rc = save_xattr_ref(c, ref); in jffs2_garbage_collect_xattr_ref()
1288 ref->ic->ino, ref->xd->xid, old_ofs, ref_offset(ref->node)); in jffs2_garbage_collect_xattr_ref()
1292 up_write(&c->xattr_sem); in jffs2_garbage_collect_xattr_ref()
1304 down_write(&c->xattr_sem); in jffs2_verify_xattr()
1305 list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) { in jffs2_verify_xattr()
1309 list_del_init(&xd->xindex); in jffs2_verify_xattr()
1310 spin_lock(&c->erase_completion_lock); in jffs2_verify_xattr()
1311 for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) { in jffs2_verify_xattr()
1314 jeb = &c->blocks[ref_offset(raw) / c->sector_size]; in jffs2_verify_xattr()
1315 totlen = PAD(ref_totlen(c, jeb, raw)); in jffs2_verify_xattr()
1316 c->unchecked_size -= totlen; c->used_size += totlen; in jffs2_verify_xattr()
1317 jeb->unchecked_size -= totlen; jeb->used_size += totlen; in jffs2_verify_xattr()
1318 raw->flash_offset = ref_offset(raw) in jffs2_verify_xattr()
1319 | ((xd->node == (void *)raw) ? REF_PRISTINE : REF_NORMAL); in jffs2_verify_xattr()
1321 if (xd->flags & JFFS2_XFLAGS_DEAD) in jffs2_verify_xattr()
1322 list_add(&xd->xindex, &c->xattr_dead_list); in jffs2_verify_xattr()
1323 spin_unlock(&c->erase_completion_lock); in jffs2_verify_xattr()
1325 up_write(&c->xattr_sem); in jffs2_verify_xattr()
1326 return list_empty(&c->xattr_unchecked) ? 1 : 0; in jffs2_verify_xattr()
1331 /* must be called under spin_lock(&c->erase_completion_lock) */ in jffs2_release_xattr_datum()
1332 if (atomic_read(&xd->refcnt) || xd->node != (void *)xd) in jffs2_release_xattr_datum()
1335 list_del(&xd->xindex); in jffs2_release_xattr_datum()
1339 void jffs2_release_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) in jffs2_release_xattr_ref() argument
1341 /* must be called under spin_lock(&c->erase_completion_lock) */ in jffs2_release_xattr_ref()
1344 if (ref->node != (void *)ref) in jffs2_release_xattr_ref()
1347 for (tmp=c->xref_dead_list, ptmp=&c->xref_dead_list; tmp; ptmp=&tmp->next, tmp=tmp->next) { in jffs2_release_xattr_ref()
1348 if (ref == tmp) { in jffs2_release_xattr_ref()
1349 *ptmp = tmp->next; in jffs2_release_xattr_ref()
1353 jffs2_free_xattr_ref(ref); in jffs2_release_xattr_ref()