diff --git a/contrib/pageinspect/pageinspect.sql.in b/contrib/pageinspect/pageinspect.sql.in
index 6ed49fa54401eb8a147f997246fa61908392be73..abf1ddc57c1e87698b1d4a370f84dcfb751dd9d8 100644
--- a/contrib/pageinspect/pageinspect.sql.in
+++ b/contrib/pageinspect/pageinspect.sql.in
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/contrib/pageinspect/pageinspect.sql.in,v 1.6 2008/10/06 14:13:17 heikki Exp $ */
+/* $PostgreSQL: pgsql/contrib/pageinspect/pageinspect.sql.in,v 1.7 2009/06/08 16:22:44 tgl Exp $ */
 
 -- Adjust this setting to control where the objects get created.
 SET search_path = public;
@@ -6,15 +6,15 @@ SET search_path = public;
 --
 -- get_raw_page()
 --
-CREATE OR REPLACE FUNCTION get_raw_page(text, text, int4)
+CREATE OR REPLACE FUNCTION get_raw_page(text, int4)
 RETURNS bytea
 AS 'MODULE_PATHNAME', 'get_raw_page'
 LANGUAGE C STRICT;
 
-CREATE OR REPLACE FUNCTION get_raw_page(text, int4) 
+CREATE OR REPLACE FUNCTION get_raw_page(text, text, int4)
 RETURNS bytea
-AS $$ SELECT get_raw_page($1, 'main', $2); $$
-LANGUAGE SQL STRICT;
+AS 'MODULE_PATHNAME', 'get_raw_page_fork'
+LANGUAGE C STRICT;
 
 --
 -- page_header()
diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c
index 91b6a1915f0518d5d74d2fe92dff95bf681b43a6..00e2535eae691d0b0873bae1093b9165989a4f38 100644
--- a/contrib/pageinspect/rawpage.c
+++ b/contrib/pageinspect/rawpage.c
@@ -8,7 +8,7 @@
  * Copyright (c) 2007-2009, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/contrib/pageinspect/rawpage.c,v 1.11 2009/03/31 22:54:31 tgl Exp $
+ *	  $PostgreSQL: pgsql/contrib/pageinspect/rawpage.c,v 1.12 2009/06/08 16:22:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -29,8 +29,13 @@
 PG_MODULE_MAGIC;
 
 Datum		get_raw_page(PG_FUNCTION_ARGS);
+Datum		get_raw_page_fork(PG_FUNCTION_ARGS);
 Datum		page_header(PG_FUNCTION_ARGS);
 
+static bytea *get_raw_page_internal(text *relname, ForkNumber forknum,
+									BlockNumber blkno);
+
+
 /*
  * get_raw_page
  *
@@ -40,15 +45,58 @@ PG_FUNCTION_INFO_V1(get_raw_page);
 
 Datum
 get_raw_page(PG_FUNCTION_ARGS)
+{
+	text	   *relname = PG_GETARG_TEXT_P(0);
+	uint32		blkno = PG_GETARG_UINT32(1);
+	bytea	   *raw_page;
+
+	/*
+	 * We don't normally bother to check the number of arguments to a C
+	 * function, but here it's needed for safety because early 8.4 beta
+	 * releases mistakenly redefined get_raw_page() as taking three arguments.
+	 */
+	if (PG_NARGS() != 2)
+		ereport(ERROR,
+				(errmsg("wrong number of arguments to get_raw_page()"),
+				 errhint("Run the updated pageinspect.sql script.")));
+
+	raw_page = get_raw_page_internal(relname, MAIN_FORKNUM, blkno);
+
+	PG_RETURN_BYTEA_P(raw_page);
+}
+
+/*
+ * get_raw_page_fork
+ *
+ * Same, for any fork
+ */
+PG_FUNCTION_INFO_V1(get_raw_page_fork);
+
+Datum
+get_raw_page_fork(PG_FUNCTION_ARGS)
 {
 	text	   *relname = PG_GETARG_TEXT_P(0);
 	text	   *forkname = PG_GETARG_TEXT_P(1);
 	uint32		blkno = PG_GETARG_UINT32(2);
+	bytea	   *raw_page;
 	ForkNumber	forknum;
 
-	Relation	rel;
-	RangeVar   *relrv;
+	forknum = forkname_to_number(text_to_cstring(forkname));
+
+	raw_page = get_raw_page_internal(relname, forknum, blkno);
+
+	PG_RETURN_BYTEA_P(raw_page);
+}
+
+/*
+ * workhorse
+ */
+static bytea *
+get_raw_page_internal(text *relname, ForkNumber forknum, BlockNumber blkno)
+{
 	bytea	   *raw_page;
+	RangeVar   *relrv;
+	Relation	rel;
 	char	   *raw_page_data;
 	Buffer		buf;
 
@@ -57,8 +105,6 @@ get_raw_page(PG_FUNCTION_ARGS)
 				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
 				 (errmsg("must be superuser to use raw functions"))));
 
