diff options
Diffstat (limited to 'fs/jffs2/write.c')
-rw-r--r-- | fs/jffs2/write.c | 157 |
1 files changed, 70 insertions, 87 deletions
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c index 69100615d9ae..1342f0158e9b 100644 --- a/fs/jffs2/write.c +++ b/fs/jffs2/write.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: write.c,v 1.92 2005/04/13 13:22:35 dwmw2 Exp $ | 10 | * $Id: write.c,v 1.97 2005/11/07 11:14:42 gleixner Exp $ |
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
@@ -54,35 +54,7 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint | |||
54 | return 0; | 54 | return 0; |
55 | } | 55 | } |
56 | 56 | ||
57 | #if CONFIG_JFFS2_FS_DEBUG > 0 | 57 | /* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it, |
58 | static void writecheck(struct jffs2_sb_info *c, uint32_t ofs) | ||
59 | { | ||
60 | unsigned char buf[16]; | ||
61 | size_t retlen; | ||
62 | int ret, i; | ||
63 | |||
64 | ret = jffs2_flash_read(c, ofs, 16, &retlen, buf); | ||
65 | if (ret || (retlen != 16)) { | ||
66 | D1(printk(KERN_DEBUG "read failed or short in writecheck(). ret %d, retlen %zd\n", ret, retlen)); | ||
67 | return; | ||
68 | } | ||
69 | ret = 0; | ||
70 | for (i=0; i<16; i++) { | ||
71 | if (buf[i] != 0xff) | ||
72 | ret = 1; | ||
73 | } | ||
74 | if (ret) { | ||
75 | printk(KERN_WARNING "ARGH. About to write node to 0x%08x on flash, but there are data already there:\n", ofs); | ||
76 | printk(KERN_WARNING "0x%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
77 | ofs, | ||
78 | buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], | ||
79 | buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]); | ||
80 | } | ||
81 | } | ||
82 | #endif | ||
83 | |||
84 | |||
85 | /* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it, | ||
86 | write it to the flash, link it into the existing inode/fragment list */ | 58 | write it to the flash, link it into the existing inode/fragment list */ |
87 | 59 | ||
88 | 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) | 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) |
@@ -106,7 +78,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 | |||
106 | vecs[1].iov_base = (unsigned char *)data; | 78 | vecs[1].iov_base = (unsigned char *)data; |
107 | vecs[1].iov_len = datalen; | 79 | vecs[1].iov_len = datalen; |
108 | 80 | ||
109 | D1(writecheck(c, flash_ofs)); | 81 | jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len); |
110 | 82 | ||
111 | if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) { | 83 | if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) { |
112 | printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", je32_to_cpu(ri->totlen), sizeof(*ri), datalen); | 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); |
@@ -114,7 +86,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 | |||
114 | raw = jffs2_alloc_raw_node_ref(); | 86 | raw = jffs2_alloc_raw_node_ref(); |
115 | if (!raw) | 87 | if (!raw) |
116 | return ERR_PTR(-ENOMEM); | 88 | return ERR_PTR(-ENOMEM); |
117 | 89 | ||
118 | fn = jffs2_alloc_full_dnode(); | 90 | fn = jffs2_alloc_full_dnode(); |
119 | if (!fn) { | 91 | if (!fn) { |
120 | jffs2_free_raw_node_ref(raw); | 92 | jffs2_free_raw_node_ref(raw); |
@@ -138,7 +110,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 | |||
138 | if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(ri->version) < f->highest_version)) { | 110 | if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(ri->version) < f->highest_version)) { |
139 | BUG_ON(!retried); | 111 | BUG_ON(!retried); |
140 | D1(printk(KERN_DEBUG "jffs2_write_dnode : dnode_version %d, " | 112 | D1(printk(KERN_DEBUG "jffs2_write_dnode : dnode_version %d, " |
141 | "highest version %d -> updating dnode\n", | 113 | "highest version %d -> updating dnode\n", |
142 | je32_to_cpu(ri->version), f->highest_version)); | 114 | je32_to_cpu(ri->version), f->highest_version)); |
143 | ri->version = cpu_to_je32(++f->highest_version); | 115 | ri->version = cpu_to_je32(++f->highest_version); |
144 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); | 116 | ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); |
@@ -148,7 +120,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 | |||
148 | (alloc_mode==ALLOC_GC)?0:f->inocache->ino); | 120 | (alloc_mode==ALLOC_GC)?0:f->inocache->ino); |
149 | 121 | ||
150 | if (ret || (retlen != sizeof(*ri) + datalen)) { | 122 | if (ret || (retlen != sizeof(*ri) + datalen)) { |
151 | printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", | 123 | printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", |
152 | sizeof(*ri)+datalen, flash_ofs, ret, retlen); | 124 | sizeof(*ri)+datalen, flash_ofs, ret, retlen); |
153 | 125 | ||
154 | /* Mark the space as dirtied */ | 126 | /* Mark the space as dirtied */ |
@@ -156,10 +128,10 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 | |||
156 | /* Doesn't belong to any inode */ | 128 | /* Doesn't belong to any inode */ |
157 | raw->next_in_ino = NULL; | 129 | raw->next_in_ino = NULL; |
158 | 130 | ||
159 | /* Don't change raw->size to match retlen. We may have | 131 | /* Don't change raw->size to match retlen. We may have |
160 | written the node header already, and only the data will | 132 | written the node header already, and only the data will |
161 | seem corrupted, in which case the scan would skip over | 133 | seem corrupted, in which case the scan would skip over |
162 | any node we write before the original intended end of | 134 | any node we write before the original intended end of |
163 | this node */ | 135 | this node */ |
164 | raw->flash_offset |= REF_OBSOLETE; | 136 | raw->flash_offset |= REF_OBSOLETE; |
165 | jffs2_add_physical_node_ref(c, raw); | 137 | jffs2_add_physical_node_ref(c, raw); |
@@ -176,26 +148,28 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 | |||
176 | retried = 1; | 148 | retried = 1; |
177 | 149 | ||
178 | D1(printk(KERN_DEBUG "Retrying failed write.\n")); | 150 | D1(printk(KERN_DEBUG "Retrying failed write.\n")); |
179 | 151 | ||
180 | ACCT_SANITY_CHECK(c,jeb); | 152 | jffs2_dbg_acct_sanity_check(c,jeb); |
181 | D1(ACCT_PARANOIA_CHECK(jeb)); | 153 | jffs2_dbg_acct_paranoia_check(c, jeb); |
182 | 154 | ||
183 | if (alloc_mode == ALLOC_GC) { | 155 | if (alloc_mode == ALLOC_GC) { |
184 | ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs, &dummy); | 156 | ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs, |
157 | &dummy, JFFS2_SUMMARY_INODE_SIZE); | ||
185 | } else { | 158 | } else { |
186 | /* Locking pain */ | 159 | /* Locking pain */ |
187 | up(&f->sem); | 160 | up(&f->sem); |
188 | jffs2_complete_reservation(c); | 161 | jffs2_complete_reservation(c); |
189 | 162 | ||
190 | ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &flash_ofs, &dummy, alloc_mode); | 163 | ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &flash_ofs, |
164 | &dummy, alloc_mode, JFFS2_SUMMARY_INODE_SIZE); | ||
191 | down(&f->sem); | 165 | down(&f->sem); |
192 | } | 166 | } |
193 | 167 | ||
194 | if (!ret) { | 168 | if (!ret) { |
195 | D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); | 169 | D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); |
196 | 170 | ||
197 | ACCT_SANITY_CHECK(c,jeb); | 171 | jffs2_dbg_acct_sanity_check(c,jeb); |
198 | D1(ACCT_PARANOIA_CHECK(jeb)); | 172 | jffs2_dbg_acct_paranoia_check(c, jeb); |
199 | 173 | ||
200 | goto retry; | 174 | goto retry; |
201 | } | 175 | } |
@@ -207,9 +181,9 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 | |||
207 | return ERR_PTR(ret?ret:-EIO); | 181 | return ERR_PTR(ret?ret:-EIO); |
208 | } | 182 | } |
209 | /* Mark the space used */ | 183 | /* Mark the space used */ |
210 | /* If node covers at least a whole page, or if it starts at the | 184 | /* If node covers at least a whole page, or if it starts at the |
211 | beginning of a page and runs to the end of the file, or if | 185 | beginning of a page and runs to the end of the file, or if |
212 | it's a hole node, mark it REF_PRISTINE, else REF_NORMAL. | 186 | it's a hole node, mark it REF_PRISTINE, else REF_NORMAL. |
213 | */ | 187 | */ |
214 | if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) || | 188 | if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) || |
215 | ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) && | 189 | ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) && |
@@ -227,12 +201,12 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 | |||
227 | spin_unlock(&c->erase_completion_lock); | 201 | spin_unlock(&c->erase_completion_lock); |
228 | 202 | ||
229 | 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", | 203 | 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", |
230 | flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize), | 204 | flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize), |
231 | je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc), | 205 | je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc), |
232 | je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen))); | 206 | je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen))); |
233 | 207 | ||
234 | if (retried) { | 208 | if (retried) { |
235 | ACCT_SANITY_CHECK(c,NULL); | 209 | jffs2_dbg_acct_sanity_check(c,NULL); |
236 | } | 210 | } |
237 | 211 | ||
238 | return fn; | 212 | return fn; |
@@ -247,10 +221,9 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff | |||
247 | int retried = 0; | 221 | int retried = 0; |
248 | int ret; | 222 | int ret; |
249 | 223 | ||
250 | D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n", | 224 | D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n", |
251 | je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino), | 225 | je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino), |
252 | je32_to_cpu(rd->name_crc))); | 226 | je32_to_cpu(rd->name_crc))); |
253 | D1(writecheck(c, flash_ofs)); | ||
254 | 227 | ||
255 | D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) { | 228 | D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) { |
256 | printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n"); | 229 | printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n"); |
@@ -262,7 +235,9 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff | |||
262 | vecs[0].iov_len = sizeof(*rd); | 235 | vecs[0].iov_len = sizeof(*rd); |
263 | vecs[1].iov_base = (unsigned char *)name; | 236 | vecs[1].iov_base = (unsigned char *)name; |
264 | vecs[1].iov_len = namelen; | 237 | vecs[1].iov_len = namelen; |
265 | 238 | ||
239 | jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len); | ||
240 | |||
266 | raw = jffs2_alloc_raw_node_ref(); | 241 | raw = jffs2_alloc_raw_node_ref(); |
267 | 242 | ||
268 | if (!raw) | 243 | if (!raw) |
@@ -301,7 +276,7 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff | |||
301 | ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen, | 276 | ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen, |
302 | (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino)); | 277 | (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino)); |
303 | if (ret || (retlen != sizeof(*rd) + namelen)) { | 278 | if (ret || (retlen != sizeof(*rd) + namelen)) { |
304 | printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", | 279 | printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", |
305 | sizeof(*rd)+namelen, flash_ofs, ret, retlen); | 280 | sizeof(*rd)+namelen, flash_ofs, ret, retlen); |
306 | /* Mark the space as dirtied */ | 281 | /* Mark the space as dirtied */ |
307 | if (retlen) { | 282 | if (retlen) { |
@@ -322,24 +297,26 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff | |||
322 | 297 | ||
323 | D1(printk(KERN_DEBUG "Retrying failed write.\n")); | 298 | D1(printk(KERN_DEBUG "Retrying failed write.\n")); |
324 | 299 | ||
325 | ACCT_SANITY_CHECK(c,jeb); | 300 | jffs2_dbg_acct_sanity_check(c,jeb); |
326 | D1(ACCT_PARANOIA_CHECK(jeb)); | 301 | jffs2_dbg_acct_paranoia_check(c, jeb); |
327 | 302 | ||
328 | if (alloc_mode == ALLOC_GC) { | 303 | if (alloc_mode == ALLOC_GC) { |
329 | ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs, &dummy); | 304 | ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs, |
305 | &dummy, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); | ||
330 | } else { | 306 | } else { |
331 | /* Locking pain */ | 307 | /* Locking pain */ |
332 | up(&f->sem); | 308 | up(&f->sem); |
333 | jffs2_complete_reservation(c); | 309 | jffs2_complete_reservation(c); |
334 | 310 | ||
335 | ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &flash_ofs, &dummy, alloc_mode); | 311 | ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &flash_ofs, |
312 | &dummy, alloc_mode, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); | ||
336 | down(&f->sem); | 313 | down(&f->sem); |
337 | } | 314 | } |
338 | 315 | ||
339 | if (!ret) { | 316 | if (!ret) { |
340 | D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); | 317 | D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); |
341 | ACCT_SANITY_CHECK(c,jeb); | 318 | jffs2_dbg_acct_sanity_check(c,jeb); |
342 | D1(ACCT_PARANOIA_CHECK(jeb)); | 319 | jffs2_dbg_acct_paranoia_check(c, jeb); |
343 | goto retry; | 320 | goto retry; |
344 | } | 321 | } |
345 | D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); | 322 | D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); |
@@ -359,7 +336,7 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff | |||
359 | spin_unlock(&c->erase_completion_lock); | 336 | spin_unlock(&c->erase_completion_lock); |
360 | 337 | ||
361 | if (retried) { | 338 | if (retried) { |
362 | ACCT_SANITY_CHECK(c,NULL); | 339 | jffs2_dbg_acct_sanity_check(c,NULL); |
363 | } | 340 | } |
364 | 341 | ||
365 | return fd; | 342 | return fd; |
@@ -369,7 +346,7 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff | |||
369 | we don't have to go digging in struct inode or its equivalent. It should set: | 346 | we don't have to go digging in struct inode or its equivalent. It should set: |
370 | mode, uid, gid, (starting)isize, atime, ctime, mtime */ | 347 | mode, uid, gid, (starting)isize, atime, ctime, mtime */ |
371 | int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, | 348 | int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, |
372 | struct jffs2_raw_inode *ri, unsigned char *buf, | 349 | struct jffs2_raw_inode *ri, unsigned char *buf, |
373 | uint32_t offset, uint32_t writelen, uint32_t *retlen) | 350 | uint32_t offset, uint32_t writelen, uint32_t *retlen) |
374 | { | 351 | { |
375 | int ret = 0; | 352 | int ret = 0; |
@@ -377,7 +354,7 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, | |||
377 | 354 | ||
378 | D1(printk(KERN_DEBUG "jffs2_write_inode_range(): Ino #%u, ofs 0x%x, len 0x%x\n", | 355 | D1(printk(KERN_DEBUG "jffs2_write_inode_range(): Ino #%u, ofs 0x%x, len 0x%x\n", |
379 | f->inocache->ino, offset, writelen)); | 356 | f->inocache->ino, offset, writelen)); |
380 | 357 | ||
381 | while(writelen) { | 358 | while(writelen) { |
382 | struct jffs2_full_dnode *fn; | 359 | struct jffs2_full_dnode *fn; |
383 | unsigned char *comprbuf = NULL; | 360 | unsigned char *comprbuf = NULL; |
@@ -389,7 +366,8 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, | |||
389 | retry: | 366 | retry: |
390 | D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, offset)); | 367 | D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, offset)); |
391 | 368 | ||
392 | ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL); | 369 | ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, |
370 | &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); | ||
393 | if (ret) { | 371 | if (ret) { |
394 | D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret)); | 372 | D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret)); |
395 | break; | 373 | break; |
@@ -473,10 +451,11 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str | |||
473 | uint32_t alloclen, phys_ofs; | 451 | uint32_t alloclen, phys_ofs; |
474 | int ret; | 452 | int ret; |
475 | 453 | ||
476 | /* Try to reserve enough space for both node and dirent. | 454 | /* Try to reserve enough space for both node and dirent. |
477 | * Just the node will do for now, though | 455 | * Just the node will do for now, though |
478 | */ | 456 | */ |
479 | ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL); | 457 | ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL, |
458 | JFFS2_SUMMARY_INODE_SIZE); | ||
480 | D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen)); | 459 | D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen)); |
481 | if (ret) { | 460 | if (ret) { |
482 | up(&f->sem); | 461 | up(&f->sem); |
@@ -498,15 +477,16 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str | |||
498 | jffs2_complete_reservation(c); | 477 | jffs2_complete_reservation(c); |
499 | return PTR_ERR(fn); | 478 | return PTR_ERR(fn); |
500 | } | 479 | } |
501 | /* No data here. Only a metadata node, which will be | 480 | /* No data here. Only a metadata node, which will be |
502 | obsoleted by the first data write | 481 | obsoleted by the first data write |
503 | */ | 482 | */ |
504 | f->metadata = fn; | 483 | f->metadata = fn; |
505 | 484 | ||
506 | up(&f->sem); | 485 | up(&f->sem); |
507 | jffs2_complete_reservation(c); | 486 | jffs2_complete_reservation(c); |
508 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL); | 487 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, |
509 | 488 | ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); | |
489 | |||
510 | if (ret) { | 490 | if (ret) { |
511 | /* Eep. */ | 491 | /* Eep. */ |
512 | D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n")); | 492 | D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n")); |
@@ -539,9 +519,9 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str | |||
539 | fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL); | 519 | fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL); |
540 | 520 | ||
541 | jffs2_free_raw_dirent(rd); | 521 | jffs2_free_raw_dirent(rd); |
542 | 522 | ||
543 | if (IS_ERR(fd)) { | 523 | if (IS_ERR(fd)) { |
544 | /* dirent failed to write. Delete the inode normally | 524 | /* dirent failed to write. Delete the inode normally |
545 | as if it were the final unlink() */ | 525 | as if it were the final unlink() */ |
546 | jffs2_complete_reservation(c); | 526 | jffs2_complete_reservation(c); |
547 | up(&dir_f->sem); | 527 | up(&dir_f->sem); |
@@ -560,14 +540,15 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str | |||
560 | 540 | ||
561 | 541 | ||
562 | int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, | 542 | int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, |
563 | const char *name, int namelen, struct jffs2_inode_info *dead_f) | 543 | const char *name, int namelen, struct jffs2_inode_info *dead_f, |
544 | uint32_t time) | ||
564 | { | 545 | { |
565 | struct jffs2_raw_dirent *rd; | 546 | struct jffs2_raw_dirent *rd; |
566 | struct jffs2_full_dirent *fd; | 547 | struct jffs2_full_dirent *fd; |
567 | uint32_t alloclen, phys_ofs; | 548 | uint32_t alloclen, phys_ofs; |
568 | int ret; | 549 | int ret; |
569 | 550 | ||
570 | if (1 /* alternative branch needs testing */ || | 551 | if (1 /* alternative branch needs testing */ || |
571 | !jffs2_can_mark_obsolete(c)) { | 552 | !jffs2_can_mark_obsolete(c)) { |
572 | /* We can't mark stuff obsolete on the medium. We need to write a deletion dirent */ | 553 | /* We can't mark stuff obsolete on the medium. We need to write a deletion dirent */ |
573 | 554 | ||
@@ -575,7 +556,8 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, | |||
575 | if (!rd) | 556 | if (!rd) |
576 | return -ENOMEM; | 557 | return -ENOMEM; |
577 | 558 | ||
578 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_DELETION); | 559 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, |
560 | ALLOC_DELETION, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); | ||
579 | if (ret) { | 561 | if (ret) { |
580 | jffs2_free_raw_dirent(rd); | 562 | jffs2_free_raw_dirent(rd); |
581 | return ret; | 563 | return ret; |
@@ -588,18 +570,18 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, | |||
588 | rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); | 570 | rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); |
589 | rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); | 571 | rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); |
590 | rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); | 572 | rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); |
591 | 573 | ||
592 | rd->pino = cpu_to_je32(dir_f->inocache->ino); | 574 | rd->pino = cpu_to_je32(dir_f->inocache->ino); |
593 | rd->version = cpu_to_je32(++dir_f->highest_version); | 575 | rd->version = cpu_to_je32(++dir_f->highest_version); |
594 | rd->ino = cpu_to_je32(0); | 576 | rd->ino = cpu_to_je32(0); |
595 | rd->mctime = cpu_to_je32(get_seconds()); | 577 | rd->mctime = cpu_to_je32(time); |
596 | rd->nsize = namelen; | 578 | rd->nsize = namelen; |
597 | rd->type = DT_UNKNOWN; | 579 | rd->type = DT_UNKNOWN; |
598 | rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); | 580 | rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); |
599 | rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); | 581 | rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); |
600 | 582 | ||
601 | fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_DELETION); | 583 | fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_DELETION); |
602 | 584 | ||
603 | jffs2_free_raw_dirent(rd); | 585 | jffs2_free_raw_dirent(rd); |
604 | 586 | ||
605 | if (IS_ERR(fd)) { | 587 | if (IS_ERR(fd)) { |
@@ -618,7 +600,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, | |||
618 | down(&dir_f->sem); | 600 | down(&dir_f->sem); |
619 | 601 | ||
620 | while ((*prev) && (*prev)->nhash <= nhash) { | 602 | while ((*prev) && (*prev)->nhash <= nhash) { |
621 | if ((*prev)->nhash == nhash && | 603 | if ((*prev)->nhash == nhash && |
622 | !memcmp((*prev)->name, name, namelen) && | 604 | !memcmp((*prev)->name, name, namelen) && |
623 | !(*prev)->name[namelen]) { | 605 | !(*prev)->name[namelen]) { |
624 | struct jffs2_full_dirent *this = *prev; | 606 | struct jffs2_full_dirent *this = *prev; |
@@ -639,7 +621,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, | |||
639 | /* dead_f is NULL if this was a rename not a real unlink */ | 621 | /* dead_f is NULL if this was a rename not a real unlink */ |
640 | /* Also catch the !f->inocache case, where there was a dirent | 622 | /* Also catch the !f->inocache case, where there was a dirent |
641 | pointing to an inode which didn't exist. */ | 623 | pointing to an inode which didn't exist. */ |
642 | if (dead_f && dead_f->inocache) { | 624 | if (dead_f && dead_f->inocache) { |
643 | 625 | ||
644 | down(&dead_f->sem); | 626 | down(&dead_f->sem); |
645 | 627 | ||
@@ -647,9 +629,9 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, | |||
647 | while (dead_f->dents) { | 629 | while (dead_f->dents) { |
648 | /* There can be only deleted ones */ | 630 | /* There can be only deleted ones */ |
649 | fd = dead_f->dents; | 631 | fd = dead_f->dents; |
650 | 632 | ||
651 | dead_f->dents = fd->next; | 633 | dead_f->dents = fd->next; |
652 | 634 | ||
653 | if (fd->ino) { | 635 | if (fd->ino) { |
654 | printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n", | 636 | printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n", |
655 | dead_f->inocache->ino, fd->name, fd->ino); | 637 | dead_f->inocache->ino, fd->name, fd->ino); |
@@ -673,7 +655,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, | |||
673 | } | 655 | } |
674 | 656 | ||
675 | 657 | ||
676 | 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) | 658 | 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, uint32_t time) |
677 | { | 659 | { |
678 | struct jffs2_raw_dirent *rd; | 660 | struct jffs2_raw_dirent *rd; |
679 | struct jffs2_full_dirent *fd; | 661 | struct jffs2_full_dirent *fd; |
@@ -684,12 +666,13 @@ int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint | |||
684 | if (!rd) | 666 | if (!rd) |
685 | return -ENOMEM; | 667 | return -ENOMEM; |
686 | 668 | ||
687 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL); | 669 | ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, |
670 | ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); | ||
688 | if (ret) { | 671 | if (ret) { |
689 | jffs2_free_raw_dirent(rd); | 672 | jffs2_free_raw_dirent(rd); |
690 | return ret; | 673 | return ret; |
691 | } | 674 | } |
692 | 675 | ||
693 | down(&dir_f->sem); | 676 | down(&dir_f->sem); |
694 | 677 | ||
695 | /* Build a deletion node */ | 678 | /* Build a deletion node */ |
@@ -701,7 +684,7 @@ int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint | |||
701 | rd->pino = cpu_to_je32(dir_f->inocache->ino); | 684 | rd->pino = cpu_to_je32(dir_f->inocache->ino); |
702 | rd->version = cpu_to_je32(++dir_f->highest_version); | 685 | rd->version = cpu_to_je32(++dir_f->highest_version); |
703 | rd->ino = cpu_to_je32(ino); | 686 | rd->ino = cpu_to_je32(ino); |
704 | rd->mctime = cpu_to_je32(get_seconds()); | 687 | rd->mctime = cpu_to_je32(time); |
705 | rd->nsize = namelen; | 688 | rd->nsize = namelen; |
706 | 689 | ||
707 | rd->type = type; | 690 | rd->type = type; |
@@ -710,7 +693,7 @@ int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint | |||
710 | rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); | 693 | rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); |
711 | 694 | ||
712 | fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL); | 695 | fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL); |
713 | 696 | ||
714 | jffs2_free_raw_dirent(rd); | 697 | jffs2_free_raw_dirent(rd); |
715 | 698 | ||
716 | if (IS_ERR(fd)) { | 699 | if (IS_ERR(fd)) { |