diff options
Diffstat (limited to 'src/backend/storage/smgr/md.c')
-rw-r--r-- | src/backend/storage/smgr/md.c | 162 |
1 files changed, 62 insertions, 100 deletions
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c index da466afe9f8..c97a46ba4b4 100644 --- a/src/backend/storage/smgr/md.c +++ b/src/backend/storage/smgr/md.c @@ -8,17 +8,17 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.77 2000/10/28 16:20:57 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.78 2000/11/08 22:10:00 tgl Exp $ * *------------------------------------------------------------------------- */ +#include "postgres.h" + #include <errno.h> #include <unistd.h> #include <fcntl.h> #include <sys/file.h> -#include "postgres.h" - #include "catalog/catalog.h" #include "miscadmin.h" #include "storage/smgr.h" @@ -123,63 +123,39 @@ mdinit() int mdcreate(Relation reln) { + char *path; int fd, vfd; - char *path; - Assert(reln->rd_unlinked && reln->rd_fd < 0); + Assert(reln->rd_fd < 0); path = relpath(reln->rd_node); - fd = FileNameOpenFile(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, 0600); - /* - * For cataloged relations, pg_class is guaranteed to have a unique - * record with the same relname by the unique index. So we are able to - * reuse existent files for new cataloged relations. Currently we reuse - * them in the following cases. 1. they are empty. 2. they are used - * for Index relations and their size == BLCKSZ * 2. - * - * During bootstrap processing, we skip that check, because pg_time, - * pg_variable, and pg_log get created before their .bki file entries - * are processed. - */ + fd = FileNameOpenFile(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, 0600); if (fd < 0) { int save_errno = errno; - if (!IsBootstrapProcessingMode() && - reln->rd_rel->relkind == RELKIND_UNCATALOGED) - return -1; - - fd = FileNameOpenFile(path, O_RDWR | PG_BINARY, 0600); + /* + * During bootstrap, there are cases where a system relation will be + * accessed (by internal backend processes) before the bootstrap + * script nominally creates it. Therefore, allow the file to exist + * already, but in bootstrap mode only. (See also mdopen) + */ + if (IsBootstrapProcessingMode()) + fd = FileNameOpenFile(path, O_RDWR | PG_BINARY, 0600); if (fd < 0) { + pfree(path); /* be sure to return the error reported by create, not open */ errno = save_errno; return -1; } - if (!IsBootstrapProcessingMode()) - { - bool reuse = false; - long len = FileSeek(fd, 0L, SEEK_END); - - if (len == 0) - reuse = true; - else if (reln->rd_rel->relkind == RELKIND_INDEX && - len == BLCKSZ * 2) - reuse = true; - if (!reuse) - { - FileClose(fd); - /* be sure to return the error reported by create */ - errno = save_errno; - return -1; - } - } errno = 0; } - reln->rd_unlinked = false; + + pfree(path); vfd = _fdvec_alloc(); if (vfd < 0) @@ -187,12 +163,10 @@ mdcreate(Relation reln) Md_fdvec[vfd].mdfd_vfd = fd; Md_fdvec[vfd].mdfd_flags = (uint16) 0; + Md_fdvec[vfd].mdfd_lstbcnt = 0; #ifndef LET_OS_MANAGE_FILESIZE Md_fdvec[vfd].mdfd_chain = (MdfdVec *) NULL; #endif - Md_fdvec[vfd].mdfd_lstbcnt = 0; - - pfree(path); return vfd; } @@ -201,65 +175,50 @@ mdcreate(Relation reln) * mdunlink() -- Unlink a relation. */ int -mdunlink(Relation reln) +mdunlink(RelFileNode rnode) { - int nblocks; - int fd; - MdfdVec *v; - - /* - * If the relation is already unlinked,we have nothing to do any more. - */ - if (reln->rd_unlinked && reln->rd_fd < 0) - return SM_SUCCESS; - - /* - * Force all segments of the relation to be opened, so that we won't - * miss deleting any of them. - */ - nblocks = mdnblocks(reln); + int status = SM_SUCCESS; + int save_errno = 0; + char *path; - /* - * Clean out the mdfd vector, letting fd.c unlink the physical files. - * - * NOTE: We truncate the file(s) before deleting 'em, because if other - * backends are holding the files open, the unlink will fail on some - * platforms (think Microsoft). Better a zero-size file gets left - * around than a big file. Those other backends will be forced to - * close the relation by cache invalidation, but that probably hasn't - * happened yet. - */ - fd = RelationGetFile(reln); - if (fd < 0) /* should not happen */ - elog(ERROR, "mdunlink: mdnblocks didn't open relation"); + path = relpath(rnode); - Md_fdvec[fd].mdfd_flags = (uint16) 0; + /* Delete the first segment, or only segment if not doing segmenting */ + if (unlink(path) < 0) + { + status = SM_FAIL; + save_errno = errno; + } #ifndef LET_OS_MANAGE_FILESIZE - for (v = &Md_fdvec[fd]; v != (MdfdVec *) NULL;) + /* Get the additional segments, if any */ + if (status == SM_SUCCESS) { - MdfdVec *ov = v; + char *segpath = (char *) palloc(strlen(path) + 12); + int segno; - FileTruncate(v->mdfd_vfd, 0); - FileUnlink(v->mdfd_vfd); - v = v->mdfd_chain; - if (ov != &Md_fdvec[fd]) - pfree(ov); + for (segno = 1; ; segno++) + { + sprintf(segpath, "%s.%d", path, segno); + if (unlink(segpath) < 0) + { + /* ENOENT is expected after the last segment... */ + if (errno != ENOENT) + { + status = SM_FAIL; + save_errno = errno; + } + break; + } + } + pfree(segpath); } - Md_fdvec[fd].mdfd_chain = (MdfdVec *) NULL; -#else - v = &Md_fdvec[fd]; - FileTruncate(v->mdfd_vfd, 0); - FileUnlink(v->mdfd_vfd); #endif - _fdvec_free(fd); - - /* be sure to mark relation closed && unlinked */ - reln->rd_fd = -1; - reln->rd_unlinked = true; + pfree(path); - return SM_SUCCESS; + errno = save_errno; + return status; } /* @@ -327,24 +286,29 @@ mdopen(Relation reln) int vfd; Assert(reln->rd_fd < 0); + path = relpath(reln->rd_node); fd = FileNameOpenFile(path, O_RDWR | PG_BINARY, 0600); + if (fd < 0) { - /* in bootstrap mode, accept mdopen as substitute for mdcreate */ + /* + * During bootstrap, there are cases where a system relation will be + * accessed (by internal backend processes) before the bootstrap + * script nominally creates it. Therefore, accept mdopen() as a + * substitute for mdcreate() in bootstrap mode only. (See mdcreate) + */ if (IsBootstrapProcessingMode()) fd = FileNameOpenFile(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, 0600); if (fd < 0) { - elog(NOTICE, "mdopen: couldn't open %s: %m", path); - /* mark relation closed and unlinked */ - reln->rd_fd = -1; - reln->rd_unlinked = true; + pfree(path); return -1; } } - reln->rd_unlinked = false; + + pfree(path); vfd = _fdvec_alloc(); if (vfd < 0) @@ -362,8 +326,6 @@ mdopen(Relation reln) #endif #endif - pfree(path); - return vfd; } |