OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [fs/] [jffs2/] [v2_0/] [src/] [write.c] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
/*
2
 * JFFS2 -- Journalling Flash File System, Version 2.
3
 *
4
 * Copyright (C) 2001, 2002 Red Hat, Inc.
5
 *
6
 * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
7
 *
8
 * For licensing information, see the file 'LICENCE' in this directory.
9
 *
10
 * $Id: write.c,v 1.1.1.1 2004-02-14 13:29:21 phoenix Exp $
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
 
22
 
23
int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri)
24
{
25
        struct jffs2_inode_cache *ic;
26
 
27
        ic = jffs2_alloc_inode_cache();
28
        if (!ic) {
29
                return -ENOMEM;
30
        }
31
 
32
        memset(ic, 0, sizeof(*ic));
33
 
34
        init_MUTEX_LOCKED(&f->sem);
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
59
static 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
 
89
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,  uint32_t *writelen)
90
 
91
{
92
        struct jffs2_raw_node_ref *raw;
93
        struct jffs2_full_dnode *fn;
94
        size_t retlen;
95
        struct iovec vecs[2];
96
        int ret;
97
        unsigned long cnt = 2;
98
 
99
        D1(if(je32_to_cpu(ri->hdr_crc) != crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)) {
100
                printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dnode()\n");
101
                BUG();
102
        }
103
           );
104
        vecs[0].iov_base = ri;
105
        vecs[0].iov_len = sizeof(*ri);
106
        vecs[1].iov_base = (unsigned char *)data;
107
        vecs[1].iov_len = datalen;
108
 
109
        D1(writecheck(c, flash_ofs));
110
 
111
        if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) {
112
                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);
113
        }
114
        raw = jffs2_alloc_raw_node_ref();
115
        if (!raw)
116
                return ERR_PTR(-ENOMEM);
117
 
118
        fn = jffs2_alloc_full_dnode();
119
        if (!fn) {
120
                jffs2_free_raw_node_ref(raw);
121
                return ERR_PTR(-ENOMEM);
122
        }
123
        raw->flash_offset = flash_ofs;
124
        raw->totlen = PAD(sizeof(*ri)+datalen);
125
        raw->next_phys = NULL;
126
 
127
        fn->ofs = je32_to_cpu(ri->offset);
128
        fn->size = je32_to_cpu(ri->dsize);
129
        fn->frags = 0;
130
        fn->raw = raw;
131
 
132
        /* check number of valid vecs */
133
        if (!datalen || !data)
134
                cnt = 1;
135
 
136
        ret = jffs2_flash_writev(c, vecs, cnt, flash_ofs, &retlen);
137
 
138
        if (ret || (retlen != sizeof(*ri) + datalen)) {
139
                printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
140
                       sizeof(*ri)+datalen, flash_ofs, ret, retlen);
141
                /* Mark the space as dirtied */
142
                if (retlen) {
143
                        /* Doesn't belong to any inode */
144
                        raw->next_in_ino = NULL;
145
 
146
                        /* Don't change raw->size to match retlen. We may have
147
                           written the node header already, and only the data will
148
                           seem corrupted, in which case the scan would skip over
149
                           any node we write before the original intended end of
150
                           this node */
151
                        raw->flash_offset |= REF_OBSOLETE;
152
                        jffs2_add_physical_node_ref(c, raw);
153
                        jffs2_mark_node_obsolete(c, raw);
154
                } else {
155
                        printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset);
156
                        jffs2_free_raw_node_ref(raw);
157
                }
158
 
159
                /* Release the full_dnode which is now useless, and return */
160
                jffs2_free_full_dnode(fn);
161
                if (writelen)
162
                        *writelen = retlen;
163
                return ERR_PTR(ret?ret:-EIO);
164
        }
165
        /* Mark the space used */
166
        /* If node covers at least a whole page, or if it starts at the
167
           beginning of a page and runs to the end of the file, or if
168
           it's a hole node, mark it REF_PRISTINE, else REF_NORMAL.
169
        */
