cluster-devel.redhat.com archive mirror
 help / color / mirror / Atom feed
From: swhiteho@redhat.com <swhiteho@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [PATCH] [GFS2] kernel changes to support new gfs2_grow command
Date: Mon,  9 Jul 2007 17:02:09 +0100	[thread overview]
Message-ID: <1183996996300-git-send-email-swhiteho@redhat.com> (raw)
In-Reply-To: <11839969911617-git-send-email-swhiteho@redhat.com>

From: Robert Peterson <rpeterso@redhat.com>

This is another revision of my gfs2 kernel patch that allows
gfs2_grow to function properly.

Steve Whitehouse expressed some concerns about the previous
patch and I restructured it based on his comments.
The previous patch was doing the statfs_change at file close time,
under its own transaction.  The current patch does the statfs_change
inside the gfs2_commit_write function, which keeps it under the
umbrella of the inode transaction.

I can't call ri_update to re-read the rindex file during the
transaction because the transaction may have outstanding unwritten
buffers attached to the rgrps that would be otherwise blown away.
So instead, I created a new function, gfs2_ri_total, that will
re-read the rindex file just to total the file system space
for the sake of the statfs_change.  The ri_update will happen
later, when gfs2 realizes the version number has changed, as it
happened before my patch.

Since the statfs_change is happening at write_commit time and there
may be multiple writes to the rindex file for one grow operation.
So one consequence of this restructuring is that instead of getting
one kernel message to indicate the change, you may see several.
For example, before when you did a gfs2_grow, you'd get a single
message like:

GFS2: File system extended by 247876 blocks (968MB)

Now you get something like:

GFS2: File system extended by 207896 blocks (812MB)
GFS2: File system extended by 39980 blocks (156MB)

This version has also 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.

Signed-off-By: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>

diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 30c1562..846c0ff 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -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
@@ -450,6 +450,30 @@ out_uninit:
 }
 
 /**
+ * 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;
+
+	/* Total up the file system space, according to the latest rindex. */
+	fs_total = gfs2_ri_total(sdp);
+
+	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);
+	fs_warn(sdp, "File system extended by %llu blocks.\n", new_free);
+	gfs2_statfs_change(sdp, new_free, new_free, 0);
+}
+
+/**
  * gfs2_commit_write - Commit write to a file
  * @file: The file to write to
  * @page: The page containing the data
@@ -511,6 +535,9 @@ static int gfs2_commit_write(struct file *file, struct page *page,
 		di->di_size = cpu_to_be64(inode->i_size);
 	}
 
+	if (inode == sdp->sd_rindex)
+		adjust_fs_space(inode);
+
 	brelse(dibh);
 	gfs2_trans_end(sdp);
 	if (al->al_requested) {
diff --git a/fs/gfs2/ops_address.h b/fs/gfs2/ops_address.h
index 35aaee4..56c30da 100644
--- a/fs/gfs2/ops_address.h
+++ b/fs/gfs2/ops_address.h
@@ -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,5 +18,8 @@ extern const struct address_space_operations gfs2_file_aops;
 extern int gfs2_get_block(struct inode *inode, sector_t lblock,
 			  struct buffer_head *bh_result, int create);
 extern int gfs2_releasepage(struct page *page, gfp_t gfp_mask);
+extern u64 gfs2_ri_total(struct gfs2_sbd *sdp);
+extern void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free,
+			       s64 dinodes);
 
 #endif /* __OPS_ADDRESS_DOT_H__ */
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 1727f50..e857f40 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -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
@@ -431,6 +431,38 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
 }
 
 /**
+ * gfs2_ri_total - Total up the file system space, according to the rindex.
+ *
+ */
+u64 gfs2_ri_total(struct gfs2_sbd *sdp)
+{
+	u64 total_data = 0;	
+	struct inode *inode = sdp->sd_rindex;
+	struct gfs2_inode *ip = GFS2_I(inode);
+	struct gfs2_rindex_host ri;
+	char buf[sizeof(struct gfs2_rindex)];
+	struct file_ra_state ra_state;
+	int error, rgrps;
+
+	mutex_lock(&sdp->sd_rindex_mutex);
+	file_ra_state_init(&ra_state, inode->i_mapping);
+	for (rgrps = 0;; rgrps++) {
+		loff_t pos = 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 != sizeof(struct gfs2_rindex))
+			break;
+		gfs2_rindex_in(&ri, buf);
+		total_data += ri.ri_data;
+	}
+	mutex_unlock(&sdp->sd_rindex_mutex);
+	return total_data;
+}
+
+/**
  * gfs2_ri_update - Pull in a new resource index from the disk
  * @gl: The glock covering the rindex inode
  *
@@ -447,7 +479,12 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
 	u64 junk = ip->i_di.di_size;
 	int error;
 
-	if (do_div(junk, sizeof(struct gfs2_rindex))) {
+	/* 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;
 	}
@@ -457,6 +494,9 @@ 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)
@@ -978,18 +1018,25 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
 {
 	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_alloc *al = &ip->i_alloc;
-	int error;
+	int error = 0;
 
 	if (gfs2_assert_warn(sdp, al->al_requested))
 		return -EINVAL;
 
-	error = gfs2_rindex_hold(sdp, &al->al_ri_gh);
+	/* We need to hold the rindex unless the inode we're using is
+	   the rindex itself, in which case it's already held. */
+	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);
+
 	if (error)
 		return error;
 
 	error = get_local_rgrp(ip);
 	if (error) {
-		gfs2_glock_dq_uninit(&al->al_ri_gh);
+		if (ip != GFS2_I(sdp->sd_rindex))
+			gfs2_glock_dq_uninit(&al->al_ri_gh);
 		return error;
 	}
 
