Commit e8b43fe0 authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by Bob Peterson

gfs2: Clean up {lookup,fillup}_metapath

Split out the entire lookup loop from lookup_metapath and
fillup_metapath.  Make both functions return the actual height in
mp->mp_aheight, and return 0 on success.  Handle lookup errors properly
in trunc_dealloc.
Signed-off-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: default avatarBob Peterson <rpeterso@redhat.com>
parent e7fdf004
...@@ -305,21 +305,22 @@ static void gfs2_metapath_ra(struct gfs2_glock *gl, ...@@ -305,21 +305,22 @@ static void gfs2_metapath_ra(struct gfs2_glock *gl,
} }
} }
/** static int __fillup_metapath(struct gfs2_inode *ip, struct metapath *mp,
* lookup_mp_height - helper function for lookup_metapath unsigned int x, unsigned int h)
* @ip: the inode
* @mp: the metapath
* @h: the height which needs looking up
*/
static int lookup_mp_height(struct gfs2_inode *ip, struct metapath *mp, int h)
{ {
__be64 *ptr = metapointer(h, mp); for (; x < h; x++) {
__be64 *ptr = metapointer(x, mp);
u64 dblock = be64_to_cpu(*ptr); u64 dblock = be64_to_cpu(*ptr);
int ret;
if (!dblock) if (!dblock)
return h + 1; break;
ret = gfs2_meta_indirect_buffer(ip, x + 1, dblock, &mp->mp_bh[x + 1]);
return gfs2_meta_indirect_buffer(ip, h + 1, dblock, &mp->mp_bh[h + 1]); if (ret)
return ret;
}
mp->mp_aheight = x + 1;
return 0;
} }
/** /**
...@@ -336,25 +337,12 @@ static int lookup_mp_height(struct gfs2_inode *ip, struct metapath *mp, int h) ...@@ -336,25 +337,12 @@ static int lookup_mp_height(struct gfs2_inode *ip, struct metapath *mp, int h)
* at which it found the unallocated block. Blocks which are found are * at which it found the unallocated block. Blocks which are found are
* added to the mp->mp_bh[] list. * added to the mp->mp_bh[] list.
* *
* Returns: error or height of metadata tree * Returns: error
*/ */
static int lookup_metapath(struct gfs2_inode *ip, struct metapath *mp) static int lookup_metapath(struct gfs2_inode *ip, struct metapath *mp)
{ {
unsigned int end_of_metadata = ip->i_height - 1; return __fillup_metapath(ip, mp, 0, ip->i_height - 1);
unsigned int x;
int ret;
for (x = 0; x < end_of_metadata; x++) {
ret = lookup_mp_height(ip, mp, x);
if (ret)
goto out;
}
ret = ip->i_height;
out:
mp->mp_aheight = ret;
return ret;
} }
/** /**
...@@ -365,25 +353,21 @@ static int lookup_metapath(struct gfs2_inode *ip, struct metapath *mp) ...@@ -365,25 +353,21 @@ static int lookup_metapath(struct gfs2_inode *ip, struct metapath *mp)
* *
* Similar to lookup_metapath, but does lookups for a range of heights * Similar to lookup_metapath, but does lookups for a range of heights
* *
* Returns: error or height of metadata tree * Returns: error
*/ */
static int fillup_metapath(struct gfs2_inode *ip, struct metapath *mp, int h) static int fillup_metapath(struct gfs2_inode *ip, struct metapath *mp, int h)
{ {
unsigned int start_h = h - 1; unsigned int x = 0;
int ret;
if (h) { if (h) {
/* find the first buffer we need to look up. */ /* find the first buffer we need to look up. */
while (start_h > 0 && mp->mp_bh[start_h] == NULL) for (x = h - 1; x > 0; x--) {
start_h--; if (mp->mp_bh[x])
for (; start_h < h; start_h++) { break;
ret = lookup_mp_height(ip, mp, start_h);
if (ret)
return ret;
} }
} }
return ip->i_height; return __fillup_metapath(ip, mp, x, h);
} }
static inline void release_metapath(struct metapath *mp) static inline void release_metapath(struct metapath *mp)
...@@ -788,7 +772,7 @@ int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length, ...@@ -788,7 +772,7 @@ int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
goto do_alloc; goto do_alloc;
ret = lookup_metapath(ip, &mp); ret = lookup_metapath(ip, &mp);
if (ret < 0) if (ret)
goto out_release; goto out_release;
if (mp.mp_aheight != ip->i_height) if (mp.mp_aheight != ip->i_height)
...@@ -1345,7 +1329,9 @@ static int trunc_dealloc(struct gfs2_inode *ip, u64 newsize) ...@@ -1345,7 +1329,9 @@ static int trunc_dealloc(struct gfs2_inode *ip, u64 newsize)
mp.mp_bh[0] = dibh; mp.mp_bh[0] = dibh;
ret = lookup_metapath(ip, &mp); ret = lookup_metapath(ip, &mp);
if (ret == ip->i_height) if (ret)
goto out_metapath;
if (mp.mp_aheight == ip->i_height)
state = DEALLOC_MP_FULL; /* We have a complete metapath */ state = DEALLOC_MP_FULL; /* We have a complete metapath */
else else
state = DEALLOC_FILL_MP; /* deal with partial metapath */ state = DEALLOC_FILL_MP; /* deal with partial metapath */
...@@ -1441,16 +1427,16 @@ static int trunc_dealloc(struct gfs2_inode *ip, u64 newsize) ...@@ -1441,16 +1427,16 @@ static int trunc_dealloc(struct gfs2_inode *ip, u64 newsize)
case DEALLOC_FILL_MP: case DEALLOC_FILL_MP:
/* Fill the buffers out to the current height. */ /* Fill the buffers out to the current height. */
ret = fillup_metapath(ip, &mp, mp_h); ret = fillup_metapath(ip, &mp, mp_h);
if (ret < 0) if (ret)
goto out; goto out;
/* If buffers found for the entire strip height */ /* If buffers found for the entire strip height */
if ((ret == ip->i_height) && (mp_h == strip_h)) { if (mp.mp_aheight - 1 == strip_h) {
state = DEALLOC_MP_FULL; state = DEALLOC_MP_FULL;
break; break;
} }
if (ret < ip->i_height) /* We have a partial height */ if (mp.mp_aheight < ip->i_height) /* We have a partial height */
mp_h = ret - 1; mp_h = mp.mp_aheight - 1;
/* If we find a non-null block pointer, crawl a bit /* If we find a non-null block pointer, crawl a bit
higher up in the metapath and try again, otherwise higher up in the metapath and try again, otherwise
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment