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