aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ufs/balloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ufs/balloc.c')
-rw-r--r--fs/ufs/balloc.c46
1 files changed, 30 insertions, 16 deletions
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index 2e0021e8f366..638f4c585e89 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -227,24 +227,27 @@ failed:
227 * We can come here from ufs_writepage or ufs_prepare_write, 227 * We can come here from ufs_writepage or ufs_prepare_write,
228 * locked_page is argument of these functions, so we already lock it. 228 * locked_page is argument of these functions, so we already lock it.
229 */ 229 */
230static void ufs_change_blocknr(struct inode *inode, unsigned int baseblk, 230static void ufs_change_blocknr(struct inode *inode, unsigned int beg,
231 unsigned int count, unsigned int oldb, 231 unsigned int count, unsigned int oldb,
232 unsigned int newb, struct page *locked_page) 232 unsigned int newb, struct page *locked_page)
233{ 233{
234 unsigned int blk_per_page = 1 << (PAGE_CACHE_SHIFT - inode->i_blkbits); 234 const unsigned mask = (1 << (PAGE_CACHE_SHIFT - inode->i_blkbits)) - 1;
235 struct address_space *mapping = inode->i_mapping; 235 struct address_space * const mapping = inode->i_mapping;
236 pgoff_t index, cur_index = locked_page->index; 236 pgoff_t index, cur_index;
237 unsigned int i, j; 237 unsigned end, pos, j;
238 struct page *page; 238 struct page *page;
239 struct buffer_head *head, *bh; 239 struct buffer_head *head, *bh;
240 240
241 UFSD("ENTER, ino %lu, count %u, oldb %u, newb %u\n", 241 UFSD("ENTER, ino %lu, count %u, oldb %u, newb %u\n",
242 inode->i_ino, count, oldb, newb); 242 inode->i_ino, count, oldb, newb);
243 243
244 BUG_ON(!locked_page);
244 BUG_ON(!PageLocked(locked_page)); 245 BUG_ON(!PageLocked(locked_page));
245 246
246 for (i = 0; i < count; i += blk_per_page) { 247 cur_index = locked_page->index;
247 index = (baseblk+i) >> (PAGE_CACHE_SHIFT - inode->i_blkbits); 248
249 for (end = count + beg; beg < end; beg = (beg | mask) + 1) {
250 index = beg >> (PAGE_CACHE_SHIFT - inode->i_blkbits);
248 251
249 if (likely(cur_index != index)) { 252 if (likely(cur_index != index)) {
250 page = ufs_get_locked_page(mapping, index); 253 page = ufs_get_locked_page(mapping, index);
@@ -253,21 +256,32 @@ static void ufs_change_blocknr(struct inode *inode, unsigned int baseblk,
253 } else 256 } else
254 page = locked_page; 257 page = locked_page;
255 258
256 j = i;
257 head = page_buffers(page); 259 head = page_buffers(page);
258 bh = head; 260 bh = head;
261 pos = beg & mask;
262 for (j = 0; j < pos; ++j)
263 bh = bh->b_this_page;
264 j = 0;
259 do { 265 do {
260 if (likely(bh->b_blocknr == j + oldb && j < count)) { 266 if (buffer_mapped(bh)) {
261 unmap_underlying_metadata(bh->b_bdev, 267 pos = bh->b_blocknr - oldb;
262 bh->b_blocknr); 268 if (pos < count) {
263 bh->b_blocknr = newb + j++; 269 UFSD(" change from %llu to %llu\n",
264 mark_buffer_dirty(bh); 270 (unsigned long long)pos + oldb,
271 (unsigned long long)pos + newb);
272 bh->b_blocknr = newb + pos;
273 unmap_underlying_metadata(bh->b_bdev,
274 bh->b_blocknr);
275 mark_buffer_dirty(bh);
276 ++j;
277 }
265 } 278 }
266 279
267 bh = bh->b_this_page; 280 bh = bh->b_this_page;
268 } while (bh != head); 281 } while (bh != head);
269 282
270 set_page_dirty(page); 283 if (j)
284 set_page_dirty(page);
271 285
272 if (likely(cur_index != index)) 286 if (likely(cur_index != index))
273 ufs_put_locked_page(page); 287 ufs_put_locked_page(page);
@@ -415,14 +429,14 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment,
415 } 429 }
416 result = ufs_alloc_fragments (inode, cgno, goal, request, err); 430 result = ufs_alloc_fragments (inode, cgno, goal, request, err);
417 if (result) { 431 if (result) {
432 ufs_clear_frags(inode, result + oldcount, newcount - oldcount,
433 locked_page != NULL);
418 ufs_change_blocknr(inode, fragment - oldcount, oldcount, tmp, 434 ufs_change_blocknr(inode, fragment - oldcount, oldcount, tmp,
419 result, locked_page); 435 result, locked_page);
420 436
421 *p = cpu_to_fs32(sb, result); 437 *p = cpu_to_fs32(sb, result);
422 *err = 0; 438 *err = 0;
423 UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); 439 UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count);
424 ufs_clear_frags(inode, result + oldcount, newcount - oldcount,
425 locked_page != NULL);
426 unlock_super(sb); 440 unlock_super(sb);
427 if (newcount < request) 441 if (newcount < request)
428 ufs_free_fragments (inode, result + newcount, request - newcount); 442 ufs_free_fragments (inode, result + newcount, request - newcount);