diff options
Diffstat (limited to 'fs/jffs2')
-rw-r--r-- | fs/jffs2/summary.c | 40 | ||||
-rw-r--r-- | fs/jffs2/summary.h | 6 |
2 files changed, 32 insertions, 14 deletions
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c index 629af01e5ade..6caf1e1ee26d 100644 --- a/fs/jffs2/summary.c +++ b/fs/jffs2/summary.c | |||
@@ -23,6 +23,8 @@ | |||
23 | 23 | ||
24 | int jffs2_sum_init(struct jffs2_sb_info *c) | 24 | int jffs2_sum_init(struct jffs2_sb_info *c) |
25 | { | 25 | { |
26 | uint32_t sum_size = max_t(uint32_t, c->sector_size, MAX_SUMMARY_SIZE); | ||
27 | |||
26 | c->summary = kzalloc(sizeof(struct jffs2_summary), GFP_KERNEL); | 28 | c->summary = kzalloc(sizeof(struct jffs2_summary), GFP_KERNEL); |
27 | 29 | ||
28 | if (!c->summary) { | 30 | if (!c->summary) { |
@@ -30,7 +32,7 @@ int jffs2_sum_init(struct jffs2_sb_info *c) | |||
30 | return -ENOMEM; | 32 | return -ENOMEM; |
31 | } | 33 | } |
32 | 34 | ||
33 | c->summary->sum_buf = vmalloc(c->sector_size); | 35 | c->summary->sum_buf = kmalloc(sum_size, GFP_KERNEL); |
34 | 36 | ||
35 | if (!c->summary->sum_buf) { | 37 | if (!c->summary->sum_buf) { |
36 | JFFS2_WARNING("Can't allocate buffer for writing out summary information!\n"); | 38 | JFFS2_WARNING("Can't allocate buffer for writing out summary information!\n"); |
@@ -49,7 +51,7 @@ void jffs2_sum_exit(struct jffs2_sb_info *c) | |||
49 | 51 | ||
50 | jffs2_sum_disable_collecting(c->summary); | 52 | jffs2_sum_disable_collecting(c->summary); |
51 | 53 | ||
52 | vfree(c->summary->sum_buf); | 54 | kfree(c->summary->sum_buf); |
53 | c->summary->sum_buf = NULL; | 55 | c->summary->sum_buf = NULL; |
54 | 56 | ||
55 | kfree(c->summary); | 57 | kfree(c->summary); |
@@ -665,7 +667,7 @@ crc_err: | |||
665 | /* Write summary data to flash - helper function for jffs2_sum_write_sumnode() */ | 667 | /* Write summary data to flash - helper function for jffs2_sum_write_sumnode() */ |
666 | 668 | ||
667 | static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | 669 | static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, |
668 | uint32_t infosize, uint32_t datasize, int padsize) | 670 | uint32_t infosize, uint32_t datasize, int padsize) |
669 | { | 671 | { |
670 | struct jffs2_raw_summary isum; | 672 | struct jffs2_raw_summary isum; |
671 | union jffs2_sum_mem *temp; | 673 | union jffs2_sum_mem *temp; |
@@ -676,6 +678,26 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock | |||
676 | int ret; | 678 | int ret; |
677 | size_t retlen; | 679 | size_t retlen; |
678 | 680 | ||
681 | if (padsize + datasize > MAX_SUMMARY_SIZE) { | ||
682 | /* It won't fit in the buffer. Abort summary for this jeb */ | ||
683 | jffs2_sum_disable_collecting(c->summary); | ||
684 | |||
685 | JFFS2_WARNING("Summary too big (%d data, %d pad) in eraseblock at %08x\n", | ||
686 | datasize, padsize, jeb->offset); | ||
687 | /* Non-fatal */ | ||
688 | return 0; | ||
689 | } | ||
690 | /* Is there enough space for summary? */ | ||
691 | if (padsize < 0) { | ||
692 | /* don't try to write out summary for this jeb */ | ||
693 | jffs2_sum_disable_collecting(c->summary); | ||
694 | |||
695 | JFFS2_WARNING("Not enough space for summary, padsize = %d\n", | ||
696 | padsize); | ||
697 | /* Non-fatal */ | ||
698 | return 0; | ||
699 | } | ||
700 | |||
679 | memset(c->summary->sum_buf, 0xff, datasize); | 701 | memset(c->summary->sum_buf, 0xff, datasize); |
680 | memset(&isum, 0, sizeof(isum)); | 702 | memset(&isum, 0, sizeof(isum)); |
681 | 703 | ||
@@ -821,7 +843,7 @@ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c) | |||
821 | { | 843 | { |
822 | int datasize, infosize, padsize; | 844 | int datasize, infosize, padsize; |
823 | struct jffs2_eraseblock *jeb; | 845 | struct jffs2_eraseblock *jeb; |
824 | int ret; | 846 | int ret = 0; |
825 | 847 | ||
826 | dbg_summary("called\n"); | 848 | dbg_summary("called\n"); |
827 | 849 | ||
@@ -841,16 +863,6 @@ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c) | |||
841 | infosize += padsize; | 863 | infosize += padsize; |
842 | datasize += padsize; | 864 | datasize += padsize; |
843 | 865 | ||
844 | /* Is there enough space for summary? */ | ||
845 | if (padsize < 0) { | ||
846 | /* don't try to write out summary for this jeb */ | ||
847 | jffs2_sum_disable_collecting(c->summary); | ||
848 | |||
849 | JFFS2_WARNING("Not enough space for summary, padsize = %d\n", padsize); | ||
850 | spin_lock(&c->erase_completion_lock); | ||
851 | return 0; | ||
852 | } | ||
853 | |||
854 | ret = jffs2_sum_write_data(c, jeb, infosize, datasize, padsize); | 866 | ret = jffs2_sum_write_data(c, jeb, infosize, datasize, padsize); |
855 | spin_lock(&c->erase_completion_lock); | 867 | spin_lock(&c->erase_completion_lock); |
856 | return ret; | 868 | return ret; |
diff --git a/fs/jffs2/summary.h b/fs/jffs2/summary.h index 8bf34f2fa5ce..60207a2ae952 100644 --- a/fs/jffs2/summary.h +++ b/fs/jffs2/summary.h | |||
@@ -13,6 +13,12 @@ | |||
13 | #ifndef JFFS2_SUMMARY_H | 13 | #ifndef JFFS2_SUMMARY_H |
14 | #define JFFS2_SUMMARY_H | 14 | #define JFFS2_SUMMARY_H |
15 | 15 | ||
16 | /* Limit summary size to 64KiB so that we can kmalloc it. If the summary | ||
17 | is larger than that, we have to just ditch it and avoid using summary | ||
18 | for the eraseblock in question... and it probably doesn't hurt us much | ||
19 | anyway. */ | ||
20 | #define MAX_SUMMARY_SIZE 65536 | ||
21 | |||
16 | #include <linux/uio.h> | 22 | #include <linux/uio.h> |
17 | #include <linux/jffs2.h> | 23 | #include <linux/jffs2.h> |
18 | 24 | ||