170
        if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) ||
171
            ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) &&
172
              (je32_to_cpu(ri->dsize)+je32_to_cpu(ri->offset) ==  je32_to_cpu(ri->isize)))) {
173
                raw->flash_offset |= REF_PRISTINE;
174
        } else {
175
                raw->flash_offset |= REF_NORMAL;
176
        }
177
        jffs2_add_physical_node_ref(c, raw);
178
 
179
        /* Link into per-inode list */
180
        raw->next_in_ino = f->inocache->nodes;
181
        f->inocache->nodes = raw;
182
 
183
        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",
184
                  flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize),
185
                  je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc),
186
                  je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen)));
187
        if (writelen)
188
                *writelen = retlen;
189
 
190
        f->inocache->nodes = raw;
191
        return fn;
192
}
193
 
194
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,  uint32_t *writelen)
195
{
196
        struct jffs2_raw_node_ref *raw;
197
        struct jffs2_full_dirent *fd;
198
        size_t retlen;
199
        struct iovec vecs[2];
200
        int ret;
201
 
202
        D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n",
203
                  je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino),
204
                  je32_to_cpu(rd->name_crc)));
205
        D1(writecheck(c, flash_ofs));
206
 
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();
210
        }
211
           );
212
 
213
        vecs[0].iov_base = rd;
214
        vecs[0].iov_len = sizeof(*rd);
215
        vecs[1].iov_base = (unsigned char *)name;
216
        vecs[1].iov_len = namelen;
217
 
218
        raw = jffs2_alloc_raw_node_ref();
219
 
220
        if (!raw)
221
                return ERR_PTR(-ENOMEM);
222
 
223
        fd = jffs2_alloc_full_dirent(namelen+1);
224
        if (!fd) {
225
                jffs2_free_raw_node_ref(raw);
226
                return ERR_PTR(-ENOMEM);
227
        }
228
        raw->flash_offset = flash_ofs;
229
        raw->totlen = PAD(sizeof(*rd)+namelen);
230
        raw->next_in_ino = f->inocache->nodes;
231
        f->inocache->nodes = raw;
232
        raw->next_phys = NULL;
233
 
234
        fd->version = je32_to_cpu(rd->version);
235
        fd->ino = je32_to_cpu(rd->ino);
236
        fd->nhash = full_name_hash(name, strlen(name));
237
        fd->type = rd->type;
238
        memcpy(fd->name, name, namelen);
239
        fd->name[namelen]=0;
240
        fd->raw = raw;
241
 
242
        ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen);
243
        if (ret || (retlen != sizeof(*rd) + namelen)) {
244
                printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
245
                               sizeof(*rd)+namelen, flash_ofs, ret, retlen);
246
                /* Mark the space as dirtied */
247
                if (retlen) {
248
                        raw->flash_offset |= REF_OBSOLETE;
249
                        jffs2_add_physical_node_ref(c, raw);
250
                        jffs2_mark_node_obsolete(c, raw);
251
                } else {
252
                        printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset);
253
                        jffs2_free_raw_node_ref(raw);
254
                }
255
 
256
                /* Release the full_dnode which is now useless, and return */
257
                jffs2_free_full_dirent(fd);
258
                if (writelen)
259
                        *writelen = retlen;
260
                return ERR_PTR(ret?ret:-EIO);
261
        }
262
        /* Mark the space used */
263
        raw->flash_offset |= REF_PRISTINE;
264
        jffs2_add_physical_node_ref(c, raw);
265
        if (writelen)
266
                *writelen = retlen;
267
 
268
        f->inocache->nodes = raw;
269
        return fd;
270
}
271
 
272
/* The OS-specific code fills in the metadata in the jffs2_raw_inode for us, so that
273
   we don't have to go digging in struct inode or its equivalent. It should set:
274
   mode, uid, gid, (starting)isize, atime, ctime, mtime */
