annotate packages/fs/jffs2/current/src/write.c @ 3292:7f8e529b4d82 default tip

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