diff options
author | Tao Ma <tao.ma@oracle.com> | 2008-08-18 05:38:44 -0400 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2008-10-13 16:57:58 -0400 |
commit | e7d4cb6bc19658646357eeff134645cd9bc3479f (patch) | |
tree | 4e24321e5c28fb90dffa1f396972fddb3c458e58 /fs/ocfs2/suballoc.c | |
parent | 811f933df1e55615fd0bb4818f31e3868a8e6e23 (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.c | 82 |
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 | */ | ||
1908 | int 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 | |||
1965 | out: | ||
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 | } | ||