Skip to contentSkip to conversation

GFS2: kernel changes to support new gfs2_grow command

PATCH New Robert Peterson 1 participant 1 message May 1, 2007 GFS2 file system

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 GFS2: kernel changes to support new gfs2_grow command

Hi All,

Attached is the long-awaited gfs2 kernel patch that allows gfs2_grow to function properly. Without the changes, gfs2_grow will seem to work, but the gfs2 kernel code won't update its file system size and free space. The df command would forever show the same values, and the new free space would only become available after an unmount and remount.

This version has been successfully run against the hours-long "gfs2_fsck_hellfire" test that does several gfs2_grow and gfs2_fsck while interjecting file system damage. It does this repeatedly under a variety Resource Group conditions. The previous version of this patch had several problems uncovered by the test.

Regards,

Bob Peterson
Red Hat Cluster Suite

--

 fs/gfs2/ops_file.c  |   43 ++++++++++++++++++++++++++-
 fs/gfs2/ops_file.h  |    5 ++-
 fs/gfs2/ops_super.c |    5 ++-
 fs/gfs2/rgrp.c      |   81 ++++++++++++++++++++++++++++++++++++++------------
 fs/gfs2/rgrp.h      |    3 +-
 5 files changed, 113 insertions(+), 24 deletions(-)
fs/gfs2/ops_file.c +42 -1
index b50180e..9e9da13 100644
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
+ * Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
  *
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
@@ -425,6 +425,45 @@ fail:
 }
 
 /**
+ * adjust_fs_space - Adjusts the free space available due to gfs2_grow
+ * @inode: the rindex inode
+ */
+static void adjust_fs_space(struct inode *inode)
+{
+	struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
+	struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
+	struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
+	__u64 fs_total, new_free, new_free_readable;
+	const char *stg_abbrev = " KMGTPEE";
+	int factor, error;
+
+	mutex_lock(&sdp->sd_rindex_mutex);
+	gfs2_ri_update(GFS2_I(inode), &fs_total);
+	mutex_unlock(&sdp->sd_rindex_mutex);
+	spin_lock(&sdp->sd_statfs_spin);
+	if (fs_total > (m_sc->sc_total + l_sc->sc_total))
+		new_free = fs_total - (m_sc->sc_total + l_sc->sc_total);
+	else
+		new_free = 0;
+	spin_unlock(&sdp->sd_statfs_spin);
+	new_free_readable = new_free * sdp->sd_sb.sb_bsize;
+	for (factor = 0; factor < 7; factor++)
+		if (new_free_readable > 1024)
+			new_free_readable /= 1024;
+		else
+			break;
+	printk(KERN_WARNING "GFS2: File system extended by %llu "
+	       "blocks (%llu%cB)\n", new_free, new_free_readable,
+	       stg_abbrev[factor]);
+	error = gfs2_trans_begin(sdp, 1, 0);
+	if (!error) {
+		gfs2_statfs_change(sdp, new_free, new_free, 0);
+		gfs2_trans_end(sdp);
+	} else
+		printk(KERN_WARNING "GFS2: error registering the new space.\n");
+}
+
+/**
  * gfs2_close - called to close a struct file
  * @inode: the inode the struct file belongs to
  * @file: the struct file being closed
@@ -437,6 +476,8 @@ static int gfs2_close(struct inode *inode, struct file *file)
 	struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
 	struct gfs2_file *fp;
 
+	if (inode == sdp->sd_rindex)
+		adjust_fs_space(inode);
 	fp = file->private_data;
 	file->private_data = NULL;
 
fs/gfs2/ops_file.h +4 -1
index 7e5d8ec..1973f0b 100644
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
+ * Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
  *
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
@@ -18,6 +18,9 @@ extern int gfs2_internal_read(struct gfs2_inode *ip,
 			      struct file_ra_state *ra_state,
 			      char *buf, loff_t *pos, unsigned size);
 extern void gfs2_set_inode_flags(struct inode *inode);
+extern int gfs2_ri_update(struct gfs2_inode *ip, __u64 *total_data);
+extern void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free,
+			       s64 dinodes);
 extern const struct file_operations gfs2_file_fops;
 extern const struct file_operations gfs2_dir_fops;
 
fs/gfs2/ops_super.c +4 -1
index 485ce3d..27f765a 100644
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
+ * Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
  *
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
@@ -222,6 +222,9 @@ static int gfs2_statfs(struct dentry *dentry, struct kstatfs *buf)
 	struct gfs2_statfs_change_host sc;
 	int error;
 
+	error = gfs2_check_rindex_version(sdp);
+	if (error)
+		return error;
 	if (gfs2_tune_get(sdp, gt_statfs_slow))
 		error = gfs2_statfs_slow(sdp, &sc);
 	else
fs/gfs2/rgrp.c +61 -20

151 lines not on this page · raw message

fs/gfs2/rgrp.h +2 -1
index b01e0cf..8850d8f 100644
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
+ * Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
  *
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
@@ -21,6 +21,7 @@ struct gfs2_rgrpd *gfs2_rgrpd_get_first(struct gfs2_sbd *sdp);
 struct gfs2_rgrpd *gfs2_rgrpd_get_next(struct gfs2_rgrpd *rgd);
 
 void gfs2_clear_rgrpd(struct gfs2_sbd *sdp);
+int gfs2_check_rindex_version(struct gfs2_sbd *sdp);
 int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh);
 
 int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd);