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.c62
1 files changed, 35 insertions, 27 deletions
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
index 319a70f531f8..0e12b7561b71 100644
--- a/fs/jffs2/write.c
+++ b/fs/jffs2/write.c
@@ -56,12 +56,15 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint
56/* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it, 56/* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it,
57 write it to the flash, link it into the existing inode/fragment list */ 57 write it to the flash, link it into the existing inode/fragment list */
58 58
59struct 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) 59struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
60 struct jffs2_raw_inode *ri, const unsigned char *data,
61 uint32_t datalen, int alloc_mode)
60 62
61{ 63{
62 struct jffs2_raw_node_ref *raw; 64 struct jffs2_raw_node_ref *raw;
63 struct jffs2_full_dnode *fn; 65 struct jffs2_full_dnode *fn;
64 size_t retlen; 66 size_t retlen;
67 uint32_t flash_ofs;
65 struct kvec vecs[2]; 68 struct kvec vecs[2];
66 int ret; 69 int ret;
67 int retried = 0; 70 int retried = 0;
@@ -77,8 +80,6 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
77 vecs[1].iov_base = (unsigned char *)data; 80 vecs[1].iov_base = (unsigned char *)data;
78 vecs[1].iov_len = datalen; 81 vecs[1].iov_len = datalen;
79 82
80 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
81
82 if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) { 83 if (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); 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);
84 } 85 }
@@ -102,7 +103,9 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
102 retry: 103 retry:
103 fn->raw = raw; 104 fn->raw = raw;
104 105
105 raw->flash_offset = flash_ofs; 106 raw->flash_offset = flash_ofs = write_ofs(c);
107
108 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
106 109
107 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)) {
108 BUG_ON(!retried); 111 BUG_ON(!retried);
@@ -147,19 +150,20 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
147 jffs2_dbg_acct_paranoia_check(c, jeb); 150 jffs2_dbg_acct_paranoia_check(c, jeb);
148 151
149 if (alloc_mode == ALLOC_GC) { 152 if (alloc_mode == ALLOC_GC) {
150 ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs, 153 ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &dummy,
151 &dummy, JFFS2_SUMMARY_INODE_SIZE); 154 JFFS2_SUMMARY_INODE_SIZE);
152 } else { 155 } else {
153 /* Locking pain */ 156 /* Locking pain */
154 up(&f->sem); 157 up(&f->sem);
155 jffs2_complete_reservation(c); 158 jffs2_complete_reservation(c);
156 159
157 ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &flash_ofs, 160 ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &dummy,
158 &dummy, alloc_mode, JFFS2_SUMMARY_INODE_SIZE); 161 alloc_mode, JFFS2_SUMMARY_INODE_SIZE);
159 down(&f->sem); 162 down(&f->sem);
160 } 163 }
161 164
162 if (!ret) { 165 if (!ret) {
166 flash_ofs = write_ofs(c);
163 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); 167 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs));
164 168
165 jffs2_dbg_acct_sanity_check(c,jeb); 169 jffs2_dbg_acct_sanity_check(c,jeb);
@@ -200,12 +204,15 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
200 return fn; 204 return fn;
201} 205}
202 206
203struct 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) 207struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
208 struct jffs2_raw_dirent *rd, const unsigned char *name,
209 uint32_t namelen, int alloc_mode)
204{ 210{
205 struct jffs2_raw_node_ref *raw; 211 struct jffs2_raw_node_ref *raw;
206 struct jffs2_full_dirent *fd; 212 struct jffs2_full_dirent *fd;
207 size_t retlen; 213 size_t retlen;
208 struct kvec vecs[2]; 214 struct kvec vecs[2];
215 uint32_t flash_ofs = write_ofs(c);
209 int retried = 0; 216 int retried = 0;
210 int ret; 217 int ret;
211 218
@@ -286,19 +293,20 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
286 jffs2_dbg_acct_paranoia_check(c, jeb); 293 jffs2_dbg_acct_paranoia_check(c, jeb);
287 294
288 if (alloc_mode == ALLOC_GC) { 295 if (alloc_mode == ALLOC_GC) {
289 ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs, 296 ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &dummy,
290 &dummy, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); 297 JFFS2_SUMMARY_DIRENT_SIZE(namelen));
291 } else { 298 } else {
292 /* Locking pain */ 299 /* Locking pain */
293 up(&f->sem); 300 up(&f->sem);
294 jffs2_complete_reservation(c); 301 jffs2_complete_reservation(c);
295 302
296 ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &flash_ofs, 303 ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &dummy,
297 &dummy, alloc_mode, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); 304 alloc_mode, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
298 down(&f->sem); 305 down(&f->sem);
299 } 306 }
300 307
301 if (!ret) { 308 if (!ret) {
309 flash_ofs = write_ofs(c);
302 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); 310 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs));
303 jffs2_dbg_acct_sanity_check(c,jeb); 311 jffs2_dbg_acct_sanity_check(c,jeb);
304 jffs2_dbg_acct_paranoia_check(c, jeb); 312 jffs2_dbg_acct_paranoia_check(c, jeb);
@@ -339,14 +347,14 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
339 struct jffs2_full_dnode *fn; 347 struct jffs2_full_dnode *fn;
340 unsigned char *comprbuf = NULL; 348 unsigned char *comprbuf = NULL;
341 uint16_t comprtype = JFFS2_COMPR_NONE; 349 uint16_t comprtype = JFFS2_COMPR_NONE;
342 uint32_t phys_ofs, alloclen; 350 uint32_t alloclen;
343 uint32_t datalen, cdatalen; 351 uint32_t datalen, cdatalen;
344 int retried = 0; 352 int retried = 0;
345 353
346 retry: 354 retry:
347 D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, offset)); 355 D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, offset));
348 356
349 ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, 357 ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN,
350 &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); 358 &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
351 if (ret) { 359 if (ret) {
352 D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret)); 360 D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret));
@@ -374,7 +382,7 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
374 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); 382 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
375 ri->data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen)); 383 ri->data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));
376 384
377 fn = jffs2_write_dnode(c, f, ri, comprbuf, cdatalen, phys_ofs, ALLOC_NORETRY); 385 fn = jffs2_write_dnode(c, f, ri, comprbuf, cdatalen, ALLOC_NORETRY);
378 386
379 jffs2_free_comprbuf(comprbuf, buf); 387 jffs2_free_comprbuf(comprbuf, buf);
380 388
@@ -428,13 +436,13 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
428 struct jffs2_raw_dirent *rd; 436 struct jffs2_raw_dirent *rd;
429 struct jffs2_full_dnode *fn; 437 struct jffs2_full_dnode *fn;
430 struct jffs2_full_dirent *fd; 438 struct jffs2_full_dirent *fd;
431 uint32_t alloclen, phys_ofs; 439 uint32_t alloclen;
432 int ret; 440 int ret;
433 441
434 /* Try to reserve enough space for both node and dirent. 442 /* Try to reserve enough space for both node and dirent.
435 * Just the node will do for now, though 443 * Just the node will do for now, though
436 */ 444 */
437 ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL, 445 ret = jffs2_reserve_space(c, sizeof(*ri), &alloclen, ALLOC_NORMAL,
438 JFFS2_SUMMARY_INODE_SIZE); 446 JFFS2_SUMMARY_INODE_SIZE);
439 D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen)); 447 D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen));
440 if (ret) { 448 if (ret) {
@@ -445,7 +453,7 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
445 ri->data_crc = cpu_to_je32(0); 453 ri->data_crc = cpu_to_je32(0);
446 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); 454 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
447 455
448 fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL); 456 fn = jffs2_write_dnode(c, f, ri, NULL, 0, ALLOC_NORMAL);
449 457
450 D1(printk(KERN_DEBUG "jffs2_do_create created file with mode 0x%x\n", 458 D1(printk(KERN_DEBUG "jffs2_do_create created file with mode 0x%x\n",
451 jemode_to_cpu(ri->mode))); 459 jemode_to_cpu(ri->mode)));
@@ -464,7 +472,7 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
464 472
465 up(&f->sem); 473 up(&f->sem);
466 jffs2_complete_reservation(c); 474 jffs2_complete_reservation(c);
467 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, 475 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
468 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); 476 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
469 477
470 if (ret) { 478 if (ret) {
@@ -496,7 +504,7 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
496 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 504 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
497 rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); 505 rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
498 506
499 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL); 507 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_NORMAL);
500 508
501 jffs2_free_raw_dirent(rd); 509 jffs2_free_raw_dirent(rd);
502 510
@@ -525,7 +533,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
525{ 533{
526 struct jffs2_raw_dirent *rd; 534 struct jffs2_raw_dirent *rd;
527 struct jffs2_full_dirent *fd; 535 struct jffs2_full_dirent *fd;
528 uint32_t alloclen, phys_ofs; 536 uint32_t alloclen;
529 int ret; 537 int ret;
530 538
531 if (1 /* alternative branch needs testing */ || 539 if (1 /* alternative branch needs testing */ ||
@@ -536,7 +544,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
536 if (!rd) 544 if (!rd)
537 return -ENOMEM; 545 return -ENOMEM;
538 546
539 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, 547 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
540 ALLOC_DELETION, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); 548 ALLOC_DELETION, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
541 if (ret) { 549 if (ret) {
542 jffs2_free_raw_dirent(rd); 550 jffs2_free_raw_dirent(rd);
@@ -560,7 +568,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
560 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 568 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
561 rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); 569 rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
562 570
563 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_DELETION); 571 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_DELETION);
564 572
565 jffs2_free_raw_dirent(rd); 573 jffs2_free_raw_dirent(rd);
566 574
@@ -639,14 +647,14 @@ int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint
639{ 647{
640 struct jffs2_raw_dirent *rd; 648 struct jffs2_raw_dirent *rd;
641 struct jffs2_full_dirent *fd; 649 struct jffs2_full_dirent *fd;
642 uint32_t alloclen, phys_ofs; 650 uint32_t alloclen;
643 int ret; 651 int ret;
644 652
645 rd = jffs2_alloc_raw_dirent(); 653 rd = jffs2_alloc_raw_dirent();
646 if (!rd) 654 if (!rd)
647 return -ENOMEM; 655 return -ENOMEM;
648 656
649 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, 657 ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
650 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen)); 658 ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
651 if (ret) { 659 if (ret) {
652 jffs2_free_raw_dirent(rd); 660 jffs2_free_raw_dirent(rd);
@@ -672,7 +680,7 @@ int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint
672 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 680 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
673 rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); 681 rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
674 682
675 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL); 683 fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, ALLOC_NORMAL);
676 684
677 jffs2_free_raw_dirent(rd); 685 jffs2_free_raw_dirent(rd);
678 686