[GFS2] Tidy up error handling in gfs2_releasepage()

This should clarify the logic in gfs2_releasepage() relating to
error handling as well as making the response to errors a bit
more graceful.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 4c59cb1..4872042 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -683,6 +683,10 @@
 	struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
 	struct gfs2_bufdata *bd = bh->b_private;
 	struct gfs2_glock *gl;
+static unsigned limit = 0;
+
+	if (limit++ > 3)
+		return;
 
 	fs_warn(sdp, "stuck in gfs2_releasepage() %p\n", inode);
 	fs_warn(sdp, "blkno = %llu, bh->b_count = %d\n",
@@ -736,28 +740,24 @@
 	struct gfs2_sbd *sdp = aspace->i_sb->s_fs_info;
 	struct buffer_head *bh, *head;
 	struct gfs2_bufdata *bd;
-	unsigned long t;
+	unsigned long t = jiffies + gfs2_tune_get(sdp, gt_stall_secs) * HZ;
 
 	if (!page_has_buffers(page))
 		goto out;
 
 	head = bh = page_buffers(page);
 	do {
-		t = jiffies;
-
 		while (atomic_read(&bh->b_count)) {
-			if (atomic_read(&aspace->i_writecount)) {
-				if (time_after_eq(jiffies, t +
-				    gfs2_tune_get(sdp, gt_stall_secs) * HZ)) {
-					stuck_releasepage(bh);
-					t = jiffies;
-				}
+			if (!atomic_read(&aspace->i_writecount))
+				return 0;
 
-				yield();
-				continue;
+			if (time_after_eq(jiffies, t)) {
+				stuck_releasepage(bh);
+				/* should we withdraw here? */
+				return 0;
 			}
 
-			return 0;
+			yield();
 		}
 
 		gfs2_assert_warn(sdp, !buffer_pinned(bh));
@@ -773,8 +773,7 @@
 		}
 
 		bh = bh->b_this_page;
-	}
-	while (bh != head);
+	} while (bh != head);
 
 out:
 	return try_to_free_buffers(page);