Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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);
}

+91 −48
Original line number Diff line number Diff line
@@ -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
 *
 * 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 inode *inode = &ip->i_inode;
	struct gfs2_rgrpd *rgd;
	loff_t pos = sdp->sd_rgrps * 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;
	struct gfs2_rgrpd *rgd;

	/* 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))) {
		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,
	error = gfs2_internal_read(ip, ra_state, buf, &pos,
				   sizeof(struct gfs2_rindex));
	if (!error)
			break;
		return 0;
	if (error != sizeof(struct gfs2_rindex)) {
		if (error > 0)
			error = -EIO;
			goto fail;
		return error;
	}

	rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS);
	error = -ENOMEM;
	if (!rgd)
			goto fail;
		return error;

	mutex_init(&rgd->rd_mutex);
	lops_init_le(&rgd->rd_le, &gfs2_rg_lops);
@@ -522,24 +503,86 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
	gfs2_rindex_in(&rgd->rd_ri, buf);
	error = compute_bitstructs(rgd);
	if (error)
			goto fail;
		return error;

	error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr,
			       &gfs2_rgrp_glops, CREATE, &rgd->rd_gl);
	if (error)
			goto fail;
		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
 */

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;
	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);
			return error;
		}
	}

	sdp->sd_rindex_vn = ip->i_gl->gl_vn;
	return 0;
}

/**
 * gfs2_rindex_hold - Grab a lock on the rindex
@@ -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;