aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2008-07-11 19:27:31 -0400
committerTheodore Ts'o <tytso@mit.edu>2008-07-11 19:27:31 -0400
commitcf108bca465dde0c015f32dd453b99457d31c7c7 (patch)
treeb1c9dfc1936579e4fd2a48f77f702effc39029e2 /fs/ext4
parentc7d206b3379f7d6462e778b74f475c470ee3dcaf (diff)
ext4: Invert the locking order of page_lock and transaction start
This changes are needed to support data=ordered mode handling via inodes. This enables us to get rid of the journal heads and buffer heads for data buffers in the ordered mode. With the changes, during tranasaction commit we writeout the inode pages using the writepages()/writepage(). That implies we take page lock during transaction commit. This can cause a deadlock with the locking order page_lock -> jbd2_journal_start, since the jbd2_journal_start can wait for the journal_commit to happen and the journal_commit now needs to take the page lock. To avoid this dead lock reverse the locking order. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Mingming Cao <cmm@us.ibm.com> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/ext4.h4
-rw-r--r--fs/ext4/extents.c15
-rw-r--r--fs/ext4/inode.c292
3 files changed, 155 insertions, 156 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 98760d14e2cd..f65829bbe7aa 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1066,7 +1066,7 @@ extern void ext4_set_inode_flags(struct inode *);
1066extern void ext4_get_inode_flags(struct ext4_inode_info *); 1066extern void ext4_get_inode_flags(struct ext4_inode_info *);
1067extern void ext4_set_aops(struct inode *inode); 1067extern void ext4_set_aops(struct inode *inode);
1068extern int ext4_writepage_trans_blocks(struct inode *); 1068extern int ext4_writepage_trans_blocks(struct inode *);
1069extern int ext4_block_truncate_page(handle_t *handle, struct page *page, 1069extern int ext4_block_truncate_page(handle_t *handle,
1070 struct address_space *mapping, loff_t from); 1070 struct address_space *mapping, loff_t from);
1071extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page); 1071extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page);
1072 1072
@@ -1225,7 +1225,7 @@ extern int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
1225 ext4_lblk_t iblock, 1225 ext4_lblk_t iblock,
1226 unsigned long max_blocks, struct buffer_head *bh_result, 1226 unsigned long max_blocks, struct buffer_head *bh_result,
1227 int create, int extend_disksize); 1227 int create, int extend_disksize);
1228extern void ext4_ext_truncate(struct inode *, struct page *); 1228extern void ext4_ext_truncate(struct inode *);
1229extern void ext4_ext_init(struct super_block *); 1229extern void ext4_ext_init(struct super_block *);
1230extern void ext4_ext_release(struct super_block *); 1230extern void ext4_ext_release(struct super_block *);
1231extern long ext4_fallocate(struct inode *inode, int mode, loff_t offset, 1231extern long ext4_fallocate(struct inode *inode, int mode, loff_t offset,
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index bb36a28f8ff3..b722bce7d662 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2749,7 +2749,7 @@ out2:
2749 return err ? err : allocated; 2749 return err ? err : allocated;
2750} 2750}
2751 2751
2752void ext4_ext_truncate(struct inode * inode, struct page *page) 2752void ext4_ext_truncate(struct inode *inode)
2753{ 2753{
2754 struct address_space *mapping = inode->i_mapping; 2754 struct address_space *mapping = inode->i_mapping;
2755 struct super_block *sb = inode->i_sb; 2755 struct super_block *sb = inode->i_sb;
@@ -2762,18 +2762,11 @@ void ext4_ext_truncate(struct inode * inode, struct page *page)
2762 */ 2762 */
2763 err = ext4_writepage_trans_blocks(inode) + 3; 2763 err = ext4_writepage_trans_blocks(inode) + 3;
2764 handle = ext4_journal_start(inode, err); 2764 handle = ext4_journal_start(inode, err);
2765 if (IS_ERR(handle)) { 2765 if (IS_ERR(handle))
2766 if (page) {
2767 clear_highpage(page);
2768 flush_dcache_page(page);
2769 unlock_page(page);
2770 page_cache_release(page);
2771 }
2772 return; 2766 return;
2773 }
2774 2767
2775 if (page) 2768 if (inode->i_size & (sb->s_blocksize - 1))
2776 ext4_block_truncate_page(handle, page, mapping, inode->i_size); 2769 ext4_block_truncate_page(handle, mapping, inode->i_size);
2777 2770
2778 down_write(&EXT4_I(inode)->i_data_sem); 2771 down_write(&EXT4_I(inode)->i_data_sem);
2779 ext4_ext_invalidate_cache(inode); 2772 ext4_ext_invalidate_cache(inode);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 034fc544aa66..320acb6c35bf 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1239,19 +1239,20 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping,
1239 to = from + len; 1239 to = from + len;
1240 1240
1241retry: 1241retry:
1242 page = __grab_cache_page(mapping, index);
1243 if (!page)
1244 return -ENOMEM;
1245 *pagep = page;
1246
1247 handle = ext4_journal_start(inode, needed_blocks); 1242 handle = ext4_journal_start(inode, needed_blocks);
1248 if (IS_ERR(handle)) { 1243 if (IS_ERR(handle)) {
1249 unlock_page(page);
1250 page_cache_release(page);
1251 ret = PTR_ERR(handle); 1244 ret = PTR_ERR(handle);
1252 goto out; 1245 goto out;
1253 } 1246 }
1254 1247
1248 page = __grab_cache_page(mapping, index);
1249 if (!page) {
1250 ext4_journal_stop(handle);
1251 ret = -ENOMEM;
1252 goto out;
1253 }
1254 *pagep = page;
1255
1255 ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, 1256 ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
1256 ext4_get_block); 1257 ext4_get_block);
1257 1258
@@ -1261,8 +1262,8 @@ retry:
1261 } 1262 }
1262 1263
1263 if (ret) { 1264 if (ret) {
1264 ext4_journal_stop(handle);
1265 unlock_page(page); 1265 unlock_page(page);
1266 ext4_journal_stop(handle);
1266 page_cache_release(page); 1267 page_cache_release(page);
1267 } 1268 }
1268 1269
@@ -1291,29 +1292,6 @@ static int write_end_fn(handle_t *handle, struct buffer_head *bh)
1291} 1292}
1292 1293
1293/* 1294/*
1294 * Generic write_end handler for ordered and writeback ext4 journal modes.
1295 * We can't use generic_write_end, because that unlocks the page and we need to
1296 * unlock the page after ext4_journal_stop, but ext4_journal_stop must run
1297 * after block_write_end.
1298 */
1299static int ext4_generic_write_end(struct file *file,
1300 struct address_space *mapping,
1301 loff_t pos, unsigned len, unsigned copied,
1302 struct page *page, void *fsdata)
1303{
1304 struct inode *inode = file->f_mapping->host;
1305
1306 copied = block_write_end(file, mapping, pos, len, copied, page, fsdata);
1307
1308 if (pos+copied > inode->i_size) {
1309 i_size_write(inode, pos+copied);
1310 mark_inode_dirty(inode);
1311 }
1312
1313 return copied;
1314}
1315
1316/*
1317 * We need to pick up the new inode size which generic_commit_write gave us 1295 * We need to pick up the new inode size which generic_commit_write gave us
1318 * `file' can be NULL - eg, when called from page_symlink(). 1296 * `file' can be NULL - eg, when called from page_symlink().
1319 * 1297 *
@@ -1326,7 +1304,7 @@ static int ext4_ordered_write_end(struct file *file,
1326 struct page *page, void *fsdata) 1304 struct page *page, void *fsdata)
1327{ 1305{
1328 handle_t *handle = ext4_journal_current_handle(); 1306 handle_t *handle = ext4_journal_current_handle();
1329 struct inode *inode = file->f_mapping->host; 1307 struct inode *inode = mapping->host;
1330 unsigned from, to; 1308 unsigned from, to;
1331 int ret = 0, ret2; 1309 int ret = 0, ret2;
1332 1310
@@ -1347,7 +1325,7 @@ static int ext4_ordered_write_end(struct file *file,
1347 new_i_size = pos + copied; 1325 new_i_size = pos + copied;
1348 if (new_i_size > EXT4_I(inode)->i_disksize) 1326 if (new_i_size > EXT4_I(inode)->i_disksize)
1349 EXT4_I(inode)->i_disksize = new_i_size; 1327 EXT4_I(inode)->i_disksize = new_i_size;
1350 ret2 = ext4_generic_write_end(file, mapping, pos, len, copied, 1328 ret2 = generic_write_end(file, mapping, pos, len, copied,
1351 page, fsdata); 1329 page, fsdata);
1352 copied = ret2; 1330 copied = ret2;
1353 if (ret2 < 0) 1331 if (ret2 < 0)
@@ -1356,8 +1334,6 @@ static int ext4_ordered_write_end(struct file *file,
1356 ret2 = ext4_journal_stop(handle); 1334 ret2 = ext4_journal_stop(handle);
1357 if (!ret) 1335 if (!ret)
1358 ret = ret2; 1336 ret = ret2;
1359 unlock_page(page);
1360 page_cache_release(page);
1361 1337
1362 return ret ? ret : copied; 1338 return ret ? ret : copied;
1363} 1339}
@@ -1368,7 +1344,7 @@ static int ext4_writeback_write_end(struct file *file,
1368 struct page *page, void *fsdata) 1344 struct page *page, void *fsdata)
1369{ 1345{
1370 handle_t *handle = ext4_journal_current_handle(); 1346 handle_t *handle = ext4_journal_current_handle();
1371 struct inode *inode = file->f_mapping->host; 1347 struct inode *inode = mapping->host;
1372 int ret = 0, ret2; 1348 int ret = 0, ret2;
1373 loff_t new_i_size; 1349 loff_t new_i_size;
1374 1350
@@ -1376,7 +1352,7 @@ static int ext4_writeback_write_end(struct file *file,
1376 if (new_i_size > EXT4_I(inode)->i_disksize) 1352 if (new_i_size > EXT4_I(inode)->i_disksize)
1377 EXT4_I(inode)->i_disksize = new_i_size; 1353 EXT4_I(inode)->i_disksize = new_i_size;
1378 1354
1379 ret2 = ext4_generic_write_end(file, mapping, pos, len, copied, 1355 ret2 = generic_write_end(file, mapping, pos, len, copied,
1380 page, fsdata); 1356 page, fsdata);
1381 copied = ret2; 1357 copied = ret2;
1382 if (ret2 < 0) 1358 if (ret2 < 0)
@@ -1385,8 +1361,6 @@ static int ext4_writeback_write_end(struct file *file,
1385 ret2 = ext4_journal_stop(handle); 1361 ret2 = ext4_journal_stop(handle);
1386 if (!ret) 1362 if (!ret)
1387 ret = ret2; 1363 ret = ret2;
1388 unlock_page(page);
1389 page_cache_release(page);
1390 1364
1391 return ret ? ret : copied; 1365 return ret ? ret : copied;
1392} 1366}
@@ -1425,10 +1399,10 @@ static int ext4_journalled_write_end(struct file *file,
1425 ret = ret2; 1399 ret = ret2;
1426 } 1400 }
1427 1401
1402 unlock_page(page);
1428 ret2 = ext4_journal_stop(handle); 1403 ret2 = ext4_journal_stop(handle);
1429 if (!ret) 1404 if (!ret)
1430 ret = ret2; 1405 ret = ret2;
1431 unlock_page(page);
1432 page_cache_release(page); 1406 page_cache_release(page);
1433 1407
1434 return ret ? ret : copied; 1408 return ret ? ret : copied;
@@ -1505,12 +1479,16 @@ static int jbd2_journal_dirty_data_fn(handle_t *handle, struct buffer_head *bh)
1505 return 0; 1479 return 0;
1506} 1480}
1507 1481
1482static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh)
1483{
1484 return !buffer_mapped(bh) || buffer_delay(bh);
1485}
1486
1508/* 1487/*
1509 * Note that we always start a transaction even if we're not journalling 1488 * Note that we don't need to start a transaction unless we're journaling
1510 * data. This is to preserve ordering: any hole instantiation within 1489 * data because we should have holes filled from ext4_page_mkwrite(). If
1511 * __block_write_full_page -> ext4_get_block() should be journalled 1490 * we are journaling data, we cannot start transaction directly because
1512 * along with the data so we don't crash and then get metadata which 1491 * transaction start ranks above page lock so we have to do some magic...
1513 * refers to old data.
1514 * 1492 *
1515 * In all journalling modes block_write_full_page() will start the I/O. 1493 * In all journalling modes block_write_full_page() will start the I/O.
1516 * 1494 *
@@ -1554,10 +1532,8 @@ static int jbd2_journal_dirty_data_fn(handle_t *handle, struct buffer_head *bh)
1554 * disastrous. Any write() or metadata operation will sync the fs for 1532 * disastrous. Any write() or metadata operation will sync the fs for
1555 * us. 1533 * us.
1556 * 1534 *
1557 * AKPM2: if all the page's buffers are mapped to disk and !data=journal,
1558 * we don't need to open a transaction here.
1559 */ 1535 */
1560static int ext4_ordered_writepage(struct page *page, 1536static int __ext4_ordered_writepage(struct page *page,
1561 struct writeback_control *wbc) 1537 struct writeback_control *wbc)
1562{ 1538{
1563 struct inode *inode = page->mapping->host; 1539 struct inode *inode = page->mapping->host;
@@ -1566,22 +1542,6 @@ static int ext4_ordered_writepage(struct page *page,
1566 int ret = 0; 1542 int ret = 0;
1567 int err; 1543 int err;
1568 1544
1569 J_ASSERT(PageLocked(page));
1570
1571 /*
1572 * We give up here if we're reentered, because it might be for a
1573 * different filesystem.
1574 */
1575 if (ext4_journal_current_handle())
1576 goto out_fail;
1577
1578 handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode));
1579
1580 if (IS_ERR(handle)) {
1581 ret = PTR_ERR(handle);
1582 goto out_fail;
1583 }
1584
1585 if (!page_has_buffers(page)) { 1545 if (!page_has_buffers(page)) {
1586 create_empty_buffers(page, inode->i_sb->s_blocksize, 1546 create_empty_buffers(page, inode->i_sb->s_blocksize,
1587 (1 << BH_Dirty)|(1 << BH_Uptodate)); 1547 (1 << BH_Dirty)|(1 << BH_Uptodate));
@@ -1605,54 +1565,135 @@ static int ext4_ordered_writepage(struct page *page,
1605 * and generally junk. 1565 * and generally junk.
1606 */ 1566 */
1607 if (ret == 0) { 1567 if (ret == 0) {
1608 err = walk_page_buffers(handle, page_bufs, 0, PAGE_CACHE_SIZE, 1568 handle = ext4_journal_start(inode,
1569 ext4_writepage_trans_blocks(inode));
1570 if (IS_ERR(handle)) {
1571 ret = PTR_ERR(handle);
1572 goto out_put;
1573 }
1574
1575 ret = walk_page_buffers(handle, page_bufs, 0, PAGE_CACHE_SIZE,
1609 NULL, jbd2_journal_dirty_data_fn); 1576 NULL, jbd2_journal_dirty_data_fn);
1577 err = ext4_journal_stop(handle);
1610 if (!ret) 1578 if (!ret)
1611 ret = err; 1579 ret = err;
1612 } 1580 }
1613 walk_page_buffers(handle, page_bufs, 0, 1581out_put:
1614 PAGE_CACHE_SIZE, NULL, bput_one); 1582 walk_page_buffers(handle, page_bufs, 0, PAGE_CACHE_SIZE, NULL,
1615 err = ext4_journal_stop(handle); 1583 bput_one);
1616 if (!ret)
1617 ret = err;
1618 return ret; 1584 return ret;
1585}
1586
1587static int ext4_ordered_writepage(struct page *page,
1588 struct writeback_control *wbc)
1589{
1590 struct inode *inode = page->mapping->host;
1591 loff_t size = i_size_read(inode);
1592 loff_t len;
1593
1594 J_ASSERT(PageLocked(page));
1595 J_ASSERT(page_has_buffers(page));
1596 if (page->index == size >> PAGE_CACHE_SHIFT)
1597 len = size & ~PAGE_CACHE_MASK;
1598 else
1599 len = PAGE_CACHE_SIZE;
1600 BUG_ON(walk_page_buffers(NULL, page_buffers(page), 0, len, NULL,
1601 ext4_bh_unmapped_or_delay));
1602
1603 /*
1604 * We give up here if we're reentered, because it might be for a
1605 * different filesystem.
1606 */
1607 if (!ext4_journal_current_handle())
1608 return __ext4_ordered_writepage(page, wbc);
1619 1609
1620out_fail:
1621 redirty_page_for_writepage(wbc, page); 1610 redirty_page_for_writepage(wbc, page);
1622 unlock_page(page); 1611 unlock_page(page);
1623 return ret; 1612 return 0;
1624} 1613}
1625 1614
1615static int __ext4_writeback_writepage(struct page *page,
1616 struct writeback_control *wbc)
1617{
1618 struct inode *inode = page->mapping->host;
1619
1620 if (test_opt(inode->i_sb, NOBH))
1621 return nobh_writepage(page, ext4_get_block, wbc);
1622 else
1623 return block_write_full_page(page, ext4_get_block, wbc);
1624}
1625
1626
1626static int ext4_writeback_writepage(struct page *page, 1627static int ext4_writeback_writepage(struct page *page,
1627 struct writeback_control *wbc) 1628 struct writeback_control *wbc)
1628{ 1629{
1629 struct inode *inode = page->mapping->host; 1630 struct inode *inode = page->mapping->host;
1631 loff_t size = i_size_read(inode);
1632 loff_t len;
1633
1634 J_ASSERT(PageLocked(page));
1635 J_ASSERT(page_has_buffers(page));
1636 if (page->index == size >> PAGE_CACHE_SHIFT)
1637 len = size & ~PAGE_CACHE_MASK;
1638 else
1639 len = PAGE_CACHE_SIZE;
1640 BUG_ON(walk_page_buffers(NULL, page_buffers(page), 0, len, NULL,
1641 ext4_bh_unmapped_or_delay));
1642
1643 if (!ext4_journal_current_handle())
1644 return __ext4_writeback_writepage(page, wbc);
1645
1646 redirty_page_for_writepage(wbc, page);
1647 unlock_page(page);
1648 return 0;
1649}
1650
1651static int __ext4_journalled_writepage(struct page *page,
1652 struct writeback_control *wbc)
1653{
1654 struct address_space *mapping = page->mapping;
1655 struct inode *inode = mapping->host;
1656 struct buffer_head *page_bufs;
1630 handle_t *handle = NULL; 1657 handle_t *handle = NULL;
1631 int ret = 0; 1658 int ret = 0;
1632 int err; 1659 int err;
1633 1660
1634 if (ext4_journal_current_handle()) 1661 ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE, ext4_get_block);
1635 goto out_fail; 1662 if (ret != 0)
1663 goto out_unlock;
1664
1665 page_bufs = page_buffers(page);
1666 walk_page_buffers(handle, page_bufs, 0, PAGE_CACHE_SIZE, NULL,
1667 bget_one);
1668 /* As soon as we unlock the page, it can go away, but we have
1669 * references to buffers so we are safe */
1670 unlock_page(page);
1636 1671
1637 handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode)); 1672 handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode));
1638 if (IS_ERR(handle)) { 1673 if (IS_ERR(handle)) {
1639 ret = PTR_ERR(handle); 1674 ret = PTR_ERR(handle);
1640 goto out_fail; 1675 goto out;
1641 } 1676 }
1642 1677
1643 if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) 1678 ret = walk_page_buffers(handle, page_bufs, 0,
1644 ret = nobh_writepage(page, ext4_get_block, wbc); 1679 PAGE_CACHE_SIZE, NULL, do_journal_get_write_access);
1645 else
1646 ret = block_write_full_page(page, ext4_get_block, wbc);
1647 1680
1681 err = walk_page_buffers(handle, page_bufs, 0,
1682 PAGE_CACHE_SIZE, NULL, write_end_fn);
1683 if (ret == 0)
1684 ret = err;
1648 err = ext4_journal_stop(handle); 1685 err = ext4_journal_stop(handle);
1649 if (!ret) 1686 if (!ret)
1650 ret = err; 1687 ret = err;
1651 return ret;
1652 1688
1653out_fail: 1689 walk_page_buffers(handle, page_bufs, 0,
1654 redirty_page_for_writepage(wbc, page); 1690 PAGE_CACHE_SIZE, NULL, bput_one);
1691 EXT4_I(inode)->i_state |= EXT4_STATE_JDATA;
1692 goto out;
1693
1694out_unlock:
1655 unlock_page(page); 1695 unlock_page(page);
1696out:
1656 return ret; 1697 return ret;
1657} 1698}
1658 1699
@@ -1660,59 +1701,40 @@ static int ext4_journalled_writepage(struct page *page,
1660 struct writeback_control *wbc) 1701 struct writeback_control *wbc)
1661{ 1702{
1662 struct inode *inode = page->mapping->host; 1703 struct inode *inode = page->mapping->host;
1663 handle_t *handle = NULL; 1704 loff_t size = i_size_read(inode);
1664 int ret = 0; 1705 loff_t len;
1665 int err;
1666 1706
1667 if (ext4_journal_current_handle()) 1707 J_ASSERT(PageLocked(page));
1668 goto no_write; 1708 J_ASSERT(page_has_buffers(page));
1709 if (page->index == size >> PAGE_CACHE_SHIFT)
1710 len = size & ~PAGE_CACHE_MASK;
1711 else
1712 len = PAGE_CACHE_SIZE;
1713 BUG_ON(walk_page_buffers(NULL, page_buffers(page), 0, len, NULL,
1714 ext4_bh_unmapped_or_delay));
1669 1715
1670 handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode)); 1716 if (ext4_journal_current_handle())
1671 if (IS_ERR(handle)) {
1672 ret = PTR_ERR(handle);
1673 goto no_write; 1717 goto no_write;
1674 }
1675 1718
1676 if (!page_has_buffers(page) || PageChecked(page)) { 1719 if (PageChecked(page)) {
1677 /* 1720 /*
1678 * It's mmapped pagecache. Add buffers and journal it. There 1721 * It's mmapped pagecache. Add buffers and journal it. There
1679 * doesn't seem much point in redirtying the page here. 1722 * doesn't seem much point in redirtying the page here.
1680 */ 1723 */
1681 ClearPageChecked(page); 1724 ClearPageChecked(page);
1682 ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE, 1725 return __ext4_journalled_writepage(page, wbc);
1683 ext4_get_block);
1684 if (ret != 0) {
1685 ext4_journal_stop(handle);
1686 goto out_unlock;
1687 }
1688 ret = walk_page_buffers(handle, page_buffers(page), 0,
1689 PAGE_CACHE_SIZE, NULL, do_journal_get_write_access);
1690
1691 err = walk_page_buffers(handle, page_buffers(page), 0,
1692 PAGE_CACHE_SIZE, NULL, write_end_fn);
1693 if (ret == 0)
1694 ret = err;
1695 EXT4_I(inode)->i_state |= EXT4_STATE_JDATA;
1696 unlock_page(page);
1697 } else { 1726 } else {
1698 /* 1727 /*
1699 * It may be a page full of checkpoint-mode buffers. We don't 1728 * It may be a page full of checkpoint-mode buffers. We don't
1700 * really know unless we go poke around in the buffer_heads. 1729 * really know unless we go poke around in the buffer_heads.
1701 * But block_write_full_page will do the right thing. 1730 * But block_write_full_page will do the right thing.
1702 */ 1731 */
1703 ret = block_write_full_page(page, ext4_get_block, wbc); 1732 return block_write_full_page(page, ext4_get_block, wbc);
1704 } 1733 }
1705 err = ext4_journal_stop(handle);
1706 if (!ret)
1707 ret = err;
1708out:
1709 return ret;
1710
1711no_write: 1734no_write:
1712 redirty_page_for_writepage(wbc, page); 1735 redirty_page_for_writepage(wbc, page);
1713out_unlock:
1714 unlock_page(page); 1736 unlock_page(page);
1715 goto out; 1737 return 0;
1716} 1738}
1717 1739
1718static int ext4_readpage(struct file *file, struct page *page) 1740static int ext4_readpage(struct file *file, struct page *page)
@@ -1909,7 +1931,7 @@ void ext4_set_aops(struct inode *inode)
1909 * This required during truncate. We need to physically zero the tail end 1931 * This required during truncate. We need to physically zero the tail end
1910 * of that block so it doesn't yield old data if the file is later grown. 1932 * of that block so it doesn't yield old data if the file is later grown.
1911 */ 1933 */
1912int ext4_block_truncate_page(handle_t *handle, struct page *page, 1934int ext4_block_truncate_page(handle_t *handle,
1913 struct address_space *mapping, loff_t from) 1935 struct address_space *mapping, loff_t from)
1914{ 1936{
1915 ext4_fsblk_t index = from >> PAGE_CACHE_SHIFT; 1937 ext4_fsblk_t index = from >> PAGE_CACHE_SHIFT;
@@ -1918,8 +1940,13 @@ int ext4_block_truncate_page(handle_t *handle, struct page *page,
1918 ext4_lblk_t iblock; 1940 ext4_lblk_t iblock;
1919 struct inode *inode = mapping->host; 1941 struct inode *inode = mapping->host;
1920 struct buffer_head *bh; 1942 struct buffer_head *bh;
1943 struct page *page;
1921 int err = 0; 1944 int err = 0;
1922 1945
1946 page = grab_cache_page(mapping, from >> PAGE_CACHE_SHIFT);
1947 if (!page)
1948 return -EINVAL;
1949
1923 blocksize = inode->i_sb->s_blocksize; 1950 blocksize = inode->i_sb->s_blocksize;
1924 length = blocksize - (offset & (blocksize - 1)); 1951 length = blocksize - (offset & (blocksize - 1));
1925 iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits); 1952 iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
@@ -2410,46 +2437,25 @@ void ext4_truncate(struct inode *inode)
2410 int n; 2437 int n;
2411 ext4_lblk_t last_block; 2438 ext4_lblk_t last_block;
2412 unsigned blocksize = inode->i_sb->s_blocksize; 2439 unsigned blocksize = inode->i_sb->s_blocksize;
2413 struct page *page;
2414 2440
2415 if (!ext4_can_truncate(inode)) 2441 if (!ext4_can_truncate(inode))
2416 return; 2442 return;
2417 2443
2418 /*
2419 * We have to lock the EOF page here, because lock_page() nests
2420 * outside jbd2_journal_start().
2421 */
2422 if ((inode->i_size & (blocksize - 1)) == 0) {
2423 /* Block boundary? Nothing to do */
2424 page = NULL;
2425 } else {
2426 page = grab_cache_page(mapping,
2427 inode->i_size >> PAGE_CACHE_SHIFT);
2428 if (!page)
2429 return;
2430 }
2431
2432 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) { 2444 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) {
2433 ext4_ext_truncate(inode, page); 2445 ext4_ext_truncate(inode);
2434 return; 2446 return;
2435 } 2447 }
2436 2448
2437 handle = start_transaction(inode); 2449 handle = start_transaction(inode);
2438 if (IS_ERR(handle)) { 2450 if (IS_ERR(handle))
2439 if (page) {
2440 clear_highpage(page);
2441 flush_dcache_page(page);
2442 unlock_page(page);
2443 page_cache_release(page);
2444 }
2445 return; /* AKPM: return what? */ 2451 return; /* AKPM: return what? */
2446 }
2447 2452
2448 last_block = (inode->i_size + blocksize-1) 2453 last_block = (inode->i_size + blocksize-1)
2449 >> EXT4_BLOCK_SIZE_BITS(inode->i_sb); 2454 >> EXT4_BLOCK_SIZE_BITS(inode->i_sb);
2450 2455
2451 if (page) 2456 if (inode->i_size & (blocksize - 1))
2452 ext4_block_truncate_page(handle, page, mapping, inode->i_size); 2457 if (ext4_block_truncate_page(handle, mapping, inode->i_size))
2458 goto out_stop;
2453 2459
2454 n = ext4_block_to_path(inode, last_block, offsets, NULL); 2460 n = ext4_block_to_path(inode, last_block, offsets, NULL);
2455 if (n == 0) 2461 if (n == 0)