275
int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
276
                            struct jffs2_raw_inode *ri, unsigned char *buf,
277
                            uint32_t offset, uint32_t writelen, uint32_t *retlen)
278
{
279
        int ret = 0;
280
        uint32_t writtenlen = 0;
281
 
282
        D1(printk(KERN_DEBUG "jffs2_write_inode_range(): Ino #%u, ofs 0x%x, len 0x%x\n",
283
                  f->inocache->ino, offset, writelen));
284
 
285
        while(writelen) {
286
                struct jffs2_full_dnode *fn;
287
                unsigned char *comprbuf = NULL;
288
                unsigned char comprtype = JFFS2_COMPR_NONE;
289
                uint32_t phys_ofs, alloclen;
290
                uint32_t datalen, cdatalen;
291
 
292
                D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, offset));
293
 
294
                ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL);
295
                if (ret) {
296
                        D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret));
297
                        break;
298
                }
299
                down(&f->sem);
300
                datalen = writelen;
301
                cdatalen = min_t(uint32_t, alloclen - sizeof(*ri), writelen);
302
 
303
                comprbuf = kmalloc(cdatalen, GFP_KERNEL);
304
                if (comprbuf) {
305
                        comprtype = jffs2_compress(buf, comprbuf, &datalen, &cdatalen);
306
                }
307
                if (comprtype == JFFS2_COMPR_NONE) {
308
                        /* Either compression failed, or the allocation of comprbuf failed */
309
                        if (comprbuf)
310
                                kfree(comprbuf);
311
                        comprbuf = buf;
312
                        datalen = cdatalen;
313
                }
314
                /* Now comprbuf points to the data to be written, be it compressed or not.
315
                   comprtype holds the compression type, and comprtype == JFFS2_COMPR_NONE means
316
                   that the comprbuf doesn't need to be kfree()d.
317
                */
318
 
319
                ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
320
                ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
321
                ri->totlen = cpu_to_je32(sizeof(*ri) + cdatalen);
322
                ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
323
 
324
                ri->ino = cpu_to_je32(f->inocache->ino);
325
                ri->version = cpu_to_je32(++f->highest_version);
326
                ri->isize = cpu_to_je32(max(je32_to_cpu(ri->isize), offset + datalen));
327
                ri->offset = cpu_to_je32(offset);
328
                ri->csize = cpu_to_je32(cdatalen);
329
                ri->dsize = cpu_to_je32(datalen);
330
                ri->compr = comprtype;
331
                ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
332
                ri->data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));
333
 
334
                fn = jffs2_write_dnode(c, f, ri, comprbuf, cdatalen, phys_ofs, NULL);
335
 
336
                if (comprtype != JFFS2_COMPR_NONE)
337
                        kfree(comprbuf);
338
 
339
                if (IS_ERR(fn)) {
340
                        ret = PTR_ERR(fn);
341
                        up(&f->sem);
342
                        jffs2_complete_reservation(c);
343
                        break;
344
                }
345
                ret = jffs2_add_full_dnode_to_inode(c, f, fn);
346
                if (f->metadata) {
347
                        jffs2_mark_node_obsolete(c, f->metadata->raw);
348
                        jffs2_free_full_dnode(f->metadata);
349
                        f->metadata = NULL;
350
                }
351
                if (ret) {
352
                        /* Eep */
353
                        D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in commit_write, returned %d\n", ret));
354
                        jffs2_mark_node_obsolete(c, fn->raw);
355
                        jffs2_free_full_dnode(fn);
356
 
357
                        up(&f->sem);
358
                        jffs2_complete_reservation(c);
359
                        break;
360
                }
361
                up(&f->sem);
362
                jffs2_complete_reservation(c);
363
                if (!datalen) {
364
                        printk(KERN_WARNING "Eep. We didn't actually write any data in jffs2_write_inode_range()\n");
365
                        ret = -EIO;
366
                        break;
367
                }
