forked from Minki/linux
[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: Bob Peterson <rpeterso@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
This commit is contained in:
parent
7ae8fa8451
commit
6c53267f05
@ -469,7 +469,8 @@ static void adjust_fs_space(struct inode *inode)
|
||||
else
|
||||
new_free = 0;
|
||||
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);
|
||||
}
|
||||
|
||||
|
143
fs/gfs2/rgrp.c
143
fs/gfs2/rgrp.c
@ -463,9 +463,62 @@ 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
|
||||
*
|
||||
* Returns: 0 on success, error code otherwise
|
||||
*/
|
||||
|
||||
static int read_rindex_entry(struct gfs2_inode *ip,
|
||||
struct file_ra_state *ra_state)
|
||||
{
|
||||
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||
loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex);
|
||||
char buf[sizeof(struct gfs2_rindex)];
|
||||
int error;
|
||||
struct gfs2_rgrpd *rgd;
|
||||
|
||||
error = gfs2_internal_read(ip, ra_state, buf, &pos,
|
||||
sizeof(struct gfs2_rindex));
|
||||
if (!error)
|
||||
return 0;
|
||||
if (error != sizeof(struct gfs2_rindex)) {
|
||||
if (error > 0)
|
||||
error = -EIO;
|
||||
return error;
|
||||
}
|
||||
|
||||
rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS);
|
||||
error = -ENOMEM;
|
||||
if (!rgd)
|
||||
return error;
|
||||
|
||||
mutex_init(&rgd->rd_mutex);
|
||||
lops_init_le(&rgd->rd_le, &gfs2_rg_lops);
|
||||
rgd->rd_sbd = sdp;
|
||||
|
||||
list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list);
|
||||
list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list);
|
||||
|
||||
gfs2_rindex_in(&rgd->rd_ri, buf);
|
||||
error = compute_bitstructs(rgd);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr,
|
||||
&gfs2_rgrp_glops, CREATE, &rgd->rd_gl);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
rgd->rd_gl->gl_object = rgd;
|
||||
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
|
||||
*/
|
||||
|
||||
@ -473,18 +526,11 @@ 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 gfs2_rgrpd *rgd;
|
||||
char buf[sizeof(struct gfs2_rindex)];
|
||||
struct file_ra_state ra_state;
|
||||
u64 junk = ip->i_di.di_size;
|
||||
int error;
|
||||
|
||||
/* If someone is holding the rindex file with a glock, they must
|
||||
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))) {
|
||||
if (do_div(junk, sizeof(struct gfs2_rindex))) {
|
||||
gfs2_consist_inode(ip);
|
||||
return -EIO;
|
||||
}
|
||||
@ -493,52 +539,49 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
|
||||
|
||||
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));
|
||||
if (!error)
|
||||
break;
|
||||
if (error != sizeof(struct gfs2_rindex)) {
|
||||
if (error > 0)
|
||||
error = -EIO;
|
||||
goto fail;
|
||||
error = read_rindex_entry(ip, &ra_state);
|
||||
if (error) {
|
||||
clear_rgrpdi(sdp);
|
||||
return error;
|
||||
}
|
||||
|
||||
rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS);
|
||||
error = -ENOMEM;
|
||||
if (!rgd)
|
||||
goto fail;
|
||||
|
||||
mutex_init(&rgd->rd_mutex);
|
||||
lops_init_le(&rgd->rd_le, &gfs2_rg_lops);
|
||||
rgd->rd_sbd = sdp;
|
||||
|
||||
list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list);
|
||||
list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list);
|
||||
|
||||
gfs2_rindex_in(&rgd->rd_ri, buf);
|
||||
error = compute_bitstructs(rgd);
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr,
|
||||
&gfs2_rgrp_glops, CREATE, &rgd->rd_gl);
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
rgd->rd_gl->gl_object = rgd;
|
||||
rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1;
|
||||
}
|
||||
|
||||
sdp->sd_rindex_vn = ip->i_gl->gl_vn;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fail:
|
||||
clear_rgrpdi(sdp);
|
||||
return error;
|
||||
/**
|
||||
* 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);
|
||||
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)
|
||||
if (ip != GFS2_I(sdp->sd_rindex))
|
||||
error = gfs2_rindex_hold(sdp, &al->al_ri_gh);
|
||||
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)
|
||||
return error;
|
||||
|
Loading…
Reference in New Issue
Block a user