diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-11 14:28:34 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-11 14:28:34 -0500 |
commit | 498f7f505dc79934c878c7667840c50c64f232fc (patch) | |
tree | 67eca6dcb6fe76ec3d2bdef5e3102591fe957776 /fs/ocfs2/aops.c | |
parent | 0969d11e201b82d30a158ccdb3aca67a7b845613 (diff) | |
parent | d6351db2073315ddebac72cc1935e912f60f86e0 (diff) |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2: (22 commits)
MAINTAINERS: Update Joel Becker's email address
ocfs2: Remove unused truncate function from alloc.c
ocfs2/cluster: dereferencing before checking in nst_seq_show()
ocfs2: fix build for OCFS2_FS_STATS not enabled
ocfs2/cluster: Show o2net timing statistics
ocfs2/cluster: Track process message timing stats for each socket
ocfs2/cluster: Track send message timing stats for each socket
ocfs2/cluster: Use ktime instead of timeval in struct o2net_sock_container
ocfs2/cluster: Replace timeval with ktime in struct o2net_send_tracking
ocfs2: Add DEBUG_FS dependency
ocfs2/dlm: Hard code the values for enums
ocfs2/dlm: Minor cleanup
ocfs2/dlm: Cleanup dlmdebug.c
ocfs2: Release buffer_head in case of error in ocfs2_double_lock.
ocfs2/cluster: Pin the local node when o2hb thread starts
ocfs2/cluster: Show pin state for each o2hb region
ocfs2/cluster: Pin/unpin o2hb regions
ocfs2/cluster: Remove dropped region from o2hb quorum region bitmap
ocfs2/cluster: Pin the remote node item in configfs
ocfs2/dlm: make existing convertion precedent over new lock
...
Diffstat (limited to 'fs/ocfs2/aops.c')
-rw-r--r-- | fs/ocfs2/aops.c | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 0d7c5540ad66..1fbb0e20131b 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -1630,6 +1630,43 @@ static int ocfs2_zero_tail(struct inode *inode, struct buffer_head *di_bh, | |||
1630 | return ret; | 1630 | return ret; |
1631 | } | 1631 | } |
1632 | 1632 | ||
1633 | /* | ||
1634 | * Try to flush truncate logs if we can free enough clusters from it. | ||
1635 | * As for return value, "< 0" means error, "0" no space and "1" means | ||
1636 | * we have freed enough spaces and let the caller try to allocate again. | ||
1637 | */ | ||
1638 | static int ocfs2_try_to_free_truncate_log(struct ocfs2_super *osb, | ||
1639 | unsigned int needed) | ||
1640 | { | ||
1641 | tid_t target; | ||
1642 | int ret = 0; | ||
1643 | unsigned int truncated_clusters; | ||
1644 | |||
1645 | mutex_lock(&osb->osb_tl_inode->i_mutex); | ||
1646 | truncated_clusters = osb->truncated_clusters; | ||
1647 | mutex_unlock(&osb->osb_tl_inode->i_mutex); | ||
1648 | |||
1649 | /* | ||
1650 | * Check whether we can succeed in allocating if we free | ||
1651 | * the truncate log. | ||
1652 | */ | ||
1653 | if (truncated_clusters < needed) | ||
1654 | goto out; | ||
1655 | |||
1656 | ret = ocfs2_flush_truncate_log(osb); | ||
1657 | if (ret) { | ||
1658 | mlog_errno(ret); | ||
1659 | goto out; | ||
1660 | } | ||
1661 | |||
1662 | if (jbd2_journal_start_commit(osb->journal->j_journal, &target)) { | ||
1663 | jbd2_log_wait_commit(osb->journal->j_journal, target); | ||
1664 | ret = 1; | ||
1665 | } | ||
1666 | out: | ||
1667 | return ret; | ||
1668 | } | ||
1669 | |||
1633 | int ocfs2_write_begin_nolock(struct file *filp, | 1670 | int ocfs2_write_begin_nolock(struct file *filp, |
1634 | struct address_space *mapping, | 1671 | struct address_space *mapping, |
1635 | loff_t pos, unsigned len, unsigned flags, | 1672 | loff_t pos, unsigned len, unsigned flags, |
@@ -1637,7 +1674,7 @@ int ocfs2_write_begin_nolock(struct file *filp, | |||
1637 | struct buffer_head *di_bh, struct page *mmap_page) | 1674 | struct buffer_head *di_bh, struct page *mmap_page) |
1638 | { | 1675 | { |
1639 | int ret, cluster_of_pages, credits = OCFS2_INODE_UPDATE_CREDITS; | 1676 | int ret, cluster_of_pages, credits = OCFS2_INODE_UPDATE_CREDITS; |
1640 | unsigned int clusters_to_alloc, extents_to_split; | 1677 | unsigned int clusters_to_alloc, extents_to_split, clusters_need = 0; |
1641 | struct ocfs2_write_ctxt *wc; | 1678 | struct ocfs2_write_ctxt *wc; |
1642 | struct inode *inode = mapping->host; | 1679 | struct inode *inode = mapping->host; |
1643 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 1680 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
@@ -1646,7 +1683,9 @@ int ocfs2_write_begin_nolock(struct file *filp, | |||
1646 | struct ocfs2_alloc_context *meta_ac = NULL; | 1683 | struct ocfs2_alloc_context *meta_ac = NULL; |
1647 | handle_t *handle; | 1684 | handle_t *handle; |
1648 | struct ocfs2_extent_tree et; | 1685 | struct ocfs2_extent_tree et; |
1686 | int try_free = 1, ret1; | ||
1649 | 1687 | ||
1688 | try_again: | ||
1650 | ret = ocfs2_alloc_write_ctxt(&wc, osb, pos, len, di_bh); | 1689 | ret = ocfs2_alloc_write_ctxt(&wc, osb, pos, len, di_bh); |
1651 | if (ret) { | 1690 | if (ret) { |
1652 | mlog_errno(ret); | 1691 | mlog_errno(ret); |
@@ -1681,6 +1720,7 @@ int ocfs2_write_begin_nolock(struct file *filp, | |||
1681 | mlog_errno(ret); | 1720 | mlog_errno(ret); |
1682 | goto out; | 1721 | goto out; |
1683 | } else if (ret == 1) { | 1722 | } else if (ret == 1) { |
1723 | clusters_need = wc->w_clen; | ||
1684 | ret = ocfs2_refcount_cow(inode, filp, di_bh, | 1724 | ret = ocfs2_refcount_cow(inode, filp, di_bh, |
1685 | wc->w_cpos, wc->w_clen, UINT_MAX); | 1725 | wc->w_cpos, wc->w_clen, UINT_MAX); |
1686 | if (ret) { | 1726 | if (ret) { |
@@ -1695,6 +1735,7 @@ int ocfs2_write_begin_nolock(struct file *filp, | |||
1695 | mlog_errno(ret); | 1735 | mlog_errno(ret); |
1696 | goto out; | 1736 | goto out; |
1697 | } | 1737 | } |
1738 | clusters_need += clusters_to_alloc; | ||
1698 | 1739 | ||
1699 | di = (struct ocfs2_dinode *)wc->w_di_bh->b_data; | 1740 | di = (struct ocfs2_dinode *)wc->w_di_bh->b_data; |
1700 | 1741 | ||
@@ -1817,6 +1858,22 @@ out: | |||
1817 | ocfs2_free_alloc_context(data_ac); | 1858 | ocfs2_free_alloc_context(data_ac); |
1818 | if (meta_ac) | 1859 | if (meta_ac) |
1819 | ocfs2_free_alloc_context(meta_ac); | 1860 | ocfs2_free_alloc_context(meta_ac); |
1861 | |||
1862 | if (ret == -ENOSPC && try_free) { | ||
1863 | /* | ||
1864 | * Try to free some truncate log so that we can have enough | ||
1865 | * clusters to allocate. | ||
1866 | */ | ||
1867 | try_free = 0; | ||
1868 | |||
1869 | ret1 = ocfs2_try_to_free_truncate_log(osb, clusters_need); | ||
1870 | if (ret1 == 1) | ||
1871 | goto try_again; | ||
1872 | |||
1873 | if (ret1 < 0) | ||
1874 | mlog_errno(ret1); | ||
1875 | } | ||
1876 | |||
1820 | return ret; | 1877 | return ret; |
1821 | } | 1878 | } |
1822 | 1879 | ||