#include "miscadmin.h"
#include "access/xlogutils.h"
#include "access/xlog.h"
+#include "commands/tablespace.h"
#include "pgstat.h"
#include "postmaster/bgwriter.h"
#include "storage/fd.h"
/* local routines */
static void mdunlinkfork(RelFileNodeBackend rnode, ForkNumber forkNum,
bool isRedo);
-static MdfdVec *mdopen(SMgrRelation reln, ForkNumber forknum, int behavior);
+static MdfdVec *mdopenfork(SMgrRelation reln, ForkNumber forknum, int behavior);
static void register_dirty_segment(SMgrRelation reln, ForkNumber forknum,
MdfdVec *seg);
static void register_unlink_segment(RelFileNodeBackend rnode, ForkNumber forknum,
*/
mdclose(reln, forkNum);
- return (mdopen(reln, forkNum, EXTENSION_RETURN_NULL) != NULL);
+ return (mdopenfork(reln, forkNum, EXTENSION_RETURN_NULL) != NULL);
}
/*
Assert(reln->md_num_open_segs[forkNum] == 0);
+ /*
+ * We may be using the target table space for the first time in this
+ * database, so create a per-database subdirectory if needed.
+ *
+ * XXX this is a fairly ugly violation of module layering, but this seems
+ * to be the best place to put the check. Maybe TablespaceCreateDbspace
+ * should be here and not in commands/tablespace.c? But that would imply
+ * importing a lot of stuff that smgr.c oughtn't know, either.
+ */
+ TablespaceCreateDbspace(reln->smgr_rnode.node.spcNode,
+ reln->smgr_rnode.node.dbNode,
+ isRedo);
+
path = relpath(reln->smgr_rnode, forkNum);
fd = PathNameOpenFile(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY);
}
/*
- * mdopen() -- Open the specified relation.
+ * mdopenfork() -- Open one fork of the specified relation.
*
* Note we only open the first segment, when there are multiple segments.
*
* invent one out of whole cloth.
*/
static MdfdVec *
-mdopen(SMgrRelation reln, ForkNumber forknum, int behavior)
+mdopenfork(SMgrRelation reln, ForkNumber forknum, int behavior)
{
MdfdVec *mdfd;
char *path;
return mdfd;
}
+/*
+ * mdopen() -- Initialize newly-opened relation.
+ */
+void
+mdopen(SMgrRelation reln)
+{
+ /* mark it not open */
+ for (int forknum = 0; forknum <= MAX_FORKNUM; forknum++)
+ reln->md_num_open_segs[forknum] = 0;
+}
+
/*
* mdclose() -- Close the specified relation, if it isn't closed already.
*/
BlockNumber
mdnblocks(SMgrRelation reln, ForkNumber forknum)
{
- MdfdVec *v = mdopen(reln, forknum, EXTENSION_FAIL);
+ MdfdVec *v = mdopenfork(reln, forknum, EXTENSION_FAIL);
BlockNumber nblocks;
BlockNumber segno = 0;
v = &reln->md_seg_fds[forknum][reln->md_num_open_segs[forknum] - 1];
else
{
- v = mdopen(reln, forknum, behavior);
+ v = mdopenfork(reln, forknum, behavior);
if (!v)
return NULL; /* if behavior & EXTENSION_RETURN_NULL */
}
*/
#include "postgres.h"
-#include "commands/tablespace.h"
#include "lib/ilist.h"
#include "storage/bufmgr.h"
#include "storage/ipc.h"
{
void (*smgr_init) (void); /* may be NULL */
void (*smgr_shutdown) (void); /* may be NULL */
+ void (*smgr_open) (SMgrRelation reln);
void (*smgr_close) (SMgrRelation reln, ForkNumber forknum);
void (*smgr_create) (SMgrRelation reln, ForkNumber forknum,
bool isRedo);
{
.smgr_init = mdinit,
.smgr_shutdown = NULL,
+ .smgr_open = mdopen,
.smgr_close = mdclose,
.smgr_create = mdcreate,
.smgr_exists = mdexists,
/* Initialize it if not present before */
if (!found)
{
- int forknum;
-
/* hash_search already filled in the lookup key */
reln->smgr_owner = NULL;
reln->smgr_targblock = InvalidBlockNumber;
reln->smgr_vm_nblocks = InvalidBlockNumber;
reln->smgr_which = 0; /* we only have md.c at present */
- /* mark it not open */
- for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
- reln->md_num_open_segs[forknum] = 0;
+ /* implementation-specific initialization */
+ smgrsw[reln->smgr_which].smgr_open(reln);
/* it has no owner yet */
dlist_push_tail(&unowned_relns, &reln->node);
* Given an already-created (but presumably unused) SMgrRelation,
* cause the underlying disk file or other storage for the fork
* to be created.
- *
- * If isRedo is true, it is okay for the underlying file to exist
- * already because we are in a WAL replay sequence.
*/
void
smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
{
- /*
- * Exit quickly in WAL replay mode if we've already opened the file. If
- * it's open, it surely must exist.
- */
- if (isRedo && reln->md_num_open_segs[forknum] > 0)
- return;
-
- /*
- * We may be using the target table space for the first time in this
- * database, so create a per-database subdirectory if needed.
- *
- * XXX this is a fairly ugly violation of module layering, but this seems
- * to be the best place to put the check. Maybe TablespaceCreateDbspace
- * should be here and not in commands/tablespace.c? But that would imply
- * importing a lot of stuff that smgr.c oughtn't know, either.
- */
- TablespaceCreateDbspace(reln->smgr_rnode.node.spcNode,
- reln->smgr_rnode.node.dbNode,
- isRedo);
-
smgrsw[reln->smgr_which].smgr_create(reln, forknum, isRedo);
}