-	forknum = forkname_to_number(text_to_cstring(forkname));
-
 	relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
 	rel = relation_openrv(relrv, AccessShareLock);
 
@@ -105,7 +151,7 @@ get_raw_page(PG_FUNCTION_ARGS)
 
 	relation_close(rel, AccessShareLock);
 
-	PG_RETURN_BYTEA_P(raw_page);
+	return raw_page;
 }
 
 /*
diff --git a/contrib/pageinspect/uninstall_pageinspect.sql b/contrib/pageinspect/uninstall_pageinspect.sql
index 161393d5a9ba378e53e1756a8a48dd9973e0c949..8c0a7f7f371eaace28f066c25dfa9455db6d8e64 100644
--- a/contrib/pageinspect/uninstall_pageinspect.sql
+++ b/contrib/pageinspect/uninstall_pageinspect.sql
@@ -1,11 +1,13 @@
-/* $PostgreSQL: pgsql/contrib/pageinspect/uninstall_pageinspect.sql,v 1.4 2007/11/13 04:24:28 momjian Exp $ */
+/* $PostgreSQL: pgsql/contrib/pageinspect/uninstall_pageinspect.sql,v 1.5 2009/06/08 16:22:44 tgl Exp $ */
 
 -- Adjust this setting to control where the objects get dropped.
 SET search_path = public;
 
 DROP FUNCTION get_raw_page(text, int4);
+DROP FUNCTION get_raw_page(text, text, int4);
 DROP FUNCTION page_header(bytea);
 DROP FUNCTION heap_page_items(bytea);
 DROP FUNCTION bt_metap(text);
 DROP FUNCTION bt_page_stats(text, int4);
 DROP FUNCTION bt_page_items(text, int4);
+DROP FUNCTION fsm_page_contents(bytea);
diff --git a/doc/src/sgml/pageinspect.sgml b/doc/src/sgml/pageinspect.sgml
index e510d202aa4ea09178003c58b8f1523d5c27ecde..a81989a2a35cdaddbdd9d37069fd798b3914ec93 100644
--- a/doc/src/sgml/pageinspect.sgml
+++ b/doc/src/sgml/pageinspect.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/pageinspect.sgml,v 1.5 2008/10/06 14:13:17 heikki Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/pageinspect.sgml,v 1.6 2009/06/08 16:22:44 tgl Exp $ -->
 
 <sect1 id="pageinspect">
  <title>pageinspect</title>
@@ -27,8 +27,9 @@
       <function>get_raw_page</function> reads the specified block of the named
       table and returns a copy as a <type>bytea</> value.  This allows a
       single time-consistent copy of the block to be obtained.
-      <literal>fork</literal> should be <literal>'main'</literal> for the main
-      data fork, or <literal>'fsm'</literal> for the FSM.
+      <replaceable>fork</replaceable> should be <literal>'main'</literal> for
+      the main data fork, or <literal>'fsm'</literal> for the free space map,
+      or <literal>'vm'</literal> for the visibility map.
      </para>
     </listitem>
    </varlistentry>
@@ -40,8 +41,9 @@
 
     <listitem>
      <para>
-      A shorthand of above, for reading from the main fork. Equal to
-      <literal>get_raw_page(relname, 0, blkno)</literal>
+      A shorthand version of <function>get_raw_page</function>, for reading
+      from the main fork.  Equivalent to
+      <literal>get_raw_page(relname, 'main', blkno)</literal>
      </para>
     </listitem>
    </varlistentry>