aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/extent_map.c
diff options
context:
space:
mode:
authorMark Fasheh <mark.fasheh@oracle.com>2007-03-09 19:26:50 -0500
committerMark Fasheh <mark.fasheh@oracle.com>2007-04-26 18:02:45 -0400
commit4f902c37727bbedbc0508a1477874c58ddcc9af8 (patch)
tree841b35387cfea5d2518c258c4de6ef868948369b /fs/ocfs2/extent_map.c
parent49cb8d2d496ce06869ccca2ab368ed6b0b5b979d (diff)
ocfs2: Fix extent lookup to return true size of holes
Initially, we had wired things to return a size '1' of holes. Cook up a small amount of code to find the next extent and calculate the number of clusters between the virtual offset and the next allocated extent. Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs/ocfs2/extent_map.c')
-rw-r--r--fs/ocfs2/extent_map.c107
1 files changed, 103 insertions, 4 deletions
diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c
index eef6c1887708..f35e04f27f32 100644
--- a/fs/ocfs2/extent_map.c
+++ b/fs/ocfs2/extent_map.c
@@ -39,6 +39,97 @@
39#include "buffer_head_io.h" 39#include "buffer_head_io.h"
40 40
41/* 41/*
42 * Return the 1st index within el which contains an extent start
43 * larger than v_cluster.
44 */
45static int ocfs2_search_for_hole_index(struct ocfs2_extent_list *el,
46 u32 v_cluster)
47{
48 int i;
49 struct ocfs2_extent_rec *rec;
50
51 for(i = 0; i < le16_to_cpu(el->l_next_free_rec); i++) {
52 rec = &el->l_recs[i];
53
54 if (v_cluster < le32_to_cpu(rec->e_cpos))
55 break;
56 }
57
58 return i;
59}
60
61/*
62 * Figure out the size of a hole which starts at v_cluster within the given
63 * extent list.
64 *
65 * If there is no more allocation past v_cluster, we return the maximum
66 * cluster size minus v_cluster.
67 *
68 * If we have in-inode extents, then el points to the dinode list and
69 * eb_bh is NULL. Otherwise, eb_bh should point to the extent block
70 * containing el.
71 */
72static int ocfs2_figure_hole_clusters(struct inode *inode,
73 struct ocfs2_extent_list *el,
74 struct buffer_head *eb_bh,
75 u32 v_cluster,
76 u32 *num_clusters)
77{
78 int ret, i;
79 struct buffer_head *next_eb_bh = NULL;
80 struct ocfs2_extent_block *eb, *next_eb;
81
82 i = ocfs2_search_for_hole_index(el, v_cluster);
83
84 if (i == le16_to_cpu(el->l_next_free_rec) && eb_bh) {
85 eb = (struct ocfs2_extent_block *)eb_bh->b_data;
86
87 /*
88 * Check the next leaf for any extents.
89 */
90
91 if (le64_to_cpu(eb->h_next_leaf_blk) == 0ULL)
92 goto no_more_extents;
93
94 ret = ocfs2_read_block(OCFS2_SB(inode->i_sb),
95 le64_to_cpu(eb->h_next_leaf_blk),
96 &next_eb_bh, OCFS2_BH_CACHED, inode);
97 if (ret) {
98 mlog_errno(ret);
99 goto out;
100 }
101 next_eb = (struct ocfs2_extent_block *)next_eb_bh->b_data;
102
103 if (!OCFS2_IS_VALID_EXTENT_BLOCK(next_eb)) {
104 ret = -EROFS;
105 OCFS2_RO_ON_INVALID_EXTENT_BLOCK(inode->i_sb, next_eb);
106 goto out;
107 }
108
109 el = &next_eb->h_list;
110
111 i = ocfs2_search_for_hole_index(el, v_cluster);
112 }
113
114no_more_extents:
115 if (i == le16_to_cpu(el->l_next_free_rec)) {
116 /*
117 * We're at the end of our existing allocation. Just
118 * return the maximum number of clusters we could
119 * possibly allocate.
120 */
121 *num_clusters = UINT_MAX - v_cluster;
122 } else {
123 *num_clusters = le32_to_cpu(el->l_recs[i].e_cpos) - v_cluster;
124 }
125
126 ret = 0;
127out:
128 brelse(next_eb_bh);
129 return ret;
130}
131
132/*
42 * Return the index of the extent record which contains cluster #v_cluster. 133 * Return the index of the extent record which contains cluster #v_cluster.
43 * -1 is returned if it was not found. 134 * -1 is returned if it was not found.
44 * 135 *
@@ -117,11 +208,19 @@ int ocfs2_get_clusters(struct inode *inode, u32 v_cluster,
117 if (i == -1) { 208 if (i == -1) {
118 /* 209 /*
119 * A hole was found. Return some canned values that 210 * A hole was found. Return some canned values that
120 * callers can key on. 211 * callers can key on. If asked for, num_clusters will
212 * be populated with the size of the hole.
121 */ 213 */
122 *p_cluster = 0; 214 *p_cluster = 0;
123 if (num_clusters) 215 if (num_clusters) {
124 *num_clusters = 1; 216 ret = ocfs2_figure_hole_clusters(inode, el, eb_bh,
217 v_cluster,
218 num_clusters);
219 if (ret) {
220 mlog_errno(ret);
221 goto out;
222 }
223 }
125 } else { 224 } else {
126 rec = &el->l_recs[i]; 225 rec = &el->l_recs[i];
127 226
@@ -162,7 +261,7 @@ out:
162 * all while the map is in the process of being updated. 261 * all while the map is in the process of being updated.
163 */ 262 */
164int ocfs2_extent_map_get_blocks(struct inode *inode, u64 v_blkno, u64 *p_blkno, 263int ocfs2_extent_map_get_blocks(struct inode *inode, u64 v_blkno, u64 *p_blkno,
165 int *ret_count, unsigned int *extent_flags) 264 u64 *ret_count, unsigned int *extent_flags)
166{ 265{
167 int ret; 266 int ret;
168 int bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1); 267 int bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1);