aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/aops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/aops.c')
-rw-r--r--fs/ocfs2/aops.c59
1 files changed, 58 insertions, 1 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index f1e962cb3b73..d55a10e2f300 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1627,6 +1627,43 @@ static int ocfs2_zero_tail(struct inode *inode, struct buffer_head *di_bh,
1627 return ret; 1627 return ret;
1628} 1628}
1629 1629
1630/*
1631 * Try to flush truncate logs if we can free enough clusters from it.
1632 * As for return value, "< 0" means error, "0" no space and "1" means
1633 * we have freed enough spaces and let the caller try to allocate again.
1634 */
1635static int ocfs2_try_to_free_truncate_log(struct ocfs2_super *osb,
1636 unsigned int needed)
1637{
1638 tid_t target;
1639 int ret = 0;
1640 unsigned int truncated_clusters;
1641
1642 mutex_lock(&osb->osb_tl_inode->i_mutex);
1643 truncated_clusters = osb->truncated_clusters;
1644 mutex_unlock(&osb->osb_tl_inode->i_mutex);
1645
1646 /*
1647 * Check whether we can succeed in allocating if we free
1648 * the truncate log.
1649 */
1650 if (truncated_clusters < needed)
1651 goto out;
1652
1653 ret = ocfs2_flush_truncate_log(osb);
1654 if (ret) {
1655 mlog_errno(ret);
1656 goto out;
1657 }
1658
1659 if (jbd2_journal_start_commit(osb->journal->j_journal, &target)) {
1660 jbd2_log_wait_commit(osb->journal->j_journal, target);
1661 ret = 1;
1662 }
1663out:
1664 return ret;
1665}
1666
1630int ocfs2_write_begin_nolock(struct file *filp, 1667int ocfs2_write_begin_nolock(struct file *filp,
1631 struct address_space *mapping, 1668 struct address_space *mapping,
1632 loff_t pos, unsigned len, unsigned flags, 1669 loff_t pos, unsigned len, unsigned flags,
@@ -1634,7 +1671,7 @@ int ocfs2_write_begin_nolock(struct file *filp,
1634 struct buffer_head *di_bh, struct page *mmap_page) 1671 struct buffer_head *di_bh, struct page *mmap_page)
1635{ 1672{
1636 int ret, cluster_of_pages, credits = OCFS2_INODE_UPDATE_CREDITS; 1673 int ret, cluster_of_pages, credits = OCFS2_INODE_UPDATE_CREDITS;
1637 unsigned int clusters_to_alloc, extents_to_split; 1674 unsigned int clusters_to_alloc, extents_to_split, clusters_need = 0;
1638 struct ocfs2_write_ctxt *wc; 1675 struct ocfs2_write_ctxt *wc;
1639 struct inode *inode = mapping->host; 1676 struct inode *inode = mapping->host;
1640 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 1677 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
@@ -1643,7 +1680,9 @@ int ocfs2_write_begin_nolock(struct file *filp,
1643 struct ocfs2_alloc_context *meta_ac = NULL; 1680 struct ocfs2_alloc_context *meta_ac = NULL;
1644 handle_t *handle; 1681 handle_t *handle;
1645 struct ocfs2_extent_tree et; 1682 struct ocfs2_extent_tree et;
1683 int try_free = 1, ret1;
1646 1684
1685try_again:
1647 ret = ocfs2_alloc_write_ctxt(&wc, osb, pos, len, di_bh); 1686 ret = ocfs2_alloc_write_ctxt(&wc, osb, pos, len, di_bh);
1648 if (ret) { 1687 if (ret) {
1649 mlog_errno(ret); 1688 mlog_errno(ret);
@@ -1678,6 +1717,7 @@ int ocfs2_write_begin_nolock(struct file *filp,
1678 mlog_errno(ret); 1717 mlog_errno(ret);
1679 goto out; 1718 goto out;
1680 } else if (ret == 1) { 1719 } else if (ret == 1) {
1720 clusters_need = wc->w_clen;
1681 ret = ocfs2_refcount_cow(inode, filp, di_bh, 1721 ret = ocfs2_refcount_cow(inode, filp, di_bh,
1682 wc->w_cpos, wc->w_clen, UINT_MAX); 1722 wc->w_cpos, wc->w_clen, UINT_MAX);
1683 if (ret) { 1723 if (ret) {
@@ -1692,6 +1732,7 @@ int ocfs2_write_begin_nolock(struct file *filp,
1692 mlog_errno(ret); 1732 mlog_errno(ret);
1693 goto out; 1733 goto out;
1694 } 1734 }
1735 clusters_need += clusters_to_alloc;
1695 1736
1696 di = (struct ocfs2_dinode *)wc->w_di_bh->b_data; 1737 di = (struct ocfs2_dinode *)wc->w_di_bh->b_data;
1697 1738
@@ -1814,6 +1855,22 @@ out:
1814 ocfs2_free_alloc_context(data_ac); 1855 ocfs2_free_alloc_context(data_ac);
1815 if (meta_ac) 1856 if (meta_ac)
1816 ocfs2_free_alloc_context(meta_ac); 1857 ocfs2_free_alloc_context(meta_ac);
1858
1859 if (ret == -ENOSPC && try_free) {
1860 /*
1861 * Try to free some truncate log so that we can have enough
1862 * clusters to allocate.
1863 */
1864 try_free = 0;
1865
1866 ret1 = ocfs2_try_to_free_truncate_log(osb, clusters_need);
1867 if (ret1 == 1)
1868 goto try_again;
1869
1870 if (ret1 < 0)
1871 mlog_errno(ret1);
1872 }
1873
1817 return ret; 1874 return ret;
1818} 1875}
1819 1876