aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/write.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-05-23 21:04:45 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-05-23 21:04:45 -0400
commit2f785402f39b96a077b6e62bf26164bfb8e0c980 (patch)
tree3f3a38b484ef2dabda1599d4d8f08b121bd03a76 /fs/jffs2/write.c
parent4cbb9b80e171107c6c34116283fe38e5a396c68b (diff)
[JFFS2] Reduce visibility of raw_node_ref to upper layers of JFFS2 code.
As the first step towards eliminating the ref->next_phys member and saving memory by using an _array_ of struct jffs2_raw_node_ref per eraseblock, stop the write functions from allocating their own refs; have them just _reserve_ the appropriate number instead. Then jffs2_link_node_ref() can just fill them in. Use a linked list of pre-allocated refs in the superblock, for now. Once we switch to an array, it'll just be a case of extending that array. Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'fs/jffs2/write.c')
-rw-r--r--fs/jffs2/write.c71
1 files changed, 21 insertions, 50 deletions
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
index 0e12b7561b71..67176792e138 100644
--- a/fs/jffs2/write.c
+++ b/fs/jffs2/write.c
@@ -61,7 +61,6 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
61 uint32_t datalen, int alloc_mode) 61 uint32_t datalen, int alloc_mode)
62 62
63{ 63{
64 struct jffs2_raw_node_ref *raw;
65 struct jffs2_full_dnode *fn; 64 struct jffs2_full_dnode *fn;
66 size_t retlen; 65 size_t retlen;
67 uint32_t flash_ofs; 66 uint32_t flash_ofs;
@@ -83,27 +82,16 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
83 if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) { 82 if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) {
84 printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", je32_to_cpu(ri->totlen), sizeof(*ri), datalen); 83 printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", je32_to_cpu(ri->totlen), sizeof(*ri), datalen);
85 } 84 }
86 raw = jffs2_alloc_raw_node_ref();
87 if (!raw)
88 return ERR_PTR(-ENOMEM);
89 85
90 fn = jffs2_alloc_full_dnode(); 86 fn = jffs2_alloc_full_dnode();
91 if (!fn) { 87 if (!fn)
92 jffs2_free_raw_node_ref(raw);
93 return ERR_PTR(-ENOMEM); 88 return ERR_PTR(-ENOMEM);
94 }
95
96 fn->ofs = je32_to_cpu(ri->offset);
97 fn->size = je32_to_cpu(ri->dsize);
98 fn->frags = 0;
99 89
100 /* check number of valid vecs */ 90 /* check number of valid vecs */
101 if (!datalen || !data) 91 if (!datalen || !data)
102 cnt = 1; 92 cnt = 1;
103 retry: 93 retry:
104 fn->raw = raw; 94 flash_ofs = write_ofs(c);
105
106 raw->flash_offset = flash_ofs = write_ofs(c);
107 95
108 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len); 96 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
109 97
@@ -130,14 +118,11 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
130 seem corrupted, in which case the scan would skip over 118 seem corrupted, in which case the scan would skip over
131 any node we write before the original intended end of 119 any node we write before the original intended end of
132 this node */ 120 this node */
133 raw->flash_offset |= REF_OBSOLETE; 121 jffs2_add_physical_node_ref(c, flash_ofs | REF_OBSOLETE, PAD(sizeof(*ri)+datalen), NULL);
134 jffs2_add_physical_node_ref(c, raw, PAD(sizeof(*ri)+datalen), NULL);
135 jffs2_mark_node_obsolete(c, raw);
136 } else { 122 } else {
137 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset); 123 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", flash_ofs);
138 jffs2_free_raw_node_ref(raw);
139 } 124 }
140 if (!retried && alloc_mode != ALLOC_NORETRY && (raw = jffs2_alloc_raw_node_ref())) { 125 if (!retried && alloc_mode != ALLOC_NORETRY) {
141 /* Try to reallocate space and retry */ 126 /* Try to reallocate space and retry */
142 uint32_t dummy; 127 uint32_t dummy;
143 struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size]; 128 struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size];
@@ -172,7 +157,6 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
172 goto retry; 157 goto retry;
173 } 158 }
174 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); 159 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret));
175 jffs2_free_raw_node_ref(raw);
176 } 160 }
177 /* Release the full_dnode which is now useless, and return */ 161 /* Release the full_dnode which is now useless, and return */
178 jffs2_free_full_dnode(fn); 162 jffs2_free_full_dnode(fn);
@@ -186,14 +170,17 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
186 if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) || 170 if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) ||
187 ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) && 171 ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) &&
188 (je32_to_cpu(ri->dsize)+je32_to_cpu(ri->offset) == je32_to_cpu(ri->isize)))) { 172 (je32_to_cpu(ri->dsize)+je32_to_cpu(ri->offset) == je32_to_cpu(ri->isize)))) {
189 raw->flash_offset |= REF_PRISTINE; 173 flash_ofs |= REF_PRISTINE;
190 } else { 174 } else {
191 raw->flash_offset |= REF_NORMAL; 175 flash_ofs |= REF_NORMAL;
192 } 176 }
193 jffs2_add_physical_node_ref(c, raw, PAD(sizeof(*ri)+datalen), f->inocache); 177 fn->raw = jffs2_add_physical_node_ref(c, flash_ofs, PAD(sizeof(*ri)+datalen), f->inocache);
178 fn->ofs = je32_to_cpu(ri->offset);
179 fn->size = je32_to_cpu(ri->dsize);
180 fn->frags = 0;
194 181
195 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", 182 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",
196 flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize), 183 flash_ofs & ~3, flash_ofs & 3, je32_to_cpu(ri->dsize),
197 je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc), 184 je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc),
198 je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen))); 185 je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen)));
199 186
@@ -208,11 +195,10 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
208 struct jffs2_raw_dirent *rd, const unsigned char *name, 195 struct jffs2_raw_dirent *rd, const unsigned char *name,
209 uint32_t namelen, int alloc_mode) 196 uint32_t namelen, int alloc_mode)
210{ 197{
211 struct jffs2_raw_node_ref *raw;
212 struct jffs2_full_dirent *fd; 198 struct jffs2_full_dirent *fd;
213 size_t retlen; 199 size_t retlen;
214 struct kvec vecs[2]; 200 struct kvec vecs[2];
215 uint32_t flash_ofs = write_ofs(c); 201 uint32_t flash_ofs;
216 int retried = 0; 202 int retried = 0;
217 int ret; 203 int ret;
218 204
@@ -223,26 +209,16 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
223 D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) { 209 D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) {
224 printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n"); 210 printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n");
225 BUG(); 211 BUG();
226 } 212 });
227 );
228 213
229 vecs[0].iov_base = rd; 214 vecs[0].iov_base = rd;
230 vecs[0].iov_len = sizeof(*rd); 215 vecs[0].iov_len = sizeof(*rd);
231 vecs[1].iov_base = (unsigned char *)name; 216 vecs[1].iov_base = (unsigned char *)name;
232 vecs[1].iov_len = namelen; 217 vecs[1].iov_len = namelen;
233 218
234 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
235
236 raw = jffs2_alloc_raw_node_ref();
237
238 if (!raw)
239 return ERR_PTR(-ENOMEM);
240
241 fd = jffs2_alloc_full_dirent(namelen+1); 219 fd = jffs2_alloc_full_dirent(namelen+1);
242 if (!fd) { 220 if (!fd)
243 jffs2_free_raw_node_ref(raw);
244 return ERR_PTR(-ENOMEM); 221 return ERR_PTR(-ENOMEM);
245 }
246 222
247 fd->version = je32_to_cpu(rd->version); 223 fd->version = je32_to_cpu(rd->version);
248 fd->ino = je32_to_cpu(rd->ino); 224 fd->ino = je32_to_cpu(rd->ino);
@@ -252,9 +228,9 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
252 fd->name[namelen]=0; 228 fd->name[namelen]=0;
253 229
254 retry: 230 retry:
255 fd->raw = raw; 231 flash_ofs = write_ofs(c);
256 232
257 raw->flash_offset = flash_ofs; 233 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
258 234
259 if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(rd->version) < f->highest_version)) { 235 if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(rd->version) < f->highest_version)) {
260 BUG_ON(!retried); 236 BUG_ON(!retried);
@@ -273,14 +249,11 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
273 sizeof(*rd)+namelen, flash_ofs, ret, retlen); 249 sizeof(*rd)+namelen, flash_ofs, ret, retlen);
274 /* Mark the space as dirtied */ 250 /* Mark the space as dirtied */
275 if (retlen) { 251 if (retlen) {
276 raw->flash_offset |= REF_OBSOLETE; 252 jffs2_add_physical_node_ref(c, flash_ofs | REF_OBSOLETE, PAD(sizeof(*rd)+namelen), NULL);
277 jffs2_add_physical_node_ref(c, raw, PAD(sizeof(*rd)+namelen), NULL);
278 jffs2_mark_node_obsolete(c, raw);
279 } else { 253 } else {
280 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset); 254 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", flash_ofs);
281 jffs2_free_raw_node_ref(raw);
282 } 255 }
283 if (!retried && (raw = jffs2_alloc_raw_node_ref())) { 256 if (!retried) {
284 /* Try to reallocate space and retry */ 257 /* Try to reallocate space and retry */
285 uint32_t dummy; 258 uint32_t dummy;
286 struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size]; 259 struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size];
@@ -313,15 +286,13 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
313 goto retry; 286 goto retry;
314 } 287 }
315 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); 288 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret));
316 jffs2_free_raw_node_ref(raw);
317 } 289 }
318 /* Release the full_dnode which is now useless, and return */ 290 /* Release the full_dnode which is now useless, and return */
319 jffs2_free_full_dirent(fd); 291 jffs2_free_full_dirent(fd);
320 return ERR_PTR(ret?ret:-EIO); 292 return ERR_PTR(ret?ret:-EIO);
321 } 293 }
322 /* Mark the space used */ 294 /* Mark the space used */
323 raw->flash_offset |= REF_PRISTINE; 295 fd->raw = jffs2_add_physical_node_ref(c, flash_ofs | REF_PRISTINE, PAD(sizeof(*rd)+namelen), f->inocache);
324 jffs2_add_physical_node_ref(c, raw, PAD(sizeof(*rd)+namelen), f->inocache);
325 296
326 if (retried) { 297 if (retried) {
327 jffs2_dbg_acct_sanity_check(c,NULL); 298 jffs2_dbg_acct_sanity_check(c,NULL);