0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0013
0014 #define JFFS2_XATTR_IS_CORRUPTED 1
0015
0016 #include <linux/kernel.h>
0017 #include <linux/slab.h>
0018 #include <linux/fs.h>
0019 #include <linux/time.h>
0020 #include <linux/pagemap.h>
0021 #include <linux/highmem.h>
0022 #include <linux/crc32.h>
0023 #include <linux/jffs2.h>
0024 #include <linux/xattr.h>
0025 #include <linux/posix_acl_xattr.h>
0026 #include <linux/mtd/mtd.h>
0027 #include "nodelist.h"
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *xvalue, int xsize)
0065 {
0066 int name_len = strlen(xname);
0067
0068 return crc32(xprefix, xname, name_len) ^ crc32(xprefix, xvalue, xsize);
0069 }
0070
0071 static int is_xattr_datum_unchecked(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
0072 {
0073 struct jffs2_raw_node_ref *raw;
0074 int rc = 0;
0075
0076 spin_lock(&c->erase_completion_lock);
0077 for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
0078 if (ref_flags(raw) == REF_UNCHECKED) {
0079 rc = 1;
0080 break;
0081 }
0082 }
0083 spin_unlock(&c->erase_completion_lock);
0084 return rc;
0085 }
0086
0087 static void unload_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
0088 {
0089
0090 D1(dbg_xattr("%s: xid=%u, version=%u\n", __func__, xd->xid, xd->version));
0091 if (xd->xname) {
0092 c->xdatum_mem_usage -= (xd->name_len + 1 + xd->value_len);
0093 kfree(xd->xname);
0094 }
0095
0096 list_del_init(&xd->xindex);
0097 xd->hashkey = 0;
0098 xd->xname = NULL;
0099 xd->xvalue = NULL;
0100 }
0101
0102 static void reclaim_xattr_datum(struct jffs2_sb_info *c)
0103 {
0104
0105 struct jffs2_xattr_datum *xd, *_xd;
0106 uint32_t target, before;
0107 static int index = 0;
0108 int count;
0109
0110 if (c->xdatum_mem_threshold > c->xdatum_mem_usage)
0111 return;
0112
0113 before = c->xdatum_mem_usage;
0114 target = c->xdatum_mem_usage * 4 / 5;
0115 for (count = 0; count < XATTRINDEX_HASHSIZE; count++) {
0116 list_for_each_entry_safe(xd, _xd, &c->xattrindex[index], xindex) {
0117 if (xd->flags & JFFS2_XFLAGS_HOT) {
0118 xd->flags &= ~JFFS2_XFLAGS_HOT;
0119 } else if (!(xd->flags & JFFS2_XFLAGS_BIND)) {
0120 unload_xattr_datum(c, xd);
0121 }
0122 if (c->xdatum_mem_usage <= target)
0123 goto out;
0124 }
0125 index = (index+1) % XATTRINDEX_HASHSIZE;
0126 }
0127 out:
0128 JFFS2_NOTICE("xdatum_mem_usage from %u byte to %u byte (%u byte reclaimed)\n",
0129 before, c->xdatum_mem_usage, before - c->xdatum_mem_usage);
0130 }
0131
0132 static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
0133 {
0134
0135 struct jffs2_eraseblock *jeb;
0136 struct jffs2_raw_node_ref *raw;
0137 struct jffs2_raw_xattr rx;
0138 size_t readlen;
0139 uint32_t crc, offset, totlen;
0140 int rc;
0141
0142 spin_lock(&c->erase_completion_lock);
0143 offset = ref_offset(xd->node);
0144 if (ref_flags(xd->node) == REF_PRISTINE)
0145 goto complete;
0146 spin_unlock(&c->erase_completion_lock);
0147
0148 rc = jffs2_flash_read(c, offset, sizeof(rx), &readlen, (char *)&rx);
0149 if (rc || readlen != sizeof(rx)) {
0150 JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu at %#08x\n",
0151 rc, sizeof(rx), readlen, offset);
0152 return rc ? rc : -EIO;
0153 }
0154 crc = crc32(0, &rx, sizeof(rx) - 4);
0155 if (crc != je32_to_cpu(rx.node_crc)) {
0156 JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
0157 offset, je32_to_cpu(rx.hdr_crc), crc);
0158 xd->flags |= JFFS2_XFLAGS_INVALID;
0159 return JFFS2_XATTR_IS_CORRUPTED;
0160 }
0161 totlen = PAD(sizeof(rx) + rx.name_len + 1 + je16_to_cpu(rx.value_len));
0162 if (je16_to_cpu(rx.magic) != JFFS2_MAGIC_BITMASK
0163 || je16_to_cpu(rx.nodetype) != JFFS2_NODETYPE_XATTR
0164 || je32_to_cpu(rx.totlen) != totlen
0165 || je32_to_cpu(rx.xid) != xd->xid
0166 || je32_to_cpu(rx.version) != xd->version) {
0167 JFFS2_ERROR("inconsistent xdatum at %#08x, magic=%#04x/%#04x, "
0168 "nodetype=%#04x/%#04x, totlen=%u/%u, xid=%u/%u, version=%u/%u\n",
0169 offset, je16_to_cpu(rx.magic), JFFS2_MAGIC_BITMASK,
0170 je16_to_cpu(rx.nodetype), JFFS2_NODETYPE_XATTR,
0171 je32_to_cpu(rx.totlen), totlen,
0172 je32_to_cpu(rx.xid), xd->xid,
0173 je32_to_cpu(rx.version), xd->version);
0174 xd->flags |= JFFS2_XFLAGS_INVALID;
0175 return JFFS2_XATTR_IS_CORRUPTED;
0176 }
0177 xd->xprefix = rx.xprefix;
0178 xd->name_len = rx.name_len;
0179 xd->value_len = je16_to_cpu(rx.value_len);
0180 xd->data_crc = je32_to_cpu(rx.data_crc);
0181
0182 spin_lock(&c->erase_completion_lock);
0183 complete:
0184 for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
0185 jeb = &c->blocks[ref_offset(raw) / c->sector_size];
0186 totlen = PAD(ref_totlen(c, jeb, raw));
0187 if (ref_flags(raw) == REF_UNCHECKED) {
0188 c->unchecked_size -= totlen; c->used_size += totlen;
0189 jeb->unchecked_size -= totlen; jeb->used_size += totlen;
0190 }
0191 raw->flash_offset = ref_offset(raw) | ((xd->node==raw) ? REF_PRISTINE : REF_NORMAL);
0192 }
0193 spin_unlock(&c->erase_completion_lock);
0194
0195
0196 list_del_init(&xd->xindex);
0197
0198 dbg_xattr("success on verifying xdatum (xid=%u, version=%u)\n",
0199 xd->xid, xd->version);
0200
0201 return 0;
0202 }
0203
0204 static int do_load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
0205 {
0206
0207 char *data;
0208 size_t readlen;
0209 uint32_t crc, length;
0210 int i, ret, retry = 0;
0211
0212 BUG_ON(ref_flags(xd->node) != REF_PRISTINE);
0213 BUG_ON(!list_empty(&xd->xindex));
0214 retry:
0215 length = xd->name_len + 1 + xd->value_len;
0216 data = kmalloc(length, GFP_KERNEL);
0217 if (!data)
0218 return -ENOMEM;
0219
0220 ret = jffs2_flash_read(c, ref_offset(xd->node)+sizeof(struct jffs2_raw_xattr),
0221 length, &readlen, data);
0222
0223 if (ret || length!=readlen) {
0224 JFFS2_WARNING("jffs2_flash_read() returned %d, request=%d, readlen=%zu, at %#08x\n",
0225 ret, length, readlen, ref_offset(xd->node));
0226 kfree(data);
0227 return ret ? ret : -EIO;
0228 }
0229
0230 data[xd->name_len] = '\0';
0231 crc = crc32(0, data, length);
0232 if (crc != xd->data_crc) {
0233 JFFS2_WARNING("node CRC failed (JFFS2_NODETYPE_XATTR)"
0234 " at %#08x, read: 0x%08x calculated: 0x%08x\n",
0235 ref_offset(xd->node), xd->data_crc, crc);
0236 kfree(data);
0237 xd->flags |= JFFS2_XFLAGS_INVALID;
0238 return JFFS2_XATTR_IS_CORRUPTED;
0239 }
0240
0241 xd->flags |= JFFS2_XFLAGS_HOT;
0242 xd->xname = data;
0243 xd->xvalue = data + xd->name_len+1;
0244
0245 c->xdatum_mem_usage += length;
0246
0247 xd->hashkey = xattr_datum_hashkey(xd->xprefix, xd->xname, xd->xvalue, xd->value_len);
0248 i = xd->hashkey % XATTRINDEX_HASHSIZE;
0249 list_add(&xd->xindex, &c->xattrindex[i]);
0250 if (!retry) {
0251 retry = 1;
0252 reclaim_xattr_datum(c);
0253 if (!xd->xname)
0254 goto retry;
0255 }
0256
0257 dbg_xattr("success on loading xdatum (xid=%u, xprefix=%u, xname='%s')\n",
0258 xd->xid, xd->xprefix, xd->xname);
0259
0260 return 0;
0261 }
0262
0263 static int load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
0264 {
0265
0266
0267
0268
0269
0270 int rc = 0;
0271
0272 BUG_ON(xd->flags & JFFS2_XFLAGS_DEAD);
0273 if (xd->xname)
0274 return 0;
0275 if (xd->flags & JFFS2_XFLAGS_INVALID)
0276 return JFFS2_XATTR_IS_CORRUPTED;
0277 if (unlikely(is_xattr_datum_unchecked(c, xd)))
0278 rc = do_verify_xattr_datum(c, xd);
0279 if (!rc)
0280 rc = do_load_xattr_datum(c, xd);
0281 return rc;
0282 }
0283
0284 static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
0285 {
0286
0287 struct jffs2_raw_xattr rx;
0288 struct kvec vecs[2];
0289 size_t length;
0290 int rc, totlen;
0291 uint32_t phys_ofs = write_ofs(c);
0292
0293 BUG_ON(!xd->xname);
0294 BUG_ON(xd->flags & (JFFS2_XFLAGS_DEAD|JFFS2_XFLAGS_INVALID));
0295
0296 vecs[0].iov_base = ℞
0297 vecs[0].iov_len = sizeof(rx);
0298 vecs[1].iov_base = xd->xname;
0299 vecs[1].iov_len = xd->name_len + 1 + xd->value_len;
0300 totlen = vecs[0].iov_len + vecs[1].iov_len;
0301
0302
0303 memset(&rx, 0, sizeof(rx));
0304 rx.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
0305 rx.nodetype = cpu_to_je16(JFFS2_NODETYPE_XATTR);
0306 rx.totlen = cpu_to_je32(PAD(totlen));
0307 rx.hdr_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_unknown_node) - 4));
0308
0309 rx.xid = cpu_to_je32(xd->xid);
0310 rx.version = cpu_to_je32(++xd->version);
0311 rx.xprefix = xd->xprefix;
0312 rx.name_len = xd->name_len;
0313 rx.value_len = cpu_to_je16(xd->value_len);
0314 rx.data_crc = cpu_to_je32(crc32(0, vecs[1].iov_base, vecs[1].iov_len));
0315 rx.node_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_raw_xattr) - 4));
0316
0317 rc = jffs2_flash_writev(c, vecs, 2, phys_ofs, &length, 0);
0318 if (rc || totlen != length) {
0319 JFFS2_WARNING("jffs2_flash_writev()=%d, req=%u, wrote=%zu, at %#08x\n",
0320 rc, totlen, length, phys_ofs);
0321 rc = rc ? rc : -EIO;
0322 if (length)
0323 jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, PAD(totlen), NULL);
0324
0325 return rc;
0326 }
0327
0328 jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(totlen), (void *)xd);
0329
0330 dbg_xattr("success on saving xdatum (xid=%u, version=%u, xprefix=%u, xname='%s')\n",
0331 xd->xid, xd->version, xd->xprefix, xd->xname);
0332
0333 return 0;
0334 }
0335
0336 static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c,
0337 int xprefix, const char *xname,
0338 const char *xvalue, int xsize)
0339 {
0340
0341 struct jffs2_xattr_datum *xd;
0342 uint32_t hashkey, name_len;
0343 char *data;
0344 int i, rc;
0345
0346
0347 hashkey = xattr_datum_hashkey(xprefix, xname, xvalue, xsize);
0348 i = hashkey % XATTRINDEX_HASHSIZE;
0349 list_for_each_entry(xd, &c->xattrindex[i], xindex) {
0350 if (xd->hashkey==hashkey
0351 && xd->xprefix==xprefix
0352 && xd->value_len==xsize
0353 && !strcmp(xd->xname, xname)
0354 && !memcmp(xd->xvalue, xvalue, xsize)) {
0355 atomic_inc(&xd->refcnt);
0356 return xd;
0357 }
0358 }
0359
0360
0361 name_len = strlen(xname);
0362
0363 xd = jffs2_alloc_xattr_datum();
0364 if (!xd)
0365 return ERR_PTR(-ENOMEM);
0366
0367 data = kmalloc(name_len + 1 + xsize, GFP_KERNEL);
0368 if (!data) {
0369 jffs2_free_xattr_datum(xd);
0370 return ERR_PTR(-ENOMEM);
0371 }
0372 strcpy(data, xname);
0373 memcpy(data + name_len + 1, xvalue, xsize);
0374
0375 atomic_set(&xd->refcnt, 1);
0376 xd->xid = ++c->highest_xid;
0377 xd->flags |= JFFS2_XFLAGS_HOT;
0378 xd->xprefix = xprefix;
0379
0380 xd->hashkey = hashkey;
0381 xd->xname = data;
0382 xd->xvalue = data + name_len + 1;
0383 xd->name_len = name_len;
0384 xd->value_len = xsize;
0385 xd->data_crc = crc32(0, data, xd->name_len + 1 + xd->value_len);
0386
0387 rc = save_xattr_datum(c, xd);
0388 if (rc) {
0389 kfree(xd->xname);
0390 jffs2_free_xattr_datum(xd);
0391 return ERR_PTR(rc);
0392 }
0393
0394
0395 i = hashkey % XATTRINDEX_HASHSIZE;
0396 list_add(&xd->xindex, &c->xattrindex[i]);
0397
0398 c->xdatum_mem_usage += (xd->name_len + 1 + xd->value_len);
0399 reclaim_xattr_datum(c);
0400
0401 return xd;
0402 }
0403
0404 static void unrefer_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
0405 {
0406
0407 if (atomic_dec_and_lock(&xd->refcnt, &c->erase_completion_lock)) {
0408 unload_xattr_datum(c, xd);
0409 xd->flags |= JFFS2_XFLAGS_DEAD;
0410 if (xd->node == (void *)xd) {
0411 BUG_ON(!(xd->flags & JFFS2_XFLAGS_INVALID));
0412 jffs2_free_xattr_datum(xd);
0413 } else {
0414 list_add(&xd->xindex, &c->xattr_dead_list);
0415 }
0416 spin_unlock(&c->erase_completion_lock);
0417
0418 dbg_xattr("xdatum(xid=%u, version=%u) was removed.\n",
0419 xd->xid, xd->version);
0420 }
0421 }
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444 static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
0445 {
0446 struct jffs2_eraseblock *jeb;
0447 struct jffs2_raw_node_ref *raw;
0448 struct jffs2_raw_xref rr;
0449 size_t readlen;
0450 uint32_t crc, offset, totlen;
0451 int rc;
0452
0453 spin_lock(&c->erase_completion_lock);
0454 if (ref_flags(ref->node) != REF_UNCHECKED)
0455 goto complete;
0456 offset = ref_offset(ref->node);
0457 spin_unlock(&c->erase_completion_lock);
0458
0459 rc = jffs2_flash_read(c, offset, sizeof(rr), &readlen, (char *)&rr);
0460 if (rc || sizeof(rr) != readlen) {
0461 JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu, at %#08x\n",
0462 rc, sizeof(rr), readlen, offset);
0463 return rc ? rc : -EIO;
0464 }
0465
0466 crc = crc32(0, &rr, sizeof(rr) - 4);
0467 if (crc != je32_to_cpu(rr.node_crc)) {
0468 JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
0469 offset, je32_to_cpu(rr.node_crc), crc);
0470 return JFFS2_XATTR_IS_CORRUPTED;
0471 }
0472 if (je16_to_cpu(rr.magic) != JFFS2_MAGIC_BITMASK
0473 || je16_to_cpu(rr.nodetype) != JFFS2_NODETYPE_XREF
0474 || je32_to_cpu(rr.totlen) != PAD(sizeof(rr))) {
0475 JFFS2_ERROR("inconsistent xref at %#08x, magic=%#04x/%#04x, "
0476 "nodetype=%#04x/%#04x, totlen=%u/%zu\n",
0477 offset, je16_to_cpu(rr.magic), JFFS2_MAGIC_BITMASK,
0478 je16_to_cpu(rr.nodetype), JFFS2_NODETYPE_XREF,
0479 je32_to_cpu(rr.totlen), PAD(sizeof(rr)));
0480 return JFFS2_XATTR_IS_CORRUPTED;
0481 }
0482 ref->ino = je32_to_cpu(rr.ino);
0483 ref->xid = je32_to_cpu(rr.xid);
0484 ref->xseqno = je32_to_cpu(rr.xseqno);
0485 if (ref->xseqno > c->highest_xseqno)
0486 c->highest_xseqno = (ref->xseqno & ~XREF_DELETE_MARKER);
0487
0488 spin_lock(&c->erase_completion_lock);
0489 complete:
0490 for (raw=ref->node; raw != (void *)ref; raw=raw->next_in_ino) {
0491 jeb = &c->blocks[ref_offset(raw) / c->sector_size];
0492 totlen = PAD(ref_totlen(c, jeb, raw));
0493 if (ref_flags(raw) == REF_UNCHECKED) {
0494 c->unchecked_size -= totlen; c->used_size += totlen;
0495 jeb->unchecked_size -= totlen; jeb->used_size += totlen;
0496 }
0497 raw->flash_offset = ref_offset(raw) | ((ref->node==raw) ? REF_PRISTINE : REF_NORMAL);
0498 }
0499 spin_unlock(&c->erase_completion_lock);
0500
0501 dbg_xattr("success on verifying xref (ino=%u, xid=%u) at %#08x\n",
0502 ref->ino, ref->xid, ref_offset(ref->node));
0503 return 0;
0504 }
0505
0506 static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
0507 {
0508
0509 struct jffs2_raw_xref rr;
0510 size_t length;
0511 uint32_t xseqno, phys_ofs = write_ofs(c);
0512 int ret;
0513
0514 rr.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
0515 rr.nodetype = cpu_to_je16(JFFS2_NODETYPE_XREF);
0516 rr.totlen = cpu_to_je32(PAD(sizeof(rr)));
0517 rr.hdr_crc = cpu_to_je32(crc32(0, &rr, sizeof(struct jffs2_unknown_node) - 4));
0518
0519 xseqno = (c->highest_xseqno += 2);
0520 if (is_xattr_ref_dead(ref)) {
0521 xseqno |= XREF_DELETE_MARKER;
0522 rr.ino = cpu_to_je32(ref->ino);
0523 rr.xid = cpu_to_je32(ref->xid);
0524 } else {
0525 rr.ino = cpu_to_je32(ref->ic->ino);
0526 rr.xid = cpu_to_je32(ref->xd->xid);
0527 }
0528 rr.xseqno = cpu_to_je32(xseqno);
0529 rr.node_crc = cpu_to_je32(crc32(0, &rr, sizeof(rr) - 4));
0530
0531 ret = jffs2_flash_write(c, phys_ofs, sizeof(rr), &length, (char *)&rr);
0532 if (ret || sizeof(rr) != length) {
0533 JFFS2_WARNING("jffs2_flash_write() returned %d, request=%zu, retlen=%zu, at %#08x\n",
0534 ret, sizeof(rr), length, phys_ofs);
0535 ret = ret ? ret : -EIO;
0536 if (length)
0537 jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, PAD(sizeof(rr)), NULL);
0538
0539 return ret;
0540 }
0541
0542 ref->xseqno = xseqno;
0543 jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(sizeof(rr)), (void *)ref);
0544
0545 dbg_xattr("success on saving xref (ino=%u, xid=%u)\n", ref->ic->ino, ref->xd->xid);
0546
0547 return 0;
0548 }
0549
0550 static struct jffs2_xattr_ref *create_xattr_ref(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic,
0551 struct jffs2_xattr_datum *xd)
0552 {
0553
0554 struct jffs2_xattr_ref *ref;
0555 int ret;
0556
0557 ref = jffs2_alloc_xattr_ref();
0558 if (!ref)
0559 return ERR_PTR(-ENOMEM);
0560 ref->ic = ic;
0561 ref->xd = xd;
0562
0563 ret = save_xattr_ref(c, ref);
0564 if (ret) {
0565 jffs2_free_xattr_ref(ref);
0566 return ERR_PTR(ret);
0567 }
0568
0569
0570 ref->next = ic->xref;
0571 ic->xref = ref;
0572
0573 return ref;
0574 }
0575
0576 static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
0577 {
0578
0579 struct jffs2_xattr_datum *xd;
0580
0581 xd = ref->xd;
0582 ref->xseqno |= XREF_DELETE_MARKER;
0583 ref->ino = ref->ic->ino;
0584 ref->xid = ref->xd->xid;
0585 spin_lock(&c->erase_completion_lock);
0586 ref->next = c->xref_dead_list;
0587 c->xref_dead_list = ref;
0588 spin_unlock(&c->erase_completion_lock);
0589
0590 dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) was removed.\n",
0591 ref->ino, ref->xid, ref->xseqno);
0592
0593 unrefer_xattr_datum(c, xd);
0594 }
0595
0596 void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
0597 {
0598
0599
0600 struct jffs2_xattr_ref *ref, *_ref;
0601
0602 if (!ic || ic->pino_nlink > 0)
0603 return;
0604
0605 down_write(&c->xattr_sem);
0606 for (ref = ic->xref; ref; ref = _ref) {
0607 _ref = ref->next;
0608 delete_xattr_ref(c, ref);
0609 }
0610 ic->xref = NULL;
0611 up_write(&c->xattr_sem);
0612 }
0613
0614 void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
0615 {
0616
0617 struct jffs2_xattr_datum *xd;
0618 struct jffs2_xattr_ref *ref, *_ref;
0619
0620 down_write(&c->xattr_sem);
0621 for (ref = ic->xref; ref; ref = _ref) {
0622 _ref = ref->next;
0623 xd = ref->xd;
0624 if (atomic_dec_and_test(&xd->refcnt)) {
0625 unload_xattr_datum(c, xd);
0626 jffs2_free_xattr_datum(xd);
0627 }
0628 jffs2_free_xattr_ref(ref);
0629 }
0630 ic->xref = NULL;
0631 up_write(&c->xattr_sem);
0632 }
0633
0634 static int check_xattr_ref_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
0635 {
0636
0637
0638
0639
0640 struct jffs2_xattr_ref *ref, *cmp, **pref, **pcmp;
0641 int rc = 0;
0642
0643 if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED))
0644 return 0;
0645 down_write(&c->xattr_sem);
0646 retry:
0647 rc = 0;
0648 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
0649 if (!ref->xd->xname) {
0650 rc = load_xattr_datum(c, ref->xd);
0651 if (unlikely(rc > 0)) {
0652 *pref = ref->next;
0653 delete_xattr_ref(c, ref);
0654 goto retry;
0655 } else if (unlikely(rc < 0))
0656 goto out;
0657 }
0658 for (cmp=ref->next, pcmp=&ref->next; cmp; pcmp=&cmp->next, cmp=cmp->next) {
0659 if (!cmp->xd->xname) {
0660 ref->xd->flags |= JFFS2_XFLAGS_BIND;
0661 rc = load_xattr_datum(c, cmp->xd);
0662 ref->xd->flags &= ~JFFS2_XFLAGS_BIND;
0663 if (unlikely(rc > 0)) {
0664 *pcmp = cmp->next;
0665 delete_xattr_ref(c, cmp);
0666 goto retry;
0667 } else if (unlikely(rc < 0))
0668 goto out;
0669 }
0670 if (ref->xd->xprefix == cmp->xd->xprefix
0671 && !strcmp(ref->xd->xname, cmp->xd->xname)) {
0672 if (ref->xseqno > cmp->xseqno) {
0673 *pcmp = cmp->next;
0674 delete_xattr_ref(c, cmp);
0675 } else {
0676 *pref = ref->next;
0677 delete_xattr_ref(c, ref);
0678 }
0679 goto retry;
0680 }
0681 }
0682 }
0683 ic->flags |= INO_FLAGS_XATTR_CHECKED;
0684 out:
0685 up_write(&c->xattr_sem);
0686
0687 return rc;
0688 }
0689
0690 void jffs2_xattr_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
0691 {
0692 check_xattr_ref_inode(c, ic);
0693 }
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707 void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c)
0708 {
0709 int i;
0710
0711 for (i=0; i < XATTRINDEX_HASHSIZE; i++)
0712 INIT_LIST_HEAD(&c->xattrindex[i]);
0713 INIT_LIST_HEAD(&c->xattr_unchecked);
0714 INIT_LIST_HEAD(&c->xattr_dead_list);
0715 c->xref_dead_list = NULL;
0716 c->xref_temp = NULL;
0717
0718 init_rwsem(&c->xattr_sem);
0719 c->highest_xid = 0;
0720 c->highest_xseqno = 0;
0721 c->xdatum_mem_usage = 0;
0722 c->xdatum_mem_threshold = 32 * 1024;
0723 }
0724
0725 static struct jffs2_xattr_datum *jffs2_find_xattr_datum(struct jffs2_sb_info *c, uint32_t xid)
0726 {
0727 struct jffs2_xattr_datum *xd;
0728 int i = xid % XATTRINDEX_HASHSIZE;
0729
0730
0731 BUG_ON(!(c->flags & (JFFS2_SB_FLAG_SCANNING|JFFS2_SB_FLAG_BUILDING)));
0732
0733 list_for_each_entry(xd, &c->xattrindex[i], xindex) {
0734 if (xd->xid==xid)
0735 return xd;
0736 }
0737 return NULL;
0738 }
0739
0740 void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c)
0741 {
0742 struct jffs2_xattr_datum *xd, *_xd;
0743 struct jffs2_xattr_ref *ref, *_ref;
0744 int i;
0745
0746 for (ref=c->xref_temp; ref; ref = _ref) {
0747 _ref = ref->next;
0748 jffs2_free_xattr_ref(ref);
0749 }
0750
0751 for (ref=c->xref_dead_list; ref; ref = _ref) {
0752 _ref = ref->next;
0753 jffs2_free_xattr_ref(ref);
0754 }
0755
0756 for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
0757 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
0758 list_del(&xd->xindex);
0759 kfree(xd->xname);
0760 jffs2_free_xattr_datum(xd);
0761 }
0762 }
0763
0764 list_for_each_entry_safe(xd, _xd, &c->xattr_dead_list, xindex) {
0765 list_del(&xd->xindex);
0766 jffs2_free_xattr_datum(xd);
0767 }
0768 list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) {
0769 list_del(&xd->xindex);
0770 jffs2_free_xattr_datum(xd);
0771 }
0772 }
0773
0774 #define XREF_TMPHASH_SIZE (128)
0775 void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
0776 {
0777 struct jffs2_xattr_ref *ref, *_ref;
0778 struct jffs2_xattr_ref *xref_tmphash[XREF_TMPHASH_SIZE];
0779 struct jffs2_xattr_datum *xd, *_xd;
0780 struct jffs2_inode_cache *ic;
0781 struct jffs2_raw_node_ref *raw;
0782 int i, xdatum_count = 0, xdatum_unchecked_count = 0, xref_count = 0;
0783 int xdatum_orphan_count = 0, xref_orphan_count = 0, xref_dead_count = 0;
0784
0785 BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING));
0786
0787
0788 for (i=0; i < XREF_TMPHASH_SIZE; i++)
0789 xref_tmphash[i] = NULL;
0790 for (ref=c->xref_temp; ref; ref=_ref) {
0791 struct jffs2_xattr_ref *tmp;
0792
0793 _ref = ref->next;
0794 if (ref_flags(ref->node) != REF_PRISTINE) {
0795 if (verify_xattr_ref(c, ref)) {
0796 BUG_ON(ref->node->next_in_ino != (void *)ref);
0797 ref->node->next_in_ino = NULL;
0798 jffs2_mark_node_obsolete(c, ref->node);
0799 jffs2_free_xattr_ref(ref);
0800 continue;
0801 }
0802 }
0803
0804 i = (ref->ino ^ ref->xid) % XREF_TMPHASH_SIZE;
0805 for (tmp=xref_tmphash[i]; tmp; tmp=tmp->next) {
0806 if (tmp->ino == ref->ino && tmp->xid == ref->xid)
0807 break;
0808 }
0809 if (tmp) {
0810 raw = ref->node;
0811 if (ref->xseqno > tmp->xseqno) {
0812 tmp->xseqno = ref->xseqno;
0813 raw->next_in_ino = tmp->node;
0814 tmp->node = raw;
0815 } else {
0816 raw->next_in_ino = tmp->node->next_in_ino;
0817 tmp->node->next_in_ino = raw;
0818 }
0819 jffs2_free_xattr_ref(ref);
0820 continue;
0821 } else {
0822 ref->next = xref_tmphash[i];
0823 xref_tmphash[i] = ref;
0824 }
0825 }
0826 c->xref_temp = NULL;
0827
0828
0829 for (i=0; i < XREF_TMPHASH_SIZE; i++) {
0830 for (ref=xref_tmphash[i]; ref; ref=_ref) {
0831 xref_count++;
0832 _ref = ref->next;
0833 if (is_xattr_ref_dead(ref)) {
0834 ref->next = c->xref_dead_list;
0835 c->xref_dead_list = ref;
0836 xref_dead_count++;
0837 continue;
0838 }
0839
0840
0841 xd = jffs2_find_xattr_datum(c, ref->xid);
0842 ic = jffs2_get_ino_cache(c, ref->ino);
0843 if (!xd || !ic || !ic->pino_nlink) {
0844 dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) is orphan.\n",
0845 ref->ino, ref->xid, ref->xseqno);
0846 ref->xseqno |= XREF_DELETE_MARKER;
0847 ref->next = c->xref_dead_list;
0848 c->xref_dead_list = ref;
0849 xref_orphan_count++;
0850 continue;
0851 }
0852 ref->xd = xd;
0853 ref->ic = ic;
0854 atomic_inc(&xd->refcnt);
0855 ref->next = ic->xref;
0856 ic->xref = ref;
0857 }
0858 }
0859
0860
0861 for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
0862 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
0863 xdatum_count++;
0864 list_del_init(&xd->xindex);
0865 if (!atomic_read(&xd->refcnt)) {
0866 dbg_xattr("xdatum(xid=%u, version=%u) is orphan.\n",
0867 xd->xid, xd->version);
0868 xd->flags |= JFFS2_XFLAGS_DEAD;
0869 list_add(&xd->xindex, &c->xattr_unchecked);
0870 xdatum_orphan_count++;
0871 continue;
0872 }
0873 if (is_xattr_datum_unchecked(c, xd)) {
0874 dbg_xattr("unchecked xdatum(xid=%u, version=%u)\n",
0875 xd->xid, xd->version);
0876 list_add(&xd->xindex, &c->xattr_unchecked);
0877 xdatum_unchecked_count++;
0878 }
0879 }
0880 }
0881
0882 JFFS2_NOTICE("complete building xattr subsystem, %u of xdatum"
0883 " (%u unchecked, %u orphan) and "
0884 "%u of xref (%u dead, %u orphan) found.\n",
0885 xdatum_count, xdatum_unchecked_count, xdatum_orphan_count,
0886 xref_count, xref_dead_count, xref_orphan_count);
0887 }
0888
0889 struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,
0890 uint32_t xid, uint32_t version)
0891 {
0892 struct jffs2_xattr_datum *xd;
0893
0894 xd = jffs2_find_xattr_datum(c, xid);
0895 if (!xd) {
0896 xd = jffs2_alloc_xattr_datum();
0897 if (!xd)
0898 return ERR_PTR(-ENOMEM);
0899 xd->xid = xid;
0900 xd->version = version;
0901 if (xd->xid > c->highest_xid)
0902 c->highest_xid = xd->xid;
0903 list_add_tail(&xd->xindex, &c->xattrindex[xid % XATTRINDEX_HASHSIZE]);
0904 }
0905 return xd;
0906 }
0907
0908
0909
0910
0911
0912
0913
0914
0915
0916
0917
0918 const struct xattr_handler *jffs2_xattr_handlers[] = {
0919 &jffs2_user_xattr_handler,
0920 #ifdef CONFIG_JFFS2_FS_SECURITY
0921 &jffs2_security_xattr_handler,
0922 #endif
0923 #ifdef CONFIG_JFFS2_FS_POSIX_ACL
0924 &posix_acl_access_xattr_handler,
0925 &posix_acl_default_xattr_handler,
0926 #endif
0927 &jffs2_trusted_xattr_handler,
0928 NULL
0929 };
0930
0931 static const struct xattr_handler *xprefix_to_handler(int xprefix) {
0932 const struct xattr_handler *ret;
0933
0934 switch (xprefix) {
0935 case JFFS2_XPREFIX_USER:
0936 ret = &jffs2_user_xattr_handler;
0937 break;
0938 #ifdef CONFIG_JFFS2_FS_SECURITY
0939 case JFFS2_XPREFIX_SECURITY:
0940 ret = &jffs2_security_xattr_handler;
0941 break;
0942 #endif
0943 #ifdef CONFIG_JFFS2_FS_POSIX_ACL
0944 case JFFS2_XPREFIX_ACL_ACCESS:
0945 ret = &posix_acl_access_xattr_handler;
0946 break;
0947 case JFFS2_XPREFIX_ACL_DEFAULT:
0948 ret = &posix_acl_default_xattr_handler;
0949 break;
0950 #endif
0951 case JFFS2_XPREFIX_TRUSTED:
0952 ret = &jffs2_trusted_xattr_handler;
0953 break;
0954 default:
0955 ret = NULL;
0956 break;
0957 }
0958 return ret;
0959 }
0960
0961 ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
0962 {
0963 struct inode *inode = d_inode(dentry);
0964 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
0965 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
0966 struct jffs2_inode_cache *ic = f->inocache;
0967 struct jffs2_xattr_ref *ref, **pref;
0968 struct jffs2_xattr_datum *xd;
0969 const struct xattr_handler *xhandle;
0970 const char *prefix;
0971 ssize_t prefix_len, len, rc;
0972 int retry = 0;
0973
0974 rc = check_xattr_ref_inode(c, ic);
0975 if (unlikely(rc))
0976 return rc;
0977
0978 down_read(&c->xattr_sem);
0979 retry:
0980 len = 0;
0981 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
0982 BUG_ON(ref->ic != ic);
0983 xd = ref->xd;
0984 if (!xd->xname) {
0985
0986 if (!retry) {
0987 retry = 1;
0988 up_read(&c->xattr_sem);
0989 down_write(&c->xattr_sem);
0990 goto retry;
0991 } else {
0992 rc = load_xattr_datum(c, xd);
0993 if (unlikely(rc > 0)) {
0994 *pref = ref->next;
0995 delete_xattr_ref(c, ref);
0996 goto retry;
0997 } else if (unlikely(rc < 0))
0998 goto out;
0999 }
1000 }
1001 xhandle = xprefix_to_handler(xd->xprefix);
1002 if (!xhandle || (xhandle->list && !xhandle->list(dentry)))
1003 continue;
1004 prefix = xhandle->prefix ?: xhandle->name;
1005 prefix_len = strlen(prefix);
1006 rc = prefix_len + xd->name_len + 1;
1007
1008 if (buffer) {
1009 if (rc > size - len) {
1010 rc = -ERANGE;
1011 goto out;
1012 }
1013 memcpy(buffer, prefix, prefix_len);
1014 buffer += prefix_len;
1015 memcpy(buffer, xd->xname, xd->name_len);
1016 buffer += xd->name_len;
1017 *buffer++ = 0;
1018 }
1019 len += rc;
1020 }
1021 rc = len;
1022 out:
1023 if (!retry) {
1024 up_read(&c->xattr_sem);
1025 } else {
1026 up_write(&c->xattr_sem);
1027 }
1028 return rc;
1029 }
1030
1031 int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname,
1032 char *buffer, size_t size)
1033 {
1034 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
1035 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
1036 struct jffs2_inode_cache *ic = f->inocache;
1037 struct jffs2_xattr_datum *xd;
1038 struct jffs2_xattr_ref *ref, **pref;
1039 int rc, retry = 0;
1040
1041 rc = check_xattr_ref_inode(c, ic);
1042 if (unlikely(rc))
1043 return rc;
1044
1045 down_read(&c->xattr_sem);
1046 retry:
1047 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
1048 BUG_ON(ref->ic!=ic);
1049
1050 xd = ref->xd;
1051 if (xd->xprefix != xprefix)
1052 continue;
1053 if (!xd->xname) {
1054
1055 if (!retry) {
1056 retry = 1;
1057 up_read(&c->xattr_sem);
1058 down_write(&c->xattr_sem);
1059 goto retry;
1060 } else {
1061 rc = load_xattr_datum(c, xd);
1062 if (unlikely(rc > 0)) {
1063 *pref = ref->next;
1064 delete_xattr_ref(c, ref);
1065 goto retry;
1066 } else if (unlikely(rc < 0)) {
1067 goto out;
1068 }
1069 }
1070 }
1071 if (!strcmp(xname, xd->xname)) {
1072 rc = xd->value_len;
1073 if (buffer) {
1074 if (size < rc) {
1075 rc = -ERANGE;
1076 } else {
1077 memcpy(buffer, xd->xvalue, rc);
1078 }
1079 }
1080 goto out;
1081 }
1082 }
1083 rc = -ENODATA;
1084 out:
1085 if (!retry) {
1086 up_read(&c->xattr_sem);
1087 } else {
1088 up_write(&c->xattr_sem);
1089 }
1090 return rc;
1091 }
1092
1093 int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1094 const char *buffer, size_t size, int flags)
1095 {
1096 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
1097 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
1098 struct jffs2_inode_cache *ic = f->inocache;
1099 struct jffs2_xattr_datum *xd;
1100 struct jffs2_xattr_ref *ref, *newref, **pref;
1101 uint32_t length, request;
1102 int rc;
1103
1104 rc = check_xattr_ref_inode(c, ic);
1105 if (unlikely(rc))
1106 return rc;
1107
1108 request = PAD(sizeof(struct jffs2_raw_xattr) + strlen(xname) + 1 + size);
1109 rc = jffs2_reserve_space(c, request, &length,
1110 ALLOC_NORMAL, JFFS2_SUMMARY_XATTR_SIZE);
1111 if (rc) {
1112 JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
1113 return rc;
1114 }
1115
1116
1117 down_write(&c->xattr_sem);
1118 retry:
1119 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
1120 xd = ref->xd;
1121 if (xd->xprefix != xprefix)
1122 continue;
1123 if (!xd->xname) {
1124 rc = load_xattr_datum(c, xd);
1125 if (unlikely(rc > 0)) {
1126 *pref = ref->next;
1127 delete_xattr_ref(c, ref);
1128 goto retry;
1129 } else if (unlikely(rc < 0))
1130 goto out;
1131 }
1132 if (!strcmp(xd->xname, xname)) {
1133 if (flags & XATTR_CREATE) {
1134 rc = -EEXIST;
1135 goto out;
1136 }
1137 if (!buffer) {
1138 ref->ino = ic->ino;
1139 ref->xid = xd->xid;
1140 ref->xseqno |= XREF_DELETE_MARKER;
1141 rc = save_xattr_ref(c, ref);
1142 if (!rc) {
1143 *pref = ref->next;
1144 spin_lock(&c->erase_completion_lock);
1145 ref->next = c->xref_dead_list;
1146 c->xref_dead_list = ref;
1147 spin_unlock(&c->erase_completion_lock);
1148 unrefer_xattr_datum(c, xd);
1149 } else {
1150 ref->ic = ic;
1151 ref->xd = xd;
1152 ref->xseqno &= ~XREF_DELETE_MARKER;
1153 }
1154 goto out;
1155 }
1156 goto found;
1157 }
1158 }
1159
1160 if (flags & XATTR_REPLACE) {
1161 rc = -ENODATA;
1162 goto out;
1163 }
1164 if (!buffer) {
1165 rc = -ENODATA;
1166 goto out;
1167 }
1168 found:
1169 xd = create_xattr_datum(c, xprefix, xname, buffer, size);
1170 if (IS_ERR(xd)) {
1171 rc = PTR_ERR(xd);
1172 goto out;
1173 }
1174 up_write(&c->xattr_sem);
1175 jffs2_complete_reservation(c);
1176
1177
1178 request = PAD(sizeof(struct jffs2_raw_xref));
1179 rc = jffs2_reserve_space(c, request, &length,
1180 ALLOC_NORMAL, JFFS2_SUMMARY_XREF_SIZE);
1181 down_write(&c->xattr_sem);
1182 if (rc) {
1183 JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
1184 unrefer_xattr_datum(c, xd);
1185 up_write(&c->xattr_sem);
1186 return rc;
1187 }
1188 if (ref)
1189 *pref = ref->next;
1190 newref = create_xattr_ref(c, ic, xd);
1191 if (IS_ERR(newref)) {
1192 if (ref) {
1193 ref->next = ic->xref;
1194 ic->xref = ref;
1195 }
1196 rc = PTR_ERR(newref);
1197 unrefer_xattr_datum(c, xd);
1198 } else if (ref) {
1199 delete_xattr_ref(c, ref);
1200 }
1201 out:
1202 up_write(&c->xattr_sem);
1203 jffs2_complete_reservation(c);
1204 return rc;
1205 }
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219 int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd,
1220 struct jffs2_raw_node_ref *raw)
1221 {
1222 uint32_t totlen, length, old_ofs;
1223 int rc = 0;
1224
1225 down_write(&c->xattr_sem);
1226 if (xd->node != raw)
1227 goto out;
1228 if (xd->flags & (JFFS2_XFLAGS_DEAD|JFFS2_XFLAGS_INVALID))
1229 goto out;
1230
1231 rc = load_xattr_datum(c, xd);
1232 if (unlikely(rc)) {
1233 rc = (rc > 0) ? 0 : rc;
1234 goto out;
1235 }
1236 old_ofs = ref_offset(xd->node);
1237 totlen = PAD(sizeof(struct jffs2_raw_xattr)
1238 + xd->name_len + 1 + xd->value_len);
1239 rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XATTR_SIZE);
1240 if (rc) {
1241 JFFS2_WARNING("jffs2_reserve_space_gc()=%d, request=%u\n", rc, totlen);
1242 goto out;
1243 }
1244 rc = save_xattr_datum(c, xd);
1245 if (!rc)
1246 dbg_xattr("xdatum (xid=%u, version=%u) GC'ed from %#08x to %08x\n",
1247 xd->xid, xd->version, old_ofs, ref_offset(xd->node));
1248 out:
1249 if (!rc)
1250 jffs2_mark_node_obsolete(c, raw);
1251 up_write(&c->xattr_sem);
1252 return rc;
1253 }
1254
1255 int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref,
1256 struct jffs2_raw_node_ref *raw)
1257 {
1258 uint32_t totlen, length, old_ofs;
1259 int rc = 0;
1260
1261 down_write(&c->xattr_sem);
1262 BUG_ON(!ref->node);
1263
1264 if (ref->node != raw)
1265 goto out;
1266 if (is_xattr_ref_dead(ref) && (raw->next_in_ino == (void *)ref))
1267 goto out;
1268
1269 old_ofs = ref_offset(ref->node);
1270 totlen = ref_totlen(c, c->gcblock, ref->node);
1271
1272 rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XREF_SIZE);
1273 if (rc) {
1274 JFFS2_WARNING("%s: jffs2_reserve_space_gc() = %d, request = %u\n",
1275 __func__, rc, totlen);
1276 goto out;
1277 }
1278 rc = save_xattr_ref(c, ref);
1279 if (!rc)
1280 dbg_xattr("xref (ino=%u, xid=%u) GC'ed from %#08x to %08x\n",
1281 ref->ic->ino, ref->xd->xid, old_ofs, ref_offset(ref->node));
1282 out:
1283 if (!rc)
1284 jffs2_mark_node_obsolete(c, raw);
1285 up_write(&c->xattr_sem);
1286 return rc;
1287 }
1288
1289 int jffs2_verify_xattr(struct jffs2_sb_info *c)
1290 {
1291 struct jffs2_xattr_datum *xd, *_xd;
1292 struct jffs2_eraseblock *jeb;
1293 struct jffs2_raw_node_ref *raw;
1294 uint32_t totlen;
1295 int rc;
1296
1297 down_write(&c->xattr_sem);
1298 list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) {
1299 rc = do_verify_xattr_datum(c, xd);
1300 if (rc < 0)
1301 continue;
1302 list_del_init(&xd->xindex);
1303 spin_lock(&c->erase_completion_lock);
1304 for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
1305 if (ref_flags(raw) != REF_UNCHECKED)
1306 continue;
1307 jeb = &c->blocks[ref_offset(raw) / c->sector_size];
1308 totlen = PAD(ref_totlen(c, jeb, raw));
1309 c->unchecked_size -= totlen; c->used_size += totlen;
1310 jeb->unchecked_size -= totlen; jeb->used_size += totlen;
1311 raw->flash_offset = ref_offset(raw)
1312 | ((xd->node == (void *)raw) ? REF_PRISTINE : REF_NORMAL);
1313 }
1314 if (xd->flags & JFFS2_XFLAGS_DEAD)
1315 list_add(&xd->xindex, &c->xattr_dead_list);
1316 spin_unlock(&c->erase_completion_lock);
1317 }
1318 up_write(&c->xattr_sem);
1319 return list_empty(&c->xattr_unchecked) ? 1 : 0;
1320 }
1321
1322 void jffs2_release_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
1323 {
1324
1325 if (atomic_read(&xd->refcnt) || xd->node != (void *)xd)
1326 return;
1327
1328 list_del(&xd->xindex);
1329 jffs2_free_xattr_datum(xd);
1330 }
1331
1332 void jffs2_release_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
1333 {
1334
1335 struct jffs2_xattr_ref *tmp, **ptmp;
1336
1337 if (ref->node != (void *)ref)
1338 return;
1339
1340 for (tmp=c->xref_dead_list, ptmp=&c->xref_dead_list; tmp; ptmp=&tmp->next, tmp=tmp->next) {
1341 if (ref == tmp) {
1342 *ptmp = tmp->next;
1343 break;
1344 }
1345 }
1346 jffs2_free_xattr_ref(ref);
1347 }