@@ -1019,7 +1066,8 @@ void gfs2_inplace_release(struct gfs2_inode *ip)
 
 	al->al_rgd = NULL;
 	gfs2_glock_dq_uninit(&al->al_rgd_gh);
-	gfs2_glock_dq_uninit(&al->al_ri_gh);
+	if (ip != GFS2_I(sdp->sd_rindex))
+		gfs2_glock_dq_uninit(&al->al_ri_gh);
 }
 
 /**
-- 
1.5.1.2



  reply	other threads:[~2007-07-09 16:02 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-07-09 16:02 [Cluster-devel] [GFS2/DLM] Pre-pull Patch Posting swhiteho
2007-07-09 16:02 ` [Cluster-devel] [PATCH] [GFS2] flush the glock completely in inode_go_sync swhiteho
2007-07-09 16:02   ` [Cluster-devel] [PATCH] [DLM] fix a couple of races swhiteho
2007-07-09 16:02     ` swhiteho [this message]
2007-07-09 16:02       ` [Cluster-devel] [PATCH] [GFS2] Kernel changes to support new gfs2_grow command (part 2) swhiteho
2007-07-09 16:02         ` [Cluster-devel] [PATCH] [GFS2] use zero_user_page swhiteho
2007-07-09 16:02           ` [Cluster-devel] [PATCH] [GFS2] Addendum patch 2 for gfs2_grow swhiteho
2007-07-09 16:02             ` [Cluster-devel] [PATCH] [GFS2] Reduce size of struct gdlm_lock swhiteho
2007-07-09 16:02               ` [Cluster-devel] [PATCH] [GFS2] Clean up inode number handling swhiteho
2007-07-09 16:02                 ` [Cluster-devel] [PATCH] [GFS2] Quotas non-functional - fix bug swhiteho
2007-07-09 16:02                   ` [Cluster-devel] [PATCH] [DLM] keep dlm from panicing when traversing rsb list in debugfs swhiteho
2007-07-09 16:02                     ` [Cluster-devel] [PATCH] [DLM] block scand during recovery [1/6] swhiteho
2007-07-09 16:02                       ` [Cluster-devel] [PATCH] [DLM] add lock timeouts and warnings [2/6] swhiteho
2007-07-09 16:02                         ` [Cluster-devel] [PATCH] [DLM] dlm_device interface changes [3/6] swhiteho
2007-07-09 16:02                           ` [Cluster-devel] [PATCH] [DLM] cancel in conversion deadlock [4/6] swhiteho
2007-07-09 16:02                             ` [Cluster-devel] [PATCH] [DLM] fix new_lockspace error exit [5/6] swhiteho
2007-07-09 16:02                               ` [Cluster-devel] [PATCH] [DLM] wait for config check during join [6/6] swhiteho
2007-07-09 16:02                                 ` [Cluster-devel] [PATCH] [DLM] fix compile breakage swhiteho
2007-07-09 16:02                                   ` [Cluster-devel] [PATCH] [GFS2] latest gfs2-nmw headers break userland build swhiteho
2007-07-09 16:02                                     ` [Cluster-devel] [PATCH] [DLM] Compile fix swhiteho
2007-07-09 16:02                                       ` [Cluster-devel] [PATCH] [DLM] timeout fixes swhiteho
2007-07-09 16:02                                         ` [Cluster-devel] [PATCH] [DLM] canceling deadlocked lock swhiteho
2007-07-09 16:02                                           ` [Cluster-devel] [PATCH] [DLM] dumping master locks swhiteho
2007-07-09 16:02                                             ` [Cluster-devel] [PATCH] [DLM] show default protocol swhiteho
2007-07-09 16:02                                               ` [Cluster-devel] [PATCH] [GFS2] Quotas non-functional - fix another bug swhiteho
2007-07-09 16:02                                                 ` [Cluster-devel] [PATCH] [GFS2] Make the log reserved blocks depend on block size swhiteho
2007-07-09 16:02                                                   ` [Cluster-devel] [PATCH] [DLM] fix socket shutdown swhiteho
2007-07-09 16:02                                                     ` [Cluster-devel] [PATCH] [GFS2] fix jdata issues swhiteho
2007-07-09 16:02                                                       ` [Cluster-devel] [PATCH] [GFS2] Fix sign problem in quota/statfs and cleanup _host structures swhiteho
2007-07-09 16:02                                                         ` [Cluster-devel] [PATCH] [GFS2] Add nanosecond timestamp feature swhiteho
2007-07-09 16:02                                                           ` [Cluster-devel] [PATCH] [DLM] fix reference counting swhiteho
2007-07-09 16:02                                                             ` [Cluster-devel] [PATCH] [DLM] variable allocation swhiteho
2007-07-09 16:02                                                               ` [Cluster-devel] [PATCH] [GFS2] Fix typo in rename of directories swhiteho
2007-07-09 16:02                                                                 ` [Cluster-devel] [PATCH] [GFS2] Fix bug in error path of inode swhiteho
2007-07-09 16:02                                                                   ` [Cluster-devel] [PATCH] [GFS2] Can't mount GFS2 file system on AoE device swhiteho
2007-07-09 16:02                                                                     ` [Cluster-devel] [PATCH] [GFS2] Recovery for lost unlinked inodes swhiteho
2007-07-09 16:02                                                                       ` [Cluster-devel] [PATCH] [GFS2] gfs2_lookupi() uninitialised var fix swhiteho
2007-07-09 16:02                                                                         ` [Cluster-devel] [PATCH] [GFS2] set plock owner in GETLK info swhiteho
2007-07-09 16:02                                                                           ` [Cluster-devel] [PATCH] [GFS2] return conflicts for GETLK swhiteho
2007-07-09 16:02                                                                             ` [Cluster-devel] [PATCH] [GFS2] Fix deallocation issues swhiteho
2007-07-09 16:02                                                                               ` [Cluster-devel] [PATCH] [DLM] don't require FS flag on all nodes swhiteho
2007-07-09 16:02                                                                                 ` [Cluster-devel] [PATCH] [GFS2] Journaled file write/unstuff bug swhiteho
2007-07-09 16:02                                                                                   ` [Cluster-devel] [PATCH] [GFS2] Remove bogus '\0' in rgrp.c swhiteho
2007-07-09 16:02                                                                                     ` [Cluster-devel] [PATCH] [GFS2] Use zero_user_page() in stuffed_readpage() swhiteho
2007-07-09 16:02                                                                                       ` [Cluster-devel] [PATCH] [GFS2] assertion failure after writing to journaled file, umount swhiteho
2007-07-09 16:02                                                                                         ` [Cluster-devel] [PATCH] [GFS2] Simplify multiple glock aquisition swhiteho
2007-07-09 16:02                                                                                           ` [Cluster-devel] [PATCH] [GFS2] Addendum to the journaled file/unmount patch swhiteho
2007-07-09 16:02                                                                                             ` [Cluster-devel] [PATCH] [GFS2] Fix gfs2_block_truncate_page err return swhiteho
2007-07-09 16:02                                                                                               ` [Cluster-devel] [PATCH] [DLM] Telnet to port 21064 can stop all lockspaces swhiteho
2007-07-09 16:02                                                                                                 ` [Cluster-devel] [PATCH] [GFS2] inode size inconsistency swhiteho
2007-07-09 16:02                                                                                                   ` [Cluster-devel] [PATCH] [GFS2] remounting w/o acl option leaves acls enabled swhiteho
2007-07-09 16:02                                                                                                     ` [Cluster-devel] [PATCH] [GFS2] System won't suspend with GFS2 file system mounted swhiteho
2007-07-09 16:02                                                                                                       ` [Cluster-devel] [PATCH] [GFS2] git-gfs2-nmw-build-fix swhiteho
2007-07-09 16:02                                                                                                         ` [Cluster-devel] [PATCH] [GFS2] Obtaining no_formal_ino from directory entry swhiteho
2007-07-09 16:03                                                                                                           ` [Cluster-devel] [PATCH] [GFS2] Remove i_mode passing from NFS File Handle swhiteho
2007-07-09 16:03                                                                                                             ` [Cluster-devel] [PATCH] [DLM] dump more lock values swhiteho
2007-07-09 16:03                                                                                                               ` [Cluster-devel] [PATCH] [GFS2] Small fixes to logging code swhiteho
2007-07-10  9:06                                                                                                             ` [Cluster-devel] Re: [PATCH] [GFS2] Remove i_mode passing from NFS File Handle Christoph Hellwig
2007-07-10 10:01                                                                                                               ` Steven Whitehouse
2007-07-10 11:36                                                                                                                 ` Christoph Hellwig
2007-07-10 11:47                                                                                                                   ` Steven Whitehouse
2007-07-10  7:50 ` [Cluster-devel] [GFS2/DLM] Pull request Steven Whitehouse

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1183996996300-git-send-email-swhiteho@redhat.com \
    --to=swhiteho@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).