aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/write.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jffs2/write.c')
-rw-r--r--fs/jffs2/write.c157
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,
58static 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
88struct 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) 60struct 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 */
371int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 348int 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
562int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, 542int 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
676int 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) 658int 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)) {