Commit 6c53267f authored by Robert Peterson's avatar Robert Peterson Committed by Steven Whitehouse

[GFS2] Kernel changes to support new gfs2_grow command (part 2)

To avoid code redundancy, I separated out the operational "guts" into
a new function called read_rindex_entry.  Then I made two functions:
the closer-to-original gfs2_ri_update (without the special condition
checks) and gfs2_ri_update_special that's designed with that condition
in mind.  (I don't like the name, but if you have a suggestion, I'm
all ears).

Oh, and there's an added benefit:  we don't need all the ugly gotos
anymore.  ;)

This patch has been tested with gfs2_fsck_hellfire (which runs for
three and a half hours, btw).
Signed-off-By: default avatarBob Peterson <rpeterso@redhat.com>
Signed-off-by: default avatarSteven Whitehouse <swhiteho@redhat.com>
parent 7ae8fa84
...@@ -469,7 +469,8 @@ static void adjust_fs_space(struct inode *inode) ...@@ -469,7 +469,8 @@ static void adjust_fs_space(struct inode *inode)
else else
new_free = 0; new_free = 0;
spin_unlock(&sdp->sd_statfs_spin); spin_unlock(&sdp->sd_statfs_spin);
fs_warn(sdp, "File system extended by %llu blocks.\n", new_free); fs_warn(sdp, "File system extended by %llu blocks.\n",
(unsigned long long)new_free);
gfs2_statfs_change(sdp, new_free, new_free, 0); gfs2_statfs_change(sdp, new_free, new_free, 0);
} }
......
...@@ -463,54 +463,35 @@ u64 gfs2_ri_total(struct gfs2_sbd *sdp) ...@@ -463,54 +463,35 @@ u64 gfs2_ri_total(struct gfs2_sbd *sdp)
} }
/** /**
* gfs2_ri_update - Pull in a new resource index from the disk * read_rindex_entry - Pull in a new resource index entry from the disk
* @gl: The glock covering the rindex inode * @gl: The glock covering the rindex inode
* *
* Returns: 0 on successful update, error code otherwise * Returns: 0 on success, error code otherwise
*/ */
static int gfs2_ri_update(struct gfs2_inode *ip) static int read_rindex_entry(struct gfs2_inode *ip,
struct file_ra_state *ra_state)
{ {
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct inode *inode = &ip->i_inode; loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex);
struct gfs2_rgrpd *rgd;
char buf[sizeof(struct gfs2_rindex)]; char buf[sizeof(struct gfs2_rindex)];
struct file_ra_state ra_state;
u64 junk = ip->i_di.di_size;
int error; int error;
struct gfs2_rgrpd *rgd;
/* If someone is holding the rindex file with a glock, they must error = gfs2_internal_read(ip, ra_state, buf, &pos,
be updating it, in which case we may have partial entries.
In this case, we ignore the partials. */
if (!gfs2_glock_is_held_excl(ip->i_gl) &&
!gfs2_glock_is_held_shrd(ip->i_gl) &&
do_div(junk, sizeof(struct gfs2_rindex))) {
gfs2_consist_inode(ip);
return -EIO;
}
clear_rgrpdi(sdp);
file_ra_state_init(&ra_state, inode->i_mapping);
for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) {
loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex);
if (pos + sizeof(struct gfs2_rindex) >= ip->i_di.di_size)
break;
error = gfs2_internal_read(ip, &ra_state, buf, &pos,
sizeof(struct gfs2_rindex)); sizeof(struct gfs2_rindex));
if (!error) if (!error)
break; return 0;
if (error != sizeof(struct gfs2_rindex)) { if (error != sizeof(struct gfs2_rindex)) {
if (error > 0) if (error > 0)
error = -EIO; error = -EIO;
goto fail; return error;
} }
rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS); rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS);
error = -ENOMEM; error = -ENOMEM;
if (!rgd) if (!rgd)
goto fail; return error;
mutex_init(&rgd->rd_mutex); mutex_init(&rgd->rd_mutex);
lops_init_le(&rgd->rd_le, &gfs2_rg_lops); lops_init_le(&rgd->rd_le, &gfs2_rg_lops);
...@@ -522,23 +503,85 @@ static int gfs2_ri_update(struct gfs2_inode *ip) ...@@ -522,23 +503,85 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
gfs2_rindex_in(&rgd->rd_ri, buf); gfs2_rindex_in(&rgd->rd_ri, buf);
error = compute_bitstructs(rgd); error = compute_bitstructs(rgd);
if (error) if (error)
goto fail; return error;
error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr, error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr,
&gfs2_rgrp_glops, CREATE, &rgd->rd_gl); &gfs2_rgrp_glops, CREATE, &rgd->rd_gl);
if (error) if (error)
goto fail; return error;
rgd->rd_gl->gl_object = rgd; rgd->rd_gl->gl_object = rgd;
rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1; rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1;
return error;
}
/**
* gfs2_ri_update - Pull in a new resource index from the disk
* @ip: pointer to the rindex inode
*
* Returns: 0 on successful update, error code otherwise
*/
static int gfs2_ri_update(struct gfs2_inode *ip)
{
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct inode *inode = &ip->i_inode;
struct file_ra_state ra_state;
u64 junk = ip->i_di.di_size;
int error;
if (do_div(junk, sizeof(struct gfs2_rindex))) {
gfs2_consist_inode(ip);
return -EIO;
}
clear_rgrpdi(sdp);
file_ra_state_init(&ra_state, inode->i_mapping);
for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) {
error = read_rindex_entry(ip, &ra_state);
if (error) {
clear_rgrpdi(sdp);
return error;
}
} }
sdp->sd_rindex_vn = ip->i_gl->gl_vn; sdp->sd_rindex_vn = ip->i_gl->gl_vn;
return 0; return 0;
}
fail: /**
* gfs2_ri_update_special - Pull in a new resource index from the disk
*
* This is a special version that's safe to call from gfs2_inplace_reserve_i.
* In this case we know that we don't have any resource groups in memory yet.
*
* @ip: pointer to the rindex inode
*
* Returns: 0 on successful update, error code otherwise
*/
static int gfs2_ri_update_special(struct gfs2_inode *ip)
{
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct inode *inode = &ip->i_inode;
struct file_ra_state ra_state;
int error;
file_ra_state_init(&ra_state, inode->i_mapping);
for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) {
/* Ignore partials */
if ((sdp->sd_rgrps + 1) * sizeof(struct gfs2_rindex) >
ip->i_di.di_size)
break;
error = read_rindex_entry(ip, &ra_state);
if (error) {
clear_rgrpdi(sdp); clear_rgrpdi(sdp);
return error; return error;
}
}
sdp->sd_rindex_vn = ip->i_gl->gl_vn;
return 0;
} }
/** /**
...@@ -1028,7 +1071,7 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line) ...@@ -1028,7 +1071,7 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
if (ip != GFS2_I(sdp->sd_rindex)) if (ip != GFS2_I(sdp->sd_rindex))
error = gfs2_rindex_hold(sdp, &al->al_ri_gh); error = gfs2_rindex_hold(sdp, &al->al_ri_gh);
else if (!sdp->sd_rgrps) /* We may not have the rindex read in, so: */ else if (!sdp->sd_rgrps) /* We may not have the rindex read in, so: */
error = gfs2_ri_update(ip); error = gfs2_ri_update_special(ip);
if (error) if (error)
return error; return error;
......
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