aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/jffs2/nodelist.c18
-rw-r--r--fs/jffs2/nodelist.h2
-rw-r--r--fs/jffs2/readinode.c9
3 files changed, 20 insertions, 9 deletions
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c
index ac2a4c422e32..4bf86088b3ae 100644
--- a/fs/jffs2/nodelist.c
+++ b/fs/jffs2/nodelist.c
@@ -52,7 +52,7 @@ void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new
52 *prev = new; 52 *prev = new;
53} 53}
54 54
55void jffs2_truncate_fragtree(struct jffs2_sb_info *c, struct rb_root *list, uint32_t size) 55uint32_t jffs2_truncate_fragtree(struct jffs2_sb_info *c, struct rb_root *list, uint32_t size)
56{ 56{
57 struct jffs2_node_frag *frag = jffs2_lookup_node_frag(list, size); 57 struct jffs2_node_frag *frag = jffs2_lookup_node_frag(list, size);
58 58
@@ -74,18 +74,24 @@ void jffs2_truncate_fragtree(struct jffs2_sb_info *c, struct rb_root *list, uint
74 } 74 }
75 75
76 if (size == 0) 76 if (size == 0)
77 return; 77 return 0;
78 78
79 /*
80 * If the last fragment starts at the RAM page boundary, it is
81 * REF_PRISTINE irrespective of its size.
82 */
83 frag = frag_last(list); 79 frag = frag_last(list);
80
81 /* Sanity check for truncation to longer than we started with... */
82 if (!frag)
83 return 0;
84 if (frag->ofs + frag->size < size)
85 return frag->ofs + frag->size;
86
87 /* If the last fragment starts at the RAM page boundary, it is
88 * REF_PRISTINE irrespective of its size. */
84 if (frag->node && (frag->ofs & (PAGE_CACHE_SIZE - 1)) == 0) { 89 if (frag->node && (frag->ofs & (PAGE_CACHE_SIZE - 1)) == 0) {
85 dbg_fragtree2("marking the last fragment 0x%08x-0x%08x REF_PRISTINE.\n", 90 dbg_fragtree2("marking the last fragment 0x%08x-0x%08x REF_PRISTINE.\n",
86 frag->ofs, frag->ofs + frag->size); 91 frag->ofs, frag->ofs + frag->size);
87 frag->node->raw->flash_offset = ref_offset(frag->node->raw) | REF_PRISTINE; 92 frag->node->raw->flash_offset = ref_offset(frag->node->raw) | REF_PRISTINE;
88 } 93 }
94 return size;
89} 95}
90 96
91static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, 97static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c,
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
index cb34cac5d0f8..25126a062cae 100644
--- a/fs/jffs2/nodelist.h
+++ b/fs/jffs2/nodelist.h
@@ -362,7 +362,7 @@ struct rb_node *rb_next(struct rb_node *);
362struct rb_node *rb_prev(struct rb_node *); 362struct rb_node *rb_prev(struct rb_node *);
363void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root); 363void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root);
364int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn); 364int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn);
365void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size); 365uint32_t jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size);
366struct jffs2_raw_node_ref *jffs2_link_node_ref(struct jffs2_sb_info *c, 366struct jffs2_raw_node_ref *jffs2_link_node_ref(struct jffs2_sb_info *c,
367 struct jffs2_eraseblock *jeb, 367 struct jffs2_eraseblock *jeb,
368 uint32_t ofs, uint32_t len, 368 uint32_t ofs, uint32_t len,
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index a42ffba2ed17..6aff38930b50 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -1132,7 +1132,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
1132 struct jffs2_raw_inode *latest_node) 1132 struct jffs2_raw_inode *latest_node)
1133{ 1133{
1134 struct jffs2_readinode_info rii; 1134 struct jffs2_readinode_info rii;
1135 uint32_t crc; 1135 uint32_t crc, new_size;
1136 size_t retlen; 1136 size_t retlen;
1137 int ret; 1137 int ret;
1138 1138
@@ -1233,7 +1233,12 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
1233 1233
1234 case S_IFREG: 1234 case S_IFREG:
1235 /* If it was a regular file, truncate it to the latest node's isize */ 1235 /* If it was a regular file, truncate it to the latest node's isize */
1236 jffs2_truncate_fragtree(c, &f->fragtree, je32_to_cpu(latest_node->isize)); 1236 new_size = jffs2_truncate_fragtree(c, &f->fragtree, je32_to_cpu(latest_node->isize));
1237 if (new_size != je32_to_cpu(latest_node->isize)) {
1238 JFFS2_WARNING("Truncating ino #%u to %d bytes failed because it only had %d bytes to start with!\n",
1239 f->inocache->ino, je32_to_cpu(latest_node->isize), new_size);
1240 latest_node->isize = cpu_to_je32(new_size);
1241 }
1237 break; 1242 break;
1238 1243
1239 case S_IFLNK: 1244 case S_IFLNK: