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