aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/suballoc.c
diff options
context:
space:
mode:
authorTao Ma <tao.ma@oracle.com>2008-08-18 05:38:44 -0400
committerMark Fasheh <mfasheh@suse.com>2008-10-13 16:57:58 -0400
commite7d4cb6bc19658646357eeff134645cd9bc3479f (patch)
tree4e24321e5c28fb90dffa1f396972fddb3c458e58 /fs/ocfs2/suballoc.c
parent811f933df1e55615fd0bb4818f31e3868a8e6e23 (diff)
ocfs2: Abstract ocfs2_extent_tree in b-tree operations.
In the old extent tree operation, we take the hypothesis that we are using the ocfs2_extent_list in ocfs2_dinode as the tree root. As xattr will also use ocfs2_extent_list to store large value for a xattr entry, we refactor the tree operation so that xattr can use it directly. The refactoring includes 4 steps: 1. Abstract set/get of last_eb_blk and update_clusters since they may be stored in different location for dinode and xattr. 2. Add a new structure named ocfs2_extent_tree to indicate the extent tree the operation will work on. 3. Remove all the use of fe_bh and di, use root_bh and root_el in extent tree instead. So now all the fe_bh is replaced with et->root_bh, el with root_el accordingly. 4. Make ocfs2_lock_allocators generic. Now it is limited to be only used in file extend allocation. But the whole function is useful when we want to store large EAs. Note: This patch doesn't touch ocfs2_commit_truncate() since it is not used for anything other than truncate inode data btrees. Signed-off-by: Tao Ma <tao.ma@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs/ocfs2/suballoc.c')
-rw-r--r--fs/ocfs2/suballoc.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index 2a817bca1ddb..b642c825fb7c 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -1894,3 +1894,85 @@ static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe)
1894 (unsigned long long)fe->id2.i_chain.cl_recs[i].c_blkno); 1894 (unsigned long long)fe->id2.i_chain.cl_recs[i].c_blkno);
1895 } 1895 }
1896} 1896}
1897
1898/*
1899 * For a given allocation, determine which allocators will need to be
1900 * accessed, and lock them, reserving the appropriate number of bits.
1901 *
1902 * Sparse file systems call this from ocfs2_write_begin_nolock()
1903 * and ocfs2_allocate_unwritten_extents().
1904 *
1905 * File systems which don't support holes call this from
1906 * ocfs2_extend_allocation().
1907 */
1908int ocfs2_lock_allocators(struct inode *inode, struct buffer_head *root_bh,
1909 struct ocfs2_extent_list *root_el,
1910 u32 clusters_to_add, u32 extents_to_split,
1911 struct ocfs2_alloc_context **data_ac,
1912 struct ocfs2_alloc_context **meta_ac)
1913{
1914 int ret = 0, num_free_extents;
1915 unsigned int max_recs_needed = clusters_to_add + 2 * extents_to_split;
1916 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1917
1918 *meta_ac = NULL;
1919 if (data_ac)
1920 *data_ac = NULL;
1921
1922 BUG_ON(clusters_to_add != 0 && data_ac == NULL);
1923
1924 num_free_extents = ocfs2_num_free_extents(osb, inode, root_bh,
1925 OCFS2_DINODE_EXTENT);
1926 if (num_free_extents < 0) {
1927 ret = num_free_extents;
1928 mlog_errno(ret);
1929 goto out;
1930 }
1931
1932 /*
1933 * Sparse allocation file systems need to be more conservative
1934 * with reserving room for expansion - the actual allocation
1935 * happens while we've got a journal handle open so re-taking
1936 * a cluster lock (because we ran out of room for another
1937 * extent) will violate ordering rules.
1938 *
1939 * Most of the time we'll only be seeing this 1 cluster at a time
1940 * anyway.
1941 *
1942 * Always lock for any unwritten extents - we might want to
1943 * add blocks during a split.
1944 */
1945 if (!num_free_extents ||
1946 (ocfs2_sparse_alloc(osb) && num_free_extents < max_recs_needed)) {
1947 ret = ocfs2_reserve_new_metadata(osb, root_el, meta_ac);
1948 if (ret < 0) {
1949 if (ret != -ENOSPC)
1950 mlog_errno(ret);
1951 goto out;
1952 }
1953 }
1954
1955 if (clusters_to_add == 0)
1956 goto out;
1957
1958 ret = ocfs2_reserve_clusters(osb, clusters_to_add, data_ac);
1959 if (ret < 0) {
1960 if (ret != -ENOSPC)
1961 mlog_errno(ret);
1962 goto out;
1963 }
1964
1965out:
1966 if (ret) {
1967 if (*meta_ac) {
1968 ocfs2_free_alloc_context(*meta_ac);
1969 *meta_ac = NULL;
1970 }
1971
1972 /*
1973 * We cannot have an error and a non null *data_ac.
1974 */
1975 }
1976
1977 return ret;
1978}