diff options
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 41f8e55afcd1..cecf9aa10811 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -1323,7 +1323,7 @@ static void ext4_da_page_release_reservation(struct page *page, | |||
1323 | unsigned int offset, | 1323 | unsigned int offset, |
1324 | unsigned int length) | 1324 | unsigned int length) |
1325 | { | 1325 | { |
1326 | int to_release = 0; | 1326 | int to_release = 0, contiguous_blks = 0; |
1327 | struct buffer_head *head, *bh; | 1327 | struct buffer_head *head, *bh; |
1328 | unsigned int curr_off = 0; | 1328 | unsigned int curr_off = 0; |
1329 | struct inode *inode = page->mapping->host; | 1329 | struct inode *inode = page->mapping->host; |
@@ -1344,14 +1344,23 @@ static void ext4_da_page_release_reservation(struct page *page, | |||
1344 | 1344 | ||
1345 | if ((offset <= curr_off) && (buffer_delay(bh))) { | 1345 | if ((offset <= curr_off) && (buffer_delay(bh))) { |
1346 | to_release++; | 1346 | to_release++; |
1347 | contiguous_blks++; | ||
1347 | clear_buffer_delay(bh); | 1348 | clear_buffer_delay(bh); |
1349 | } else if (contiguous_blks) { | ||
1350 | lblk = page->index << | ||
1351 | (PAGE_CACHE_SHIFT - inode->i_blkbits); | ||
1352 | lblk += (curr_off >> inode->i_blkbits) - | ||
1353 | contiguous_blks; | ||
1354 | ext4_es_remove_extent(inode, lblk, contiguous_blks); | ||
1355 | contiguous_blks = 0; | ||
1348 | } | 1356 | } |
1349 | curr_off = next_off; | 1357 | curr_off = next_off; |
1350 | } while ((bh = bh->b_this_page) != head); | 1358 | } while ((bh = bh->b_this_page) != head); |
1351 | 1359 | ||
1352 | if (to_release) { | 1360 | if (contiguous_blks) { |
1353 | lblk = page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits); | 1361 | lblk = page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits); |
1354 | ext4_es_remove_extent(inode, lblk, to_release); | 1362 | lblk += (curr_off >> inode->i_blkbits) - contiguous_blks; |
1363 | ext4_es_remove_extent(inode, lblk, contiguous_blks); | ||
1355 | } | 1364 | } |
1356 | 1365 | ||
1357 | /* If we have released all the blocks belonging to a cluster, then we | 1366 | /* If we have released all the blocks belonging to a cluster, then we |
@@ -4344,7 +4353,12 @@ static void ext4_update_other_inodes_time(struct super_block *sb, | |||
4344 | int inode_size = EXT4_INODE_SIZE(sb); | 4353 | int inode_size = EXT4_INODE_SIZE(sb); |
4345 | 4354 | ||
4346 | oi.orig_ino = orig_ino; | 4355 | oi.orig_ino = orig_ino; |
4347 | ino = (orig_ino & ~(inodes_per_block - 1)) + 1; | 4356 | /* |
4357 | * Calculate the first inode in the inode table block. Inode | ||
4358 | * numbers are one-based. That is, the first inode in a block | ||
4359 | * (assuming 4k blocks and 256 byte inodes) is (n*16 + 1). | ||
4360 | */ | ||
4361 | ino = ((orig_ino - 1) & ~(inodes_per_block - 1)) + 1; | ||
4348 | for (i = 0; i < inodes_per_block; i++, ino++, buf += inode_size) { | 4362 | for (i = 0; i < inodes_per_block; i++, ino++, buf += inode_size) { |
4349 | if (ino == orig_ino) | 4363 | if (ino == orig_ino) |
4350 | continue; | 4364 | continue; |