aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext3/inode.c')
-rw-r--r--fs/ext3/inode.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 5fa453b49a64..4a09ff169870 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1435,6 +1435,10 @@ static int journal_dirty_data_fn(handle_t *handle, struct buffer_head *bh)
1435 return 0; 1435 return 0;
1436} 1436}
1437 1437
1438static int buffer_unmapped(handle_t *handle, struct buffer_head *bh)
1439{
1440 return !buffer_mapped(bh);
1441}
1438/* 1442/*
1439 * Note that we always start a transaction even if we're not journalling 1443 * Note that we always start a transaction even if we're not journalling
1440 * data. This is to preserve ordering: any hole instantiation within 1444 * data. This is to preserve ordering: any hole instantiation within
@@ -1505,6 +1509,15 @@ static int ext3_ordered_writepage(struct page *page,
1505 if (ext3_journal_current_handle()) 1509 if (ext3_journal_current_handle())
1506 goto out_fail; 1510 goto out_fail;
1507 1511
1512 if (!page_has_buffers(page)) {
1513 create_empty_buffers(page, inode->i_sb->s_blocksize,
1514 (1 << BH_Dirty)|(1 << BH_Uptodate));
1515 } else if (!walk_page_buffers(NULL, page_buffers(page), 0, PAGE_CACHE_SIZE, NULL, buffer_unmapped)) {
1516 /* Provide NULL instead of get_block so that we catch bugs if buffers weren't really mapped */
1517 return block_write_full_page(page, NULL, wbc);
1518 }
1519 page_bufs = page_buffers(page);
1520
1508 handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode)); 1521 handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode));
1509 1522
1510 if (IS_ERR(handle)) { 1523 if (IS_ERR(handle)) {
@@ -1512,11 +1525,6 @@ static int ext3_ordered_writepage(struct page *page,
1512 goto out_fail; 1525 goto out_fail;
1513 } 1526 }
1514 1527
1515 if (!page_has_buffers(page)) {
1516 create_empty_buffers(page, inode->i_sb->s_blocksize,
1517 (1 << BH_Dirty)|(1 << BH_Uptodate));
1518 }
1519 page_bufs = page_buffers(page);
1520 walk_page_buffers(handle, page_bufs, 0, 1528 walk_page_buffers(handle, page_bufs, 0,
1521 PAGE_CACHE_SIZE, NULL, bget_one); 1529 PAGE_CACHE_SIZE, NULL, bget_one);
1522 1530
@@ -3055,7 +3063,7 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr)
3055 error = PTR_ERR(handle); 3063 error = PTR_ERR(handle);
3056 goto err_out; 3064 goto err_out;
3057 } 3065 }
3058 error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0; 3066 error = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
3059 if (error) { 3067 if (error) {
3060 ext3_journal_stop(handle); 3068 ext3_journal_stop(handle);
3061 return error; 3069 return error;
@@ -3146,7 +3154,7 @@ static int ext3_writepage_trans_blocks(struct inode *inode)
3146 ret = 2 * (bpp + indirects) + 2; 3154 ret = 2 * (bpp + indirects) + 2;
3147 3155
3148#ifdef CONFIG_QUOTA 3156#ifdef CONFIG_QUOTA
3149 /* We know that structure was already allocated during DQUOT_INIT so 3157 /* We know that structure was already allocated during vfs_dq_init so
3150 * we will be updating only the data blocks + inodes */ 3158 * we will be updating only the data blocks + inodes */
3151 ret += 2*EXT3_QUOTA_TRANS_BLOCKS(inode->i_sb); 3159 ret += 2*EXT3_QUOTA_TRANS_BLOCKS(inode->i_sb);
3152#endif 3160#endif
@@ -3237,7 +3245,7 @@ int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode)
3237 * i_size has been changed by generic_commit_write() and we thus need 3245 * i_size has been changed by generic_commit_write() and we thus need
3238 * to include the updated inode in the current transaction. 3246 * to include the updated inode in the current transaction.
3239 * 3247 *
3240 * Also, DQUOT_ALLOC_SPACE() will always dirty the inode when blocks 3248 * Also, vfs_dq_alloc_space() will always dirty the inode when blocks
3241 * are allocated to the file. 3249 * are allocated to the file.
3242 * 3250 *
3243 * If the inode is marked synchronous, we don't honour that here - doing 3251 * If the inode is marked synchronous, we don't honour that here - doing