forked from Minki/linux
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: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: Bob Peterson <rpeterso@redhat.com>
This commit is contained in:
parent
e7fdf00406
commit
e8b43fe0c1
@ -305,21 +305,22 @@ static void gfs2_metapath_ra(struct gfs2_glock *gl,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* lookup_mp_height - helper function for lookup_metapath
|
||||
* @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)
|
||||
static int __fillup_metapath(struct gfs2_inode *ip, struct metapath *mp,
|
||||
unsigned int x, unsigned int h)
|
||||
{
|
||||
__be64 *ptr = metapointer(h, mp);
|
||||
u64 dblock = be64_to_cpu(*ptr);
|
||||
for (; x < h; x++) {
|
||||
__be64 *ptr = metapointer(x, mp);
|
||||
u64 dblock = be64_to_cpu(*ptr);
|
||||
int ret;
|
||||
|
||||
if (!dblock)
|
||||
return h + 1;
|
||||
|
||||
return gfs2_meta_indirect_buffer(ip, h + 1, dblock, &mp->mp_bh[h + 1]);
|
||||
if (!dblock)
|
||||
break;
|
||||
ret = gfs2_meta_indirect_buffer(ip, x + 1, dblock, &mp->mp_bh[x + 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)
|
||||
* at which it found the unallocated block. Blocks which are found are
|
||||
* 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)
|
||||
{
|
||||
unsigned int end_of_metadata = 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;
|
||||
return __fillup_metapath(ip, mp, 0, ip->i_height - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -365,25 +353,21 @@ out:
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
unsigned int start_h = h - 1;
|
||||
int ret;
|
||||
unsigned int x = 0;
|
||||
|
||||
if (h) {
|
||||
/* find the first buffer we need to look up. */
|
||||
while (start_h > 0 && mp->mp_bh[start_h] == NULL)
|
||||
start_h--;
|
||||
for (; start_h < h; start_h++) {
|
||||
ret = lookup_mp_height(ip, mp, start_h);
|
||||
if (ret)
|
||||
return ret;
|
||||
for (x = h - 1; x > 0; x--) {
|
||||
if (mp->mp_bh[x])
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ip->i_height;
|
||||
return __fillup_metapath(ip, mp, x, h);
|
||||
}
|
||||
|
||||
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,
|
||||
goto do_alloc;
|
||||
|
||||
ret = lookup_metapath(ip, &mp);
|
||||
if (ret < 0)
|
||||
if (ret)
|
||||
goto out_release;
|
||||
|
||||
if (mp.mp_aheight != ip->i_height)
|
||||
@ -1345,7 +1329,9 @@ static int trunc_dealloc(struct gfs2_inode *ip, u64 newsize)
|
||||
|
||||
mp.mp_bh[0] = dibh;
|
||||
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 */
|
||||
else
|
||||
state = DEALLOC_FILL_MP; /* deal with partial metapath */
|
||||
@ -1441,16 +1427,16 @@ static int trunc_dealloc(struct gfs2_inode *ip, u64 newsize)
|
||||
case DEALLOC_FILL_MP:
|
||||
/* Fill the buffers out to the current height. */
|
||||
ret = fillup_metapath(ip, &mp, mp_h);
|
||||
if (ret < 0)
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* 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;
|
||||
break;
|
||||
}
|
||||
if (ret < ip->i_height) /* We have a partial height */
|
||||
mp_h = ret - 1;
|
||||
if (mp.mp_aheight < ip->i_height) /* We have a partial height */
|
||||
mp_h = mp.mp_aheight - 1;
|
||||
|
||||
/* If we find a non-null block pointer, crawl a bit
|
||||
higher up in the metapath and try again, otherwise
|
||||
|
Loading…
Reference in New Issue
Block a user