diff options
Diffstat (limited to 'fs/jffs2/file.c')
-rw-r--r-- | fs/jffs2/file.c | 39 |
1 files changed, 18 insertions, 21 deletions
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index c5ac5944bc1b..cad86bac3453 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c | |||
@@ -137,39 +137,33 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, | |||
137 | struct page *pg; | 137 | struct page *pg; |
138 | struct inode *inode = mapping->host; | 138 | struct inode *inode = mapping->host; |
139 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); | 139 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); |
140 | struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); | ||
141 | struct jffs2_raw_inode ri; | ||
142 | uint32_t alloc_len = 0; | ||
143 | pgoff_t index = pos >> PAGE_CACHE_SHIFT; | 140 | pgoff_t index = pos >> PAGE_CACHE_SHIFT; |
144 | uint32_t pageofs = index << PAGE_CACHE_SHIFT; | 141 | uint32_t pageofs = index << PAGE_CACHE_SHIFT; |
145 | int ret = 0; | 142 | int ret = 0; |
146 | 143 | ||
147 | jffs2_dbg(1, "%s()\n", __func__); | ||
148 | |||
149 | if (pageofs > inode->i_size) { | ||
150 | ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len, | ||
151 | ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); | ||
152 | if (ret) | ||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | mutex_lock(&f->sem); | ||
157 | pg = grab_cache_page_write_begin(mapping, index, flags); | 144 | pg = grab_cache_page_write_begin(mapping, index, flags); |
158 | if (!pg) { | 145 | if (!pg) |
159 | if (alloc_len) | ||
160 | jffs2_complete_reservation(c); | ||
161 | mutex_unlock(&f->sem); | ||
162 | return -ENOMEM; | 146 | return -ENOMEM; |
163 | } | ||
164 | *pagep = pg; | 147 | *pagep = pg; |
165 | 148 | ||
166 | if (alloc_len) { | 149 | jffs2_dbg(1, "%s()\n", __func__); |
150 | |||
151 | if (pageofs > inode->i_size) { | ||
167 | /* Make new hole frag from old EOF to new page */ | 152 | /* Make new hole frag from old EOF to new page */ |
153 | struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); | ||
154 | struct jffs2_raw_inode ri; | ||
168 | struct jffs2_full_dnode *fn; | 155 | struct jffs2_full_dnode *fn; |
156 | uint32_t alloc_len; | ||
169 | 157 | ||
170 | jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n", | 158 | jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n", |
171 | (unsigned int)inode->i_size, pageofs); | 159 | (unsigned int)inode->i_size, pageofs); |
172 | 160 | ||
161 | ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len, | ||
162 | ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); | ||
163 | if (ret) | ||
164 | goto out_page; | ||
165 | |||
166 | mutex_lock(&f->sem); | ||
173 | memset(&ri, 0, sizeof(ri)); | 167 | memset(&ri, 0, sizeof(ri)); |
174 | 168 | ||
175 | ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); | 169 | ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); |
@@ -196,6 +190,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, | |||
196 | if (IS_ERR(fn)) { | 190 | if (IS_ERR(fn)) { |
197 | ret = PTR_ERR(fn); | 191 | ret = PTR_ERR(fn); |
198 | jffs2_complete_reservation(c); | 192 | jffs2_complete_reservation(c); |
193 | mutex_unlock(&f->sem); | ||
199 | goto out_page; | 194 | goto out_page; |
200 | } | 195 | } |
201 | ret = jffs2_add_full_dnode_to_inode(c, f, fn); | 196 | ret = jffs2_add_full_dnode_to_inode(c, f, fn); |
@@ -210,10 +205,12 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, | |||
210 | jffs2_mark_node_obsolete(c, fn->raw); | 205 | jffs2_mark_node_obsolete(c, fn->raw); |
211 | jffs2_free_full_dnode(fn); | 206 | jffs2_free_full_dnode(fn); |
212 | jffs2_complete_reservation(c); | 207 | jffs2_complete_reservation(c); |
208 | mutex_unlock(&f->sem); | ||
213 | goto out_page; | 209 | goto out_page; |
214 | } | 210 | } |
215 | jffs2_complete_reservation(c); | 211 | jffs2_complete_reservation(c); |
216 | inode->i_size = pageofs; | 212 | inode->i_size = pageofs; |
213 | mutex_unlock(&f->sem); | ||
217 | } | 214 | } |
218 | 215 | ||
219 | /* | 216 | /* |
@@ -222,18 +219,18 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, | |||
222 | * case of a short-copy. | 219 | * case of a short-copy. |
223 | */ | 220 | */ |
224 | if (!PageUptodate(pg)) { | 221 | if (!PageUptodate(pg)) { |
222 | mutex_lock(&f->sem); | ||
225 | ret = jffs2_do_readpage_nolock(inode, pg); | 223 | ret = jffs2_do_readpage_nolock(inode, pg); |
224 | mutex_unlock(&f->sem); | ||
226 | if (ret) | 225 | if (ret) |
227 | goto out_page; | 226 | goto out_page; |
228 | } | 227 | } |
229 | mutex_unlock(&f->sem); | ||
230 | jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags); | 228 | jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags); |
231 | return ret; | 229 | return ret; |
232 | 230 | ||
233 | out_page: | 231 | out_page: |
234 | unlock_page(pg); | 232 | unlock_page(pg); |
235 | page_cache_release(pg); | 233 | page_cache_release(pg); |
236 | mutex_unlock(&f->sem); | ||
237 | return ret; | 234 | return ret; |
238 | } | 235 | } |
239 | 236 | ||