This source file includes following definitions.
- xattr_datum_hashkey
- is_xattr_datum_unchecked
- unload_xattr_datum
- reclaim_xattr_datum
- do_verify_xattr_datum
- do_load_xattr_datum
- load_xattr_datum
- save_xattr_datum
- create_xattr_datum
- unrefer_xattr_datum
- verify_xattr_ref
- save_xattr_ref
- create_xattr_ref
- delete_xattr_ref
- jffs2_xattr_delete_inode
- jffs2_xattr_free_inode
- check_xattr_ref_inode
- jffs2_xattr_do_crccheck_inode
- jffs2_init_xattr_subsystem
- jffs2_find_xattr_datum
- jffs2_clear_xattr_subsystem
- jffs2_build_xattr_subsystem
- jffs2_setup_xattr_datum
- xprefix_to_handler
- jffs2_listxattr
- do_jffs2_getxattr
- do_jffs2_setxattr
- jffs2_garbage_collect_xattr_datum
- jffs2_garbage_collect_xattr_ref
- jffs2_verify_xattr
- jffs2_release_xattr_datum
- jffs2_release_xattr_ref
1
2
3
4
5
6
7
8
9
10
11
12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13
14 #define JFFS2_XATTR_IS_CORRUPTED 1
15
16 #include <linux/kernel.h>
17 #include <linux/slab.h>
18 #include <linux/fs.h>
19 #include <linux/time.h>
20 #include <linux/pagemap.h>
21 #include <linux/highmem.h>
22 #include <linux/crc32.h>
23 #include <linux/jffs2.h>
24 #include <linux/xattr.h>
25 #include <linux/posix_acl_xattr.h>
26 #include <linux/mtd/mtd.h>
27 #include "nodelist.h"
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *xvalue, int xsize)
65 {
66 int name_len = strlen(xname);
67
68 return crc32(xprefix, xname, name_len) ^ crc32(xprefix, xvalue, xsize);
69 }
70
71 static int is_xattr_datum_unchecked(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
72 {
73 struct jffs2_raw_node_ref *raw;
74 int rc = 0;
75
76 spin_lock(&c->erase_completion_lock);
77 for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
78 if (ref_flags(raw) == REF_UNCHECKED) {
79 rc = 1;
80 break;
81 }
82 }
83 spin_unlock(&c->erase_completion_lock);
84 return rc;
85 }
86
87 static void unload_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
88 {
89
90 D1(dbg_xattr("%s: xid=%u, version=%u\n", __func__, xd->xid, xd->version));
91 if (xd->xname) {
92 c->xdatum_mem_usage -= (xd->name_len + 1 + xd->value_len);
93 kfree(xd->xname);
94 }
95
96 list_del_init(&xd->xindex);
97 xd->hashkey = 0;
98 xd->xname = NULL;
99 xd->xvalue = NULL;
100 }
101
102 static void reclaim_xattr_datum(struct jffs2_sb_info *c)
103 {
104
105 struct jffs2_xattr_datum *xd, *_xd;
106 uint32_t target, before;
107 static int index = 0;
108 int count;
109
110 if (c->xdatum_mem_threshold > c->xdatum_mem_usage)
111 return;
112
113 before = c->xdatum_mem_usage;
114 target = c->xdatum_mem_usage * 4 / 5;
115 for (count = 0; count < XATTRINDEX_HASHSIZE; count++) {
116 list_for_each_entry_safe(xd, _xd, &c->xattrindex[index], xindex) {
117 if (xd->flags & JFFS2_XFLAGS_HOT) {
118 xd->flags &= ~JFFS2_XFLAGS_HOT;
119 } else if (!(xd->flags & JFFS2_XFLAGS_BIND)) {
120 unload_xattr_datum(c, xd);
121 }
122 if (c->xdatum_mem_usage <= target)
123 goto out;
124 }
125 index = (index+1) % XATTRINDEX_HASHSIZE;
126 }
127 out:
128 JFFS2_NOTICE("xdatum_mem_usage from %u byte to %u byte (%u byte reclaimed)\n",
129 before, c->xdatum_mem_usage, before - c->xdatum_mem_usage);
130 }
131
132 static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
133 {
134
135 struct jffs2_eraseblock *jeb;
136 struct jffs2_raw_node_ref *raw;
137 struct jffs2_raw_xattr rx;
138 size_t readlen;
139 uint32_t crc, offset, totlen;
140 int rc;
141
142 spin_lock(&c->erase_completion_lock);
143 offset = ref_offset(xd->node);
144 if (ref_flags(xd->node) == REF_PRISTINE)
145 goto complete;
146 spin_unlock(&c->erase_completion_lock);
147
148 rc = jffs2_flash_read(c, offset, sizeof(rx), &readlen, (char *)&rx);
149 if (rc || readlen != sizeof(rx)) {
150 JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu at %#08x\n",
151 rc, sizeof(rx), readlen, offset);
152 return rc ? rc : -EIO;
153 }
154 crc = crc32(0, &rx, sizeof(rx) - 4);
155 if (crc != je32_to_cpu(rx.node_crc)) {
156 JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
157 offset, je32_to_cpu(rx.hdr_crc), crc);
158 xd->flags |= JFFS2_XFLAGS_INVALID;
159 return JFFS2_XATTR_IS_CORRUPTED;
160 }
161 totlen = PAD(sizeof(rx) + rx.name_len + 1 + je16_to_cpu(rx.value_len));
162 if (je16_to_cpu(rx.magic) != JFFS2_MAGIC_BITMASK
163 || je16_to_cpu(rx.nodetype) != JFFS2_NODETYPE_XATTR
164 || je32_to_cpu(rx.totlen) != totlen
165 || je32_to_cpu(rx.xid) != xd->xid
166 || je32_to_cpu(rx.version) != xd->version) {
167 JFFS2_ERROR("inconsistent xdatum at %#08x, magic=%#04x/%#04x, "
168 "nodetype=%#04x/%#04x, totlen=%u/%u, xid=%u/%u, version=%u/%u\n",
169 offset, je16_to_cpu(rx.magic), JFFS2_MAGIC_BITMASK,
170 je16_to_cpu(rx.nodetype), JFFS2_NODETYPE_XATTR,
171 je32_to_cpu(rx.totlen), totlen,
172 je32_to_cpu(rx.xid), xd->xid,
173 je32_to_cpu(rx.version), xd->version);
174 xd->flags |= JFFS2_XFLAGS_INVALID;
175 return JFFS2_XATTR_IS_CORRUPTED;
176 }
177 xd->xprefix = rx.xprefix;
178 xd->name_len = rx.name_len;
179 xd->value_len = je16_to_cpu(rx.value_len);
180 xd->data_crc = je32_to_cpu(rx.data_crc);
181
182 spin_lock(&c->erase_completion_lock);
183 complete:
184 for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
185 jeb = &c->blocks[ref_offset(raw) / c->sector_size];
186 totlen = PAD(ref_totlen(c, jeb, raw));
187 if (ref_flags(raw) == REF_UNCHECKED) {
188 c->unchecked_size -= totlen; c->used_size += totlen;
189 jeb->unchecked_size -= totlen; jeb->used_size += totlen;
190 }
191 raw->flash_offset = ref_offset(raw) | ((xd->node==raw) ? REF_PRISTINE : REF_NORMAL);
192 }
193 spin_unlock(&c->erase_completion_lock);
194
195
196 list_del_init(&xd->xindex);
197
198 dbg_xattr("success on verifying xdatum (xid=%u, version=%u)\n",
199 xd->xid, xd->version);
200
201 return 0;
202 }
203
204 static int do_load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
205 {
206
207 char *data;
208 size_t readlen;
209 uint32_t crc, length;
210 int i, ret, retry = 0;
211
212 BUG_ON(ref_flags(xd->node) != REF_PRISTINE);
213 BUG_ON(!list_empty(&xd->xindex));
214 retry:
215 length = xd->name_len + 1 + xd->value_len;
216 data = kmalloc(length, GFP_KERNEL);
217 if (!data)
218 return -ENOMEM;
219
220 ret = jffs2_flash_read(c, ref_offset(xd->node)+sizeof(struct jffs2_raw_xattr),
221 length, &readlen, data);
222
223 if (ret || length!=readlen) {
224 JFFS2_WARNING("jffs2_flash_read() returned %d, request=%d, readlen=%zu, at %#08x\n",
225 ret, length, readlen, ref_offset(xd->node));
226 kfree(data);
227 return ret ? ret : -EIO;
228 }
229
230 data[xd->name_len] = '\0';
231 crc = crc32(0, data, length);
232 if (crc != xd->data_crc) {
233 JFFS2_WARNING("node CRC failed (JFFS2_NODETYPE_XATTR)"
234 " at %#08x, read: 0x%08x calculated: 0x%08x\n",
235 ref_offset(xd->node), xd->data_crc, crc);
236 kfree(data);
237 xd->flags |= JFFS2_XFLAGS_INVALID;
238 return JFFS2_XATTR_IS_CORRUPTED;
239 }
240
241 xd->flags |= JFFS2_XFLAGS_HOT;
242 xd->xname = data;
243 xd->xvalue = data + xd->name_len+1;
244
245 c->xdatum_mem_usage += length;
246
247 xd->hashkey = xattr_datum_hashkey(xd->xprefix, xd->xname, xd->xvalue, xd->value_len);
248 i = xd->hashkey % XATTRINDEX_HASHSIZE;
249 list_add(&xd->xindex, &c->xattrindex[i]);
250 if (!retry) {
251 retry = 1;
252 reclaim_xattr_datum(c);
253 if (!xd->xname)
254 goto retry;
255 }
256
257 dbg_xattr("success on loading xdatum (xid=%u, xprefix=%u, xname='%s')\n",
258 xd->xid, xd->xprefix, xd->xname);
259
260 return 0;
261 }
262
263 static int load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
264 {
265
266
267
268
269
270 int rc = 0;
271
272 BUG_ON(xd->flags & JFFS2_XFLAGS_DEAD);
273 if (xd->xname)
274 return 0;
275 if (xd->flags & JFFS2_XFLAGS_INVALID)
276 return JFFS2_XATTR_IS_CORRUPTED;
277 if (unlikely(is_xattr_datum_unchecked(c, xd)))
278 rc = do_verify_xattr_datum(c, xd);
279 if (!rc)
280 rc = do_load_xattr_datum(c, xd);
281 return rc;
282 }
283
284 static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
285 {
286
287 struct jffs2_raw_xattr rx;
288 struct kvec vecs[2];
289 size_t length;
290 int rc, totlen;
291 uint32_t phys_ofs = write_ofs(c);
292
293 BUG_ON(!xd->xname);
294 BUG_ON(xd->flags & (JFFS2_XFLAGS_DEAD|JFFS2_XFLAGS_INVALID));
295
296 vecs[0].iov_base = ℞
297 vecs[0].iov_len = sizeof(rx);
298 vecs[1].iov_base = xd->xname;
299 vecs[1].iov_len = xd->name_len + 1 + xd->value_len;
300 totlen = vecs[0].iov_len + vecs[1].iov_len;
301
302
303 memset(&rx, 0, sizeof(rx));
304 rx.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
305 rx.nodetype = cpu_to_je16(JFFS2_NODETYPE_XATTR);
306 rx.totlen = cpu_to_je32(PAD(totlen));
307 rx.hdr_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_unknown_node) - 4));
308
309 rx.xid = cpu_to_je32(xd->xid);
310 rx.version = cpu_to_je32(++xd->version);
311 rx.xprefix = xd->xprefix;
312 rx.name_len = xd->name_len;
313 rx.value_len = cpu_to_je16(xd->value_len);
314 rx.data_crc = cpu_to_je32(crc32(0, vecs[1].iov_base, vecs[1].iov_len));
315 rx.node_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_raw_xattr) - 4));
316
317 rc = jffs2_flash_writev(c, vecs, 2, phys_ofs, &length, 0);
318 if (rc || totlen != length) {
319 JFFS2_WARNING("jffs2_flash_writev()=%d, req=%u, wrote=%zu, at %#08x\n",
320 rc, totlen, length, phys_ofs);
321 rc = rc ? rc : -EIO;
322 if (length)
323 jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, PAD(totlen), NULL);
324
325 return rc;
326 }
327
328 jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(totlen), (void *)xd);
329
330 dbg_xattr("success on saving xdatum (xid=%u, version=%u, xprefix=%u, xname='%s')\n",
331 xd->xid, xd->version, xd->xprefix, xd->xname);
332
333 return 0;
334 }
335
336 static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c,
337 int xprefix, const char *xname,
338 const char *xvalue, int xsize)
339 {
340
341 struct jffs2_xattr_datum *xd;
342 uint32_t hashkey, name_len;
343 char *data;
344 int i, rc;
345
346
347 hashkey = xattr_datum_hashkey(xprefix, xname, xvalue, xsize);
348 i = hashkey % XATTRINDEX_HASHSIZE;
349 list_for_each_entry(xd, &c->xattrindex[i], xindex) {
350 if (xd->hashkey==hashkey
351 && xd->xprefix==xprefix
352 && xd->value_len==xsize
353 && !strcmp(xd->xname, xname)
354 && !memcmp(xd->xvalue, xvalue, xsize)) {
355 atomic_inc(&xd->refcnt);
356 return xd;
357 }
358 }
359
360
361 name_len = strlen(xname);
362
363 xd = jffs2_alloc_xattr_datum();
364 if (!xd)
365 return ERR_PTR(-ENOMEM);
366
367 data = kmalloc(name_len + 1 + xsize, GFP_KERNEL);
368 if (!data) {
369 jffs2_free_xattr_datum(xd);
370 return ERR_PTR(-ENOMEM);
371 }
372 strcpy(data, xname);
373 memcpy(data + name_len + 1, xvalue, xsize);
374
375 atomic_set(&xd->refcnt, 1);
376 xd->xid = ++c->highest_xid;
377 xd->flags |= JFFS2_XFLAGS_HOT;
378 xd->xprefix = xprefix;
379
380 xd->hashkey = hashkey;
381 xd->xname = data;
382 xd->xvalue = data + name_len + 1;
383 xd->name_len = name_len;
384 xd->value_len = xsize;
385 xd->data_crc = crc32(0, data, xd->name_len + 1 + xd->value_len);
386
387 rc = save_xattr_datum(c, xd);
388 if (rc) {
389 kfree(xd->xname);
390 jffs2_free_xattr_datum(xd);
391 return ERR_PTR(rc);
392 }
393
394
395 i = hashkey % XATTRINDEX_HASHSIZE;
396 list_add(&xd->xindex, &c->xattrindex[i]);
397
398 c->xdatum_mem_usage += (xd->name_len + 1 + xd->value_len);
399 reclaim_xattr_datum(c);
400
401 return xd;
402 }
403
404 static void unrefer_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
405 {
406
407 if (atomic_dec_and_lock(&xd->refcnt, &c->erase_completion_lock)) {
408 unload_xattr_datum(c, xd);
409 xd->flags |= JFFS2_XFLAGS_DEAD;
410 if (xd->node == (void *)xd) {
411 BUG_ON(!(xd->flags & JFFS2_XFLAGS_INVALID));
412 jffs2_free_xattr_datum(xd);
413 } else {
414 list_add(&xd->xindex, &c->xattr_dead_list);
415 }
416 spin_unlock(&c->erase_completion_lock);
417
418 dbg_xattr("xdatum(xid=%u, version=%u) was removed.\n",
419 xd->xid, xd->version);
420 }
421 }
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444 static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
445 {
446 struct jffs2_eraseblock *jeb;
447 struct jffs2_raw_node_ref *raw;
448 struct jffs2_raw_xref rr;
449 size_t readlen;
450 uint32_t crc, offset, totlen;
451 int rc;
452
453 spin_lock(&c->erase_completion_lock);
454 if (ref_flags(ref->node) != REF_UNCHECKED)
455 goto complete;
456 offset = ref_offset(ref->node);
457 spin_unlock(&c->erase_completion_lock);
458
459 rc = jffs2_flash_read(c, offset, sizeof(rr), &readlen, (char *)&rr);
460 if (rc || sizeof(rr) != readlen) {
461 JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu, at %#08x\n",
462 rc, sizeof(rr), readlen, offset);
463 return rc ? rc : -EIO;
464 }
465
466 crc = crc32(0, &rr, sizeof(rr) - 4);
467 if (crc != je32_to_cpu(rr.node_crc)) {
468 JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
469 offset, je32_to_cpu(rr.node_crc), crc);
470 return JFFS2_XATTR_IS_CORRUPTED;
471 }
472 if (je16_to_cpu(rr.magic) != JFFS2_MAGIC_BITMASK
473 || je16_to_cpu(rr.nodetype) != JFFS2_NODETYPE_XREF
474 || je32_to_cpu(rr.totlen) != PAD(sizeof(rr))) {
475 JFFS2_ERROR("inconsistent xref at %#08x, magic=%#04x/%#04x, "
476 "nodetype=%#04x/%#04x, totlen=%u/%zu\n",
477 offset, je16_to_cpu(rr.magic), JFFS2_MAGIC_BITMASK,
478 je16_to_cpu(rr.nodetype), JFFS2_NODETYPE_XREF,
479 je32_to_cpu(rr.totlen), PAD(sizeof(rr)));
480 return JFFS2_XATTR_IS_CORRUPTED;
481 }
482 ref->ino = je32_to_cpu(rr.ino);
483 ref->xid = je32_to_cpu(rr.xid);
484 ref->xseqno = je32_to_cpu(rr.xseqno);
485 if (ref->xseqno > c->highest_xseqno)
486 c->highest_xseqno = (ref->xseqno & ~XREF_DELETE_MARKER);
487
488 spin_lock(&c->erase_completion_lock);
489 complete:
490 for (raw=ref->node; raw != (void *)ref; raw=raw->next_in_ino) {
491 jeb = &c->blocks[ref_offset(raw) / c->sector_size];
492 totlen = PAD(ref_totlen(c, jeb, raw));
493 if (ref_flags(raw) == REF_UNCHECKED) {
494 c->unchecked_size -= totlen; c->used_size += totlen;
495 jeb->unchecked_size -= totlen; jeb->used_size += totlen;
496 }
497 raw->flash_offset = ref_offset(raw) | ((ref->node==raw) ? REF_PRISTINE : REF_NORMAL);
498 }
499 spin_unlock(&c->erase_completion_lock);
500
501 dbg_xattr("success on verifying xref (ino=%u, xid=%u) at %#08x\n",
502 ref->ino, ref->xid, ref_offset(ref->node));
503 return 0;
504 }
505
506 static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
507 {
508
509 struct jffs2_raw_xref rr;
510 size_t length;
511 uint32_t xseqno, phys_ofs = write_ofs(c);
512 int ret;
513
514 rr.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
515 rr.nodetype = cpu_to_je16(JFFS2_NODETYPE_XREF);
516 rr.totlen = cpu_to_je32(PAD(sizeof(rr)));
517 rr.hdr_crc = cpu_to_je32(crc32(0, &rr, sizeof(struct jffs2_unknown_node) - 4));
518
519 xseqno = (c->highest_xseqno += 2);
520 if (is_xattr_ref_dead(ref)) {
521 xseqno |= XREF_DELETE_MARKER;
522 rr.ino = cpu_to_je32(ref->ino);
523 rr.xid = cpu_to_je32(ref->xid);
524 } else {
525 rr.ino = cpu_to_je32(ref->ic->ino);
526 rr.xid = cpu_to_je32(ref->xd->xid);
527 }
528 rr.xseqno = cpu_to_je32(xseqno);
529 rr.node_crc = cpu_to_je32(crc32(0, &rr, sizeof(rr) - 4));
530
531 ret = jffs2_flash_write(c, phys_ofs, sizeof(rr), &length, (char *)&rr);
532 if (ret || sizeof(rr) != length) {
533 JFFS2_WARNING("jffs2_flash_write() returned %d, request=%zu, retlen=%zu, at %#08x\n",
534 ret, sizeof(rr), length, phys_ofs);
535 ret = ret ? ret : -EIO;
536 if (length)
537 jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, PAD(sizeof(rr)), NULL);
538
539 return ret;
540 }
541
542 ref->xseqno = xseqno;
543 jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(sizeof(rr)), (void *)ref);
544
545 dbg_xattr("success on saving xref (ino=%u, xid=%u)\n", ref->ic->ino, ref->xd->xid);
546
547 return 0;
548 }
549
550 static struct jffs2_xattr_ref *create_xattr_ref(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic,
551 struct jffs2_xattr_datum *xd)
552 {
553
554 struct jffs2_xattr_ref *ref;
555 int ret;
556
557 ref = jffs2_alloc_xattr_ref();
558 if (!ref)
559 return ERR_PTR(-ENOMEM);
560 ref->ic = ic;
561 ref->xd = xd;
562
563 ret = save_xattr_ref(c, ref);
564 if (ret) {
565 jffs2_free_xattr_ref(ref);
566 return ERR_PTR(ret);
567 }
568
569
570 ref->next = ic->xref;
571 ic->xref = ref;
572
573 return ref;
574 }
575
576 static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
577 {
578
579 struct jffs2_xattr_datum *xd;
580
581 xd = ref->xd;
582 ref->xseqno |= XREF_DELETE_MARKER;
583 ref->ino = ref->ic->ino;
584 ref->xid = ref->xd->xid;
585 spin_lock(&c->erase_completion_lock);
586 ref->next = c->xref_dead_list;
587 c->xref_dead_list = ref;
588 spin_unlock(&c->erase_completion_lock);
589
590 dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) was removed.\n",
591 ref->ino, ref->xid, ref->xseqno);
592
593 unrefer_xattr_datum(c, xd);
594 }
595
596 void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
597 {
598
599
600 struct jffs2_xattr_ref *ref, *_ref;
601
602 if (!ic || ic->pino_nlink > 0)
603 return;
604
605 down_write(&c->xattr_sem);
606 for (ref = ic->xref; ref; ref = _ref) {
607 _ref = ref->next;
608 delete_xattr_ref(c, ref);
609 }
610 ic->xref = NULL;
611 up_write(&c->xattr_sem);
612 }
613
614 void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
615 {
616
617 struct jffs2_xattr_datum *xd;
618 struct jffs2_xattr_ref *ref, *_ref;
619
620 down_write(&c->xattr_sem);
621 for (ref = ic->xref; ref; ref = _ref) {
622 _ref = ref->next;
623 xd = ref->xd;
624 if (atomic_dec_and_test(&xd->refcnt)) {
625 unload_xattr_datum(c, xd);
626 jffs2_free_xattr_datum(xd);
627 }
628 jffs2_free_xattr_ref(ref);
629 }
630 ic->xref = NULL;
631 up_write(&c->xattr_sem);
632 }
633
634 static int check_xattr_ref_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
635 {
636
637
638
639
640 struct jffs2_xattr_ref *ref, *cmp, **pref, **pcmp;
641 int rc = 0;
642
643 if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED))
644 return 0;
645 down_write(&c->xattr_sem);
646 retry:
647 rc = 0;
648 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
649 if (!ref->xd->xname) {
650 rc = load_xattr_datum(c, ref->xd);
651 if (unlikely(rc > 0)) {
652 *pref = ref->next;
653 delete_xattr_ref(c, ref);
654 goto retry;
655 } else if (unlikely(rc < 0))
656 goto out;
657 }
658 for (cmp=ref->next, pcmp=&ref->next; cmp; pcmp=&cmp->next, cmp=cmp->next) {
659 if (!cmp->xd->xname) {
660 ref->xd->flags |= JFFS2_XFLAGS_BIND;
661 rc = load_xattr_datum(c, cmp->xd);
662 ref->xd->flags &= ~JFFS2_XFLAGS_BIND;
663 if (unlikely(rc > 0)) {
664 *pcmp = cmp->next;
665 delete_xattr_ref(c, cmp);
666 goto retry;
667 } else if (unlikely(rc < 0))
668 goto out;
669 }
670 if (ref->xd->xprefix == cmp->xd->xprefix
671 && !strcmp(ref->xd->xname, cmp->xd->xname)) {
672 if (ref->xseqno > cmp->xseqno) {
673 *pcmp = cmp->next;
674 delete_xattr_ref(c, cmp);
675 } else {
676 *pref = ref->next;
677 delete_xattr_ref(c, ref);
678 }
679 goto retry;
680 }
681 }
682 }
683 ic->flags |= INO_FLAGS_XATTR_CHECKED;
684 out:
685 up_write(&c->xattr_sem);
686
687 return rc;
688 }
689
690 void jffs2_xattr_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
691 {
692 check_xattr_ref_inode(c, ic);
693 }
694
695
696
697
698
699
700
701
702
703
704
705
706
707 void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c)
708 {
709 int i;
710
711 for (i=0; i < XATTRINDEX_HASHSIZE; i++)
712 INIT_LIST_HEAD(&c->xattrindex[i]);
713 INIT_LIST_HEAD(&c->xattr_unchecked);
714 INIT_LIST_HEAD(&c->xattr_dead_list);
715 c->xref_dead_list = NULL;
716 c->xref_temp = NULL;
717
718 init_rwsem(&c->xattr_sem);
719 c->highest_xid = 0;
720 c->highest_xseqno = 0;
721 c->xdatum_mem_usage = 0;
722 c->xdatum_mem_threshold = 32 * 1024;
723 }
724
725 static struct jffs2_xattr_datum *jffs2_find_xattr_datum(struct jffs2_sb_info *c, uint32_t xid)
726 {
727 struct jffs2_xattr_datum *xd;
728 int i = xid % XATTRINDEX_HASHSIZE;
729
730
731 BUG_ON(!(c->flags & (JFFS2_SB_FLAG_SCANNING|JFFS2_SB_FLAG_BUILDING)));
732
733 list_for_each_entry(xd, &c->xattrindex[i], xindex) {
734 if (xd->xid==xid)
735 return xd;
736 }
737 return NULL;
738 }
739
740 void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c)
741 {
742 struct jffs2_xattr_datum *xd, *_xd;
743 struct jffs2_xattr_ref *ref, *_ref;
744 int i;
745
746 for (ref=c->xref_temp; ref; ref = _ref) {
747 _ref = ref->next;
748 jffs2_free_xattr_ref(ref);
749 }
750
751 for (ref=c->xref_dead_list; ref; ref = _ref) {
752 _ref = ref->next;
753 jffs2_free_xattr_ref(ref);
754 }
755
756 for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
757 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
758 list_del(&xd->xindex);
759 kfree(xd->xname);
760 jffs2_free_xattr_datum(xd);
761 }
762 }
763
764 list_for_each_entry_safe(xd, _xd, &c->xattr_dead_list, xindex) {
765 list_del(&xd->xindex);
766 jffs2_free_xattr_datum(xd);
767 }
768 list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) {
769 list_del(&xd->xindex);
770 jffs2_free_xattr_datum(xd);
771 }
772 }
773
774 #define XREF_TMPHASH_SIZE (128)
775 void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
776 {
777 struct jffs2_xattr_ref *ref, *_ref;
778 struct jffs2_xattr_ref *xref_tmphash[XREF_TMPHASH_SIZE];
779 struct jffs2_xattr_datum *xd, *_xd;
780 struct jffs2_inode_cache *ic;
781 struct jffs2_raw_node_ref *raw;
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;
784
785 BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING));
786
787
788 for (i=0; i < XREF_TMPHASH_SIZE; i++)
789 xref_tmphash[i] = NULL;
790 for (ref=c->xref_temp; ref; ref=_ref) {
791 struct jffs2_xattr_ref *tmp;
792
793 _ref = ref->next;
794 if (ref_flags(ref->node) != REF_PRISTINE) {
795 if (verify_xattr_ref(c, ref)) {
796 BUG_ON(ref->node->next_in_ino != (void *)ref);
797 ref->node->next_in_ino = NULL;
798 jffs2_mark_node_obsolete(c, ref->node);
799 jffs2_free_xattr_ref(ref);
800 continue;
801 }
802 }
803
804 i = (ref->ino ^ ref->xid) % XREF_TMPHASH_SIZE;
805 for (tmp=xref_tmphash[i]; tmp; tmp=tmp->next) {
806 if (tmp->ino == ref->ino && tmp->xid == ref->xid)
807 break;
808 }
809 if (tmp) {
810 raw = ref->node;
811 if (ref->xseqno > tmp->xseqno) {
812 tmp->xseqno = ref->xseqno;
813 raw->next_in_ino = tmp->node;
814 tmp->node = raw;
815 } else {
816 raw->next_in_ino = tmp->node->next_in_ino;
817 tmp->node->next_in_ino = raw;
818 }
819 jffs2_free_xattr_ref(ref);
820 continue;
821 } else {
822 ref->next = xref_tmphash[i];
823 xref_tmphash[i] = ref;
824 }
825 }
826 c->xref_temp = NULL;
827
828
829 for (i=0; i < XREF_TMPHASH_SIZE; i++) {
830 for (ref=xref_tmphash[i]; ref; ref=_ref) {
831 xref_count++;
832 _ref = ref->next;
833 if (is_xattr_ref_dead(ref)) {
834 ref->next = c->xref_dead_list;
835 c->xref_dead_list = ref;
836 xref_dead_count++;
837 continue;
838 }
839
840
841 xd = jffs2_find_xattr_datum(c, ref->xid);
842 ic = jffs2_get_ino_cache(c, ref->ino);
843 if (!xd || !ic || !ic->pino_nlink) {
844 dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) is orphan.\n",
845 ref->ino, ref->xid, ref->xseqno);
846 ref->xseqno |= XREF_DELETE_MARKER;
847 ref->next = c->xref_dead_list;
848 c->xref_dead_list = ref;
849 xref_orphan_count++;
850 continue;
851 }
852 ref->xd = xd;
853 ref->ic = ic;
854 atomic_inc(&xd->refcnt);
855 ref->next = ic->xref;
856 ic->xref = ref;
857 }
858 }
859
860
861 for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
862 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
863 xdatum_count++;
864 list_del_init(&xd->xindex);
865 if (!atomic_read(&xd->refcnt)) {
866 dbg_xattr("xdatum(xid=%u, version=%u) is orphan.\n",
867 xd->xid, xd->version);
868 xd->flags |= JFFS2_XFLAGS_DEAD;
869 list_add(&xd->xindex, &c->xattr_unchecked);
870 xdatum_orphan_count++;
871 continue;
872 }
873 if (is_xattr_datum_unchecked(c, xd)) {
874 dbg_xattr("unchecked xdatum(xid=%u, version=%u)\n",
875 xd->xid, xd->version);
876 list_add(&xd->xindex, &c->xattr_unchecked);
877 xdatum_unchecked_count++;
878 }
879 }
880 }
881
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);
887 }
888
889 struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,
890 uint32_t xid, uint32_t version)
891 {
892 struct jffs2_xattr_datum *xd;
893
894 xd = jffs2_find_xattr_datum(c, xid);
895 if (!xd) {
896 xd = jffs2_alloc_xattr_datum();
897 if (!xd)
898 return ERR_PTR(-ENOMEM);
899 xd->xid = xid;
900 xd->version = version;
901 if (xd->xid > c->highest_xid)
902 c->highest_xid = xd->xid;
903 list_add_tail(&xd->xindex, &c->xattrindex[xid % XATTRINDEX_HASHSIZE]);
904 }
905 return xd;
906 }
907
908
909
910
911
912
913
914
915
916
917
918 const struct xattr_handler *jffs2_xattr_handlers[] = {
919 &jffs2_user_xattr_handler,
920 #ifdef CONFIG_JFFS2_FS_SECURITY
921 &jffs2_security_xattr_handler,
922 #endif
923 #ifdef CONFIG_JFFS2_FS_POSIX_ACL
924 &posix_acl_access_xattr_handler,
925 &posix_acl_default_xattr_handler,
926 #endif
927 &jffs2_trusted_xattr_handler,
928 NULL
929 };
930
931 static const struct xattr_handler *xprefix_to_handler(int xprefix) {
932 const struct xattr_handler *ret;
933
934 switch (xprefix) {
935 case JFFS2_XPREFIX_USER:
936 ret = &jffs2_user_xattr_handler;
937 break;
938 #ifdef CONFIG_JFFS2_FS_SECURITY
939 case JFFS2_XPREFIX_SECURITY:
940 ret = &jffs2_security_xattr_handler;
941 break;
942 #endif
943 #ifdef CONFIG_JFFS2_FS_POSIX_ACL
944 case JFFS2_XPREFIX_ACL_ACCESS:
945 ret = &posix_acl_access_xattr_handler;
946 break;
947 case JFFS2_XPREFIX_ACL_DEFAULT:
948 ret = &posix_acl_default_xattr_handler;
949 break;
950 #endif
951 case JFFS2_XPREFIX_TRUSTED:
952 ret = &jffs2_trusted_xattr_handler;
953 break;
954 default:
955 ret = NULL;
956 break;
957 }
958 return ret;
959 }
960
961 ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
962 {
963 struct inode *inode = d_inode(dentry);
964 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
965 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
966 struct jffs2_inode_cache *ic = f->inocache;
967 struct jffs2_xattr_ref *ref, **pref;
968 struct jffs2_xattr_datum *xd;
969 const struct xattr_handler *xhandle;
970 const char *prefix;
971 ssize_t prefix_len, len, rc;
972 int retry = 0;
973
974 rc = check_xattr_ref_inode(c, ic);
975 if (unlikely(rc))
976 return rc;
977
978 down_read(&c->xattr_sem);
979 retry:
980 len = 0;
981 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
982 BUG_ON(ref->ic != ic);
983 xd = ref->xd;
984 if (!xd->xname) {
985
986 if (!retry) {
987 retry = 1;
988 up_read(&c->xattr_sem);
989 down_write(&c->xattr_sem);
990 goto retry;
991 } else {
992 rc = load_xattr_datum(c, xd);
993 if (unlikely(rc > 0)) {
994 *pref = ref->next;
995 delete_xattr_ref(c, ref);
996 goto retry;
997 } else if (unlikely(rc < 0))
998 goto out;
999 }
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 }