1
2
3
4
5
6
7
8
9
10
11
12#include <linux/kernel.h>
13#include <linux/slab.h>
14#include <linux/fs.h>
15#include <linux/time.h>
16#include <linux/pagemap.h>
17#include <linux/highmem.h>
18#include <linux/crc32.h>
19#include <linux/jffs2.h>
20#include <linux/xattr.h>
21#include <linux/mtd/mtd.h>
22#include "nodelist.h"
23
24
25
26
27
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
59static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *xvalue, int xsize)
60{
61 int name_len = strlen(xname);
62
63 return crc32(xprefix, xname, name_len) ^ crc32(xprefix, xvalue, xsize);
64}
65
66static int is_xattr_datum_unchecked(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
67{
68 struct jffs2_raw_node_ref *raw;
69 int rc = 0;
70
71 spin_lock(&c->erase_completion_lock);
72 for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
73 if (ref_flags(raw) == REF_UNCHECKED) {
74 rc = 1;
75 break;
76 }
77 }
78 spin_unlock(&c->erase_completion_lock);
79 return rc;
80}
81
82static void unload_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
83{
84
85 D1(dbg_xattr("%s: xid=%u, version=%u\n", __func__, xd->xid, xd->version));
86 if (xd->xname) {
87 c->xdatum_mem_usage -= (xd->name_len + 1 + xd->value_len);
88 kfree(xd->xname);
89 }
90
91 list_del_init(&xd->xindex);
92 xd->hashkey = 0;
93 xd->xname = NULL;
94 xd->xvalue = NULL;
95}
96
97static void reclaim_xattr_datum(struct jffs2_sb_info *c)
98{
99
100 struct jffs2_xattr_datum *xd, *_xd;
101 uint32_t target, before;
102 static int index = 0;
103 int count;
104
105 if (c->xdatum_mem_threshold > c->xdatum_mem_usage)
106 return;
107
108 before = c->xdatum_mem_usage;
109 target = c->xdatum_mem_usage * 4 / 5;
110 for (count = 0; count < XATTRINDEX_HASHSIZE; count++) {
111 list_for_each_entry_safe(xd, _xd, &c->xattrindex[index], xindex) {
112 if (xd->flags & JFFS2_XFLAGS_HOT) {
113 xd->flags &= ~JFFS2_XFLAGS_HOT;
114 } else if (!(xd->flags & JFFS2_XFLAGS_BIND)) {
115 unload_xattr_datum(c, xd);
116 }
117 if (c->xdatum_mem_usage <= target)
118 goto out;
119 }
120 index = (index+1) % XATTRINDEX_HASHSIZE;
121 }
122 out:
123 JFFS2_NOTICE("xdatum_mem_usage from %u byte to %u byte (%u byte reclaimed)\n",
124 before, c->xdatum_mem_usage, before - c->xdatum_mem_usage);
125}
126
127static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
128{
129
130 struct jffs2_eraseblock *jeb;
131 struct jffs2_raw_node_ref *raw;
132 struct jffs2_raw_xattr rx;
133 size_t readlen;
134 uint32_t crc, offset, totlen;
135 int rc;
136
137 spin_lock(&c->erase_completion_lock);
138 offset = ref_offset(xd->node);
139 if (ref_flags(xd->node) == REF_PRISTINE)
140 goto complete;
141 spin_unlock(&c->erase_completion_lock);
142
143 rc = jffs2_flash_read(c, offset, sizeof(rx), &readlen, (char *)&rx);
144 if (rc || readlen != sizeof(rx)) {
145 JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu at %#08x\n",
146 rc, sizeof(rx), readlen, offset);
147 return rc ? rc : -EIO;
148 }
149 crc = crc32(0, &rx, sizeof(rx) - 4);
150 if (crc != je32_to_cpu(rx.node_crc)) {
151 JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
152 offset, je32_to_cpu(rx.hdr_crc), crc);
153 xd->flags |= JFFS2_XFLAGS_INVALID;
154 return EIO;
155 }
156 totlen = PAD(sizeof(rx) + rx.name_len + 1 + je16_to_cpu(rx.value_len));
157 if (je16_to_cpu(rx.magic) != JFFS2_MAGIC_BITMASK
158 || je16_to_cpu(rx.nodetype) != JFFS2_NODETYPE_XATTR
159 || je32_to_cpu(rx.totlen) != totlen
160 || je32_to_cpu(rx.xid) != xd->xid
161 || je32_to_cpu(rx.version) != xd->version) {
162 JFFS2_ERROR("inconsistent xdatum at %#08x, magic=%#04x/%#04x, "
163 "nodetype=%#04x/%#04x, totlen=%u/%u, xid=%u/%u, version=%u/%u\n",
164 offset, je16_to_cpu(rx.magic), JFFS2_MAGIC_BITMASK,
165 je16_to_cpu(rx.nodetype), JFFS2_NODETYPE_XATTR,
166 je32_to_cpu(rx.totlen), totlen,
167 je32_to_cpu(rx.xid), xd->xid,
168 je32_to_cpu(rx.version), xd->version);
169 xd->flags |= JFFS2_XFLAGS_INVALID;
170 return EIO;
171 }
172 xd->xprefix = rx.xprefix;
173 xd->name_len = rx.name_len;
174 xd->value_len = je16_to_cpu(rx.value_len);
175 xd->data_crc = je32_to_cpu(rx.data_crc);
176
177 spin_lock(&c->erase_completion_lock);
178 complete:
179 for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
180 jeb = &c->blocks[ref_offset(raw) / c->sector_size];
181 totlen = PAD(ref_totlen(c, jeb, raw));
182 if (ref_flags(raw) == REF_UNCHECKED) {
183 c->unchecked_size -= totlen; c->used_size += totlen;
184 jeb->unchecked_size -= totlen; jeb->used_size += totlen;
185 }
186 raw->flash_offset = ref_offset(raw) | ((xd->node==raw) ? REF_PRISTINE : REF_NORMAL);
187 }
188 spin_unlock(&c->erase_completion_lock);
189
190
191 list_del_init(&xd->xindex);
192
193 dbg_xattr("success on verfying xdatum (xid=%u, version=%u)\n",
194 xd->xid, xd->version);
195
196 return 0;
197}
198
199static int do_load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
200{
201
202 char *data;
203 size_t readlen;
204 uint32_t crc, length;
205 int i, ret, retry = 0;
206
207 BUG_ON(ref_flags(xd->node) != REF_PRISTINE);
208 BUG_ON(!list_empty(&xd->xindex));
209 retry:
210 length = xd->name_len + 1 + xd->value_len;
211 data = kmalloc(length, GFP_KERNEL);
212 if (!data)
213 return -ENOMEM;
214
215 ret = jffs2_flash_read(c, ref_offset(xd->node)+sizeof(struct jffs2_raw_xattr),
216 length, &readlen, data);
217
218 if (ret || length!=readlen) {
219 JFFS2_WARNING("jffs2_flash_read() returned %d, request=%d, readlen=%zu, at %#08x\n",
220 ret, length, readlen, ref_offset(xd->node));
221 kfree(data);
222 return ret ? ret : -EIO;
223 }
224
225 data[xd->name_len] = '\0';
226 crc = crc32(0, data, length);
227 if (crc != xd->data_crc) {
228 JFFS2_WARNING("node CRC failed (JFFS2_NODETYPE_XREF)"
229 " at %#08x, read: 0x%08x calculated: 0x%08x\n",
230 ref_offset(xd->node), xd->data_crc, crc);
231 kfree(data);
232 xd->flags |= JFFS2_XFLAGS_INVALID;
233 return EIO;
234 }
235
236 xd->flags |= JFFS2_XFLAGS_HOT;
237 xd->xname = data;
238 xd->xvalue = data + xd->name_len+1;
239
240 c->xdatum_mem_usage += length;
241
242 xd->hashkey = xattr_datum_hashkey(xd->xprefix, xd->xname, xd->xvalue, xd->value_len);
243 i = xd->hashkey % XATTRINDEX_HASHSIZE;
244 list_add(&xd->xindex, &c->xattrindex[i]);
245 if (!retry) {
246 retry = 1;
247 reclaim_xattr_datum(c);
248 if (!xd->xname)
249 goto retry;
250 }
251
252 dbg_xattr("success on loading xdatum (xid=%u, xprefix=%u, xname='%s')\n",
253 xd->xid, xd->xprefix, xd->xname);
254
255 return 0;
256}
257
258static int load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
259{
260
261
262
263
264
265 int rc = 0;
266
267 BUG_ON(xd->flags & JFFS2_XFLAGS_DEAD);
268 if (xd->xname)
269 return 0;
270 if (xd->flags & JFFS2_XFLAGS_INVALID)
271 return EIO;
272 if (unlikely(is_xattr_datum_unchecked(c, xd)))
273 rc = do_verify_xattr_datum(c, xd);
274 if (!rc)
275 rc = do_load_xattr_datum(c, xd);
276 return rc;
277}
278
279static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
280{
281
282 struct jffs2_raw_xattr rx;
283 struct kvec vecs[2];
284 size_t length;
285 int rc, totlen;
286 uint32_t phys_ofs = write_ofs(c);
287
288 BUG_ON(!xd->xname);
289 BUG_ON(xd->flags & (JFFS2_XFLAGS_DEAD|JFFS2_XFLAGS_INVALID));
290
291 vecs[0].iov_base = ℞
292 vecs[0].iov_len = sizeof(rx);
293 vecs[1].iov_base = xd->xname;
294 vecs[1].iov_len = xd->name_len + 1 + xd->value_len;
295 totlen = vecs[0].iov_len + vecs[1].iov_len;
296
297
298 memset(&rx, 0, sizeof(rx));
299 rx.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
300 rx.nodetype = cpu_to_je16(JFFS2_NODETYPE_XATTR);
301 rx.totlen = cpu_to_je32(PAD(totlen));
302 rx.hdr_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_unknown_node) - 4));
303
304 rx.xid = cpu_to_je32(xd->xid);
305 rx.version = cpu_to_je32(++xd->version);
306 rx.xprefix = xd->xprefix;
307 rx.name_len = xd->name_len;
308 rx.value_len = cpu_to_je16(xd->value_len);
309 rx.data_crc = cpu_to_je32(crc32(0, vecs[1].iov_base, vecs[1].iov_len));
310 rx.node_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_raw_xattr) - 4));
311
312 rc = jffs2_flash_writev(c, vecs, 2, phys_ofs, &length, 0);
313 if (rc || totlen != length) {
314 JFFS2_WARNING("jffs2_flash_writev()=%d, req=%u, wrote=%zu, at %#08x\n",
315 rc, totlen, length, phys_ofs);
316 rc = rc ? rc : -EIO;
317 if (length)
318 jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, PAD(totlen), NULL);
319
320 return rc;
321 }
322
323 jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(totlen), (void *)xd);
324
325 dbg_xattr("success on saving xdatum (xid=%u, version=%u, xprefix=%u, xname='%s')\n",
326 xd->xid, xd->version, xd->xprefix, xd->xname);
327
328 return 0;
329}
330
331static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c,
332 int xprefix, const char *xname,
333 const char *xvalue, int xsize)
334{
335
336 struct jffs2_xattr_datum *xd;
337 uint32_t hashkey, name_len;
338 char *data;
339 int i, rc;
340
341
342 hashkey = xattr_datum_hashkey(xprefix, xname, xvalue, xsize);
343 i = hashkey % XATTRINDEX_HASHSIZE;
344 list_for_each_entry(xd, &c->xattrindex[i], xindex) {
345 if (xd->hashkey==hashkey
346 && xd->xprefix==xprefix
347 && xd->value_len==xsize
348 && !strcmp(xd->xname, xname)
349 && !memcmp(xd->xvalue, xvalue, xsize)) {
350 atomic_inc(&xd->refcnt);
351 return xd;
352 }
353 }
354
355
356 name_len = strlen(xname);
357
358 xd = jffs2_alloc_xattr_datum();
359 if (!xd)
360 return ERR_PTR(-ENOMEM);
361
362 data = kmalloc(name_len + 1 + xsize, GFP_KERNEL);
363 if (!data) {
364 jffs2_free_xattr_datum(xd);
365 return ERR_PTR(-ENOMEM);
366 }
367 strcpy(data, xname);
368 memcpy(data + name_len + 1, xvalue, xsize);
369
370 atomic_set(&xd->refcnt, 1);
371 xd->xid = ++c->highest_xid;
372 xd->flags |= JFFS2_XFLAGS_HOT;
373 xd->xprefix = xprefix;
374
375 xd->hashkey = hashkey;
376 xd->xname = data;
377 xd->xvalue = data + name_len + 1;
378 xd->name_len = name_len;
379 xd->value_len = xsize;
380 xd->data_crc = crc32(0, data, xd->name_len + 1 + xd->value_len);
381
382 rc = save_xattr_datum(c, xd);
383 if (rc) {
384 kfree(xd->xname);
385 jffs2_free_xattr_datum(xd);
386 return ERR_PTR(rc);
387 }
388
389
390 i = hashkey % XATTRINDEX_HASHSIZE;
391 list_add(&xd->xindex, &c->xattrindex[i]);
392
393 c->xdatum_mem_usage += (xd->name_len + 1 + xd->value_len);
394 reclaim_xattr_datum(c);
395
396 return xd;
397}
398
399static void unrefer_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
400{
401
402 if (atomic_dec_and_lock(&xd->refcnt, &c->erase_completion_lock)) {
403 unload_xattr_datum(c, xd);
404 xd->flags |= JFFS2_XFLAGS_DEAD;
405 if (xd->node == (void *)xd) {
406 BUG_ON(!(xd->flags & JFFS2_XFLAGS_INVALID));
407 jffs2_free_xattr_datum(xd);
408 } else {
409 list_add(&xd->xindex, &c->xattr_dead_list);
410 }
411 spin_unlock(&c->erase_completion_lock);
412
413 dbg_xattr("xdatum(xid=%u, version=%u) was removed.\n",
414 xd->xid, xd->version);
415 }
416}
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
438{
439 struct jffs2_eraseblock *jeb;
440 struct jffs2_raw_node_ref *raw;
441 struct jffs2_raw_xref rr;
442 size_t readlen;
443 uint32_t crc, offset, totlen;
444 int rc;
445
446 spin_lock(&c->erase_completion_lock);
447 if (ref_flags(ref->node) != REF_UNCHECKED)
448 goto complete;
449 offset = ref_offset(ref->node);
450 spin_unlock(&c->erase_completion_lock);
451
452 rc = jffs2_flash_read(c, offset, sizeof(rr), &readlen, (char *)&rr);
453 if (rc || sizeof(rr) != readlen) {
454 JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu, at %#08x\n",
455 rc, sizeof(rr), readlen, offset);
456 return rc ? rc : -EIO;
457 }
458
459 crc = crc32(0, &rr, sizeof(rr) - 4);
460 if (crc != je32_to_cpu(rr.node_crc)) {
461 JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
462 offset, je32_to_cpu(rr.node_crc), crc);
463 return EIO;
464 }
465 if (je16_to_cpu(rr.magic) != JFFS2_MAGIC_BITMASK
466 || je16_to_cpu(rr.nodetype) != JFFS2_NODETYPE_XREF
467 || je32_to_cpu(rr.totlen) != PAD(sizeof(rr))) {
468 JFFS2_ERROR("inconsistent xref at %#08x, magic=%#04x/%#04x, "
469 "nodetype=%#04x/%#04x, totlen=%u/%zu\n",
470 offset, je16_to_cpu(rr.magic), JFFS2_MAGIC_BITMASK,
471 je16_to_cpu(rr.nodetype), JFFS2_NODETYPE_XREF,
472 je32_to_cpu(rr.totlen), PAD(sizeof(rr)));
473 return EIO;
474 }
475 ref->ino = je32_to_cpu(rr.ino);
476 ref->xid = je32_to_cpu(rr.xid);
477 ref->xseqno = je32_to_cpu(rr.xseqno);
478 if (ref->xseqno > c->highest_xseqno)
479 c->highest_xseqno = (ref->xseqno & ~XREF_DELETE_MARKER);
480
481 spin_lock(&c->erase_completion_lock);
482 complete:
483 for (raw=ref->node; raw != (void *)ref; raw=raw->next_in_ino) {
484 jeb = &c->blocks[ref_offset(raw) / c->sector_size];
485 totlen = PAD(ref_totlen(c, jeb, raw));
486 if (ref_flags(raw) == REF_UNCHECKED) {
487 c->unchecked_size -= totlen; c->used_size += totlen;
488 jeb->unchecked_size -= totlen; jeb->used_size += totlen;
489 }
490 raw->flash_offset = ref_offset(raw) | ((ref->node==raw) ? REF_PRISTINE : REF_NORMAL);
491 }
492 spin_unlock(&c->erase_completion_lock);
493
494 dbg_xattr("success on verifying xref (ino=%u, xid=%u) at %#08x\n",
495 ref->ino, ref->xid, ref_offset(ref->node));
496 return 0;
497}
498
499static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
500{
501
502 struct jffs2_raw_xref rr;
503 size_t length;
504 uint32_t xseqno, phys_ofs = write_ofs(c);
505 int ret;
506
507 rr.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
508 rr.nodetype = cpu_to_je16(JFFS2_NODETYPE_XREF);
509 rr.totlen = cpu_to_je32(PAD(sizeof(rr)));
510 rr.hdr_crc = cpu_to_je32(crc32(0, &rr, sizeof(struct jffs2_unknown_node) - 4));
511
512 xseqno = (c->highest_xseqno += 2);
513 if (is_xattr_ref_dead(ref)) {
514 xseqno |= XREF_DELETE_MARKER;
515 rr.ino = cpu_to_je32(ref->ino);
516 rr.xid = cpu_to_je32(ref->xid);
517 } else {
518 rr.ino = cpu_to_je32(ref->ic->ino);
519 rr.xid = cpu_to_je32(ref->xd->xid);
520 }
521 rr.xseqno = cpu_to_je32(xseqno);
522 rr.node_crc = cpu_to_je32(crc32(0, &rr, sizeof(rr) - 4));
523
524 ret = jffs2_flash_write(c, phys_ofs, sizeof(rr), &length, (char *)&rr);
525 if (ret || sizeof(rr) != length) {
526 JFFS2_WARNING("jffs2_flash_write() returned %d, request=%zu, retlen=%zu, at %#08x\n",
527 ret, sizeof(rr), length, phys_ofs);
528 ret = ret ? ret : -EIO;
529 if (length)
530 jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, PAD(sizeof(rr)), NULL);
531
532 return ret;
533 }
534
535 ref->xseqno = xseqno;
536 jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(sizeof(rr)), (void *)ref);
537
538 dbg_xattr("success on saving xref (ino=%u, xid=%u)\n", ref->ic->ino, ref->xd->xid);
539
540 return 0;
541}
542
543static struct jffs2_xattr_ref *create_xattr_ref(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic,
544 struct jffs2_xattr_datum *xd)
545{
546
547 struct jffs2_xattr_ref *ref;
548 int ret;
549
550 ref = jffs2_alloc_xattr_ref();
551 if (!ref)
552 return ERR_PTR(-ENOMEM);
553 ref->ic = ic;
554 ref->xd = xd;
555
556 ret = save_xattr_ref(c, ref);
557 if (ret) {
558 jffs2_free_xattr_ref(ref);
559 return ERR_PTR(ret);
560 }
561
562
563 ref->next = ic->xref;
564 ic->xref = ref;
565
566 return ref;
567}
568
569static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
570{
571
572 struct jffs2_xattr_datum *xd;
573
574 xd = ref->xd;
575 ref->xseqno |= XREF_DELETE_MARKER;
576 ref->ino = ref->ic->ino;
577 ref->xid = ref->xd->xid;
578 spin_lock(&c->erase_completion_lock);
579 ref->next = c->xref_dead_list;
580 c->xref_dead_list = ref;
581 spin_unlock(&c->erase_completion_lock);
582
583 dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) was removed.\n",
584 ref->ino, ref->xid, ref->xseqno);
585
586 unrefer_xattr_datum(c, xd);
587}
588
589void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
590{
591
592
593 struct jffs2_xattr_ref *ref, *_ref;
594
595 if (!ic || ic->pino_nlink > 0)
596 return;
597
598 down_write(&c->xattr_sem);
599 for (ref = ic->xref; ref; ref = _ref) {
600 _ref = ref->next;
601 delete_xattr_ref(c, ref);
602 }
603 ic->xref = NULL;
604 up_write(&c->xattr_sem);
605}
606
607void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
608{
609
610 struct jffs2_xattr_datum *xd;
611 struct jffs2_xattr_ref *ref, *_ref;
612
613 down_write(&c->xattr_sem);
614 for (ref = ic->xref; ref; ref = _ref) {
615 _ref = ref->next;
616 xd = ref->xd;
617 if (atomic_dec_and_test(&xd->refcnt)) {
618 unload_xattr_datum(c, xd);
619 jffs2_free_xattr_datum(xd);
620 }
621 jffs2_free_xattr_ref(ref);
622 }
623 ic->xref = NULL;
624 up_write(&c->xattr_sem);
625}
626
627static int check_xattr_ref_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
628{
629
630
631
632
633 struct jffs2_xattr_ref *ref, *cmp, **pref, **pcmp;
634 int rc = 0;
635
636 if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED))
637 return 0;
638 down_write(&c->xattr_sem);
639 retry:
640 rc = 0;
641 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
642 if (!ref->xd->xname) {
643 rc = load_xattr_datum(c, ref->xd);
644 if (unlikely(rc > 0)) {
645 *pref = ref->next;
646 delete_xattr_ref(c, ref);
647 goto retry;
648 } else if (unlikely(rc < 0))
649 goto out;
650 }
651 for (cmp=ref->next, pcmp=&ref->next; cmp; pcmp=&cmp->next, cmp=cmp->next) {
652 if (!cmp->xd->xname) {
653 ref->xd->flags |= JFFS2_XFLAGS_BIND;
654 rc = load_xattr_datum(c, cmp->xd);
655 ref->xd->flags &= ~JFFS2_XFLAGS_BIND;
656 if (unlikely(rc > 0)) {
657 *pcmp = cmp->next;
658 delete_xattr_ref(c, cmp);
659 goto retry;
660 } else if (unlikely(rc < 0))
661 goto out;
662 }
663 if (ref->xd->xprefix == cmp->xd->xprefix
664 && !strcmp(ref->xd->xname, cmp->xd->xname)) {
665 if (ref->xseqno > cmp->xseqno) {
666 *pcmp = cmp->next;
667 delete_xattr_ref(c, cmp);
668 } else {
669 *pref = ref->next;
670 delete_xattr_ref(c, ref);
671 }
672 goto retry;
673 }
674 }
675 }
676 ic->flags |= INO_FLAGS_XATTR_CHECKED;
677 out:
678 up_write(&c->xattr_sem);
679
680 return rc;
681}
682
683
684
685
686
687
688
689
690
691
692
693
694
695void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c)
696{
697 int i;
698
699 for (i=0; i < XATTRINDEX_HASHSIZE; i++)
700 INIT_LIST_HEAD(&c->xattrindex[i]);
701 INIT_LIST_HEAD(&c->xattr_unchecked);
702 INIT_LIST_HEAD(&c->xattr_dead_list);
703 c->xref_dead_list = NULL;
704 c->xref_temp = NULL;
705
706 init_rwsem(&c->xattr_sem);
707 c->highest_xid = 0;
708 c->highest_xseqno = 0;
709 c->xdatum_mem_usage = 0;
710 c->xdatum_mem_threshold = 32 * 1024;
711}
712
713static struct jffs2_xattr_datum *jffs2_find_xattr_datum(struct jffs2_sb_info *c, uint32_t xid)
714{
715 struct jffs2_xattr_datum *xd;
716 int i = xid % XATTRINDEX_HASHSIZE;
717
718
719 BUG_ON(!(c->flags & (JFFS2_SB_FLAG_SCANNING|JFFS2_SB_FLAG_BUILDING)));
720
721 list_for_each_entry(xd, &c->xattrindex[i], xindex) {
722 if (xd->xid==xid)
723 return xd;
724 }
725 return NULL;
726}
727
728void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c)
729{
730 struct jffs2_xattr_datum *xd, *_xd;
731 struct jffs2_xattr_ref *ref, *_ref;
732 int i;
733
734 for (ref=c->xref_temp; ref; ref = _ref) {
735 _ref = ref->next;
736 jffs2_free_xattr_ref(ref);
737 }
738
739 for (ref=c->xref_dead_list; ref; ref = _ref) {
740 _ref = ref->next;
741 jffs2_free_xattr_ref(ref);
742 }
743
744 for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
745 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
746 list_del(&xd->xindex);
747 if (xd->xname)
748 kfree(xd->xname);
749 jffs2_free_xattr_datum(xd);
750 }
751 }
752
753 list_for_each_entry_safe(xd, _xd, &c->xattr_dead_list, xindex) {
754 list_del(&xd->xindex);
755 jffs2_free_xattr_datum(xd);
756 }
757 list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) {
758 list_del(&xd->xindex);
759 jffs2_free_xattr_datum(xd);
760 }
761}
762
763#define XREF_TMPHASH_SIZE (128)
764void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
765{
766 struct jffs2_xattr_ref *ref, *_ref;
767 struct jffs2_xattr_ref *xref_tmphash[XREF_TMPHASH_SIZE];
768 struct jffs2_xattr_datum *xd, *_xd;
769 struct jffs2_inode_cache *ic;
770 struct jffs2_raw_node_ref *raw;
771 int i, xdatum_count = 0, xdatum_unchecked_count = 0, xref_count = 0;
772 int xdatum_orphan_count = 0, xref_orphan_count = 0, xref_dead_count = 0;
773
774 BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING));
775
776
777 for (i=0; i < XREF_TMPHASH_SIZE; i++)
778 xref_tmphash[i] = NULL;
779 for (ref=c->xref_temp; ref; ref=_ref) {
780 struct jffs2_xattr_ref *tmp;
781
782 _ref = ref->next;
783 if (ref_flags(ref->node) != REF_PRISTINE) {
784 if (verify_xattr_ref(c, ref)) {
785 BUG_ON(ref->node->next_in_ino != (void *)ref);
786 ref->node->next_in_ino = NULL;
787 jffs2_mark_node_obsolete(c, ref->node);
788 jffs2_free_xattr_ref(ref);
789 continue;
790 }
791 }
792
793 i = (ref->ino ^ ref->xid) % XREF_TMPHASH_SIZE;
794 for (tmp=xref_tmphash[i]; tmp; tmp=tmp->next) {
795 if (tmp->ino == ref->ino && tmp->xid == ref->xid)
796 break;
797 }
798 if (tmp) {
799 raw = ref->node;
800 if (ref->xseqno > tmp->xseqno) {
801 tmp->xseqno = ref->xseqno;
802 raw->next_in_ino = tmp->node;
803 tmp->node = raw;
804 } else {
805 raw->next_in_ino = tmp->node->next_in_ino;
806 tmp->node->next_in_ino = raw;
807 }
808 jffs2_free_xattr_ref(ref);
809 continue;
810 } else {
811 ref->next = xref_tmphash[i];
812 xref_tmphash[i] = ref;
813 }
814 }
815 c->xref_temp = NULL;
816
817
818 for (i=0; i < XREF_TMPHASH_SIZE; i++) {
819 for (ref=xref_tmphash[i]; ref; ref=_ref) {
820 xref_count++;
821 _ref = ref->next;
822 if (is_xattr_ref_dead(ref)) {
823 ref->next = c->xref_dead_list;
824 c->xref_dead_list = ref;
825 xref_dead_count++;
826 continue;
827 }
828
829
830 xd = jffs2_find_xattr_datum(c, ref->xid);
831 ic = jffs2_get_ino_cache(c, ref->ino);
832 if (!xd || !ic || !ic->pino_nlink) {
833 dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) is orphan.\n",
834 ref->ino, ref->xid, ref->xseqno);
835 ref->xseqno |= XREF_DELETE_MARKER;
836 ref->next = c->xref_dead_list;
837 c->xref_dead_list = ref;
838 xref_orphan_count++;
839 continue;
840 }
841 ref->xd = xd;
842 ref->ic = ic;
843 atomic_inc(&xd->refcnt);
844 ref->next = ic->xref;
845 ic->xref = ref;
846 }
847 }
848
849
850 for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
851 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
852 xdatum_count++;
853 list_del_init(&xd->xindex);
854 if (!atomic_read(&xd->refcnt)) {
855 dbg_xattr("xdatum(xid=%u, version=%u) is orphan.\n",
856 xd->xid, xd->version);
857 xd->flags |= JFFS2_XFLAGS_DEAD;
858 list_add(&xd->xindex, &c->xattr_unchecked);
859 xdatum_orphan_count++;
860 continue;
861 }
862 if (is_xattr_datum_unchecked(c, xd)) {
863 dbg_xattr("unchecked xdatum(xid=%u, version=%u)\n",
864 xd->xid, xd->version);
865 list_add(&xd->xindex, &c->xattr_unchecked);
866 xdatum_unchecked_count++;
867 }
868 }
869 }
870
871 JFFS2_NOTICE("complete building xattr subsystem, %u of xdatum"
872 " (%u unchecked, %u orphan) and "
873 "%u of xref (%u dead, %u orphan) found.\n",
874 xdatum_count, xdatum_unchecked_count, xdatum_orphan_count,
875 xref_count, xref_dead_count, xref_orphan_count);
876}
877
878struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,
879 uint32_t xid, uint32_t version)
880{
881 struct jffs2_xattr_datum *xd;
882
883 xd = jffs2_find_xattr_datum(c, xid);
884 if (!xd) {
885 xd = jffs2_alloc_xattr_datum();
886 if (!xd)
887 return ERR_PTR(-ENOMEM);
888 xd->xid = xid;
889 xd->version = version;
890 if (xd->xid > c->highest_xid)
891 c->highest_xid = xd->xid;
892 list_add_tail(&xd->xindex, &c->xattrindex[xid % XATTRINDEX_HASHSIZE]);
893 }
894 return xd;
895}
896
897
898
899
900
901
902
903
904
905
906
907struct xattr_handler *jffs2_xattr_handlers[] = {
908 &jffs2_user_xattr_handler,
909#ifdef CONFIG_JFFS2_FS_SECURITY
910 &jffs2_security_xattr_handler,
911#endif
912#ifdef CONFIG_JFFS2_FS_POSIX_ACL
913 &jffs2_acl_access_xattr_handler,
914 &jffs2_acl_default_xattr_handler,
915#endif
916 &jffs2_trusted_xattr_handler,
917 NULL
918};
919
920static struct xattr_handler *xprefix_to_handler(int xprefix) {
921 struct xattr_handler *ret;
922
923 switch (xprefix) {
924 case JFFS2_XPREFIX_USER:
925 ret = &jffs2_user_xattr_handler;
926 break;
927#ifdef CONFIG_JFFS2_FS_SECURITY
928 case JFFS2_XPREFIX_SECURITY:
929 ret = &jffs2_security_xattr_handler;
930 break;
931#endif
932#ifdef CONFIG_JFFS2_FS_POSIX_ACL
933 case JFFS2_XPREFIX_ACL_ACCESS:
934 ret = &jffs2_acl_access_xattr_handler;
935 break;
936 case JFFS2_XPREFIX_ACL_DEFAULT:
937 ret = &jffs2_acl_default_xattr_handler;
938 break;
939#endif
940 case JFFS2_XPREFIX_TRUSTED:
941 ret = &jffs2_trusted_xattr_handler;
942 break;
943 default:
944 ret = NULL;
945 break;
946 }
947 return ret;
948}
949
950ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
951{
952 struct inode *inode = dentry->d_inode;
953 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
954 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
955 struct jffs2_inode_cache *ic = f->inocache;
956 struct jffs2_xattr_ref *ref, **pref;
957 struct jffs2_xattr_datum *xd;
958 struct xattr_handler *xhandle;
959 ssize_t len, rc;
960 int retry = 0;
961
962 rc = check_xattr_ref_inode(c, ic);
963 if (unlikely(rc))
964 return rc;
965
966 down_read(&c->xattr_sem);
967 retry:
968 len = 0;
969 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
970 BUG_ON(ref->ic != ic);
971 xd = ref->xd;
972 if (!xd->xname) {
973
974 if (!retry) {
975 retry = 1;
976 up_read(&c->xattr_sem);
977 down_write(&c->xattr_sem);
978 goto retry;
979 } else {
980 rc = load_xattr_datum(c, xd);
981 if (unlikely(rc > 0)) {
982 *pref = ref->next;
983 delete_xattr_ref(c, ref);
984 goto retry;
985 } else if (unlikely(rc < 0))
986 goto out;
987 }
988 }
989 xhandle = xprefix_to_handler(xd->xprefix);
990 if (!xhandle)
991 continue;
992 if (buffer) {
993 rc = xhandle->list(inode, buffer+len, size-len, xd->xname, xd->name_len);
994 } else {
995 rc = xhandle->list(inode, NULL, 0, xd->xname, xd->name_len);
996 }
997 if (rc < 0)
998 goto out;
999 len += rc;
1000 }
1001 rc = len;
1002 out:
1003 if (!retry) {
1004 up_read(&c->xattr_sem);
1005 } else {
1006 up_write(&c->xattr_sem);
1007 }
1008 return rc;
1009}
1010
1011int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname,
1012 char *buffer, size_t size)
1013{
1014 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
1015 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
1016 struct jffs2_inode_cache *ic = f->inocache;
1017 struct jffs2_xattr_datum *xd;
1018 struct jffs2_xattr_ref *ref, **pref;
1019 int rc, retry = 0;
1020
1021 rc = check_xattr_ref_inode(c, ic);
1022 if (unlikely(rc))
1023 return rc;
1024
1025 down_read(&c->xattr_sem);
1026 retry:
1027 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
1028 BUG_ON(ref->ic!=ic);
1029
1030 xd = ref->xd;
1031 if (xd->xprefix != xprefix)
1032 continue;
1033 if (!xd->xname) {
1034
1035 if (!retry) {
1036 retry = 1;
1037 up_read(&c->xattr_sem);
1038 down_write(&c->xattr_sem);
1039 goto retry;
1040 } else {
1041 rc = load_xattr_datum(c, xd);
1042 if (unlikely(rc > 0)) {
1043 *pref = ref->next;
1044 delete_xattr_ref(c, ref);
1045 goto retry;
1046 } else if (unlikely(rc < 0)) {
1047 goto out;
1048 }
1049 }
1050 }
1051 if (!strcmp(xname, xd->xname)) {
1052 rc = xd->value_len;
1053 if (buffer) {
1054 if (size < rc) {
1055 rc = -ERANGE;
1056 } else {
1057 memcpy(buffer, xd->xvalue, rc);
1058 }
1059 }
1060 goto out;
1061 }
1062 }
1063 rc = -ENODATA;
1064 out:
1065 if (!retry) {
1066 up_read(&c->xattr_sem);
1067 } else {
1068 up_write(&c->xattr_sem);
1069 }
1070 return rc;
1071}
1072
1073int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1074 const char *buffer, size_t size, int flags)
1075{
1076 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
1077 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
1078 struct jffs2_inode_cache *ic = f->inocache;
1079 struct jffs2_xattr_datum *xd;
1080 struct jffs2_xattr_ref *ref, *newref, **pref;
1081 uint32_t length, request;
1082 int rc;
1083
1084 rc = check_xattr_ref_inode(c, ic);
1085 if (unlikely(rc))
1086 return rc;
1087
1088 request = PAD(sizeof(struct jffs2_raw_xattr) + strlen(xname) + 1 + size);
1089 rc = jffs2_reserve_space(c, request, &length,
1090 ALLOC_NORMAL, JFFS2_SUMMARY_XATTR_SIZE);
1091 if (rc) {
1092 JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
1093 return rc;
1094 }
1095
1096
1097 down_write(&c->xattr_sem);
1098 retry:
1099 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
1100 xd = ref->xd;
1101 if (xd->xprefix != xprefix)
1102 continue;
1103 if (!xd->xname) {
1104 rc = load_xattr_datum(c, xd);
1105 if (unlikely(rc > 0)) {
1106 *pref = ref->next;
1107 delete_xattr_ref(c, ref);
1108 goto retry;
1109 } else if (unlikely(rc < 0))
1110 goto out;
1111 }
1112 if (!strcmp(xd->xname, xname)) {
1113 if (flags & XATTR_CREATE) {
1114 rc = -EEXIST;
1115 goto out;
1116 }
1117 if (!buffer) {
1118 ref->ino = ic->ino;
1119 ref->xid = xd->xid;
1120 ref->xseqno |= XREF_DELETE_MARKER;
1121 rc = save_xattr_ref(c, ref);
1122 if (!rc) {
1123 *pref = ref->next;
1124 spin_lock(&c->erase_completion_lock);
1125 ref->next = c->xref_dead_list;
1126 c->xref_dead_list = ref;
1127 spin_unlock(&c->erase_completion_lock);
1128 unrefer_xattr_datum(c, xd);
1129 } else {
1130 ref->ic = ic;
1131 ref->xd = xd;
1132 ref->xseqno &= ~XREF_DELETE_MARKER;
1133 }
1134 goto out;
1135 }
1136 goto found;
1137 }
1138 }
1139
1140 if (flags & XATTR_REPLACE) {
1141 rc = -ENODATA;
1142 goto out;
1143 }
1144 if (!buffer) {
1145 rc = -ENODATA;
1146 goto out;
1147 }
1148 found:
1149 xd = create_xattr_datum(c, xprefix, xname, buffer, size);
1150 if (IS_ERR(xd)) {
1151 rc = PTR_ERR(xd);
1152 goto out;
1153 }
1154 up_write(&c->xattr_sem);
1155 jffs2_complete_reservation(c);
1156
1157
1158 request = PAD(sizeof(struct jffs2_raw_xref));
1159 rc = jffs2_reserve_space(c, request, &length,
1160 ALLOC_NORMAL, JFFS2_SUMMARY_XREF_SIZE);
1161 down_write(&c->xattr_sem);
1162 if (rc) {
1163 JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
1164 unrefer_xattr_datum(c, xd);
1165 up_write(&c->xattr_sem);
1166 return rc;
1167 }
1168 if (ref)
1169 *pref = ref->next;
1170 newref = create_xattr_ref(c, ic, xd);
1171 if (IS_ERR(newref)) {
1172 if (ref) {
1173 ref->next = ic->xref;
1174 ic->xref = ref;
1175 }
1176 rc = PTR_ERR(newref);
1177 unrefer_xattr_datum(c, xd);
1178 } else if (ref) {
1179 delete_xattr_ref(c, ref);
1180 }
1181 out:
1182 up_write(&c->xattr_sem);
1183 jffs2_complete_reservation(c);
1184 return rc;
1185}
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd,
1200 struct jffs2_raw_node_ref *raw)
1201{
1202 uint32_t totlen, length, old_ofs;
1203 int rc = 0;
1204
1205 down_write(&c->xattr_sem);
1206 if (xd->node != raw)
1207 goto out;
1208 if (xd->flags & (JFFS2_XFLAGS_DEAD|JFFS2_XFLAGS_INVALID))
1209 goto out;
1210
1211 rc = load_xattr_datum(c, xd);
1212 if (unlikely(rc)) {
1213 rc = (rc > 0) ? 0 : rc;
1214 goto out;
1215 }
1216 old_ofs = ref_offset(xd->node);
1217 totlen = PAD(sizeof(struct jffs2_raw_xattr)
1218 + xd->name_len + 1 + xd->value_len);
1219 rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XATTR_SIZE);
1220 if (rc) {
1221 JFFS2_WARNING("jffs2_reserve_space_gc()=%d, request=%u\n", rc, totlen);
1222 goto out;
1223 }
1224 rc = save_xattr_datum(c, xd);
1225 if (!rc)
1226 dbg_xattr("xdatum (xid=%u, version=%u) GC'ed from %#08x to %08x\n",
1227 xd->xid, xd->version, old_ofs, ref_offset(xd->node));
1228 out:
1229 if (!rc)
1230 jffs2_mark_node_obsolete(c, raw);
1231 up_write(&c->xattr_sem);
1232 return rc;
1233}
1234
1235int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref,
1236 struct jffs2_raw_node_ref *raw)
1237{
1238 uint32_t totlen, length, old_ofs;
1239 int rc = 0;
1240
1241 down_write(&c->xattr_sem);
1242 BUG_ON(!ref->node);
1243
1244 if (ref->node != raw)
1245 goto out;
1246 if (is_xattr_ref_dead(ref) && (raw->next_in_ino == (void *)ref))
1247 goto out;
1248
1249 old_ofs = ref_offset(ref->node);
1250 totlen = ref_totlen(c, c->gcblock, ref->node);
1251
1252 rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XREF_SIZE);
1253 if (rc) {
1254 JFFS2_WARNING("%s: jffs2_reserve_space_gc() = %d, request = %u\n",
1255 __func__, rc, totlen);
1256 rc = rc ? rc : -EBADFD;
1257 goto out;
1258 }
1259 rc = save_xattr_ref(c, ref);
1260 if (!rc)
1261 dbg_xattr("xref (ino=%u, xid=%u) GC'ed from %#08x to %08x\n",
1262 ref->ic->ino, ref->xd->xid, old_ofs, ref_offset(ref->node));
1263 out:
1264 if (!rc)
1265 jffs2_mark_node_obsolete(c, raw);
1266 up_write(&c->xattr_sem);
1267 return rc;
1268}
1269
1270int jffs2_verify_xattr(struct jffs2_sb_info *c)
1271{
1272 struct jffs2_xattr_datum *xd, *_xd;
1273 struct jffs2_eraseblock *jeb;
1274 struct jffs2_raw_node_ref *raw;
1275 uint32_t totlen;
1276 int rc;
1277
1278 down_write(&c->xattr_sem);
1279 list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) {
1280 rc = do_verify_xattr_datum(c, xd);
1281 if (rc < 0)
1282 continue;
1283 list_del_init(&xd->xindex);
1284 spin_lock(&c->erase_completion_lock);
1285 for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
1286 if (ref_flags(raw) != REF_UNCHECKED)
1287 continue;
1288 jeb = &c->blocks[ref_offset(raw) / c->sector_size];
1289 totlen = PAD(ref_totlen(c, jeb, raw));
1290 c->unchecked_size -= totlen; c->used_size += totlen;
1291 jeb->unchecked_size -= totlen; jeb->used_size += totlen;
1292 raw->flash_offset = ref_offset(raw)
1293 | ((xd->node == (void *)raw) ? REF_PRISTINE : REF_NORMAL);
1294 }
1295 if (xd->flags & JFFS2_XFLAGS_DEAD)
1296 list_add(&xd->xindex, &c->xattr_dead_list);
1297 spin_unlock(&c->erase_completion_lock);
1298 }
1299 up_write(&c->xattr_sem);
1300 return list_empty(&c->xattr_unchecked) ? 1 : 0;
1301}
1302
1303void jffs2_release_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
1304{
1305
1306 if (atomic_read(&xd->refcnt) || xd->node != (void *)xd)
1307 return;
1308
1309 list_del(&xd->xindex);
1310 jffs2_free_xattr_datum(xd);
1311}
1312
1313void jffs2_release_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
1314{
1315
1316 struct jffs2_xattr_ref *tmp, **ptmp;
1317
1318 if (ref->node != (void *)ref)
1319 return;
1320
1321 for (tmp=c->xref_dead_list, ptmp=&c->xref_dead_list; tmp; ptmp=&tmp->next, tmp=tmp->next) {
1322 if (ref == tmp) {
1323 *ptmp = tmp->next;
1324 break;
1325 }
1326 }
1327 jffs2_free_xattr_ref(ref);
1328}