blob: d6b4d55e70e4d062bdc706c09c686c98e2497ca5 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * Copyright (C) 2001-2003 Red Hat, Inc.
5 *
6 * Created by David Woodhouse <dwmw2@infradead.org>
7 *
8 * For licensing information, see the file 'LICENCE' in this directory.
9 *
Estelle Hammache9b88f472005-01-28 18:53:05 +000010 * $Id: write.c,v 1.90 2005/01/28 18:53:01 hammache Exp $
Linus Torvalds1da177e2005-04-16 15:20:36 -070011 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/fs.h>
16#include <linux/crc32.h>
17#include <linux/slab.h>
18#include <linux/pagemap.h>
19#include <linux/mtd/mtd.h>
20#include "nodelist.h"
21#include "compr.h"
22
23
24int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri)
25{
26 struct jffs2_inode_cache *ic;
27
28 ic = jffs2_alloc_inode_cache();
29 if (!ic) {
30 return -ENOMEM;
31 }
32
33 memset(ic, 0, sizeof(*ic));
34
35 f->inocache = ic;
36 f->inocache->nlink = 1;
37 f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
38 f->inocache->ino = ++c->highest_ino;
39 f->inocache->state = INO_STATE_PRESENT;
40
41 ri->ino = cpu_to_je32(f->inocache->ino);
42
43 D1(printk(KERN_DEBUG "jffs2_do_new_inode(): Assigned ino# %d\n", f->inocache->ino));
44 jffs2_add_ino_cache(c, f->inocache);
45
46 ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
47 ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
48 ri->totlen = cpu_to_je32(PAD(sizeof(*ri)));
49 ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
50 ri->mode = cpu_to_jemode(mode);
51
52 f->highest_version = 1;
53 ri->version = cpu_to_je32(f->highest_version);
54
55 return 0;
56}
57
58#if CONFIG_JFFS2_FS_DEBUG > 0
59static void writecheck(struct jffs2_sb_info *c, uint32_t ofs)
60{
61 unsigned char buf[16];
62 size_t retlen;
63 int ret, i;
64
65 ret = jffs2_flash_read(c, ofs, 16, &retlen, buf);
66 if (ret || (retlen != 16)) {
67 D1(printk(KERN_DEBUG "read failed or short in writecheck(). ret %d, retlen %zd\n", ret, retlen));
68 return;
69 }
70 ret = 0;
71 for (i=0; i<16; i++) {
72 if (buf[i] != 0xff)
73 ret = 1;
74 }
75 if (ret) {
76 printk(KERN_WARNING "ARGH. About to write node to 0x%08x on flash, but there are data already there:\n", ofs);
77 printk(KERN_WARNING "0x%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
78 ofs,
79 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7],
80 buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]);
81 }
82}
83#endif
84
85
86/* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it,
87 write it to the flash, link it into the existing inode/fragment list */
88
89struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode)
90
91{
92 struct jffs2_raw_node_ref *raw;
93 struct jffs2_full_dnode *fn;
94 size_t retlen;
95 struct kvec vecs[2];
96 int ret;
97 int retried = 0;
98 unsigned long cnt = 2;
99
100 D1(if(je32_to_cpu(ri->hdr_crc) != crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)) {
101 printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dnode()\n");
102 BUG();
103 }
104 );
105 vecs[0].iov_base = ri;
106 vecs[0].iov_len = sizeof(*ri);
107 vecs[1].iov_base = (unsigned char *)data;
108 vecs[1].iov_len = datalen;
109
110 D1(writecheck(c, flash_ofs));
111
112 if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) {
113 printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", je32_to_cpu(ri->totlen), sizeof(*ri), datalen);
114 }
115 raw = jffs2_alloc_raw_node_ref();
116 if (!raw)
117 return ERR_PTR(-ENOMEM);
118
119 fn = jffs2_alloc_full_dnode();
120 if (!fn) {
121 jffs2_free_raw_node_ref(raw);
122 return ERR_PTR(-ENOMEM);
123 }
124
125 fn->ofs = je32_to_cpu(ri->offset);
126 fn->size = je32_to_cpu(ri->dsize);
127 fn->frags = 0;
128
129 /* check number of valid vecs */
130 if (!datalen || !data)
131 cnt = 1;
132 retry:
133 fn->raw = raw;
134
135 raw->flash_offset = flash_ofs;
136 raw->__totlen = PAD(sizeof(*ri)+datalen);
137 raw->next_phys = NULL;
138
Estelle Hammache9b88f472005-01-28 18:53:05 +0000139 if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(ri->version) < f->highest_version)) {
140 BUG_ON(!retried);
141 D1(printk(KERN_DEBUG "jffs2_write_dnode : dnode_version %d, "
142 "highest version %d -> updating dnode\n",
143 je32_to_cpu(ri->version), f->highest_version));
144 ri->version = cpu_to_je32(++f->highest_version);
145 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
Estelle Hammachee4803c32005-01-24 21:13:42 +0000146 }
147
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148 ret = jffs2_flash_writev(c, vecs, cnt, flash_ofs, &retlen,
149 (alloc_mode==ALLOC_GC)?0:f->inocache->ino);
150
151 if (ret || (retlen != sizeof(*ri) + datalen)) {
152 printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
153 sizeof(*ri)+datalen, flash_ofs, ret, retlen);
154
155 /* Mark the space as dirtied */
156 if (retlen) {
157 /* Doesn't belong to any inode */
158 raw->next_in_ino = NULL;
159
160 /* Don't change raw->size to match retlen. We may have
161 written the node header already, and only the data will
162 seem corrupted, in which case the scan would skip over
163 any node we write before the original intended end of
164 this node */
165 raw->flash_offset |= REF_OBSOLETE;
166 jffs2_add_physical_node_ref(c, raw);
167 jffs2_mark_node_obsolete(c, raw);
168 } else {
169 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset);
170 jffs2_free_raw_node_ref(raw);
171 }
172 if (!retried && alloc_mode != ALLOC_NORETRY && (raw = jffs2_alloc_raw_node_ref())) {
173 /* Try to reallocate space and retry */
174 uint32_t dummy;
175 struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size];
176
177 retried = 1;
178
179 D1(printk(KERN_DEBUG "Retrying failed write.\n"));
180
181 ACCT_SANITY_CHECK(c,jeb);
182 D1(ACCT_PARANOIA_CHECK(jeb));
183
184 if (alloc_mode == ALLOC_GC) {
185 ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs, &dummy);
186 } else {
187 /* Locking pain */
188 up(&f->sem);
189 jffs2_complete_reservation(c);
190
191 ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &flash_ofs, &dummy, alloc_mode);
192 down(&f->sem);
193 }
194
195 if (!ret) {
196 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs));
197
198 ACCT_SANITY_CHECK(c,jeb);
199 D1(ACCT_PARANOIA_CHECK(jeb));
200
201 goto retry;
202 }
203 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret));
204 jffs2_free_raw_node_ref(raw);
205 }
206 /* Release the full_dnode which is now useless, and return */
207 jffs2_free_full_dnode(fn);
208 return ERR_PTR(ret?ret:-EIO);
209 }
210 /* Mark the space used */
211 /* If node covers at least a whole page, or if it starts at the
212 beginning of a page and runs to the end of the file, or if
213 it's a hole node, mark it REF_PRISTINE, else REF_NORMAL.
214 */
215 if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) ||
216 ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) &&
217 (je32_to_cpu(ri->dsize)+je32_to_cpu(ri->offset) == je32_to_cpu(ri->isize)))) {
218 raw->flash_offset |= REF_PRISTINE;
219 } else {
220 raw->flash_offset |= REF_NORMAL;
221 }
222 jffs2_add_physical_node_ref(c, raw);
223
224 /* Link into per-inode list */
225 spin_lock(&c->erase_completion_lock);
226 raw->next_in_ino = f->inocache->nodes;
227 f->inocache->nodes = raw;
228 spin_unlock(&c->erase_completion_lock);
229
230 D1(printk(KERN_DEBUG "jffs2_write_dnode wrote node at 0x%08x(%d) with dsize 0x%x, csize 0x%x, node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n",
231 flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize),
232 je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc),
233 je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen)));
234
235 if (retried) {
236 ACCT_SANITY_CHECK(c,NULL);
237 }
238
239 return fn;
240}
241
242struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_dirent *rd, const unsigned char *name, uint32_t namelen, uint32_t flash_ofs, int alloc_mode)
243{
244 struct jffs2_raw_node_ref *raw;
245 struct jffs2_full_dirent *fd;
246 size_t retlen;
247 struct kvec vecs[2];
248 int retried = 0;
249 int ret;
250
251 D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n",
252 je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino),
253 je32_to_cpu(rd->name_crc)));
254 D1(writecheck(c, flash_ofs));
255
256 D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) {
257 printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n");
258 BUG();
259 }
260 );
261
262 vecs[0].iov_base = rd;
263 vecs[0].iov_len = sizeof(*rd);
264 vecs[1].iov_base = (unsigned char *)name;
265 vecs[1].iov_len = namelen;
266
267 raw = jffs2_alloc_raw_node_ref();
268
269 if (!raw)
270 return ERR_PTR(-ENOMEM);
271
272 fd = jffs2_alloc_full_dirent(namelen+1);
273 if (!fd) {
274 jffs2_free_raw_node_ref(raw);
275 return ERR_PTR(-ENOMEM);
276 }
277
278 fd->version = je32_to_cpu(rd->version);
279 fd->ino = je32_to_cpu(rd->ino);
280 fd->nhash = full_name_hash(name, strlen(name));
281 fd->type = rd->type;
282 memcpy(fd->name, name, namelen);
283 fd->name[namelen]=0;
284
285 retry:
286 fd->raw = raw;
287
288 raw->flash_offset = flash_ofs;
289 raw->__totlen = PAD(sizeof(*rd)+namelen);
290 raw->next_phys = NULL;
291
Estelle Hammache9b88f472005-01-28 18:53:05 +0000292 if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(rd->version) < f->highest_version)) {
293 BUG_ON(!retried);
294 D1(printk(KERN_DEBUG "jffs2_write_dirent : dirent_version %d, "
295 "highest version %d -> updating dirent\n",
296 je32_to_cpu(rd->version), f->highest_version));
297 rd->version = cpu_to_je32(++f->highest_version);
298 fd->version = je32_to_cpu(rd->version);
299 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
Estelle Hammachee4803c32005-01-24 21:13:42 +0000300 }
301
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302 ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen,
303 (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino));
304 if (ret || (retlen != sizeof(*rd) + namelen)) {
305 printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
306 sizeof(*rd)+namelen, flash_ofs, ret, retlen);
307 /* Mark the space as dirtied */
308 if (retlen) {
309 raw->next_in_ino = NULL;
310 raw->flash_offset |= REF_OBSOLETE;
311 jffs2_add_physical_node_ref(c, raw);
312 jffs2_mark_node_obsolete(c, raw);
313 } else {
314 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset);
315 jffs2_free_raw_node_ref(raw);
316 }
317 if (!retried && (raw = jffs2_alloc_raw_node_ref())) {
318 /* Try to reallocate space and retry */
319 uint32_t dummy;
320 struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size];
321
322 retried = 1;
323
324 D1(printk(KERN_DEBUG "Retrying failed write.\n"));
325
326 ACCT_SANITY_CHECK(c,jeb);
327 D1(ACCT_PARANOIA_CHECK(jeb));
328
329 if (alloc_mode == ALLOC_GC) {
330 ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs, &dummy);
331 } else {
332 /* Locking pain */
333 up(&f->sem);
334 jffs2_complete_reservation(c);
335
336 ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &flash_ofs, &dummy, alloc_mode);
337 down(&f->sem);
338 }
339
340 if (!ret) {
341 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs));
342 ACCT_SANITY_CHECK(c,jeb);
343 D1(ACCT_PARANOIA_CHECK(jeb));
344 goto retry;
345 }
346 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret));
347 jffs2_free_raw_node_ref(raw);
348 }
349 /* Release the full_dnode which is now useless, and return */
350 jffs2_free_full_dirent(fd);
351 return ERR_PTR(ret?ret:-EIO);
352 }
353 /* Mark the space used */
354 raw->flash_offset |= REF_PRISTINE;
355 jffs2_add_physical_node_ref(c, raw);
356
357 spin_lock(&c->erase_completion_lock);
358 raw->next_in_ino = f->inocache->nodes;
359 f->inocache->nodes = raw;
360 spin_unlock(&c->erase_completion_lock);
361
362 if (retried) {
363 ACCT_SANITY_CHECK(c,NULL);
364 }
365
366 return fd;
367}
368
369/* The OS-specific code fills in the metadata in the jffs2_raw_inode for us, so that
370 we don't have to go digging in struct inode or its equivalent. It should set:
371 mode, uid, gid, (starting)isize, atime, ctime, mtime */
372int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
373 struct jffs2_raw_inode *ri, unsigned char *buf,
374 uint32_t offset, uint32_t writelen, uint32_t *retlen)
375{
376 int ret = 0;
377 uint32_t writtenlen = 0;
378
379 D1(printk(KERN_DEBUG "jffs2_write_inode_range(): Ino #%u, ofs 0x%x, len 0x%x\n",
380 f->inocache->ino, offset, writelen));
381
382 while(writelen) {
383 struct jffs2_full_dnode *fn;
384 unsigned char *comprbuf = NULL;
385 uint16_t comprtype = JFFS2_COMPR_NONE;
386 uint32_t phys_ofs, alloclen;
387 uint32_t datalen, cdatalen;
388 int retried = 0;
389
390 retry:
391 D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, offset));
392
393 ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL);
394 if (ret) {
395 D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret));
396 break;
397 }
398 down(&f->sem);
399 datalen = min_t(uint32_t, writelen, PAGE_CACHE_SIZE - (offset & (PAGE_CACHE_SIZE-1)));
400 cdatalen = min_t(uint32_t, alloclen - sizeof(*ri), datalen);
401
402 comprtype = jffs2_compress(c, f, buf, &comprbuf, &datalen, &cdatalen);
403
404 ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
405 ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
406 ri->totlen = cpu_to_je32(sizeof(*ri) + cdatalen);
407 ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
408
409 ri->ino = cpu_to_je32(f->inocache->ino);
410 ri->version = cpu_to_je32(++f->highest_version);
411 ri->isize = cpu_to_je32(max(je32_to_cpu(ri->isize), offset + datalen));
412 ri->offset = cpu_to_je32(offset);
413 ri->csize = cpu_to_je32(cdatalen);
414 ri->dsize = cpu_to_je32(datalen);
415 ri->compr = comprtype & 0xff;
416 ri->usercompr = (comprtype >> 8 ) & 0xff;
417 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
418 ri->data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));
419
420 fn = jffs2_write_dnode(c, f, ri, comprbuf, cdatalen, phys_ofs, ALLOC_NORETRY);
421
422 jffs2_free_comprbuf(comprbuf, buf);
423
424 if (IS_ERR(fn)) {
425 ret = PTR_ERR(fn);
426 up(&f->sem);
427 jffs2_complete_reservation(c);
428 if (!retried) {
429 /* Write error to be retried */
430 retried = 1;
431 D1(printk(KERN_DEBUG "Retrying node write in jffs2_write_inode_range()\n"));
432 goto retry;
433 }
434 break;
435 }
436 ret = jffs2_add_full_dnode_to_inode(c, f, fn);
437 if (f->metadata) {
438 jffs2_mark_node_obsolete(c, f->metadata->raw);
439 jffs2_free_full_dnode(f->metadata);
440 f->metadata = NULL;
441 }
442 if (ret) {
443 /* Eep */
444 D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in commit_write, returned %d\n", ret));
445 jffs2_mark_node_obsolete(c, fn->raw);
446 jffs2_free_full_dnode(fn);
447
448 up(&f->sem);
449 jffs2_complete_reservation(c);
450 break;
451 }
452 up(&f->sem);
453 jffs2_complete_reservation(c);
454 if (!datalen) {
455 printk(KERN_WARNING "Eep. We didn't actually write any data in jffs2_write_inode_range()\n");
456 ret = -EIO;
457 break;
458 }
459 D1(printk(KERN_DEBUG "increasing writtenlen by %d\n", datalen));
460 writtenlen += datalen;
461 offset += datalen;
462 writelen -= datalen;
463 buf += datalen;
464 }
465 *retlen = writtenlen;
466 return ret;
467}
468
469int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const char *name, int namelen)
470{
471 struct jffs2_raw_dirent *rd;
472 struct jffs2_full_dnode *fn;
473 struct jffs2_full_dirent *fd;
474 uint32_t alloclen, phys_ofs;
475 int ret;
476
477 /* Try to reserve enough space for both node and dirent.
478 * Just the node will do for now, though
479 */
480 ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL);
481 D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen));
482 if (ret) {
483 up(&f->sem);
484 return ret;
485 }
486
487 ri->data_crc = cpu_to_je32(0);
488 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
489
490 fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL);
491
492 D1(printk(KERN_DEBUG "jffs2_do_create created file with mode 0x%x\n",
493 jemode_to_cpu(ri->mode)));
494
495 if (IS_ERR(fn)) {
496 D1(printk(KERN_DEBUG "jffs2_write_dnode() failed\n"));
497 /* Eeek. Wave bye bye */
498 up(&f->sem);
499 jffs2_complete_reservation(c);
500 return PTR_ERR(fn);
501 }
502 /* No data here. Only a metadata node, which will be
503 obsoleted by the first data write
504 */
505 f->metadata = fn;
506
507 up(&f->sem);
508 jffs2_complete_reservation(c);
509 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
510
511 if (ret) {
512 /* Eep. */
513 D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n"));
514 return ret;
515 }
516
517 rd = jffs2_alloc_raw_dirent();
518 if (!rd) {
519 /* Argh. Now we treat it like a normal delete */
520 jffs2_complete_reservation(c);
521 return -ENOMEM;
522 }
523
524 down(&dir_f->sem);
525
526 rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
527 rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
528 rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
529 rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
530
531 rd->pino = cpu_to_je32(dir_f->inocache->ino);
532 rd->version = cpu_to_je32(++dir_f->highest_version);
533 rd->ino = ri->ino;
534 rd->mctime = ri->ctime;
535 rd->nsize = namelen;
536 rd->type = DT_REG;
537 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
538 rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
539
540 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL);
541
542 jffs2_free_raw_dirent(rd);
543
544 if (IS_ERR(fd)) {
545 /* dirent failed to write. Delete the inode normally
546 as if it were the final unlink() */
547 jffs2_complete_reservation(c);
548 up(&dir_f->sem);
549 return PTR_ERR(fd);
550 }
551
552 /* Link the fd into the inode's list, obsoleting an old
553 one if necessary. */
554 jffs2_add_fd_to_list(c, fd, &dir_f->dents);
555
556 jffs2_complete_reservation(c);
557 up(&dir_f->sem);
558
559 return 0;
560}
561
562
563int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
564 const char *name, int namelen, struct jffs2_inode_info *dead_f)
565{
566 struct jffs2_raw_dirent *rd;
567 struct jffs2_full_dirent *fd;
568 uint32_t alloclen, phys_ofs;
569 int ret;
570
571 if (1 /* alternative branch needs testing */ ||
572 !jffs2_can_mark_obsolete(c)) {
573 /* We can't mark stuff obsolete on the medium. We need to write a deletion dirent */
574
575 rd = jffs2_alloc_raw_dirent();
576 if (!rd)
577 return -ENOMEM;
578
579 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_DELETION);
580 if (ret) {
581 jffs2_free_raw_dirent(rd);
582 return ret;
583 }
584
585 down(&dir_f->sem);
586
587 /* Build a deletion node */
588 rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
589 rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
590 rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
591 rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
592
593 rd->pino = cpu_to_je32(dir_f->inocache->ino);
594 rd->version = cpu_to_je32(++dir_f->highest_version);
595 rd->ino = cpu_to_je32(0);
596 rd->mctime = cpu_to_je32(get_seconds());
597 rd->nsize = namelen;
598 rd->type = DT_UNKNOWN;
599 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
600 rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
601
602 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_DELETION);
603
604 jffs2_free_raw_dirent(rd);
605
606 if (IS_ERR(fd)) {
607 jffs2_complete_reservation(c);
608 up(&dir_f->sem);
609 return PTR_ERR(fd);
610 }
611
612 /* File it. This will mark the old one obsolete. */
613 jffs2_add_fd_to_list(c, fd, &dir_f->dents);
614 up(&dir_f->sem);
615 } else {
616 struct jffs2_full_dirent **prev = &dir_f->dents;
617 uint32_t nhash = full_name_hash(name, namelen);
618
619 down(&dir_f->sem);
620
621 while ((*prev) && (*prev)->nhash <= nhash) {
622 if ((*prev)->nhash == nhash &&
623 !memcmp((*prev)->name, name, namelen) &&
624 !(*prev)->name[namelen]) {
625 struct jffs2_full_dirent *this = *prev;
626
627 D1(printk(KERN_DEBUG "Marking old dirent node (ino #%u) @%08x obsolete\n",
628 this->ino, ref_offset(this->raw)));
629
630 *prev = this->next;
631 jffs2_mark_node_obsolete(c, (this->raw));
632 jffs2_free_full_dirent(this);
633 break;
634 }
635 prev = &((*prev)->next);
636 }
637 up(&dir_f->sem);
638 }
639
640 /* dead_f is NULL if this was a rename not a real unlink */
641 /* Also catch the !f->inocache case, where there was a dirent
642 pointing to an inode which didn't exist. */
643 if (dead_f && dead_f->inocache) {
644
645 down(&dead_f->sem);
646
647 while (dead_f->dents) {
648 /* There can be only deleted ones */
649 fd = dead_f->dents;
650
651 dead_f->dents = fd->next;
652
653 if (fd->ino) {
654 printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n",
655 dead_f->inocache->ino, fd->name, fd->ino);
656 } else {
657 D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", fd->name, dead_f->inocache->ino));
658 }
659 jffs2_mark_node_obsolete(c, fd->raw);
660 jffs2_free_full_dirent(fd);
661 }
662
663 dead_f->inocache->nlink--;
664 /* NB: Caller must set inode nlink if appropriate */
665 up(&dead_f->sem);
666 }
667
668 jffs2_complete_reservation(c);
669
670 return 0;
671}
672
673
674int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen)
675{
676 struct jffs2_raw_dirent *rd;
677 struct jffs2_full_dirent *fd;
678 uint32_t alloclen, phys_ofs;
679 int ret;
680
681 rd = jffs2_alloc_raw_dirent();
682 if (!rd)
683 return -ENOMEM;
684
685 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
686 if (ret) {
687 jffs2_free_raw_dirent(rd);
688 return ret;
689 }
690
691 down(&dir_f->sem);
692
693 /* Build a deletion node */
694 rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
695 rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
696 rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
697 rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
698
699 rd->pino = cpu_to_je32(dir_f->inocache->ino);
700 rd->version = cpu_to_je32(++dir_f->highest_version);
701 rd->ino = cpu_to_je32(ino);
702 rd->mctime = cpu_to_je32(get_seconds());
703 rd->nsize = namelen;
704
705 rd->type = type;
706
707 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
708 rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
709
710 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL);
711
712 jffs2_free_raw_dirent(rd);
713
714 if (IS_ERR(fd)) {
715 jffs2_complete_reservation(c);
716 up(&dir_f->sem);
717 return PTR_ERR(fd);
718 }
719
720 /* File it. This will mark the old one obsolete. */
721 jffs2_add_fd_to_list(c, fd, &dir_f->dents);
722
723 jffs2_complete_reservation(c);
724 up(&dir_f->sem);
725
726 return 0;
727}