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