aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/xattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jffs2/xattr.c')
-rw-r--r--fs/jffs2/xattr.c736
1 files changed, 463 insertions, 273 deletions
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c
index 2d82e250be34..03871ab7c26d 100644
--- a/fs/jffs2/xattr.c
+++ b/fs/jffs2/xattr.c
@@ -23,18 +23,15 @@
23 * xattr_datum_hashkey(xprefix, xname, xvalue, xsize) 23 * xattr_datum_hashkey(xprefix, xname, xvalue, xsize)
24 * is used to calcurate xdatum hashkey. The reminder of hashkey into XATTRINDEX_HASHSIZE is 24 * is used to calcurate xdatum hashkey. The reminder of hashkey into XATTRINDEX_HASHSIZE is
25 * the index of the xattr name/value pair cache (c->xattrindex). 25 * the index of the xattr name/value pair cache (c->xattrindex).
26 * is_xattr_datum_unchecked(c, xd)
27 * returns 1, if xdatum contains any unchecked raw nodes. if all raw nodes are not
28 * unchecked, it returns 0.
26 * unload_xattr_datum(c, xd) 29 * unload_xattr_datum(c, xd)
27 * is used to release xattr name/value pair and detach from c->xattrindex. 30 * is used to release xattr name/value pair and detach from c->xattrindex.
28 * reclaim_xattr_datum(c) 31 * reclaim_xattr_datum(c)
29 * is used to reclaim xattr name/value pairs on the xattr name/value pair cache when 32 * is used to reclaim xattr name/value pairs on the xattr name/value pair cache when
30 * memory usage by cache is over c->xdatum_mem_threshold. Currentry, this threshold 33 * memory usage by cache is over c->xdatum_mem_threshold. Currentry, this threshold
31 * is hard coded as 32KiB. 34 * is hard coded as 32KiB.
32 * delete_xattr_datum_node(c, xd)
33 * is used to delete a jffs2 node is dominated by xdatum. When EBS(Erase Block Summary) is
34 * enabled, it overwrites the obsolete node by myself.
35 * delete_xattr_datum(c, xd)
36 * is used to delete jffs2_xattr_datum object. It must be called with 0-value of reference
37 * counter. (It means how many jffs2_xattr_ref object refers this xdatum.)
38 * do_verify_xattr_datum(c, xd) 35 * do_verify_xattr_datum(c, xd)
39 * is used to load the xdatum informations without name/value pair from the medium. 36 * is used to load the xdatum informations without name/value pair from the medium.
40 * It's necessary once, because those informations are not collected during mounting 37 * It's necessary once, because those informations are not collected during mounting
@@ -53,8 +50,13 @@
53 * is used to write xdatum to medium. xd->version will be incremented. 50 * is used to write xdatum to medium. xd->version will be incremented.
54 * create_xattr_datum(c, xprefix, xname, xvalue, xsize) 51 * create_xattr_datum(c, xprefix, xname, xvalue, xsize)
55 * is used to create new xdatum and write to medium. 52 * is used to create new xdatum and write to medium.
53 * delete_xattr_datum_delay(c, xd)
54 * is used to delete a xdatum without 'delete marker'. It has a possibility to detect
55 * orphan xdatum on next mounting.
56 * delete_xattr_datum(c, xd)
57 * is used to delete a xdatum with 'delete marker'. Calling jffs2_reserve_space() is
58 * necessary before this function.
56 * -------------------------------------------------- */ 59 * -------------------------------------------------- */
57
58static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *xvalue, int xsize) 60static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *xvalue, int xsize)
59{ 61{
60 int name_len = strlen(xname); 62 int name_len = strlen(xname);
@@ -62,6 +64,22 @@ static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *
62 return crc32(xprefix, xname, name_len) ^ crc32(xprefix, xvalue, xsize); 64 return crc32(xprefix, xname, name_len) ^ crc32(xprefix, xvalue, xsize);
63} 65}
64 66
67static int is_xattr_datum_unchecked(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
68{
69 struct jffs2_raw_node_ref *raw;
70 int rc = 0;
71
72 spin_lock(&c->erase_completion_lock);
73 for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
74 if (ref_flags(raw) == REF_UNCHECKED) {
75 rc = 1;
76 break;
77 }
78 }
79 spin_unlock(&c->erase_completion_lock);
80 return rc;
81}
82
65static void unload_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) 83static void unload_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
66{ 84{
67 /* must be called under down_write(xattr_sem) */ 85 /* must be called under down_write(xattr_sem) */
@@ -107,80 +125,39 @@ static void reclaim_xattr_datum(struct jffs2_sb_info *c)
107 before, c->xdatum_mem_usage, before - c->xdatum_mem_usage); 125 before, c->xdatum_mem_usage, before - c->xdatum_mem_usage);
108} 126}
109 127
110static void delete_xattr_datum_node(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
111{
112 /* must be called under down_write(xattr_sem) */
113 struct jffs2_raw_xattr rx;
114 size_t length;
115 int rc;
116
117 if (!xd->node) {
118 JFFS2_WARNING("xdatum (xid=%u) is removed twice.\n", xd->xid);
119 return;
120 }
121 if (jffs2_sum_active()) {
122 memset(&rx, 0xff, sizeof(struct jffs2_raw_xattr));
123 rc = jffs2_flash_read(c, ref_offset(xd->node),
124 sizeof(struct jffs2_unknown_node),
125 &length, (char *)&rx);
126 if (rc || length != sizeof(struct jffs2_unknown_node)) {
127 JFFS2_ERROR("jffs2_flash_read()=%d, req=%zu, read=%zu at %#08x\n",
128 rc, sizeof(struct jffs2_unknown_node),
129 length, ref_offset(xd->node));
130 }
131 rc = jffs2_flash_write(c, ref_offset(xd->node), sizeof(rx),
132 &length, (char *)&rx);
133 if (rc || length != sizeof(struct jffs2_raw_xattr)) {
134 JFFS2_ERROR("jffs2_flash_write()=%d, req=%zu, wrote=%zu ar %#08x\n",
135 rc, sizeof(rx), length, ref_offset(xd->node));
136 }
137 }
138 spin_lock(&c->erase_completion_lock);
139 xd->node->next_in_ino = NULL;
140 spin_unlock(&c->erase_completion_lock);
141 jffs2_mark_node_obsolete(c, xd->node);
142 xd->node = NULL;
143}
144
145static void delete_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
146{
147 /* must be called under down_write(xattr_sem) */
148 BUG_ON(xd->refcnt);
149
150 unload_xattr_datum(c, xd);
151 if (xd->node) {
152 delete_xattr_datum_node(c, xd);
153 xd->node = NULL;
154 }
155 jffs2_free_xattr_datum(xd);
156}
157
158static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) 128static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
159{ 129{
160 /* must be called under down_write(xattr_sem) */ 130 /* must be called under down_write(xattr_sem) */
161 struct jffs2_eraseblock *jeb; 131 struct jffs2_eraseblock *jeb;
132 struct jffs2_raw_node_ref *raw;
162 struct jffs2_raw_xattr rx; 133 struct jffs2_raw_xattr rx;
163 size_t readlen; 134 size_t readlen;
164 uint32_t crc, totlen; 135 uint32_t crc, offset, totlen;
165 int rc; 136 int rc;
166 137
167 BUG_ON(!xd->node); 138 spin_lock(&c->erase_completion_lock);
168 BUG_ON(ref_flags(xd->node) != REF_UNCHECKED); 139 offset = ref_offset(xd->node);
140 if (ref_flags(xd->node) == REF_PRISTINE)
141 goto complete;
142 spin_unlock(&c->erase_completion_lock);
169 143
170 rc = jffs2_flash_read(c, ref_offset(xd->node), sizeof(rx), &readlen, (char *)&rx); 144 rc = jffs2_flash_read(c, offset, sizeof(rx), &readlen, (char *)&rx);
171 if (rc || readlen != sizeof(rx)) { 145 if (rc || readlen != sizeof(rx)) {
172 JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu at %#08x\n", 146 JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu at %#08x\n",
173 rc, sizeof(rx), readlen, ref_offset(xd->node)); 147 rc, sizeof(rx), readlen, offset);
174 return rc ? rc : -EIO; 148 return rc ? rc : -EIO;
175 } 149 }
176 crc = crc32(0, &rx, sizeof(rx) - 4); 150 crc = crc32(0, &rx, sizeof(rx) - 4);
177 if (crc != je32_to_cpu(rx.node_crc)) { 151 if (crc != je32_to_cpu(rx.node_crc)) {
178 if (je32_to_cpu(rx.node_crc) != 0xffffffff) 152 JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
179 JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", 153 offset, je32_to_cpu(rx.hdr_crc), crc);
180 ref_offset(xd->node), je32_to_cpu(rx.hdr_crc), crc); 154 xd->flags |= JFFS2_XFLAGS_INVALID;
181 return EIO; 155 return EIO;
182 } 156 }
183 totlen = PAD(sizeof(rx) + rx.name_len + 1 + je16_to_cpu(rx.value_len)); 157 totlen = sizeof(rx);
158 if (xd->version != XDATUM_DELETE_MARKER)
159 totlen += rx.name_len + 1 + je16_to_cpu(rx.value_len);
160 totlen = PAD(totlen);
184 if (je16_to_cpu(rx.magic) != JFFS2_MAGIC_BITMASK 161 if (je16_to_cpu(rx.magic) != JFFS2_MAGIC_BITMASK
185 || je16_to_cpu(rx.nodetype) != JFFS2_NODETYPE_XATTR 162 || je16_to_cpu(rx.nodetype) != JFFS2_NODETYPE_XATTR
186 || je32_to_cpu(rx.totlen) != totlen 163 || je32_to_cpu(rx.totlen) != totlen
@@ -188,11 +165,12 @@ static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_dat
188 || je32_to_cpu(rx.version) != xd->version) { 165 || je32_to_cpu(rx.version) != xd->version) {
189 JFFS2_ERROR("inconsistent xdatum at %#08x, magic=%#04x/%#04x, " 166 JFFS2_ERROR("inconsistent xdatum at %#08x, magic=%#04x/%#04x, "
190 "nodetype=%#04x/%#04x, totlen=%u/%u, xid=%u/%u, version=%u/%u\n", 167 "nodetype=%#04x/%#04x, totlen=%u/%u, xid=%u/%u, version=%u/%u\n",
191 ref_offset(xd->node), je16_to_cpu(rx.magic), JFFS2_MAGIC_BITMASK, 168 offset, je16_to_cpu(rx.magic), JFFS2_MAGIC_BITMASK,
192 je16_to_cpu(rx.nodetype), JFFS2_NODETYPE_XATTR, 169 je16_to_cpu(rx.nodetype), JFFS2_NODETYPE_XATTR,
193 je32_to_cpu(rx.totlen), totlen, 170 je32_to_cpu(rx.totlen), totlen,
194 je32_to_cpu(rx.xid), xd->xid, 171 je32_to_cpu(rx.xid), xd->xid,
195 je32_to_cpu(rx.version), xd->version); 172 je32_to_cpu(rx.version), xd->version);
173 xd->flags |= JFFS2_XFLAGS_INVALID;
196 return EIO; 174 return EIO;
197 } 175 }
198 xd->xprefix = rx.xprefix; 176 xd->xprefix = rx.xprefix;
@@ -200,14 +178,17 @@ static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_dat
200 xd->value_len = je16_to_cpu(rx.value_len); 178 xd->value_len = je16_to_cpu(rx.value_len);
201 xd->data_crc = je32_to_cpu(rx.data_crc); 179 xd->data_crc = je32_to_cpu(rx.data_crc);
202 180
203 /* This JFFS2_NODETYPE_XATTR node is checked */
204 jeb = &c->blocks[ref_offset(xd->node) / c->sector_size];
205 totlen = PAD(je32_to_cpu(rx.totlen));
206
207 spin_lock(&c->erase_completion_lock); 181 spin_lock(&c->erase_completion_lock);
208 c->unchecked_size -= totlen; c->used_size += totlen; 182 complete:
209 jeb->unchecked_size -= totlen; jeb->used_size += totlen; 183 for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
210 xd->node->flash_offset = ref_offset(xd->node) | REF_PRISTINE; 184 jeb = &c->blocks[ref_offset(raw) / c->sector_size];
185 totlen = PAD(ref_totlen(c, jeb, raw));
186 if (ref_flags(raw) == REF_UNCHECKED) {
187 c->unchecked_size -= totlen; c->used_size += totlen;
188 jeb->unchecked_size -= totlen; jeb->used_size += totlen;
189 }
190 raw->flash_offset = ref_offset(raw) | ((xd->node==raw) ? REF_PRISTINE : REF_NORMAL);
191 }
211 spin_unlock(&c->erase_completion_lock); 192 spin_unlock(&c->erase_completion_lock);
212 193
213 /* unchecked xdatum is chained with c->xattr_unchecked */ 194 /* unchecked xdatum is chained with c->xattr_unchecked */
@@ -227,7 +208,6 @@ static int do_load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum
227 uint32_t crc, length; 208 uint32_t crc, length;
228 int i, ret, retry = 0; 209 int i, ret, retry = 0;
229 210
230 BUG_ON(!xd->node);
231 BUG_ON(ref_flags(xd->node) != REF_PRISTINE); 211 BUG_ON(ref_flags(xd->node) != REF_PRISTINE);
232 BUG_ON(!list_empty(&xd->xindex)); 212 BUG_ON(!list_empty(&xd->xindex));
233 retry: 213 retry:
@@ -253,6 +233,7 @@ static int do_load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum
253 " at %#08x, read: 0x%08x calculated: 0x%08x\n", 233 " at %#08x, read: 0x%08x calculated: 0x%08x\n",
254 ref_offset(xd->node), xd->data_crc, crc); 234 ref_offset(xd->node), xd->data_crc, crc);
255 kfree(data); 235 kfree(data);
236 xd->flags |= JFFS2_XFLAGS_INVALID;
256 return EIO; 237 return EIO;
257 } 238 }
258 239
@@ -286,16 +267,13 @@ static int load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *x
286 * rc > 0 : Unrecoverable error, this node should be deleted. 267 * rc > 0 : Unrecoverable error, this node should be deleted.
287 */ 268 */
288 int rc = 0; 269 int rc = 0;
289 BUG_ON(xd->xname); 270
290 if (!xd->node) 271 if (xd->xname)
272 return 0;
273 if (xd->flags & JFFS2_XFLAGS_INVALID)
291 return EIO; 274 return EIO;
292 if (unlikely(ref_flags(xd->node) != REF_PRISTINE)) { 275 if (unlikely(is_xattr_datum_unchecked(c, xd)))
293 rc = do_verify_xattr_datum(c, xd); 276 rc = do_verify_xattr_datum(c, xd);
294 if (rc > 0) {
295 list_del_init(&xd->xindex);
296 delete_xattr_datum_node(c, xd);
297 }
298 }
299 if (!rc) 277 if (!rc)
300 rc = do_load_xattr_datum(c, xd); 278 rc = do_load_xattr_datum(c, xd);
301 return rc; 279 return rc;
@@ -304,36 +282,43 @@ static int load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *x
304static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) 282static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
305{ 283{
306 /* must be called under down_write(xattr_sem) */ 284 /* must be called under down_write(xattr_sem) */
307 struct jffs2_raw_node_ref *raw;
308 struct jffs2_raw_xattr rx; 285 struct jffs2_raw_xattr rx;
309 struct kvec vecs[2]; 286 struct kvec vecs[2];
310 size_t length; 287 size_t length;
311 int rc, totlen; 288 int rc, totlen, nvecs = 1;
312 uint32_t phys_ofs = write_ofs(c); 289 uint32_t phys_ofs = write_ofs(c);
313 290
314 BUG_ON(!xd->xname); 291 BUG_ON(is_xattr_datum_dead(xd) || (xd->flags & JFFS2_XFLAGS_INVALID)
292 ? !!xd->xname : !xd->xname);
315 293
316 vecs[0].iov_base = ℞ 294 vecs[0].iov_base = ℞
317 vecs[0].iov_len = PAD(sizeof(rx)); 295 vecs[0].iov_len = totlen = sizeof(rx);
318 vecs[1].iov_base = xd->xname; 296 if (!is_xattr_datum_dead(xd) && !(xd->flags & JFFS2_XFLAGS_INVALID)) {
319 vecs[1].iov_len = xd->name_len + 1 + xd->value_len; 297 nvecs++;
320 totlen = vecs[0].iov_len + vecs[1].iov_len; 298 vecs[1].iov_base = xd->xname;
321 299 vecs[1].iov_len = xd->name_len + 1 + xd->value_len;
300 totlen += vecs[1].iov_len;
301 }
322 /* Setup raw-xattr */ 302 /* Setup raw-xattr */
303 memset(&rx, 0, sizeof(rx));
323 rx.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 304 rx.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
324 rx.nodetype = cpu_to_je16(JFFS2_NODETYPE_XATTR); 305 rx.nodetype = cpu_to_je16(JFFS2_NODETYPE_XATTR);
325 rx.totlen = cpu_to_je32(PAD(totlen)); 306 rx.totlen = cpu_to_je32(PAD(totlen));
326 rx.hdr_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_unknown_node) - 4)); 307 rx.hdr_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_unknown_node) - 4));
327 308
328 rx.xid = cpu_to_je32(xd->xid); 309 rx.xid = cpu_to_je32(xd->xid);
329 rx.version = cpu_to_je32(++xd->version); 310 if (!is_xattr_datum_dead(xd) && !(xd->flags & JFFS2_XFLAGS_INVALID)) {
330 rx.xprefix = xd->xprefix; 311 rx.version = cpu_to_je32(++xd->version);
331 rx.name_len = xd->name_len; 312 rx.xprefix = xd->xprefix;
332 rx.value_len = cpu_to_je16(xd->value_len); 313 rx.name_len = xd->name_len;
333 rx.data_crc = cpu_to_je32(crc32(0, vecs[1].iov_base, vecs[1].iov_len)); 314 rx.value_len = cpu_to_je16(xd->value_len);
315 rx.data_crc = cpu_to_je32(crc32(0, vecs[1].iov_base, vecs[1].iov_len));
316 } else {
317 rx.version = cpu_to_je32(XDATUM_DELETE_MARKER);
318 }
334 rx.node_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_raw_xattr) - 4)); 319 rx.node_crc = cpu_to_je32(crc32(0, &rx, sizeof(struct jffs2_raw_xattr) - 4));
335 320
336 rc = jffs2_flash_writev(c, vecs, 2, phys_ofs, &length, 0); 321 rc = jffs2_flash_writev(c, vecs, nvecs, phys_ofs, &length, 0);
337 if (rc || totlen != length) { 322 if (rc || totlen != length) {
338 JFFS2_WARNING("jffs2_flash_writev()=%d, req=%u, wrote=%zu, at %#08x\n", 323 JFFS2_WARNING("jffs2_flash_writev()=%d, req=%u, wrote=%zu, at %#08x\n",
339 rc, totlen, length, phys_ofs); 324 rc, totlen, length, phys_ofs);
@@ -343,14 +328,8 @@ static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *x
343 328
344 return rc; 329 return rc;
345 } 330 }
346
347 /* success */ 331 /* success */
348 raw = jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(totlen), NULL); 332 jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(totlen), (void *)xd);
349 /* FIXME */ raw->next_in_ino = (void *)xd;
350
351 if (xd->node)
352 delete_xattr_datum_node(c, xd);
353 xd->node = raw;
354 333
355 dbg_xattr("success on saving xdatum (xid=%u, version=%u, xprefix=%u, xname='%s')\n", 334 dbg_xattr("success on saving xdatum (xid=%u, version=%u, xprefix=%u, xname='%s')\n",
356 xd->xid, xd->version, xd->xprefix, xd->xname); 335 xd->xid, xd->version, xd->xprefix, xd->xname);
@@ -426,6 +405,39 @@ static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c,
426 return xd; 405 return xd;
427} 406}
428 407
408static void delete_xattr_datum_delay(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
409{
410 /* must be called under down_write(xattr_sem) */
411 BUG_ON(xd->refcnt);
412
413 unload_xattr_datum(c, xd);
414 set_xattr_datum_dead(xd);
415 spin_lock(&c->erase_completion_lock);
416 list_add(&xd->xindex, &c->xattr_dead_list);
417 spin_unlock(&c->erase_completion_lock);
418 JFFS2_NOTICE("xdatum(xid=%u) was removed without delete marker. "
419 "An orphan xdatum may be detected on next mounting.\n", xd->xid);
420}
421
422static void delete_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
423{
424 /* must be called under jffs2_reserve_space() and down_write(xattr_sem) */
425 int rc;
426 BUG_ON(xd->refcnt);
427
428 unload_xattr_datum(c, xd);
429 set_xattr_datum_dead(xd);
430 rc = save_xattr_datum(c, xd);
431 if (rc) {
432 JFFS2_NOTICE("xdatum(xid=%u) was removed without delete marker. "
433 "An orphan xdatum may be detected on next mounting.\n",
434 xd->xid);
435 }
436 spin_lock(&c->erase_completion_lock);
437 list_add(&xd->xindex, &c->xattr_dead_list);
438 spin_unlock(&c->erase_completion_lock);
439}
440
429/* -------- xref related functions ------------------ 441/* -------- xref related functions ------------------
430 * verify_xattr_ref(c, ref) 442 * verify_xattr_ref(c, ref)
431 * is used to load xref information from medium. Because summary data does not 443 * is used to load xref information from medium. Because summary data does not
@@ -450,25 +462,29 @@ static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c,
450static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) 462static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
451{ 463{
452 struct jffs2_eraseblock *jeb; 464 struct jffs2_eraseblock *jeb;
465 struct jffs2_raw_node_ref *raw;
453 struct jffs2_raw_xref rr; 466 struct jffs2_raw_xref rr;
454 size_t readlen; 467 size_t readlen;
455 uint32_t crc, totlen; 468 uint32_t crc, offset, totlen;
456 int rc; 469 int rc;
457 470
458 BUG_ON(ref_flags(ref->node) != REF_UNCHECKED); 471 spin_lock(&c->erase_completion_lock);
472 if (ref_flags(ref->node) != REF_UNCHECKED)
473 goto complete;
474 offset = ref_offset(ref->node);
475 spin_unlock(&c->erase_completion_lock);
459 476
460 rc = jffs2_flash_read(c, ref_offset(ref->node), sizeof(rr), &readlen, (char *)&rr); 477 rc = jffs2_flash_read(c, offset, sizeof(rr), &readlen, (char *)&rr);
461 if (rc || sizeof(rr) != readlen) { 478 if (rc || sizeof(rr) != readlen) {
462 JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu, at %#08x\n", 479 JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu, at %#08x\n",
463 rc, sizeof(rr), readlen, ref_offset(ref->node)); 480 rc, sizeof(rr), readlen, offset);
464 return rc ? rc : -EIO; 481 return rc ? rc : -EIO;
465 } 482 }
466 /* obsolete node */ 483 /* obsolete node */
467 crc = crc32(0, &rr, sizeof(rr) - 4); 484 crc = crc32(0, &rr, sizeof(rr) - 4);
468 if (crc != je32_to_cpu(rr.node_crc)) { 485 if (crc != je32_to_cpu(rr.node_crc)) {
469 if (je32_to_cpu(rr.node_crc) != 0xffffffff) 486 JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
470 JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", 487 offset, je32_to_cpu(rr.node_crc), crc);
471 ref_offset(ref->node), je32_to_cpu(rr.node_crc), crc);
472 return EIO; 488 return EIO;
473 } 489 }
474 if (je16_to_cpu(rr.magic) != JFFS2_MAGIC_BITMASK 490 if (je16_to_cpu(rr.magic) != JFFS2_MAGIC_BITMASK
@@ -476,22 +492,28 @@ static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref
476 || je32_to_cpu(rr.totlen) != PAD(sizeof(rr))) { 492 || je32_to_cpu(rr.totlen) != PAD(sizeof(rr))) {
477 JFFS2_ERROR("inconsistent xref at %#08x, magic=%#04x/%#04x, " 493 JFFS2_ERROR("inconsistent xref at %#08x, magic=%#04x/%#04x, "
478 "nodetype=%#04x/%#04x, totlen=%u/%zu\n", 494 "nodetype=%#04x/%#04x, totlen=%u/%zu\n",
479 ref_offset(ref->node), je16_to_cpu(rr.magic), JFFS2_MAGIC_BITMASK, 495 offset, je16_to_cpu(rr.magic), JFFS2_MAGIC_BITMASK,
480 je16_to_cpu(rr.nodetype), JFFS2_NODETYPE_XREF, 496 je16_to_cpu(rr.nodetype), JFFS2_NODETYPE_XREF,
481 je32_to_cpu(rr.totlen), PAD(sizeof(rr))); 497 je32_to_cpu(rr.totlen), PAD(sizeof(rr)));
482 return EIO; 498 return EIO;
483 } 499 }
484 ref->ino = je32_to_cpu(rr.ino); 500 ref->ino = je32_to_cpu(rr.ino);
485 ref->xid = je32_to_cpu(rr.xid); 501 ref->xid = je32_to_cpu(rr.xid);
486 502 ref->xseqno = je32_to_cpu(rr.xseqno);
487 /* fixup superblock/eraseblock info */ 503 if (ref->xseqno > c->highest_xseqno)
488 jeb = &c->blocks[ref_offset(ref->node) / c->sector_size]; 504 c->highest_xseqno = (ref->xseqno & ~XREF_DELETE_MARKER);
489 totlen = PAD(sizeof(rr));
490 505
491 spin_lock(&c->erase_completion_lock); 506 spin_lock(&c->erase_completion_lock);
492 c->unchecked_size -= totlen; c->used_size += totlen; 507 complete:
493 jeb->unchecked_size -= totlen; jeb->used_size += totlen; 508 for (raw=ref->node; raw != (void *)ref; raw=raw->next_in_ino) {
494 ref->node->flash_offset = ref_offset(ref->node) | REF_PRISTINE; 509 jeb = &c->blocks[ref_offset(raw) / c->sector_size];
510 totlen = PAD(ref_totlen(c, jeb, raw));
511 if (ref_flags(raw) == REF_UNCHECKED) {
512 c->unchecked_size -= totlen; c->used_size += totlen;
513 jeb->unchecked_size -= totlen; jeb->used_size += totlen;
514 }
515 raw->flash_offset = ref_offset(raw) | ((ref->node==raw) ? REF_PRISTINE : REF_NORMAL);
516 }
495 spin_unlock(&c->erase_completion_lock); 517 spin_unlock(&c->erase_completion_lock);
496 518
497 dbg_xattr("success on verifying xref (ino=%u, xid=%u) at %#08x\n", 519 dbg_xattr("success on verifying xref (ino=%u, xid=%u) at %#08x\n",
@@ -499,58 +521,12 @@ static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref
499 return 0; 521 return 0;
500} 522}
501 523
502static void delete_xattr_ref_node(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
503{
504 struct jffs2_raw_xref rr;
505 size_t length;
506 int rc;
507
508 if (jffs2_sum_active()) {
509 memset(&rr, 0xff, sizeof(rr));
510 rc = jffs2_flash_read(c, ref_offset(ref->node),
511 sizeof(struct jffs2_unknown_node),
512 &length, (char *)&rr);
513 if (rc || length != sizeof(struct jffs2_unknown_node)) {
514 JFFS2_ERROR("jffs2_flash_read()=%d, req=%zu, read=%zu at %#08x\n",
515 rc, sizeof(struct jffs2_unknown_node),
516 length, ref_offset(ref->node));
517 }
518 rc = jffs2_flash_write(c, ref_offset(ref->node), sizeof(rr),
519 &length, (char *)&rr);
520 if (rc || length != sizeof(struct jffs2_raw_xref)) {
521 JFFS2_ERROR("jffs2_flash_write()=%d, req=%zu, wrote=%zu at %#08x\n",
522 rc, sizeof(rr), length, ref_offset(ref->node));
523 }
524 }
525 spin_lock(&c->erase_completion_lock);
526 ref->node->next_in_ino = NULL;
527 spin_unlock(&c->erase_completion_lock);
528 jffs2_mark_node_obsolete(c, ref->node);
529 ref->node = NULL;
530}
531
532static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
533{
534 /* must be called under down_write(xattr_sem) */
535 struct jffs2_xattr_datum *xd;
536
537 BUG_ON(!ref->node);
538 delete_xattr_ref_node(c, ref);
539
540 xd = ref->xd;
541 xd->refcnt--;
542 if (!xd->refcnt)
543 delete_xattr_datum(c, xd);
544 jffs2_free_xattr_ref(ref);
545}
546
547static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) 524static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
548{ 525{
549 /* must be called under down_write(xattr_sem) */ 526 /* must be called under down_write(xattr_sem) */
550 struct jffs2_raw_node_ref *raw;
551 struct jffs2_raw_xref rr; 527 struct jffs2_raw_xref rr;
552 size_t length; 528 size_t length;
553 uint32_t phys_ofs = write_ofs(c); 529 uint32_t xseqno, phys_ofs = write_ofs(c);
554 int ret; 530 int ret;
555 531
556 rr.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 532 rr.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -558,8 +534,16 @@ static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
558 rr.totlen = cpu_to_je32(PAD(sizeof(rr))); 534 rr.totlen = cpu_to_je32(PAD(sizeof(rr)));
559 rr.hdr_crc = cpu_to_je32(crc32(0, &rr, sizeof(struct jffs2_unknown_node) - 4)); 535 rr.hdr_crc = cpu_to_je32(crc32(0, &rr, sizeof(struct jffs2_unknown_node) - 4));
560 536
561 rr.ino = cpu_to_je32(ref->ic->ino); 537 xseqno = (c->highest_xseqno += 2);
562 rr.xid = cpu_to_je32(ref->xd->xid); 538 if (is_xattr_ref_dead(ref)) {
539 xseqno |= XREF_DELETE_MARKER;
540 rr.ino = cpu_to_je32(ref->ino);
541 rr.xid = cpu_to_je32(ref->xid);
542 } else {
543 rr.ino = cpu_to_je32(ref->ic->ino);
544 rr.xid = cpu_to_je32(ref->xd->xid);
545 }
546 rr.xseqno = cpu_to_je32(xseqno);
563 rr.node_crc = cpu_to_je32(crc32(0, &rr, sizeof(rr) - 4)); 547 rr.node_crc = cpu_to_je32(crc32(0, &rr, sizeof(rr) - 4));
564 548
565 ret = jffs2_flash_write(c, phys_ofs, sizeof(rr), &length, (char *)&rr); 549 ret = jffs2_flash_write(c, phys_ofs, sizeof(rr), &length, (char *)&rr);
@@ -572,12 +556,9 @@ static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
572 556
573 return ret; 557 return ret;
574 } 558 }
575 559 /* success */
576 raw = jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(sizeof(rr)), NULL); 560 ref->xseqno = xseqno;
577 /* FIXME */ raw->next_in_ino = (void *)ref; 561 jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(sizeof(rr)), (void *)ref);
578 if (ref->node)
579 delete_xattr_ref_node(c, ref);
580 ref->node = raw;
581 562
582 dbg_xattr("success on saving xref (ino=%u, xid=%u)\n", ref->ic->ino, ref->xd->xid); 563 dbg_xattr("success on saving xref (ino=%u, xid=%u)\n", ref->ic->ino, ref->xd->xid);
583 564
@@ -610,22 +591,116 @@ static struct jffs2_xattr_ref *create_xattr_ref(struct jffs2_sb_info *c, struct
610 return ref; /* success */ 591 return ref; /* success */
611} 592}
612 593
594static void delete_xattr_ref_delay(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
595{
596 /* must be called under down_write(xattr_sem) */
597 struct jffs2_xattr_datum *xd;
598
599 set_xattr_ref_dead(ref);
600 xd = ref->xd;
601 ref->ino = ref->ic->ino;
602 ref->xid = ref->xd->xid;
603 spin_lock(&c->erase_completion_lock);
604 ref->next = c->xref_dead_list;
605 c->xref_dead_list = ref;
606 spin_unlock(&c->erase_completion_lock);
607
608 JFFS2_NOTICE("xref(ino=%u, xid=%u) was removed without delete marker. "
609 "An orphan xref may be detected on next mounting.\n",
610 ref->ino, ref->xid);
611
612 if (!--xd->refcnt)
613 delete_xattr_datum_delay(c, xd);
614}
615
616static int delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref, int enforce)
617{
618 /* must be called under jffs2_reserve_space() and down_write(xattr_sem) */
619 struct jffs2_inode_cache *ic;
620 struct jffs2_xattr_datum *xd;
621 uint32_t length;
622 int rc;
623
624 set_xattr_ref_dead(ref);
625 ic = ref->ic;
626 xd = ref->xd;
627 ref->ino = ic->ino;
628 ref->xid = xd->xid;
629 rc = save_xattr_ref(c, ref);
630 if (rc) {
631 if (!enforce) {
632 clr_xattr_ref_dead(ref);
633 ref->ic = ic;
634 ref->xd = xd;
635 return rc;
636 }
637 JFFS2_WARNING("could not write delete marker of xref(ino=%u, xid=%u). "
638 "An orphan xref may be detected on next mounting.\n",
639 ref->ic->ino, ref->xd->xid);
640 }
641 spin_lock(&c->erase_completion_lock);
642 ref->next = c->xref_dead_list;
643 c->xref_dead_list = ref;
644 spin_unlock(&c->erase_completion_lock);
645
646 xd->refcnt--;
647 if (xd->refcnt)
648 return 0;
649
650 /* delete xdatum */
651 unload_xattr_datum(c, xd);
652 up_write(&c->xattr_sem);
653 jffs2_complete_reservation(c);
654
655 rc = jffs2_reserve_space(c, PAD(sizeof(struct jffs2_raw_xattr)), &length,
656 ALLOC_DELETION, JFFS2_SUMMARY_XATTR_SIZE);
657 if (rc) {
658 down(&c->alloc_sem);
659 down_write(&c->xattr_sem);
660 delete_xattr_datum_delay(c, xd);
661 } else {
662 down_write(&c->xattr_sem);
663 delete_xattr_datum(c, xd);
664 }
665 return 0;
666}
667
613void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) 668void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
614{ 669{
615 /* It's called from jffs2_clear_inode() on inode removing. 670 /* It's called from jffs2_clear_inode() on inode removing.
616 When an inode with XATTR is removed, those XATTRs must be removed. */ 671 When an inode with XATTR is removed, those XATTRs must be removed. */
617 struct jffs2_xattr_ref *ref, *_ref; 672 struct jffs2_xattr_ref *ref;
673 uint32_t length;
674 int rc, retry;
618 675
619 if (!ic || ic->nlink > 0) 676 if (!ic || ic->nlink > 0)
620 return; 677 return;
621 678
679 down_read(&c->xattr_sem);
680 if (!ic->xref) {
681 up_read(&c->xattr_sem);
682 return;
683 }
684 up_read(&c->xattr_sem);
685 retry:
686 rc = jffs2_reserve_space(c, PAD(sizeof(struct jffs2_raw_xref)), &length,
687 ALLOC_DELETION, JFFS2_SUMMARY_XREF_SIZE);
622 down_write(&c->xattr_sem); 688 down_write(&c->xattr_sem);
623 for (ref = ic->xref; ref; ref = _ref) { 689 if (ic->xref) {
624 _ref = ref->next; 690 ref = ic->xref;
625 delete_xattr_ref(c, ref); 691 ic->xref = ref->next;
692 if (rc) {
693 delete_xattr_ref_delay(c, ref);
694 } else {
695 delete_xattr_ref(c, ref, 1);
696 }
626 } 697 }
627 ic->xref = NULL; 698 retry = ic->xref ? 1 : 0;
628 up_write(&c->xattr_sem); 699 up_write(&c->xattr_sem);
700 if (!rc)
701 jffs2_complete_reservation(c);
702 if (retry)
703 goto retry;
629} 704}
630 705
631void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) 706void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
@@ -655,7 +730,7 @@ static int check_xattr_ref_inode(struct jffs2_sb_info *c, struct jffs2_inode_cac
655 * duplicate name/value pairs. If duplicate name/value pair would be found, 730 * duplicate name/value pairs. If duplicate name/value pair would be found,
656 * one will be removed. 731 * one will be removed.
657 */ 732 */
658 struct jffs2_xattr_ref *ref, *cmp, **pref; 733 struct jffs2_xattr_ref *ref, *cmp, **pref, **pcmp;
659 int rc = 0; 734 int rc = 0;
660 735
661 if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED)) 736 if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED))
@@ -668,27 +743,32 @@ static int check_xattr_ref_inode(struct jffs2_sb_info *c, struct jffs2_inode_cac
668 rc = load_xattr_datum(c, ref->xd); 743 rc = load_xattr_datum(c, ref->xd);
669 if (unlikely(rc > 0)) { 744 if (unlikely(rc > 0)) {
670 *pref = ref->next; 745 *pref = ref->next;
671 delete_xattr_ref(c, ref); 746 delete_xattr_ref_delay(c, ref);
672 goto retry; 747 goto retry;
673 } else if (unlikely(rc < 0)) 748 } else if (unlikely(rc < 0))
674 goto out; 749 goto out;
675 } 750 }
676 for (cmp=ref->next, pref=&ref->next; cmp; pref=&cmp->next, cmp=cmp->next) { 751 for (cmp=ref->next, pcmp=&ref->next; cmp; pcmp=&cmp->next, cmp=cmp->next) {
677 if (!cmp->xd->xname) { 752 if (!cmp->xd->xname) {
678 ref->xd->flags |= JFFS2_XFLAGS_BIND; 753 ref->xd->flags |= JFFS2_XFLAGS_BIND;
679 rc = load_xattr_datum(c, cmp->xd); 754 rc = load_xattr_datum(c, cmp->xd);
680 ref->xd->flags &= ~JFFS2_XFLAGS_BIND; 755 ref->xd->flags &= ~JFFS2_XFLAGS_BIND;
681 if (unlikely(rc > 0)) { 756 if (unlikely(rc > 0)) {
682 *pref = cmp->next; 757 *pcmp = cmp->next;
683 delete_xattr_ref(c, cmp); 758 delete_xattr_ref_delay(c, cmp);
684 goto retry; 759 goto retry;
685 } else if (unlikely(rc < 0)) 760 } else if (unlikely(rc < 0))
686 goto out; 761 goto out;
687 } 762 }
688 if (ref->xd->xprefix == cmp->xd->xprefix 763 if (ref->xd->xprefix == cmp->xd->xprefix
689 && !strcmp(ref->xd->xname, cmp->xd->xname)) { 764 && !strcmp(ref->xd->xname, cmp->xd->xname)) {
690 *pref = cmp->next; 765 if (ref->xseqno > cmp->xseqno) {
691 delete_xattr_ref(c, cmp); 766 *pcmp = cmp->next;
767 delete_xattr_ref_delay(c, cmp);
768 } else {
769 *pref = ref->next;
770 delete_xattr_ref_delay(c, ref);
771 }
692 goto retry; 772 goto retry;
693 } 773 }
694 } 774 }
@@ -719,9 +799,13 @@ void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c)
719 for (i=0; i < XATTRINDEX_HASHSIZE; i++) 799 for (i=0; i < XATTRINDEX_HASHSIZE; i++)
720 INIT_LIST_HEAD(&c->xattrindex[i]); 800 INIT_LIST_HEAD(&c->xattrindex[i]);
721 INIT_LIST_HEAD(&c->xattr_unchecked); 801 INIT_LIST_HEAD(&c->xattr_unchecked);
802 INIT_LIST_HEAD(&c->xattr_dead_list);
803 c->xref_dead_list = NULL;
722 c->xref_temp = NULL; 804 c->xref_temp = NULL;
723 805
724 init_rwsem(&c->xattr_sem); 806 init_rwsem(&c->xattr_sem);
807 c->highest_xid = 0;
808 c->highest_xseqno = 0;
725 c->xdatum_mem_usage = 0; 809 c->xdatum_mem_usage = 0;
726 c->xdatum_mem_threshold = 32 * 1024; /* Default 32KB */ 810 c->xdatum_mem_threshold = 32 * 1024; /* Default 32KB */
727} 811}
@@ -751,7 +835,11 @@ void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c)
751 _ref = ref->next; 835 _ref = ref->next;
752 jffs2_free_xattr_ref(ref); 836 jffs2_free_xattr_ref(ref);
753 } 837 }
754 c->xref_temp = NULL; 838
839 for (ref=c->xref_dead_list; ref; ref = _ref) {
840 _ref = ref->next;
841 jffs2_free_xattr_ref(ref);
842 }
755 843
756 for (i=0; i < XATTRINDEX_HASHSIZE; i++) { 844 for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
757 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) { 845 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
@@ -761,64 +849,120 @@ void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c)
761 jffs2_free_xattr_datum(xd); 849 jffs2_free_xattr_datum(xd);
762 } 850 }
763 } 851 }
852
853 list_for_each_entry_safe(xd, _xd, &c->xattr_dead_list, xindex) {
854 list_del(&xd->xindex);
855 jffs2_free_xattr_datum(xd);
856 }
764} 857}
765 858
859#define XREF_TMPHASH_SIZE (128)
766void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) 860void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
767{ 861{
768 struct jffs2_xattr_ref *ref, *_ref; 862 struct jffs2_xattr_ref *ref, *_ref;
863 struct jffs2_xattr_ref *xref_tmphash[XREF_TMPHASH_SIZE];
769 struct jffs2_xattr_datum *xd, *_xd; 864 struct jffs2_xattr_datum *xd, *_xd;
770 struct jffs2_inode_cache *ic; 865 struct jffs2_inode_cache *ic;
771 int i, xdatum_count =0, xdatum_unchecked_count = 0, xref_count = 0; 866 struct jffs2_raw_node_ref *raw;
867 int i, xdatum_count = 0, xdatum_unchecked_count = 0, xref_count = 0;
772 868
773 BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING)); 869 BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING));
870 /* Phase.1 : Drop dead xdatum */
871 for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
872 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
873 BUG_ON(xd->node == (void *)xd);
874 if (is_xattr_datum_dead(xd)) {
875 list_del_init(&xd->xindex);
876 list_add(&xd->xindex, &c->xattr_unchecked);
877 }
878 }
879 }
774 880
775 /* Phase.1 */ 881 /* Phase.2 : Merge same xref */
882 for (i=0; i < XREF_TMPHASH_SIZE; i++)
883 xref_tmphash[i] = NULL;
776 for (ref=c->xref_temp; ref; ref=_ref) { 884 for (ref=c->xref_temp; ref; ref=_ref) {
885 struct jffs2_xattr_ref *tmp;
886
777 _ref = ref->next; 887 _ref = ref->next;
778 /* checking REF_UNCHECKED nodes */
779 if (ref_flags(ref->node) != REF_PRISTINE) { 888 if (ref_flags(ref->node) != REF_PRISTINE) {
780 if (verify_xattr_ref(c, ref)) { 889 if (verify_xattr_ref(c, ref)) {
781 delete_xattr_ref_node(c, ref); 890 BUG_ON(ref->node->next_in_ino != (void *)ref);
891 ref->node->next_in_ino = NULL;
892 jffs2_mark_node_obsolete(c, ref->node);
782 jffs2_free_xattr_ref(ref); 893 jffs2_free_xattr_ref(ref);
783 continue; 894 continue;
784 } 895 }
785 } 896 }
786 /* At this point, ref->xid and ref->ino contain XID and inode number. 897
787 ref->xd and ref->ic are not valid yet. */ 898 i = (ref->ino ^ ref->xid) % XREF_TMPHASH_SIZE;
788 xd = jffs2_find_xattr_datum(c, ref->xid); 899 for (tmp=xref_tmphash[i]; tmp; tmp=tmp->next) {
789 ic = jffs2_get_ino_cache(c, ref->ino); 900 if (tmp->ino == ref->ino && tmp->xid == ref->xid)
790 if (!xd || !ic) { 901 break;
791 if (ref_flags(ref->node) != REF_UNCHECKED) 902 }
792 JFFS2_WARNING("xref(ino=%u, xid=%u) is orphan. \n", 903 if (tmp) {
793 ref->ino, ref->xid); 904 raw = ref->node;
794 delete_xattr_ref_node(c, ref); 905 if (ref->xseqno > tmp->xseqno) {
906 tmp->xseqno = ref->xseqno;
907 raw->next_in_ino = tmp->node;
908 tmp->node = raw;
909 } else {
910 raw->next_in_ino = tmp->node->next_in_ino;
911 tmp->node->next_in_ino = raw;
912 }
795 jffs2_free_xattr_ref(ref); 913 jffs2_free_xattr_ref(ref);
796 continue; 914 continue;
915 } else {
916 ref->next = xref_tmphash[i];
917 xref_tmphash[i] = ref;
797 } 918 }
798 ref->xd = xd;
799 ref->ic = ic;
800 xd->refcnt++;
801 ref->next = ic->xref;
802 ic->xref = ref;
803 xref_count++;
804 } 919 }
805 c->xref_temp = NULL; 920 c->xref_temp = NULL;
806 /* After this, ref->xid/ino are NEVER used. */
807 921
808 /* Phase.2 */ 922 /* Phase.3 : Bind xref with inode_cache and xattr_datum */
923 for (i=0; i < XREF_TMPHASH_SIZE; i++) {
924 for (ref=xref_tmphash[i]; ref; ref=_ref) {
925 _ref = ref->next;
926 if (is_xattr_ref_dead(ref)) {
927 ref->next = c->xref_dead_list;
928 c->xref_dead_list = ref;
929 continue;
930 }
931 /* At this point, ref->xid and ref->ino contain XID and inode number.
932 ref->xd and ref->ic are not valid yet. */
933 xd = jffs2_find_xattr_datum(c, ref->xid);
934 ic = jffs2_get_ino_cache(c, ref->ino);
935 if (!xd || !ic) {
936 JFFS2_WARNING("xref(ino=%u, xid=%u, xseqno=%u) is orphan. \n",
937 ref->ino, ref->xid, ref->xseqno);
938 set_xattr_ref_dead(ref);
939 ref->next = c->xref_dead_list;
940 c->xref_dead_list = ref;
941 continue;
942 }
943 ref->xd = xd;
944 ref->ic = ic;
945 xd->refcnt++;
946 ref->next = ic->xref;
947 ic->xref = ref;
948 xref_count++;
949 }
950 }
951
952 /* Phase.4 : Link unchecked xdatum to xattr_unchecked list */
809 for (i=0; i < XATTRINDEX_HASHSIZE; i++) { 953 for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
810 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) { 954 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
811 list_del_init(&xd->xindex); 955 list_del_init(&xd->xindex);
812 if (!xd->refcnt) { 956 if (!xd->refcnt) {
813 if (ref_flags(xd->node) != REF_UNCHECKED) 957 JFFS2_WARNING("orphan xdatum(xid=%u, version=%u)\n",
814 JFFS2_WARNING("orphan xdatum(xid=%u, version=%u) at %#08x\n", 958 xd->xid, xd->version);
815 xd->xid, xd->version, ref_offset(xd->node)); 959 set_xattr_datum_dead(xd);
816 delete_xattr_datum(c, xd); 960 list_add(&xd->xindex, &c->xattr_unchecked);
817 continue; 961 continue;
818 } 962 }
819 if (ref_flags(xd->node) != REF_PRISTINE) { 963 if (is_xattr_datum_unchecked(c, xd)) {
820 dbg_xattr("unchecked xdatum(xid=%u) at %#08x\n", 964 dbg_xattr("unchecked xdatum(xid=%u, version=%u)\n",
821 xd->xid, ref_offset(xd->node)); 965 xd->xid, xd->version);
822 list_add(&xd->xindex, &c->xattr_unchecked); 966 list_add(&xd->xindex, &c->xattr_unchecked);
823 xdatum_unchecked_count++; 967 xdatum_unchecked_count++;
824 } 968 }
@@ -833,28 +977,18 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
833struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c, 977struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,
834 uint32_t xid, uint32_t version) 978 uint32_t xid, uint32_t version)
835{ 979{
836 struct jffs2_xattr_datum *xd, *_xd; 980 struct jffs2_xattr_datum *xd;
837 981
838 _xd = jffs2_find_xattr_datum(c, xid); 982 xd = jffs2_find_xattr_datum(c, xid);
839 if (_xd) { 983 if (!xd) {
840 dbg_xattr("duplicate xdatum (xid=%u, version=%u/%u) at %#08x\n", 984 xd = jffs2_alloc_xattr_datum();
841 xid, version, _xd->version, ref_offset(_xd->node)); 985 if (!xd)
842 if (version < _xd->version) 986 return ERR_PTR(-ENOMEM);
843 return ERR_PTR(-EEXIST); 987 xd->xid = xid;
844 } 988 xd->version = version;
845 xd = jffs2_alloc_xattr_datum(); 989 if (xd->xid > c->highest_xid)
846 if (!xd) 990 c->highest_xid = xd->xid;
847 return ERR_PTR(-ENOMEM); 991 list_add_tail(&xd->xindex, &c->xattrindex[xid % XATTRINDEX_HASHSIZE]);
848 xd->xid = xid;
849 xd->version = version;
850 if (xd->xid > c->highest_xid)
851 c->highest_xid = xd->xid;
852 list_add_tail(&xd->xindex, &c->xattrindex[xid % XATTRINDEX_HASHSIZE]);
853
854 if (_xd) {
855 list_del_init(&_xd->xindex);
856 delete_xattr_datum_node(c, _xd);
857 jffs2_free_xattr_datum(_xd);
858 } 992 }
859 return xd; 993 return xd;
860} 994}
@@ -945,7 +1079,7 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
945 rc = load_xattr_datum(c, xd); 1079 rc = load_xattr_datum(c, xd);
946 if (unlikely(rc > 0)) { 1080 if (unlikely(rc > 0)) {
947 *pref = ref->next; 1081 *pref = ref->next;
948 delete_xattr_ref(c, ref); 1082 delete_xattr_ref_delay(c, ref);
949 goto retry; 1083 goto retry;
950 } else if (unlikely(rc < 0)) 1084 } else if (unlikely(rc < 0))
951 goto out; 1085 goto out;
@@ -1006,7 +1140,7 @@ int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname,
1006 rc = load_xattr_datum(c, xd); 1140 rc = load_xattr_datum(c, xd);
1007 if (unlikely(rc > 0)) { 1141 if (unlikely(rc > 0)) {
1008 *pref = ref->next; 1142 *pref = ref->next;
1009 delete_xattr_ref(c, ref); 1143 delete_xattr_ref_delay(c, ref);
1010 goto retry; 1144 goto retry;
1011 } else if (unlikely(rc < 0)) { 1145 } else if (unlikely(rc < 0)) {
1012 goto out; 1146 goto out;
@@ -1069,7 +1203,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1069 rc = load_xattr_datum(c, xd); 1203 rc = load_xattr_datum(c, xd);
1070 if (unlikely(rc > 0)) { 1204 if (unlikely(rc > 0)) {
1071 *pref = ref->next; 1205 *pref = ref->next;
1072 delete_xattr_ref(c, ref); 1206 delete_xattr_ref_delay(c, ref);
1073 goto retry; 1207 goto retry;
1074 } else if (unlikely(rc < 0)) 1208 } else if (unlikely(rc < 0))
1075 goto out; 1209 goto out;
@@ -1081,8 +1215,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1081 } 1215 }
1082 if (!buffer) { 1216 if (!buffer) {
1083 *pref = ref->next; 1217 *pref = ref->next;
1084 delete_xattr_ref(c, ref); 1218 rc = delete_xattr_ref(c, ref, 0);
1085 rc = 0;
1086 goto out; 1219 goto out;
1087 } 1220 }
1088 goto found; 1221 goto found;
@@ -1094,7 +1227,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1094 goto out; 1227 goto out;
1095 } 1228 }
1096 if (!buffer) { 1229 if (!buffer) {
1097 rc = -EINVAL; 1230 rc = -ENODATA;
1098 goto out; 1231 goto out;
1099 } 1232 }
1100 found: 1233 found:
@@ -1110,16 +1243,15 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1110 request = PAD(sizeof(struct jffs2_raw_xref)); 1243 request = PAD(sizeof(struct jffs2_raw_xref));
1111 rc = jffs2_reserve_space(c, request, &length, 1244 rc = jffs2_reserve_space(c, request, &length,
1112 ALLOC_NORMAL, JFFS2_SUMMARY_XREF_SIZE); 1245 ALLOC_NORMAL, JFFS2_SUMMARY_XREF_SIZE);
1246 down_write(&c->xattr_sem);
1113 if (rc) { 1247 if (rc) {
1114 JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request); 1248 JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
1115 down_write(&c->xattr_sem);
1116 xd->refcnt--; 1249 xd->refcnt--;
1117 if (!xd->refcnt) 1250 if (!xd->refcnt)
1118 delete_xattr_datum(c, xd); 1251 delete_xattr_datum_delay(c, xd);
1119 up_write(&c->xattr_sem); 1252 up_write(&c->xattr_sem);
1120 return rc; 1253 return rc;
1121 } 1254 }
1122 down_write(&c->xattr_sem);
1123 if (ref) 1255 if (ref)
1124 *pref = ref->next; 1256 *pref = ref->next;
1125 newref = create_xattr_ref(c, ic, xd); 1257 newref = create_xattr_ref(c, ic, xd);
@@ -1131,9 +1263,21 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1131 rc = PTR_ERR(newref); 1263 rc = PTR_ERR(newref);
1132 xd->refcnt--; 1264 xd->refcnt--;
1133 if (!xd->refcnt) 1265 if (!xd->refcnt)
1134 delete_xattr_datum(c, xd); 1266 delete_xattr_datum_delay(c, xd);
1135 } else if (ref) { 1267 } else if (ref) {
1136 delete_xattr_ref(c, ref); 1268 up_write(&c->xattr_sem);
1269 jffs2_complete_reservation(c);
1270
1271 rc = jffs2_reserve_space(c, request, &length,
1272 ALLOC_DELETION, JFFS2_SUMMARY_XREF_SIZE);
1273 down_write(&c->xattr_sem);
1274 if (rc) {
1275 JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
1276 delete_xattr_ref_delay(c, ref);
1277 up_write(&c->xattr_sem);
1278 return 0;
1279 }
1280 delete_xattr_ref(c, ref, 1);
1137 } 1281 }
1138 out: 1282 out:
1139 up_write(&c->xattr_sem); 1283 up_write(&c->xattr_sem);
@@ -1142,38 +1286,37 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1142} 1286}
1143 1287
1144/* -------- garbage collector functions ------------- 1288/* -------- garbage collector functions -------------
1145 * jffs2_garbage_collect_xattr_datum(c, xd) 1289 * jffs2_garbage_collect_xattr_datum(c, xd, raw)
1146 * is used to move xdatum into new node. 1290 * is used to move xdatum into new node.
1147 * jffs2_garbage_collect_xattr_ref(c, ref) 1291 * jffs2_garbage_collect_xattr_ref(c, ref, raw)
1148 * is used to move xref into new node. 1292 * is used to move xref into new node.
1149 * jffs2_verify_xattr(c) 1293 * jffs2_verify_xattr(c)
1150 * is used to call do_verify_xattr_datum() before garbage collecting. 1294 * is used to call do_verify_xattr_datum() before garbage collecting.
1151 * -------------------------------------------------- */ 1295 * -------------------------------------------------- */
1152int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) 1296int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd,
1297 struct jffs2_raw_node_ref *raw)
1153{ 1298{
1154 uint32_t totlen, length, old_ofs; 1299 uint32_t totlen, length, old_ofs;
1155 int rc = -EINVAL; 1300 int rc = 0;
1156 1301
1157 down_write(&c->xattr_sem); 1302 down_write(&c->xattr_sem);
1158 BUG_ON(!xd->node); 1303 if (xd->node != raw)
1304 goto out;
1305 if (is_xattr_datum_dead(xd) && (raw->next_in_ino == (void *)xd))
1306 goto out;
1159 1307
1160 old_ofs = ref_offset(xd->node); 1308 old_ofs = ref_offset(xd->node);
1161 totlen = ref_totlen(c, c->gcblock, xd->node); 1309 totlen = ref_totlen(c, c->gcblock, xd->node);
1162 if (totlen < sizeof(struct jffs2_raw_xattr))
1163 goto out;
1164 1310
1165 if (!xd->xname) { 1311 if (!is_xattr_datum_dead(xd)) {
1166 rc = load_xattr_datum(c, xd); 1312 rc = load_xattr_datum(c, xd);
1167 if (unlikely(rc > 0)) { 1313 if (unlikely(rc < 0))
1168 delete_xattr_datum_node(c, xd);
1169 rc = 0;
1170 goto out;
1171 } else if (unlikely(rc < 0))
1172 goto out; 1314 goto out;
1173 } 1315 }
1316
1174 rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XATTR_SIZE); 1317 rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XATTR_SIZE);
1175 if (rc || length < totlen) { 1318 if (rc) {
1176 JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, totlen); 1319 JFFS2_WARNING("jffs2_reserve_space_gc()=%d, request=%u\n", rc, totlen);
1177 rc = rc ? rc : -EBADFD; 1320 rc = rc ? rc : -EBADFD;
1178 goto out; 1321 goto out;
1179 } 1322 }
@@ -1182,27 +1325,33 @@ int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xatt
1182 dbg_xattr("xdatum (xid=%u, version=%u) GC'ed from %#08x to %08x\n", 1325 dbg_xattr("xdatum (xid=%u, version=%u) GC'ed from %#08x to %08x\n",
1183 xd->xid, xd->version, old_ofs, ref_offset(xd->node)); 1326 xd->xid, xd->version, old_ofs, ref_offset(xd->node));
1184 out: 1327 out:
1328 if (!rc)
1329 jffs2_mark_node_obsolete(c, raw);
1185 up_write(&c->xattr_sem); 1330 up_write(&c->xattr_sem);
1186 return rc; 1331 return rc;
1187} 1332}
1188 1333
1189 1334
1190int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) 1335int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref,
1336 struct jffs2_raw_node_ref *raw)
1191{ 1337{
1192 uint32_t totlen, length, old_ofs; 1338 uint32_t totlen, length, old_ofs;
1193 int rc = -EINVAL; 1339 int rc = 0;
1194 1340
1195 down_write(&c->xattr_sem); 1341 down_write(&c->xattr_sem);
1196 BUG_ON(!ref->node); 1342 BUG_ON(!ref->node);
1197 1343
1344 if (ref->node != raw)
1345 goto out;
1346 if (is_xattr_ref_dead(ref) && (raw->next_in_ino == (void *)ref))
1347 goto out;
1348
1198 old_ofs = ref_offset(ref->node); 1349 old_ofs = ref_offset(ref->node);
1199 totlen = ref_totlen(c, c->gcblock, ref->node); 1350 totlen = ref_totlen(c, c->gcblock, ref->node);
1200 if (totlen != sizeof(struct jffs2_raw_xref))
1201 goto out;
1202 1351
1203 rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XREF_SIZE); 1352 rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XREF_SIZE);
1204 if (rc || length < totlen) { 1353 if (rc) {
1205 JFFS2_WARNING("%s: jffs2_reserve_space() = %d, request = %u\n", 1354 JFFS2_WARNING("%s: jffs2_reserve_space_gc() = %d, request = %u\n",
1206 __FUNCTION__, rc, totlen); 1355 __FUNCTION__, rc, totlen);
1207 rc = rc ? rc : -EBADFD; 1356 rc = rc ? rc : -EBADFD;
1208 goto out; 1357 goto out;
@@ -1212,6 +1361,8 @@ int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_
1212 dbg_xattr("xref (ino=%u, xid=%u) GC'ed from %#08x to %08x\n", 1361 dbg_xattr("xref (ino=%u, xid=%u) GC'ed from %#08x to %08x\n",
1213 ref->ic->ino, ref->xd->xid, old_ofs, ref_offset(ref->node)); 1362 ref->ic->ino, ref->xd->xid, old_ofs, ref_offset(ref->node));
1214 out: 1363 out:
1364 if (!rc)
1365 jffs2_mark_node_obsolete(c, raw);
1215 up_write(&c->xattr_sem); 1366 up_write(&c->xattr_sem);
1216 return rc; 1367 return rc;
1217} 1368}
@@ -1219,20 +1370,59 @@ int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_
1219int jffs2_verify_xattr(struct jffs2_sb_info *c) 1370int jffs2_verify_xattr(struct jffs2_sb_info *c)
1220{ 1371{
1221 struct jffs2_xattr_datum *xd, *_xd; 1372 struct jffs2_xattr_datum *xd, *_xd;
1373 struct jffs2_eraseblock *jeb;
1374 struct jffs2_raw_node_ref *raw;
1375 uint32_t totlen;
1222 int rc; 1376 int rc;
1223 1377
1224 down_write(&c->xattr_sem); 1378 down_write(&c->xattr_sem);
1225 list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) { 1379 list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) {
1226 rc = do_verify_xattr_datum(c, xd); 1380 rc = do_verify_xattr_datum(c, xd);
1227 if (rc == 0) { 1381 if (rc < 0)
1228 list_del_init(&xd->xindex); 1382 continue;
1229 break; 1383 list_del_init(&xd->xindex);
1230 } else if (rc > 0) { 1384 spin_lock(&c->erase_completion_lock);
1231 list_del_init(&xd->xindex); 1385 for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
1232 delete_xattr_datum_node(c, xd); 1386 if (ref_flags(raw) != REF_UNCHECKED)
1387 continue;
1388 jeb = &c->blocks[ref_offset(raw) / c->sector_size];
1389 totlen = PAD(ref_totlen(c, jeb, raw));
1390 c->unchecked_size -= totlen; c->used_size += totlen;
1391 jeb->unchecked_size -= totlen; jeb->used_size += totlen;
1392 raw->flash_offset = ref_offset(raw)
1393 | ((xd->node == (void *)raw) ? REF_PRISTINE : REF_NORMAL);
1233 } 1394 }
1395 if (is_xattr_datum_dead(xd))
1396 list_add(&xd->xindex, &c->xattr_dead_list);
1397 spin_unlock(&c->erase_completion_lock);
1234 } 1398 }
1235 up_write(&c->xattr_sem); 1399 up_write(&c->xattr_sem);
1236
1237 return list_empty(&c->xattr_unchecked) ? 1 : 0; 1400 return list_empty(&c->xattr_unchecked) ? 1 : 0;
1238} 1401}
1402
1403void jffs2_release_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
1404{
1405 /* must be called under spin_lock(&c->erase_completion_lock) */
1406 if (xd->node != (void *)xd)
1407 return;
1408
1409 list_del(&xd->xindex);
1410 jffs2_free_xattr_datum(xd);
1411}
1412
1413void jffs2_release_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
1414{
1415 /* must be called under spin_lock(&c->erase_completion_lock) */
1416 struct jffs2_xattr_ref *tmp, **ptmp;
1417
1418 if (ref->node != (void *)ref)
1419 return;
1420
1421 for (tmp=c->xref_dead_list, ptmp=&c->xref_dead_list; tmp; ptmp=&tmp->next, tmp=tmp->next) {
1422 if (ref == tmp) {
1423 *ptmp = tmp->next;
1424 jffs2_free_xattr_ref(ref);
1425 break;
1426 }
1427 }
1428}