12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 #define JFFS2_XATTR_IS_CORRUPTED 1
16 #include <linux/kernel.h>
17 #include <linux/slab.h>
19 #include <linux/time.h>
24 #include <linux/xattr.h>
63 static uint32_t xattr_datum_hashkey(
int xprefix,
const char *xname,
const char *xvalue,
int xsize)
67 return crc32(xprefix, xname, name_len) ^
crc32(xprefix, xvalue, xsize);
95 list_del_init(&xd->
xindex);
106 static int index = 0;
109 if (c->xdatum_mem_threshold > c->xdatum_mem_usage)
112 before = c->xdatum_mem_usage;
113 target = c->xdatum_mem_usage * 4 / 5;
114 for (count = 0; count < XATTRINDEX_HASHSIZE; count++) {
119 unload_xattr_datum(c, xd);
121 if (c->xdatum_mem_usage <= target)
124 index = (index+1) % XATTRINDEX_HASHSIZE;
127 JFFS2_NOTICE(
"xdatum_mem_usage from %u byte to %u byte (%u byte reclaimed)\n",
128 before, c->xdatum_mem_usage, before - c->xdatum_mem_usage);
148 if (rc || readlen !=
sizeof(
rx)) {
149 JFFS2_WARNING(
"jffs2_flash_read()=%d, req=%zu, read=%zu at %#08x\n",
150 rc,
sizeof(
rx), readlen, offset);
151 return rc ? rc : -
EIO;
155 JFFS2_ERROR(
"node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
166 JFFS2_ERROR(
"inconsistent xdatum at %#08x, magic=%#04x/%#04x, "
167 "nodetype=%#04x/%#04x, totlen=%u/%u, xid=%u/%u, version=%u/%u\n",
195 list_del_init(&xd->
xindex);
197 dbg_xattr(
"success on verfying xdatum (xid=%u, version=%u)\n",
220 length, &readlen, data);
222 if (ret || length!=readlen) {
223 JFFS2_WARNING(
"jffs2_flash_read() returned %d, request=%d, readlen=%zu, at %#08x\n",
226 return ret ? ret : -
EIO;
230 crc =
crc32(0, data, length);
233 " at %#08x, read: 0x%08x calculated: 0x%08x\n",
244 c->xdatum_mem_usage +=
length;
247 i = xd->
hashkey % XATTRINDEX_HASHSIZE;
248 list_add(&xd->
xindex, &c->xattrindex[i]);
251 reclaim_xattr_datum(c);
256 dbg_xattr(
"success on loading xdatum (xid=%u, xprefix=%u, xname='%s')\n",
276 if (
unlikely(is_xattr_datum_unchecked(c, xd)))
277 rc = do_verify_xattr_datum(c, xd);
279 rc = do_load_xattr_datum(c, xd);
295 vecs[0].iov_base = &
rx;
296 vecs[0].iov_len =
sizeof(
rx);
297 vecs[1].iov_base = xd->
xname;
299 totlen = vecs[0].iov_len + vecs[1].iov_len;
317 if (rc || totlen != length) {
318 JFFS2_WARNING(
"jffs2_flash_writev()=%d, req=%u, wrote=%zu, at %#08x\n",
319 rc, totlen, length, phys_ofs);
329 dbg_xattr(
"success on saving xdatum (xid=%u, version=%u, xprefix=%u, xname='%s')\n",
337 const char *
xvalue,
int xsize)
346 hashkey = xattr_datum_hashkey(xprefix, xname, xvalue, xsize);
347 i = hashkey % XATTRINDEX_HASHSIZE;
362 xd = jffs2_alloc_xattr_datum();
368 jffs2_free_xattr_datum(xd);
372 memcpy(data + name_len + 1, xvalue, xsize);
375 xd->
xid = ++c->highest_xid;
381 xd->
xvalue = data + name_len + 1;
386 rc = save_xattr_datum(c, xd);
389 jffs2_free_xattr_datum(xd);
394 i = hashkey % XATTRINDEX_HASHSIZE;
395 list_add(&xd->
xindex, &c->xattrindex[i]);
398 reclaim_xattr_datum(c);
407 unload_xattr_datum(c, xd);
409 if (xd->
node == (
void *)xd) {
411 jffs2_free_xattr_datum(xd);
413 list_add(&xd->
xindex, &c->xattr_dead_list);
417 dbg_xattr(
"xdatum(xid=%u, version=%u) was removed.\n",
459 if (rc ||
sizeof(rr) != readlen) {
460 JFFS2_WARNING(
"jffs2_flash_read()=%d, req=%zu, read=%zu, at %#08x\n",
461 rc,
sizeof(rr), readlen, offset);
462 return rc ? rc : -
EIO;
465 crc =
crc32(0, &rr,
sizeof(rr) - 4);
467 JFFS2_ERROR(
"node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
474 JFFS2_ERROR(
"inconsistent xref at %#08x, magic=%#04x/%#04x, "
475 "nodetype=%#04x/%#04x, totlen=%u/%zu\n",
484 if (ref->
xseqno > c->highest_xseqno)
500 dbg_xattr(
"success on verifying xref (ino=%u, xid=%u) at %#08x\n",
518 xseqno = (c->highest_xseqno += 2);
519 if (is_xattr_ref_dead(ref)) {
531 if (ret ||
sizeof(rr) != length) {
532 JFFS2_WARNING(
"jffs2_flash_write() returned %d, request=%zu, retlen=%zu, at %#08x\n",
533 ret,
sizeof(rr), length, phys_ofs);
534 ret = ret ? ret : -
EIO;
544 dbg_xattr(
"success on saving xref (ino=%u, xid=%u)\n", ref->
ic->ino, ref->
xd->xid);
556 ref = jffs2_alloc_xattr_ref();
562 ret = save_xattr_ref(c, ref);
564 jffs2_free_xattr_ref(ref);
569 ref->
next = ic->xref;
582 ref->
ino = ref->
ic->ino;
583 ref->
xid = ref->
xd->xid;
585 ref->
next = c->xref_dead_list;
586 c->xref_dead_list = ref;
589 dbg_xattr(
"xref(ino=%u, xid=%u, xseqno=%u) was removed.\n",
592 unrefer_xattr_datum(c, xd);
605 for (ref = ic->xref; ref; ref = _ref) {
607 delete_xattr_ref(c, ref);
620 for (ref = ic->xref; ref; ref = _ref) {
624 unload_xattr_datum(c, xd);
625 jffs2_free_xattr_datum(xd);
627 jffs2_free_xattr_ref(ref);
647 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->
next, ref=ref->
next) {
648 if (!ref->
xd->xname) {
649 rc = load_xattr_datum(c, ref->
xd);
652 delete_xattr_ref(c, ref);
658 if (!cmp->
xd->xname) {
660 rc = load_xattr_datum(c, cmp->
xd);
664 delete_xattr_ref(c, cmp);
669 if (ref->
xd->xprefix == cmp->
xd->xprefix
673 delete_xattr_ref(c, cmp);
676 delete_xattr_ref(c, ref);
691 check_xattr_ref_inode(c, ic);
710 for (i=0; i < XATTRINDEX_HASHSIZE; i++)
711 INIT_LIST_HEAD(&c->xattrindex[i]);
712 INIT_LIST_HEAD(&c->xattr_unchecked);
713 INIT_LIST_HEAD(&c->xattr_dead_list);
714 c->xref_dead_list =
NULL;
719 c->highest_xseqno = 0;
720 c->xdatum_mem_usage = 0;
721 c->xdatum_mem_threshold = 32 * 1024;
727 int i = xid % XATTRINDEX_HASHSIZE;
745 for (ref=c->xref_temp; ref; ref = _ref) {
747 jffs2_free_xattr_ref(ref);
750 for (ref=c->xref_dead_list; ref; ref = _ref) {
752 jffs2_free_xattr_ref(ref);
755 for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
760 jffs2_free_xattr_datum(xd);
766 jffs2_free_xattr_datum(xd);
770 jffs2_free_xattr_datum(xd);
774 #define XREF_TMPHASH_SIZE (128)
782 int i, xdatum_count = 0, xdatum_unchecked_count = 0, xref_count = 0;
783 int xdatum_orphan_count = 0, xref_orphan_count = 0, xref_dead_count = 0;
789 xref_tmphash[i] =
NULL;
790 for (ref=c->xref_temp; ref; ref=_ref) {
795 if (verify_xattr_ref(c, ref)) {
796 BUG_ON(ref->
node->next_in_ino != (
void *)ref);
799 jffs2_free_xattr_ref(ref);
804 i = (ref->
ino ^ ref->
xid) % XREF_TMPHASH_SIZE;
805 for (tmp=xref_tmphash[i];
tmp; tmp=tmp->
next) {
819 jffs2_free_xattr_ref(ref);
822 ref->
next = xref_tmphash[
i];
823 xref_tmphash[
i] = ref;
830 for (ref=xref_tmphash[i]; ref; ref=_ref) {
833 if (is_xattr_ref_dead(ref)) {
834 ref->
next = c->xref_dead_list;
835 c->xref_dead_list = ref;
841 xd = jffs2_find_xattr_datum(c, ref->
xid);
844 dbg_xattr(
"xref(ino=%u, xid=%u, xseqno=%u) is orphan.\n",
847 ref->
next = c->xref_dead_list;
848 c->xref_dead_list = ref;
855 ref->
next = ic->xref;
861 for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
864 list_del_init(&xd->
xindex);
866 dbg_xattr(
"xdatum(xid=%u, version=%u) is orphan.\n",
869 list_add(&xd->
xindex, &c->xattr_unchecked);
870 xdatum_orphan_count++;
873 if (is_xattr_datum_unchecked(c, xd)) {
874 dbg_xattr(
"unchecked xdatum(xid=%u, version=%u)\n",
876 list_add(&xd->
xindex, &c->xattr_unchecked);
877 xdatum_unchecked_count++;
882 JFFS2_NOTICE(
"complete building xattr subsystem, %u of xdatum"
883 " (%u unchecked, %u orphan) and "
884 "%u of xref (%u dead, %u orphan) found.\n",
885 xdatum_count, xdatum_unchecked_count, xdatum_orphan_count,
886 xref_count, xref_dead_count, xref_orphan_count);
894 xd = jffs2_find_xattr_datum(c, xid);
896 xd = jffs2_alloc_xattr_datum();
901 if (xd->
xid > c->highest_xid)
902 c->highest_xid = xd->
xid;
920 #ifdef CONFIG_JFFS2_FS_SECURITY
923 #ifdef CONFIG_JFFS2_FS_POSIX_ACL
931 static const struct xattr_handler *xprefix_to_handler(
int xprefix) {
938 #ifdef CONFIG_JFFS2_FS_SECURITY
943 #ifdef CONFIG_JFFS2_FS_POSIX_ACL
973 rc = check_xattr_ref_inode(c, ic);
980 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->
next, ref=ref->
next) {
991 rc = load_xattr_datum(c, xd);
994 delete_xattr_ref(c, ref);
1000 xhandle = xprefix_to_handler(xd->
xprefix);
1004 rc = xhandle->
list(dentry, buffer+len, size-len,
1034 rc = check_xattr_ref_inode(c, ic);
1040 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->
next, ref=ref->
next) {
1054 rc = load_xattr_datum(c, xd);
1057 delete_xattr_ref(c, ref);
1097 rc = check_xattr_ref_inode(c, ic);
1105 JFFS2_WARNING(
"jffs2_reserve_space()=%d, request=%u\n", rc, request);
1112 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->
next, ref=ref->
next) {
1117 rc = load_xattr_datum(c, xd);
1120 delete_xattr_ref(c, ref);
1134 rc = save_xattr_ref(c, ref);
1138 ref->
next = c->xref_dead_list;
1139 c->xref_dead_list = ref;
1141 unrefer_xattr_datum(c, xd);
1162 xd = create_xattr_datum(c, xprefix, xname, buffer, size);
1176 JFFS2_WARNING(
"jffs2_reserve_space()=%d, request=%u\n", rc, request);
1177 unrefer_xattr_datum(c, xd);
1183 newref = create_xattr_ref(c, ic, xd);
1184 if (IS_ERR(newref)) {
1186 ref->
next = ic->xref;
1189 rc = PTR_ERR(newref);
1190 unrefer_xattr_datum(c, xd);
1192 delete_xattr_ref(c, ref);
1219 if (xd->
node != raw)
1224 rc = load_xattr_datum(c, xd);
1226 rc = (rc > 0) ? 0 : rc;
1234 JFFS2_WARNING(
"jffs2_reserve_space_gc()=%d, request=%u\n", rc, totlen);
1237 rc = save_xattr_datum(c, xd);
1239 dbg_xattr(
"xdatum (xid=%u, version=%u) GC'ed from %#08x to %08x\n",
1257 if (ref->
node != raw)
1259 if (is_xattr_ref_dead(ref) && (raw->
next_in_ino == (
void *)ref))
1267 JFFS2_WARNING(
"%s: jffs2_reserve_space_gc() = %d, request = %u\n",
1268 __func__, rc, totlen);
1272 rc = save_xattr_ref(c, ref);
1274 dbg_xattr(
"xref (ino=%u, xid=%u) GC'ed from %#08x to %08x\n",
1293 rc = do_verify_xattr_datum(c, xd);
1296 list_del_init(&xd->
xindex);
1309 list_add(&xd->
xindex, &c->xattr_dead_list);
1313 return list_empty(&c->xattr_unchecked) ? 1 : 0;
1323 jffs2_free_xattr_datum(xd);
1331 if (ref->
node != (
void *)ref)
1334 for (tmp=c->xref_dead_list, ptmp=&c->xref_dead_list; tmp; ptmp=&tmp->
next, tmp=tmp->
next) {
1340 jffs2_free_xattr_ref(ref);