368
                D1(printk(KERN_DEBUG "increasing writtenlen by %d\n", datalen));
369
                writtenlen += datalen;
370
                offset += datalen;
371
                writelen -= datalen;
372
                buf += datalen;
373
        }
374
        *retlen = writtenlen;
375
        return ret;
376
}
377
 
378
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)
379
{
380
        struct jffs2_raw_dirent *rd;
381
        struct jffs2_full_dnode *fn;
382
        struct jffs2_full_dirent *fd;
383
        uint32_t alloclen, phys_ofs;
384
        uint32_t writtenlen;
385
        int ret;
386
 
387
        /* Try to reserve enough space for both node and dirent.
388
         * Just the node will do for now, though
389
         */
390
        ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL);
391
        D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen));
392
        if (ret) {
393
                up(&f->sem);
394
                return ret;
395
        }
396
 
397
        ri->data_crc = cpu_to_je32(0);
398
        ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
399
 
400
        fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, &writtenlen);
401
 
402
        D1(printk(KERN_DEBUG "jffs2_do_create created file with mode 0x%x\n",
403
                  jemode_to_cpu(ri->mode)));
404
 
405
        if (IS_ERR(fn)) {
406
                D1(printk(KERN_DEBUG "jffs2_write_dnode() failed\n"));
407
                /* Eeek. Wave bye bye */
408
                up(&f->sem);
409
                jffs2_complete_reservation(c);
410
                return PTR_ERR(fn);
411
        }
412
        /* No data here. Only a metadata node, which will be
413
           obsoleted by the first data write
414
        */
415
        f->metadata = fn;
416
 
417
        /* Work out where to put the dirent node now. */
418
        writtenlen = PAD(writtenlen);
419
        phys_ofs += writtenlen;
420
        alloclen -= writtenlen;
421
        up(&f->sem);
422
 
423
        if (alloclen < sizeof(*rd)+namelen) {
424
                /* Not enough space left in this chunk. Get some more */
425
                jffs2_complete_reservation(c);
426
                ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
427
 
428
                if (ret) {
429
                        /* Eep. */
430
                        D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n"));
431
                        return ret;
432
                }
433
        }
434
 
435
        rd = jffs2_alloc_raw_dirent();
436
        if (!rd) {
437
                /* Argh. Now we treat it like a normal delete */
438
                jffs2_complete_reservation(c);
439
                return -ENOMEM;
440
        }
441
 
442
        down(&dir_f->sem);
443
 
444
        rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
445
        rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
446
        rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
447
        rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
448
 
449
        rd->pino = cpu_to_je32(dir_f->inocache->ino);
450
        rd->version = cpu_to_je32(++dir_f->highest_version);
451
        rd->ino = ri->ino;
452
        rd->mctime = ri->ctime;
453
        rd->nsize = namelen;
454
        rd->type = DT_REG;
455
        rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
456
        rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
457
 
458
        fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, &writtenlen);
459
 
460
        jffs2_free_raw_dirent(rd);
461
 
462
        if (IS_ERR(fd)) {
463
                /* dirent failed to write. Delete the inode normally
464
                   as if it were the final unlink() */
465
                jffs2_complete_reservation(c);
466
                up(&dir_f->sem);
467
                return PTR_ERR(fd);
468
        }
469
 
470
        /* Link the fd into the inode's list, obsoleting an old
471
           one if necessary. */
472
        jffs2_add_fd_to_list(c, fd, &dir_f->dents);
473
 
474
        jffs2_complete_reservation(c);
475
        up(&dir_f->sem);
476
 
477
        return 0;
478
}
479
 
480
 
481
int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
482
                    const char *name, int namelen, struct jffs2_inode_info *dead_f)
483
{
484
        struct jffs2_raw_dirent *rd;
485
        struct jffs2_full_dirent *fd;
486
        uint32_t alloclen, phys_ofs;
487
        int ret;
488
 
489
        rd = jffs2_alloc_raw_dirent();
490
        if (!rd)
491
                return -ENOMEM;
492
 
493
        ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_DELETION);
