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
907const struct 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 const struct xattr_handler *xprefix_to_handler(int xprefix) {
921 const 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 const 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(dentry, buffer+len, size-len,
994 xd->xname, xd->name_len, xd->flags);
995 } else {
996 rc = xhandle->list(dentry, NULL, 0, xd->xname,
997 xd->name_len, xd->flags);
998 }
999 if (rc < 0)
1000 goto out;
1001 len += rc;
1002 }
1003 rc = len;
1004 out:
1005 if (!retry) {
1006 up_read(&c->xattr_sem);
1007 } else {
1008 up_write(&c->xattr_sem);
1009 }
1010 return rc;
1011}
1012
1013int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname,
1014 char *buffer, size_t size)
1015{
1016 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
1017 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
1018 struct jffs2_inode_cache *ic = f->inocache;
1019 struct jffs2_xattr_datum *xd;
1020 struct jffs2_xattr_ref *ref, **pref;
1021 int rc, retry = 0;
1022
1023 rc = check_xattr_ref_inode(c, ic);
1024 if (unlikely(rc))
1025 return rc;
1026
1027 down_read(&c->xattr_sem);
1028 retry:
1029 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
1030 BUG_ON(ref->ic!=ic);
1031
1032 xd = ref->xd;
1033 if (xd->xprefix != xprefix)
1034 continue;
1035 if (!xd->xname) {
1036
1037 if (!retry) {
1038 retry = 1;
1039 up_read(&c->xattr_sem);
1040 down_write(&c->xattr_sem);
1041 goto retry;
1042 } else {
1043 rc = load_xattr_datum(c, xd);
1044 if (unlikely(rc > 0)) {
1045 *pref = ref->next;
1046 delete_xattr_ref(c, ref);
1047 goto retry;
1048 } else if (unlikely(rc < 0)) {
1049 goto out;
1050 }
1051 }
1052 }
1053 if (!strcmp(xname, xd->xname)) {
1054 rc = xd->value_len;
1055 if (buffer) {
1056 if (size < rc) {
1057 rc = -ERANGE;
1058 } else {
1059 memcpy(buffer, xd->xvalue, rc);
1060 }
1061 }
1062 goto out;
1063 }
1064 }
1065 rc = -ENODATA;
1066 out:
1067 if (!retry) {
1068 up_read(&c->xattr_sem);
1069 } else {
1070 up_write(&c->xattr_sem);
1071 }
1072 return rc;
1073}
1074
1075int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1076 const char *buffer, size_t size, int flags)
1077{
1078 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
1079 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
1080 struct jffs2_inode_cache *ic = f->inocache;
1081 struct jffs2_xattr_datum *xd;
1082 struct jffs2_xattr_ref *ref, *newref, **pref;
1083 uint32_t length, request;
1084 int rc;
1085
1086 rc = check_xattr_ref_inode(c, ic);
1087 if (unlikely(rc))
1088 return rc;
1089
1090 request = PAD(sizeof(struct jffs2_raw_xattr) + strlen(xname) + 1 + size);
1091 rc = jffs2_reserve_space(c, request, &length,
1092 ALLOC_NORMAL, JFFS2_SUMMARY_XATTR_SIZE);
1093 if (rc) {
1094 JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
1095 return rc;
1096 }
1097
1098
1099 down_write(&c->xattr_sem);
1100 retry:
1101 for (ref=ic->xref, pref=&ic->xref; ref; pref=&ref->next, ref=ref->next) {
1102 xd = ref->xd;
1103 if (xd->xprefix != xprefix)
1104 continue;
1105 if (!xd->xname) {
1106 rc = load_xattr_datum(c, xd);
1107 if (unlikely(rc > 0)) {
1108 *pref = ref->next;
1109 delete_xattr_ref(c, ref);
1110 goto retry;
1111 } else if (unlikely(rc < 0))
1112 goto out;
1113 }
1114 if (!strcmp(xd->xname, xname)) {
1115 if (flags & XATTR_CREATE) {
1116 rc = -EEXIST;
1117 goto out;
1118 }
1119 if (!buffer) {
1120 ref->ino = ic->ino;
1121 ref->xid = xd->xid;
1122 ref->xseqno |= XREF_DELETE_MARKER;
1123 rc = save_xattr_ref(c, ref);
1124 if (!rc) {
1125 *pref = ref->next;
1126 spin_lock(&c->erase_completion_lock);
1127 ref->next = c->xref_dead_list;
1128 c->xref_dead_list = ref;
1129 spin_unlock(&c->erase_completion_lock);
1130 unrefer_xattr_datum(c, xd);
1131 } else {
1132 ref->ic = ic;
1133 ref->xd = xd;
1134 ref->xseqno &= ~XREF_DELETE_MARKER;
1135 }
1136 goto out;
1137 }
1138 goto found;
1139 }
1140 }
1141
1142 if (flags & XATTR_REPLACE) {
1143 rc = -ENODATA;
1144 goto out;
1145 }
1146 if (!buffer) {
1147 rc = -ENODATA;
1148 goto out;
1149 }
1150 found:
1151 xd = create_xattr_datum(c, xprefix, xname, buffer, size);
1152 if (IS_ERR(xd)) {
1153 rc = PTR_ERR(xd);
1154 goto out;
1155 }
1156 up_write(&c->xattr_sem);
1157 jffs2_complete_reservation(c);
1158
1159
1160 request = PAD(sizeof(struct jffs2_raw_xref));
1161 rc = jffs2_reserve_space(c, request, &length,
1162 ALLOC_NORMAL, JFFS2_SUMMARY_XREF_SIZE);
1163 down_write(&c->xattr_sem);
1164 if (rc) {
1165 JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
1166 unrefer_xattr_datum(c, xd);
1167 up_write(&c->xattr_sem);
1168 return rc;
1169 }
1170 if (ref)
1171 *pref = ref->next;
1172 newref = create_xattr_ref(c, ic, xd);
1173 if (IS_ERR(newref)) {
1174 if (ref) {
1175 ref->next = ic->xref;
1176 ic->xref = ref;
1177 }
1178 rc = PTR_ERR(newref);
1179 unrefer_xattr_datum(c, xd);
1180 } else if (ref) {
1181 delete_xattr_ref(c, ref);
1182 }
1183 out:
1184 up_write(&c->xattr_sem);
1185 jffs2_complete_reservation(c);
1186 return rc;
1187}
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd,
1202 struct jffs2_raw_node_ref *raw)
1203{
1204 uint32_t totlen, length, old_ofs;
1205 int rc = 0;
1206
1207 down_write(&c->xattr_sem);
1208 if (xd->node != raw)
1209 goto out;
1210 if (xd->flags & (JFFS2_XFLAGS_DEAD|JFFS2_XFLAGS_INVALID))
1211 goto out;
1212
1213 rc = load_xattr_datum(c, xd);
1214 if (unlikely(rc)) {
1215 rc = (rc > 0) ? 0 : rc;
1216 goto out;
1217 }
1218 old_ofs = ref_offset(xd->node);
1219 totlen = PAD(sizeof(struct jffs2_raw_xattr)
1220 + xd->name_len + 1 + xd->value_len);
1221 rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XATTR_SIZE);
1222 if (rc) {
1223 JFFS2_WARNING("jffs2_reserve_space_gc()=%d, request=%u\n", rc, totlen);
1224 goto out;
1225 }
1226 rc = save_xattr_datum(c, xd);
1227 if (!rc)
1228 dbg_xattr("xdatum (xid=%u, version=%u) GC'ed from %#08x to %08x\n",
1229 xd->xid, xd->version, old_ofs, ref_offset(xd->node));
1230 out:
1231 if (!rc)
1232 jffs2_mark_node_obsolete(c, raw);
1233 up_write(&c->xattr_sem);
1234 return rc;
1235}
1236
1237int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref,
1238 struct jffs2_raw_node_ref *raw)
1239{
1240 uint32_t totlen, length, old_ofs;
1241 int rc = 0;
1242
1243 down_write(&c->xattr_sem);
1244 BUG_ON(!ref->node);
1245
1246 if (ref->node != raw)
1247 goto out;
1248 if (is_xattr_ref_dead(ref) && (raw->next_in_ino == (void *)ref))
1249 goto out;
1250
1251 old_ofs = ref_offset(ref->node);
1252 totlen = ref_totlen(c, c->gcblock, ref->node);
1253
1254 rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XREF_SIZE);
1255 if (rc) {
1256 JFFS2_WARNING("%s: jffs2_reserve_space_gc() = %d, request = %u\n",
1257 __func__, rc, totlen);
1258 rc = rc ? rc : -EBADFD;
1259 goto out;
1260 }
1261 rc = save_xattr_ref(c, ref);
1262 if (!rc)
1263 dbg_xattr("xref (ino=%u, xid=%u) GC'ed from %#08x to %08x\n",
1264 ref->ic->ino, ref->xd->xid, old_ofs, ref_offset(ref->node));
1265 out:
1266 if (!rc)
1267 jffs2_mark_node_obsolete(c, raw);
1268 up_write(&c->xattr_sem);
1269 return rc;
1270}
1271
1272int jffs2_verify_xattr(struct jffs2_sb_info *c)
1273{
1274 struct jffs2_xattr_datum *xd, *_xd;
1275 struct jffs2_eraseblock *jeb;
1276 struct jffs2_raw_node_ref *raw;
1277 uint32_t totlen;
1278 int rc;
1279
1280 down_write(&c->xattr_sem);
1281 list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) {
1282 rc = do_verify_xattr_datum(c, xd);
1283 if (rc < 0)
1284 continue;
1285 list_del_init(&xd->xindex);
1286 spin_lock(&c->erase_completion_lock);
1287 for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
1288 if (ref_flags(raw) != REF_UNCHECKED)
1289 continue;
1290 jeb = &c->blocks[ref_offset(raw) / c->sector_size];
1291 totlen = PAD(ref_totlen(c, jeb, raw));
1292 c->unchecked_size -= totlen; c->used_size += totlen;
1293 jeb->unchecked_size -= totlen; jeb->used_size += totlen;
1294 raw->flash_offset = ref_offset(raw)
1295 | ((xd->node == (void *)raw) ? REF_PRISTINE : REF_NORMAL);
1296 }
1297 if (xd->flags & JFFS2_XFLAGS_DEAD)
1298 list_add(&xd->xindex, &c->xattr_dead_list);
1299 spin_unlock(&c->erase_completion_lock);
1300 }
1301 up_write(&c->xattr_sem);
1302 return list_empty(&c->xattr_unchecked) ? 1 : 0;
1303}
1304
1305void jffs2_release_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
1306{
1307
1308 if (atomic_read(&xd->refcnt) || xd->node != (void *)xd)
1309 return;
1310
1311 list_del(&xd->xindex);
1312 jffs2_free_xattr_datum(xd);
1313}
1314
1315void jffs2_release_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
1316{
1317
1318 struct jffs2_xattr_ref *tmp, **ptmp;
1319
1320 if (ref->node != (void *)ref)
1321 return;
1322
1323 for (tmp=c->xref_dead_list, ptmp=&c->xref_dead_list; tmp; ptmp=&tmp->next, tmp=tmp->next) {
1324 if (ref == tmp) {
1325 *ptmp = tmp->next;
1326 break;
1327 }
1328 }
1329 jffs2_free_xattr_ref(ref);
1330}
1331