494
        if (ret) {
495
                jffs2_free_raw_dirent(rd);
496
                return ret;
497
        }
498
 
499
        down(&dir_f->sem);
500
 
501
        /* Build a deletion node */
502
        rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
503
        rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
504
        rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
505
        rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
506
 
507
        rd->pino = cpu_to_je32(dir_f->inocache->ino);
508
        rd->version = cpu_to_je32(++dir_f->highest_version);
509
        rd->ino = cpu_to_je32(0);
510
        rd->mctime = cpu_to_je32(get_seconds());
511
        rd->nsize = namelen;
512
        rd->type = DT_UNKNOWN;
513
        rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
514
        rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
515
 
516
        fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, NULL);
517
 
518
        jffs2_free_raw_dirent(rd);
519
 
520
        if (IS_ERR(fd)) {
521
                jffs2_complete_reservation(c);
522
                up(&dir_f->sem);
523
                return PTR_ERR(fd);
524
        }
525
 
526
        /* File it. This will mark the old one obsolete. */
527
        jffs2_add_fd_to_list(c, fd, &dir_f->dents);
528
 
529
        up(&dir_f->sem);
530
 
531
        /* dead_f is NULL if this was a rename not a real unlink */
532
        /* Also catch the !f->inocache case, where there was a dirent
533
           pointing to an inode which didn't exist. */
534
        if (dead_f && dead_f->inocache) {
535
 
536
                down(&dead_f->sem);
537
 
538
                while (dead_f->dents) {
539
                        /* There can be only deleted ones */
540
                        fd = dead_f->dents;
541
 
542
                        dead_f->dents = fd->next;
543
 
544
                        if (fd->ino) {
545
                                printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n",
546
                                       dead_f->inocache->ino, fd->name, fd->ino);
547
                        } else {
548
                                D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", fd->name, dead_f->inocache->ino));
549
                        }
550
                        jffs2_mark_node_obsolete(c, fd->raw);
551
                        jffs2_free_full_dirent(fd);
552
                }
553
 
554
                dead_f->inocache->nlink--;
555
                /* NB: Caller must set inode nlink if appropriate */
556
                up(&dead_f->sem);
557
        }
558
 
559
        jffs2_complete_reservation(c);
560
 
561
        return 0;
562
}
563
 
564
 
565
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)
566
{
567
        struct jffs2_raw_dirent *rd;
568
        struct jffs2_full_dirent *fd;
569
        uint32_t alloclen, phys_ofs;
570
        int ret;
571
 
572
        rd = jffs2_alloc_raw_dirent();
573
        if (!rd)
574
                return -ENOMEM;
575
 
576
        ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
577
        if (ret) {
578
                jffs2_free_raw_dirent(rd);
579
                return ret;
580
        }
581
 
582
        down(&dir_f->sem);
583
 
584
        /* Build a deletion node */
585
        rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
586
        rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
587
        rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
588
        rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
589
 
590
        rd->pino = cpu_to_je32(dir_f->inocache->ino);
591
        rd->version = cpu_to_je32(++dir_f->highest_version);
592
        rd->ino = cpu_to_je32(ino);
593
        rd->mctime = cpu_to_je32(get_seconds());
594
        rd->nsize = namelen;
595
 
596
        rd->type = type;
597
 
598
        rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
599
        rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
600
 
601
        fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, NULL);
602
 
603
        jffs2_free_raw_dirent(rd);
604
 
605
        if (IS_ERR(fd)) {
606
                jffs2_complete_reservation(c);
607
                up(&dir_f->sem);
608
                return PTR_ERR(fd);
609
        }
610
 
611
        /* File it. This will mark the old one obsolete. */
612
        jffs2_add_fd_to_list(c, fd, &dir_f->dents);
613
 
614
        jffs2_complete_reservation(c);
615
        up(&dir_f->sem);
616
 
617
        return 0;
618
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.