diff options
Diffstat (limited to 'src/backend/storage/smgr')
-rw-r--r-- | src/backend/storage/smgr/md.c | 1088 | ||||
-rw-r--r-- | src/backend/storage/smgr/mm.c | 761 | ||||
-rw-r--r-- | src/backend/storage/smgr/smgr.c | 432 | ||||
-rw-r--r-- | src/backend/storage/smgr/smgrtype.c | 66 |
4 files changed, 1212 insertions, 1135 deletions
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c index 2688ad3aed1..7a2903fff5c 100644 --- a/src/backend/storage/smgr/md.c +++ b/src/backend/storage/smgr/md.c @@ -1,28 +1,28 @@ /*------------------------------------------------------------------------- * * md.c-- - * This code manages relations that reside on magnetic disk. + * This code manages relations that reside on magnetic disk. * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.18 1997/08/18 20:53:14 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.19 1997/09/07 04:49:17 momjian Exp $ * *------------------------------------------------------------------------- */ #include <unistd.h> -#include <stdio.h> /* for sprintf() */ +#include <stdio.h> /* for sprintf() */ #include <string.h> -#include <fcntl.h> /* for open() flags */ +#include <fcntl.h> /* for open() flags */ #include <sys/file.h> #include "postgres.h" -#include "miscadmin.h" /* for DataDir */ +#include "miscadmin.h" /* for DataDir */ #include "storage/block.h" #include "storage/fd.h" -#include "storage/smgr.h" /* where the declarations go */ +#include "storage/smgr.h" /* where the declarations go */ #include "storage/fd.h" #include "utils/mcxt.h" #include "utils/rel.h" @@ -32,764 +32,802 @@ #undef DIAGNOSTIC /* - * The magnetic disk storage manager keeps track of open file descriptors - * in its own descriptor pool. This happens for two reasons. First, at - * transaction boundaries, we walk the list of descriptors and flush - * anything that we've dirtied in the current transaction. Second, we - * have to support relations of > 4GBytes. In order to do this, we break - * relations up into chunks of < 2GBytes and store one chunk in each of - * several files that represent the relation. + * The magnetic disk storage manager keeps track of open file descriptors + * in its own descriptor pool. This happens for two reasons. First, at + * transaction boundaries, we walk the list of descriptors and flush + * anything that we've dirtied in the current transaction. Second, we + * have to support relations of > 4GBytes. In order to do this, we break + * relations up into chunks of < 2GBytes and store one chunk in each of + * several files that represent the relation. */ -typedef struct _MdfdVec { - int mdfd_vfd; /* fd number in vfd pool */ - uint16 mdfd_flags; /* clean, dirty, free */ - int mdfd_lstbcnt; /* most recent block count */ - int mdfd_nextFree; /* next free vector */ - struct _MdfdVec *mdfd_chain; /* for large relations */ -} MdfdVec; +typedef struct _MdfdVec +{ + int mdfd_vfd; /* fd number in vfd pool */ + uint16 mdfd_flags; /* clean, dirty, free */ + int mdfd_lstbcnt; /* most recent block count */ + int mdfd_nextFree; /* next free vector */ + struct _MdfdVec *mdfd_chain;/* for large relations */ +} MdfdVec; -static int Nfds = 100; -static MdfdVec *Md_fdvec = (MdfdVec *) NULL; -static int Md_Free = -1; -static int CurFd = 0; -static MemoryContext MdCxt; +static int Nfds = 100; +static MdfdVec *Md_fdvec = (MdfdVec *) NULL; +static int Md_Free = -1; +static int CurFd = 0; +static MemoryContext MdCxt; -#define MDFD_DIRTY (uint16) 0x01 -#define MDFD_FREE (uint16) 0x02 +#define MDFD_DIRTY (uint16) 0x01 +#define MDFD_FREE (uint16) 0x02 -#define RELSEG_SIZE 262144 /* (2 ** 31) / 8192 -- 2GB file */ +#define RELSEG_SIZE 262144 /* (2 ** 31) / 8192 -- 2GB file */ /* routines declared here */ -static MdfdVec *_mdfd_openseg(Relation reln, int segno, int oflags); -static MdfdVec *_mdfd_getseg(Relation reln, int blkno, int oflag); -static int _fdvec_alloc (void); -static void _fdvec_free (int); +static MdfdVec *_mdfd_openseg(Relation reln, int segno, int oflags); +static MdfdVec *_mdfd_getseg(Relation reln, int blkno, int oflag); +static int _fdvec_alloc(void); +static void _fdvec_free(int); static BlockNumber _mdnblocks(File file, Size blcksz); /* - * mdinit() -- Initialize private state for magnetic disk storage manager. + * mdinit() -- Initialize private state for magnetic disk storage manager. * - * We keep a private table of all file descriptors. Whenever we do - * a write to one, we mark it dirty in our table. Whenever we force - * changes to disk, we mark the file descriptor clean. At transaction - * commit, we force changes to disk for all dirty file descriptors. - * This routine allocates and initializes the table. + * We keep a private table of all file descriptors. Whenever we do + * a write to one, we mark it dirty in our table. Whenever we force + * changes to disk, we mark the file descriptor clean. At transaction + * commit, we force changes to disk for all dirty file descriptors. + * This routine allocates and initializes the table. * - * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate. + * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate. */ int mdinit() { - MemoryContext oldcxt; - int i; + MemoryContext oldcxt; + int i; - MdCxt = (MemoryContext) CreateGlobalMemory("MdSmgr"); - if (MdCxt == (MemoryContext) NULL) - return (SM_FAIL); + MdCxt = (MemoryContext) CreateGlobalMemory("MdSmgr"); + if (MdCxt == (MemoryContext) NULL) + return (SM_FAIL); - oldcxt = MemoryContextSwitchTo(MdCxt); - Md_fdvec = (MdfdVec *) palloc(Nfds * sizeof(MdfdVec)); - MemoryContextSwitchTo(oldcxt); + oldcxt = MemoryContextSwitchTo(MdCxt); + Md_fdvec = (MdfdVec *) palloc(Nfds * sizeof(MdfdVec)); + MemoryContextSwitchTo(oldcxt); - if (Md_fdvec == (MdfdVec *) NULL) - return (SM_FAIL); + if (Md_fdvec == (MdfdVec *) NULL) + return (SM_FAIL); - memset(Md_fdvec, 0, Nfds * sizeof(MdfdVec)); + memset(Md_fdvec, 0, Nfds * sizeof(MdfdVec)); - /* Set free list */ - for (i = 0; i < Nfds; i++ ) - { - Md_fdvec[i].mdfd_nextFree = i + 1; - Md_fdvec[i].mdfd_flags = MDFD_FREE; - } - Md_Free = 0; - Md_fdvec[Nfds - 1].mdfd_nextFree = -1; + /* Set free list */ + for (i = 0; i < Nfds; i++) + { + Md_fdvec[i].mdfd_nextFree = i + 1; + Md_fdvec[i].mdfd_flags = MDFD_FREE; + } + Md_Free = 0; + Md_fdvec[Nfds - 1].mdfd_nextFree = -1; - return (SM_SUCCESS); + return (SM_SUCCESS); } int mdcreate(Relation reln) { - int fd, vfd; - char *path; - - path = relpath(&(reln->rd_rel->relname.data[0])); - fd = FileNameOpenFile(path, O_RDWR|O_CREAT|O_EXCL, 0600); - - /* - * If the file already exists and is empty, we pretend that the - * create succeeded. During bootstrap processing, we skip that check, - * because pg_time, pg_variable, and pg_log get created before their - * .bki file entries are processed. - * - * As the result of this pretence it was possible to have in - * pg_class > 1 records with the same relname. Actually, it - * should be fixed in upper levels, too, but... - vadim 05/06/97 - */ - - if (fd < 0) - { - if ( !IsBootstrapProcessingMode() ) - return (-1); - fd = FileNameOpenFile(path, O_RDWR, 0600); /* Bootstrap */ - if ( fd < 0 ) - return (-1); - } - - vfd = _fdvec_alloc (); - if ( vfd < 0 ) - return (-1); - - Md_fdvec[vfd].mdfd_vfd = fd; - Md_fdvec[vfd].mdfd_flags = (uint16) 0; - Md_fdvec[vfd].mdfd_chain = (MdfdVec *) NULL; - Md_fdvec[vfd].mdfd_lstbcnt = 0; - - return (vfd); + int fd, + vfd; + char *path; + + path = relpath(&(reln->rd_rel->relname.data[0])); + fd = FileNameOpenFile(path, O_RDWR | O_CREAT | O_EXCL, 0600); + + /* + * If the file already exists and is empty, we pretend that the create + * succeeded. During bootstrap processing, we skip that check, + * because pg_time, pg_variable, and pg_log get created before their + * .bki file entries are processed. + * + * As the result of this pretence it was possible to have in pg_class > 1 + * records with the same relname. Actually, it should be fixed in + * upper levels, too, but... - vadim 05/06/97 + */ + + if (fd < 0) + { + if (!IsBootstrapProcessingMode()) + return (-1); + fd = FileNameOpenFile(path, O_RDWR, 0600); /* Bootstrap */ + if (fd < 0) + return (-1); + } + + vfd = _fdvec_alloc(); + if (vfd < 0) + return (-1); + + Md_fdvec[vfd].mdfd_vfd = fd; + Md_fdvec[vfd].mdfd_flags = (uint16) 0; + Md_fdvec[vfd].mdfd_chain = (MdfdVec *) NULL; + Md_fdvec[vfd].mdfd_lstbcnt = 0; + + return (vfd); } /* - * mdunlink() -- Unlink a relation. + * mdunlink() -- Unlink a relation. */ int mdunlink(Relation reln) { - int fd; - int i; - MdfdVec *v, *ov; - MemoryContext oldcxt; - char fname[NAMEDATALEN]; - char tname[NAMEDATALEN+10]; /* leave room for overflow suffixes*/ - - /* On Windows NT you can't unlink a file if it is open so we have - ** to do this. - */ + int fd; + int i; + MdfdVec *v, + *ov; + MemoryContext oldcxt; + char fname[NAMEDATALEN]; + char tname[NAMEDATALEN + 10]; /* leave room for overflow + * suffixes */ + + /* + * On Windows NT you can't unlink a file if it is open so we have * to + * do this. + */ + + strNcpy(fname, RelationGetRelationName(reln)->data, NAMEDATALEN - 1); + + if (FileNameUnlink(fname) < 0) + return (SM_FAIL); + + /* unlink all the overflow files for large relations */ + for (i = 1;; i++) + { + sprintf(tname, "%s.%d", fname, i); + if (FileNameUnlink(tname) < 0) + break; + } + + /* finally, clean out the mdfd vector */ + fd = RelationGetFile(reln); + Md_fdvec[fd].mdfd_flags = (uint16) 0; + + oldcxt = MemoryContextSwitchTo(MdCxt); + for (v = &Md_fdvec[fd]; v != (MdfdVec *) NULL;) + { + FileUnlink(v->mdfd_vfd); + ov = v; + v = v->mdfd_chain; + if (ov != &Md_fdvec[fd]) + pfree(ov); + } + Md_fdvec[fd].mdfd_chain = (MdfdVec *) NULL; + MemoryContextSwitchTo(oldcxt); - strNcpy(fname, RelationGetRelationName(reln)->data, NAMEDATALEN-1); - - if (FileNameUnlink(fname) < 0) - return (SM_FAIL); - - /* unlink all the overflow files for large relations */ - for (i = 1; ; i++) { - sprintf(tname, "%s.%d", fname, i); - if (FileNameUnlink(tname) < 0) - break; - } - - /* finally, clean out the mdfd vector */ - fd = RelationGetFile(reln); - Md_fdvec[fd].mdfd_flags = (uint16) 0; - - oldcxt = MemoryContextSwitchTo(MdCxt); - for (v = &Md_fdvec[fd]; v != (MdfdVec *) NULL; ) - { - FileUnlink(v->mdfd_vfd); - ov = v; - v = v->mdfd_chain; - if (ov != &Md_fdvec[fd]) - pfree(ov); - } - Md_fdvec[fd].mdfd_chain = (MdfdVec *) NULL; - MemoryContextSwitchTo(oldcxt); - - _fdvec_free (fd); - - return (SM_SUCCESS); + _fdvec_free(fd); + + return (SM_SUCCESS); } /* - * mdextend() -- Add a block to the specified relation. + * mdextend() -- Add a block to the specified relation. * - * This routine returns SM_FAIL or SM_SUCCESS, with errno set as - * appropriate. + * This routine returns SM_FAIL or SM_SUCCESS, with errno set as + * appropriate. */ int mdextend(Relation reln, char *buffer) { - long pos; - int nblocks; - MdfdVec *v; + long pos; + int nblocks; + MdfdVec *v; - nblocks = mdnblocks(reln); - v = _mdfd_getseg(reln, nblocks, O_CREAT); + nblocks = mdnblocks(reln); + v = _mdfd_getseg(reln, nblocks, O_CREAT); - if ((pos = FileSeek(v->mdfd_vfd, 0L, SEEK_END)) < 0) - return (SM_FAIL); + if ((pos = FileSeek(v->mdfd_vfd, 0L, SEEK_END)) < 0) + return (SM_FAIL); - if (FileWrite(v->mdfd_vfd, buffer, BLCKSZ) != BLCKSZ) - return (SM_FAIL); + if (FileWrite(v->mdfd_vfd, buffer, BLCKSZ) != BLCKSZ) + return (SM_FAIL); - /* remember that we did a write, so we can sync at xact commit */ - v->mdfd_flags |= MDFD_DIRTY; + /* remember that we did a write, so we can sync at xact commit */ + v->mdfd_flags |= MDFD_DIRTY; - /* try to keep the last block count current, though it's just a hint */ - if ((v->mdfd_lstbcnt = (++nblocks % RELSEG_SIZE)) == 0) - v->mdfd_lstbcnt = RELSEG_SIZE; + /* try to keep the last block count current, though it's just a hint */ + if ((v->mdfd_lstbcnt = (++nblocks % RELSEG_SIZE)) == 0) + v->mdfd_lstbcnt = RELSEG_SIZE; #ifdef DIAGNOSTIC - if (_mdnblocks(v->mdfd_vfd, BLCKSZ) > RELSEG_SIZE - || v->mdfd_lstbcnt > RELSEG_SIZE) - elog(FATAL, "segment too big!"); + if (_mdnblocks(v->mdfd_vfd, BLCKSZ) > RELSEG_SIZE + || v->mdfd_lstbcnt > RELSEG_SIZE) + elog(FATAL, "segment too big!"); #endif - return (SM_SUCCESS); + return (SM_SUCCESS); } /* - * mdopen() -- Open the specified relation. + * mdopen() -- Open the specified relation. */ int mdopen(Relation reln) { - char *path; - int fd; - int vfd; + char *path; + int fd; + int vfd; - path = relpath(&(reln->rd_rel->relname.data[0])); + path = relpath(&(reln->rd_rel->relname.data[0])); - fd = FileNameOpenFile(path, O_RDWR, 0600); + fd = FileNameOpenFile(path, O_RDWR, 0600); - /* this should only happen during bootstrap processing */ - if (fd < 0) - fd = FileNameOpenFile(path, O_RDWR|O_CREAT|O_EXCL, 0600); + /* this should only happen during bootstrap processing */ + if (fd < 0) + fd = FileNameOpenFile(path, O_RDWR | O_CREAT | O_EXCL, 0600); - vfd = _fdvec_alloc (); - if ( vfd < 0 ) - return (-1); + vfd = _fdvec_alloc(); + if (vfd < 0) + return (-1); - Md_fdvec[vfd].mdfd_vfd = fd; - Md_fdvec[vfd].mdfd_flags = (uint16) 0; - Md_fdvec[vfd].mdfd_chain = (MdfdVec *) NULL; - Md_fdvec[vfd].mdfd_lstbcnt = _mdnblocks(fd, BLCKSZ); + Md_fdvec[vfd].mdfd_vfd = fd; + Md_fdvec[vfd].mdfd_flags = (uint16) 0; + Md_fdvec[vfd].mdfd_chain = (MdfdVec *) NULL; + Md_fdvec[vfd].mdfd_lstbcnt = _mdnblocks(fd, BLCKSZ); #ifdef DIAGNOSTIC - if (Md_fdvec[vfd].mdfd_lstbcnt > RELSEG_SIZE) - elog(FATAL, "segment too big on relopen!"); + if (Md_fdvec[vfd].mdfd_lstbcnt > RELSEG_SIZE) + elog(FATAL, "segment too big on relopen!"); #endif - return (vfd); + return (vfd); } /* - * mdclose() -- Close the specified relation + * mdclose() -- Close the specified relation * - * AND FREE fd vector! It may be re-used for other relation! - * reln should be flushed from cache after closing !.. + * AND FREE fd vector! It may be re-used for other relation! + * reln should be flushed from cache after closing !.. * - * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate. + * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate. */ int mdclose(Relation reln) { - int fd; - MdfdVec *v, *ov; - MemoryContext oldcxt; + int fd; + MdfdVec *v, + *ov; + MemoryContext oldcxt; - fd = RelationGetFile(reln); + fd = RelationGetFile(reln); - oldcxt = MemoryContextSwitchTo(MdCxt); - for (v = &Md_fdvec[fd]; v != (MdfdVec *) NULL; ) - { - /* if not closed already */ - if ( v->mdfd_vfd >= 0 ) + oldcxt = MemoryContextSwitchTo(MdCxt); + for (v = &Md_fdvec[fd]; v != (MdfdVec *) NULL;) { - /* - * We sync the file descriptor so that we don't need to reopen it at - * transaction commit to force changes to disk. - */ + /* if not closed already */ + if (v->mdfd_vfd >= 0) + { + + /* + * We sync the file descriptor so that we don't need to reopen + * it at transaction commit to force changes to disk. + */ + + FileSync(v->mdfd_vfd); + FileClose(v->mdfd_vfd); + + /* mark this file descriptor as clean in our private table */ + v->mdfd_flags &= ~MDFD_DIRTY; + } + /* Now free vector */ + ov = v; + v = v->mdfd_chain; + if (ov != &Md_fdvec[fd]) + pfree(ov); + } - FileSync(v->mdfd_vfd); - FileClose(v->mdfd_vfd); + MemoryContextSwitchTo(oldcxt); + Md_fdvec[fd].mdfd_chain = (MdfdVec *) NULL; - /* mark this file descriptor as clean in our private table */ - v->mdfd_flags &= ~MDFD_DIRTY; - } - /* Now free vector */ - ov = v; - v = v->mdfd_chain; - if (ov != &Md_fdvec[fd]) - pfree(ov); - } - - MemoryContextSwitchTo(oldcxt); - Md_fdvec[fd].mdfd_chain = (MdfdVec *) NULL; - - _fdvec_free (fd); - - return (SM_SUCCESS); + _fdvec_free(fd); + + return (SM_SUCCESS); } /* - * mdread() -- Read the specified block from a relation. + * mdread() -- Read the specified block from a relation. * - * Returns SM_SUCCESS or SM_FAIL. + * Returns SM_SUCCESS or SM_FAIL. */ int mdread(Relation reln, BlockNumber blocknum, char *buffer) { - int status; - long seekpos; - int nbytes; - MdfdVec *v; + int status; + long seekpos; + int nbytes; + MdfdVec *v; - v = _mdfd_getseg(reln, blocknum, 0); + v = _mdfd_getseg(reln, blocknum, 0); - seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE)); + seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE)); #ifdef DIAGNOSTIC - if (seekpos >= BLCKSZ * RELSEG_SIZE) - elog(FATAL, "seekpos too big!"); + if (seekpos >= BLCKSZ * RELSEG_SIZE) + elog(FATAL, "seekpos too big!"); #endif - if (FileSeek(v->mdfd_vfd, seekpos, SEEK_SET) != seekpos) { - return (SM_FAIL); - } + if (FileSeek(v->mdfd_vfd, seekpos, SEEK_SET) != seekpos) + { + return (SM_FAIL); + } - status = SM_SUCCESS; - if ((nbytes = FileRead(v->mdfd_vfd, buffer, BLCKSZ)) != BLCKSZ) { - if (nbytes == 0) { - memset(buffer, 0, BLCKSZ); - } else { - status = SM_FAIL; + status = SM_SUCCESS; + if ((nbytes = FileRead(v->mdfd_vfd, buffer, BLCKSZ)) != BLCKSZ) + { + if (nbytes == 0) + { + memset(buffer, 0, BLCKSZ); + } + else + { + status = SM_FAIL; + } } - } - return (status); + return (status); } /* - * mdwrite() -- Write the supplied block at the appropriate location. + * mdwrite() -- Write the supplied block at the appropriate location. * - * Returns SM_SUCCESS or SM_FAIL. + * Returns SM_SUCCESS or SM_FAIL. */ int mdwrite(Relation reln, BlockNumber blocknum, char *buffer) { - int status; - long seekpos; - MdfdVec *v; + int status; + long seekpos; + MdfdVec *v; - v = _mdfd_getseg(reln, blocknum, 0); + v = _mdfd_getseg(reln, blocknum, 0); - seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE)); + seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE)); #ifdef DIAGNOSTIC - if (seekpos >= BLCKSZ * RELSEG_SIZE) - elog(FATAL, "seekpos too big!"); + if (seekpos >= BLCKSZ * RELSEG_SIZE) + elog(FATAL, "seekpos too big!"); #endif - if (FileSeek(v->mdfd_vfd, seekpos, SEEK_SET) != seekpos) { - return (SM_FAIL); - } + if (FileSeek(v->mdfd_vfd, seekpos, SEEK_SET) != seekpos) + { + return (SM_FAIL); + } - status = SM_SUCCESS; - if (FileWrite(v->mdfd_vfd, buffer, BLCKSZ) != BLCKSZ) - status = SM_FAIL; + status = SM_SUCCESS; + if (FileWrite(v->mdfd_vfd, buffer, BLCKSZ) != BLCKSZ) + status = SM_FAIL; - v->mdfd_flags |= MDFD_DIRTY; + v->mdfd_flags |= MDFD_DIRTY; - return (status); + return (status); } /* - * mdflush() -- Synchronously write a block to disk. + * mdflush() -- Synchronously write a block to disk. * - * This is exactly like mdwrite(), but doesn't return until the file - * system buffer cache has been flushed. + * This is exactly like mdwrite(), but doesn't return until the file + * system buffer cache has been flushed. */ int mdflush(Relation reln, BlockNumber blocknum, char *buffer) { - int status; - long seekpos; - MdfdVec *v; + int status; + long seekpos; + MdfdVec *v; - v = _mdfd_getseg(reln, blocknum, 0); + v = _mdfd_getseg(reln, blocknum, 0); - seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE)); + seekpos = (long) (BLCKSZ * (blocknum % RELSEG_SIZE)); #ifdef DIAGNOSTIC - if (seekpos >= BLCKSZ * RELSEG_SIZE) - elog(FATAL, "seekpos too big!"); + if (seekpos >= BLCKSZ * RELSEG_SIZE) + elog(FATAL, "seekpos too big!"); #endif - if (FileSeek(v->mdfd_vfd, seekpos, SEEK_SET) != seekpos) { - return (SM_FAIL); - } + if (FileSeek(v->mdfd_vfd, seekpos, SEEK_SET) != seekpos) + { + return (SM_FAIL); + } - /* write and sync the block */ - status = SM_SUCCESS; - if (FileWrite(v->mdfd_vfd, buffer, BLCKSZ) != BLCKSZ - || FileSync(v->mdfd_vfd) < 0) - status = SM_FAIL; + /* write and sync the block */ + status = SM_SUCCESS; + if (FileWrite(v->mdfd_vfd, buffer, BLCKSZ) != BLCKSZ + || FileSync(v->mdfd_vfd) < 0) + status = SM_FAIL; - /* - * By here, the block is written and changes have been forced to stable - * storage. Mark the descriptor as clean until the next write, so we - * don't sync it again unnecessarily at transaction commit. - */ + /* + * By here, the block is written and changes have been forced to + * stable storage. Mark the descriptor as clean until the next write, + * so we don't sync it again unnecessarily at transaction commit. + */ - v->mdfd_flags &= ~MDFD_DIRTY; + v->mdfd_flags &= ~MDFD_DIRTY; - return (status); + return (status); } /* - * mdblindwrt() -- Write a block to disk blind. + * mdblindwrt() -- Write a block to disk blind. * - * We have to be able to do this using only the name and OID of - * the database and relation in which the block belongs. This - * is a synchronous write. + * We have to be able to do this using only the name and OID of + * the database and relation in which the block belongs. This + * is a synchronous write. */ int mdblindwrt(char *dbstr, - char *relstr, - Oid dbid, - Oid relid, - BlockNumber blkno, - char *buffer) + char *relstr, + Oid dbid, + Oid relid, + BlockNumber blkno, + char *buffer) { - int fd; - int segno; - long seekpos; - int status; - char *path; - int nchars; - - /* be sure we have enough space for the '.segno', if any */ - segno = blkno / RELSEG_SIZE; - if (segno > 0) - nchars = 10; - else - nchars = 0; - - /* construct the path to the file and open it */ - if (dbid == (Oid) 0) { - path = (char *) palloc(strlen(DataDir) + sizeof(NameData) + 2 + nchars); - if (segno == 0) - sprintf(path, "%s/%s", DataDir, relstr); + int fd; + int segno; + long seekpos; + int status; + char *path; + int nchars; + + /* be sure we have enough space for the '.segno', if any */ + segno = blkno / RELSEG_SIZE; + if (segno > 0) + nchars = 10; else - sprintf(path, "%s/%s.%d", DataDir, relstr, segno); - } else { - path = (char *) palloc(strlen(DataDir) + strlen("/base/") + 2 * sizeof(NameData) + 2 + nchars); - if (segno == 0) - sprintf(path, "%s/base/%s/%s", DataDir, - dbstr, relstr); + nchars = 0; + + /* construct the path to the file and open it */ + if (dbid == (Oid) 0) + { + path = (char *) palloc(strlen(DataDir) + sizeof(NameData) + 2 + nchars); + if (segno == 0) + sprintf(path, "%s/%s", DataDir, relstr); + else + sprintf(path, "%s/%s.%d", DataDir, relstr, segno); + } else - sprintf(path, "%s/base/%s/%s.%d", DataDir, dbstr, - relstr, segno); - } + { + path = (char *) palloc(strlen(DataDir) + strlen("/base/") + 2 * sizeof(NameData) + 2 + nchars); + if (segno == 0) + sprintf(path, "%s/base/%s/%s", DataDir, + dbstr, relstr); + else + sprintf(path, "%s/base/%s/%s.%d", DataDir, dbstr, + relstr, segno); + } - if ((fd = open(path, O_RDWR, 0600)) < 0) - return (SM_FAIL); + if ((fd = open(path, O_RDWR, 0600)) < 0) + return (SM_FAIL); - /* seek to the right spot */ - seekpos = (long) (BLCKSZ * (blkno % RELSEG_SIZE)); - if (lseek(fd, seekpos, SEEK_SET) != seekpos) { - close(fd); - return (SM_FAIL); - } + /* seek to the right spot */ + seekpos = (long) (BLCKSZ * (blkno % RELSEG_SIZE)); + if (lseek(fd, seekpos, SEEK_SET) != seekpos) + { + close(fd); + return (SM_FAIL); + } - status = SM_SUCCESS; + status = SM_SUCCESS; - /* write and sync the block */ - if (write(fd, buffer, BLCKSZ) != BLCKSZ || (pg_fsync(fd) < 0)) - status = SM_FAIL; + /* write and sync the block */ + if (write(fd, buffer, BLCKSZ) != BLCKSZ || (pg_fsync(fd) < 0)) + status = SM_FAIL; - if (close(fd) < 0) - status = SM_FAIL; + if (close(fd) < 0) + status = SM_FAIL; - pfree(path); + pfree(path); - return (status); + return (status); } /* - * mdnblocks() -- Get the number of blocks stored in a relation. + * mdnblocks() -- Get the number of blocks stored in a relation. * - * Returns # of blocks or -1 on error. + * Returns # of blocks or -1 on error. */ int mdnblocks(Relation reln) { - int fd; - MdfdVec *v; - int nblocks; - int segno; + int fd; + MdfdVec *v; + int nblocks; + int segno; - fd = RelationGetFile(reln); - v = &Md_fdvec[fd]; + fd = RelationGetFile(reln); + v = &Md_fdvec[fd]; #ifdef DIAGNOSTIC - if (_mdnblocks(v->mdfd_vfd, BLCKSZ) > RELSEG_SIZE) - elog(FATAL, "segment too big in getseg!"); + if (_mdnblocks(v->mdfd_vfd, BLCKSZ) > RELSEG_SIZE) + elog(FATAL, "segment too big in getseg!"); #endif - segno = 0; - for (;;) { - if (v->mdfd_lstbcnt == RELSEG_SIZE - || (nblocks = _mdnblocks(v->mdfd_vfd, BLCKSZ)) == RELSEG_SIZE) { - - v->mdfd_lstbcnt = RELSEG_SIZE; - segno++; - - if (v->mdfd_chain == (MdfdVec *) NULL) { - v->mdfd_chain = _mdfd_openseg(reln, segno, O_CREAT); - if (v->mdfd_chain == (MdfdVec *) NULL) - elog(WARN, "cannot count blocks for %.16s -- open failed", - RelationGetRelationName(reln)); - } - - v = v->mdfd_chain; - } else { - return ((segno * RELSEG_SIZE) + nblocks); + segno = 0; + for (;;) + { + if (v->mdfd_lstbcnt == RELSEG_SIZE + || (nblocks = _mdnblocks(v->mdfd_vfd, BLCKSZ)) == RELSEG_SIZE) + { + + v->mdfd_lstbcnt = RELSEG_SIZE; + segno++; + + if (v->mdfd_chain == (MdfdVec *) NULL) + { + v->mdfd_chain = _mdfd_openseg(reln, segno, O_CREAT); + if (v->mdfd_chain == (MdfdVec *) NULL) + elog(WARN, "cannot count blocks for %.16s -- open failed", + RelationGetRelationName(reln)); + } + + v = v->mdfd_chain; + } + else + { + return ((segno * RELSEG_SIZE) + nblocks); + } } - } } /* - * mdtruncate() -- Truncate relation to specified number of blocks. + * mdtruncate() -- Truncate relation to specified number of blocks. * - * Returns # of blocks or -1 on error. + * Returns # of blocks or -1 on error. */ int -mdtruncate (Relation reln, int nblocks) +mdtruncate(Relation reln, int nblocks) { - int fd; - MdfdVec *v; - int curnblk; + int fd; + MdfdVec *v; + int curnblk; - curnblk = mdnblocks (reln); - if ( curnblk / RELSEG_SIZE > 0 ) - { - elog (NOTICE, "Can't truncate multi-segments relation %s", - &(reln->rd_rel->relname.data[0])); - return (curnblk); - } + curnblk = mdnblocks(reln); + if (curnblk / RELSEG_SIZE > 0) + { + elog(NOTICE, "Can't truncate multi-segments relation %s", + &(reln->rd_rel->relname.data[0])); + return (curnblk); + } + + fd = RelationGetFile(reln); + v = &Md_fdvec[fd]; - fd = RelationGetFile(reln); - v = &Md_fdvec[fd]; + if (FileTruncate(v->mdfd_vfd, nblocks * BLCKSZ) < 0) + return (-1); - if ( FileTruncate (v->mdfd_vfd, nblocks * BLCKSZ) < 0 ) - return (-1); - - return (nblocks); + return (nblocks); -} /* mdtruncate */ +} /* mdtruncate */ /* - * mdcommit() -- Commit a transaction. + * mdcommit() -- Commit a transaction. * - * All changes to magnetic disk relations must be forced to stable - * storage. This routine makes a pass over the private table of - * file descriptors. Any descriptors to which we have done writes, - * but not synced, are synced here. + * All changes to magnetic disk relations must be forced to stable + * storage. This routine makes a pass over the private table of + * file descriptors. Any descriptors to which we have done writes, + * but not synced, are synced here. * - * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate. + * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate. */ int mdcommit() { - int i; - MdfdVec *v; + int i; + MdfdVec *v; - for (i = 0; i < CurFd; i++) { - for (v = &Md_fdvec[i]; v != (MdfdVec *) NULL; v = v->mdfd_chain) { - if (v->mdfd_flags & MDFD_DIRTY) { - if (FileSync(v->mdfd_vfd) < 0) - return (SM_FAIL); - - v->mdfd_flags &= ~MDFD_DIRTY; - } + for (i = 0; i < CurFd; i++) + { + for (v = &Md_fdvec[i]; v != (MdfdVec *) NULL; v = v->mdfd_chain) + { + if (v->mdfd_flags & MDFD_DIRTY) + { + if (FileSync(v->mdfd_vfd) < 0) + return (SM_FAIL); + + v->mdfd_flags &= ~MDFD_DIRTY; + } + } } - } - return (SM_SUCCESS); + return (SM_SUCCESS); } /* - * mdabort() -- Abort a transaction. + * mdabort() -- Abort a transaction. * - * Changes need not be forced to disk at transaction abort. We mark - * all file descriptors as clean here. Always returns SM_SUCCESS. + * Changes need not be forced to disk at transaction abort. We mark + * all file descriptors as clean here. Always returns SM_SUCCESS. */ int mdabort() { - int i; - MdfdVec *v; + int i; + MdfdVec *v; - for (i = 0; i < CurFd; i++) { - for (v = &Md_fdvec[i]; v != (MdfdVec *) NULL; v = v->mdfd_chain) { - v->mdfd_flags &= ~MDFD_DIRTY; + for (i = 0; i < CurFd; i++) + { + for (v = &Md_fdvec[i]; v != (MdfdVec *) NULL; v = v->mdfd_chain) + { + v->mdfd_flags &= ~MDFD_DIRTY; + } } - } - return (SM_SUCCESS); + return (SM_SUCCESS); } /* - * _fdvec_alloc () -- grab a free (or new) md file descriptor vector. + * _fdvec_alloc () -- grab a free (or new) md file descriptor vector. * */ static -int _fdvec_alloc () +int +_fdvec_alloc() { - MdfdVec *nvec; - int fdvec, i; - MemoryContext oldcxt; - - if ( Md_Free >= 0 ) /* get from free list */ - { - fdvec = Md_Free; - Md_Free = Md_fdvec[fdvec].mdfd_nextFree; - Assert ( Md_fdvec[fdvec].mdfd_flags == MDFD_FREE ); - Md_fdvec[fdvec].mdfd_flags = 0; - if ( fdvec >= CurFd ) + MdfdVec *nvec; + int fdvec, + i; + MemoryContext oldcxt; + + if (Md_Free >= 0) /* get from free list */ { - Assert ( fdvec == CurFd ); - CurFd++; + fdvec = Md_Free; + Md_Free = Md_fdvec[fdvec].mdfd_nextFree; + Assert(Md_fdvec[fdvec].mdfd_flags == MDFD_FREE); + Md_fdvec[fdvec].mdfd_flags = 0; + if (fdvec >= CurFd) + { + Assert(fdvec == CurFd); + CurFd++; + } + return (fdvec); } - return (fdvec); - } - /* Must allocate more room */ - - if ( Nfds != CurFd ) - elog (FATAL, "_fdvec_alloc error"); - - Nfds *= 2; + /* Must allocate more room */ + + if (Nfds != CurFd) + elog(FATAL, "_fdvec_alloc error"); - oldcxt = MemoryContextSwitchTo(MdCxt); + Nfds *= 2; - nvec = (MdfdVec *) palloc(Nfds * sizeof(MdfdVec)); - memset(nvec, 0, Nfds * sizeof(MdfdVec)); - memmove(nvec, (char *) Md_fdvec, CurFd * sizeof(MdfdVec)); - pfree(Md_fdvec); + oldcxt = MemoryContextSwitchTo(MdCxt); - MemoryContextSwitchTo(oldcxt); + nvec = (MdfdVec *) palloc(Nfds * sizeof(MdfdVec)); + memset(nvec, 0, Nfds * sizeof(MdfdVec)); + memmove(nvec, (char *) Md_fdvec, CurFd * sizeof(MdfdVec)); + pfree(Md_fdvec); - Md_fdvec = nvec; + MemoryContextSwitchTo(oldcxt); - /* Set new free list */ - for (i = CurFd; i < Nfds; i++ ) - { - Md_fdvec[i].mdfd_nextFree = i + 1; - Md_fdvec[i].mdfd_flags = MDFD_FREE; - } - Md_fdvec[Nfds - 1].mdfd_nextFree = -1; - Md_Free = CurFd + 1; + Md_fdvec = nvec; - fdvec = CurFd; - CurFd++; - Md_fdvec[fdvec].mdfd_flags = 0; + /* Set new free list */ + for (i = CurFd; i < Nfds; i++) + { + Md_fdvec[i].mdfd_nextFree = i + 1; + Md_fdvec[i].mdfd_flags = MDFD_FREE; + } + Md_fdvec[Nfds - 1].mdfd_nextFree = -1; + Md_Free = CurFd + 1; - return (fdvec); + fdvec = CurFd; + CurFd++; + Md_fdvec[fdvec].mdfd_flags = 0; + + return (fdvec); } /* - * _fdvec_free () -- free md file descriptor vector. + * _fdvec_free () -- free md file descriptor vector. * */ static -void _fdvec_free (int fdvec) +void +_fdvec_free(int fdvec) { - - Assert ( Md_Free < 0 || Md_fdvec[Md_Free].mdfd_flags == MDFD_FREE ); - Md_fdvec[fdvec].mdfd_nextFree = Md_Free; - Md_fdvec[fdvec].mdfd_flags = MDFD_FREE; - Md_Free = fdvec; + + Assert(Md_Free < 0 || Md_fdvec[Md_Free].mdfd_flags == MDFD_FREE); + Md_fdvec[fdvec].mdfd_nextFree = Md_Free; + Md_fdvec[fdvec].mdfd_flags = MDFD_FREE; + Md_Free = fdvec; } static MdfdVec * _mdfd_openseg(Relation reln, int segno, int oflags) { - MemoryContext oldcxt; - MdfdVec *v; - int fd; - bool dofree; - char *path, *fullpath; - - /* be sure we have enough space for the '.segno', if any */ - path = relpath(RelationGetRelationName(reln)->data); - - dofree = false; - if (segno > 0) { - dofree = true; - fullpath = (char *) palloc(strlen(path) + 12); - sprintf(fullpath, "%s.%d", path, segno); - } else - fullpath = path; - - /* open the file */ - fd = PathNameOpenFile(fullpath, O_RDWR|oflags, 0600); - - if (dofree) - pfree(fullpath); - - if (fd < 0) - return ((MdfdVec *) NULL); - - /* allocate an mdfdvec entry for it */ - oldcxt = MemoryContextSwitchTo(MdCxt); - v = (MdfdVec *) palloc(sizeof(MdfdVec)); - MemoryContextSwitchTo(oldcxt); - - /* fill the entry */ - v->mdfd_vfd = fd; - v->mdfd_flags = (uint16) 0; - v->mdfd_chain = (MdfdVec *) NULL; - v->mdfd_lstbcnt = _mdnblocks(fd, BLCKSZ); + MemoryContext oldcxt; + MdfdVec *v; + int fd; + bool dofree; + char *path, + *fullpath; + + /* be sure we have enough space for the '.segno', if any */ + path = relpath(RelationGetRelationName(reln)->data); + + dofree = false; + if (segno > 0) + { + dofree = true; + fullpath = (char *) palloc(strlen(path) + 12); + sprintf(fullpath, "%s.%d", path, segno); + } + else + fullpath = path; + + /* open the file */ + fd = PathNameOpenFile(fullpath, O_RDWR | oflags, 0600); + + if (dofree) + pfree(fullpath); + + if (fd < 0) + return ((MdfdVec *) NULL); + + /* allocate an mdfdvec entry for it */ + oldcxt = MemoryContextSwitchTo(MdCxt); + v = (MdfdVec *) palloc(sizeof(MdfdVec)); + MemoryContextSwitchTo(oldcxt); + + /* fill the entry */ + v->mdfd_vfd = fd; + v->mdfd_flags = (uint16) 0; + v->mdfd_chain = (MdfdVec *) NULL; + v->mdfd_lstbcnt = _mdnblocks(fd, BLCKSZ); #ifdef DIAGNOSTIC - if (v->mdfd_lstbcnt > RELSEG_SIZE) - elog(FATAL, "segment too big on open!"); + if (v->mdfd_lstbcnt > RELSEG_SIZE) + elog(FATAL, "segment too big on open!"); #endif - /* all done */ - return (v); + /* all done */ + return (v); } static MdfdVec * _mdfd_getseg(Relation reln, int blkno, int oflag) { - MdfdVec *v; - int segno; - int fd; - int i; - - fd = RelationGetFile(reln); - if (fd < 0) { - if ((fd = mdopen(reln)) < 0) - elog(WARN, "cannot open relation %.16s", - RelationGetRelationName(reln)); - reln->rd_fd = fd; - } - - for (v = &Md_fdvec[fd], segno = blkno / RELSEG_SIZE, i = 1; - segno > 0; - i++, segno--) { - - if (v->mdfd_chain == (MdfdVec *) NULL) { - v->mdfd_chain = _mdfd_openseg(reln, i, oflag); - - if (v->mdfd_chain == (MdfdVec *) NULL) - elog(WARN, "cannot open segment %d of relation %.16s", - i, RelationGetRelationName(reln)); + MdfdVec *v; + int segno; + int fd; + int i; + + fd = RelationGetFile(reln); + if (fd < 0) + { + if ((fd = mdopen(reln)) < 0) + elog(WARN, "cannot open relation %.16s", + RelationGetRelationName(reln)); + reln->rd_fd = fd; + } + + for (v = &Md_fdvec[fd], segno = blkno / RELSEG_SIZE, i = 1; + segno > 0; + i++, segno--) + { + + if (v->mdfd_chain == (MdfdVec *) NULL) + { + v->mdfd_chain = _mdfd_openseg(reln, i, oflag); + + if (v->mdfd_chain == (MdfdVec *) NULL) + elog(WARN, "cannot open segment %d of relation %.16s", + i, RelationGetRelationName(reln)); + } + v = v->mdfd_chain; } - v = v->mdfd_chain; - } - return (v); + return (v); } -static BlockNumber +static BlockNumber _mdnblocks(File file, Size blcksz) { - long len; - - len = FileSeek(file, 0L, SEEK_END) - 1; - return((BlockNumber)((len < 0) ? 0 : 1 + len / blcksz)); + long len; + + len = FileSeek(file, 0L, SEEK_END) - 1; + return ((BlockNumber) ((len < 0) ? 0 : 1 + len / blcksz)); } diff --git a/src/backend/storage/smgr/mm.c b/src/backend/storage/smgr/mm.c index fd6c32da3a3..d0015e4f138 100644 --- a/src/backend/storage/smgr/mm.c +++ b/src/backend/storage/smgr/mm.c @@ -1,16 +1,16 @@ /*------------------------------------------------------------------------- * * mm.c-- - * main memory storage manager + * main memory storage manager * - * This code manages relations that reside in (presumably stable) - * main memory. + * This code manages relations that reside in (presumably stable) + * main memory. * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/smgr/Attic/mm.c,v 1.4 1996/11/08 05:59:11 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/smgr/Attic/mm.c,v 1.5 1997/09/07 04:49:22 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -20,7 +20,7 @@ #include <math.h> #include "storage/ipc.h" -#include "storage/smgr.h" /* where the declarations go */ +#include "storage/smgr.h" /* where the declarations go */ #include "storage/block.h" #include "storage/shmem.h" #include "storage/spin.h" @@ -31,555 +31,582 @@ #include "utils/memutils.h" /* - * MMCacheTag -- Unique triplet for blocks stored by the main memory - * storage manager. + * MMCacheTag -- Unique triplet for blocks stored by the main memory + * storage manager. */ -typedef struct MMCacheTag { - Oid mmct_dbid; - Oid mmct_relid; - BlockNumber mmct_blkno; -} MMCacheTag; +typedef struct MMCacheTag +{ + Oid mmct_dbid; + Oid mmct_relid; + BlockNumber mmct_blkno; +} MMCacheTag; /* - * Shared-memory hash table for main memory relations contains - * entries of this form. + * Shared-memory hash table for main memory relations contains + * entries of this form. */ -typedef struct MMHashEntry { - MMCacheTag mmhe_tag; - int mmhe_bufno; -} MMHashEntry; +typedef struct MMHashEntry +{ + MMCacheTag mmhe_tag; + int mmhe_bufno; +} MMHashEntry; /* * MMRelTag -- Unique identifier for each relation that is stored in the - * main-memory storage manager. + * main-memory storage manager. */ -typedef struct MMRelTag { - Oid mmrt_dbid; - Oid mmrt_relid; -} MMRelTag; +typedef struct MMRelTag +{ + Oid mmrt_dbid; + Oid mmrt_relid; +} MMRelTag; /* - * Shared-memory hash table for # blocks in main memory relations contains - * entries of this form. + * Shared-memory hash table for # blocks in main memory relations contains + * entries of this form. */ -typedef struct MMRelHashEntry { - MMRelTag mmrhe_tag; - int mmrhe_nblocks; -} MMRelHashEntry; +typedef struct MMRelHashEntry +{ + MMRelTag mmrhe_tag; + int mmrhe_nblocks; +} MMRelHashEntry; -#define MMNBUFFERS 10 +#define MMNBUFFERS 10 #define MMNRELATIONS 2 -SPINLOCK MMCacheLock; -extern bool IsPostmaster; -extern Oid MyDatabaseId; +SPINLOCK MMCacheLock; +extern bool IsPostmaster; +extern Oid MyDatabaseId; -static int *MMCurTop; -static int *MMCurRelno; -static MMCacheTag *MMBlockTags; -static char *MMBlockCache; -static HTAB *MMCacheHT; -static HTAB *MMRelCacheHT; +static int *MMCurTop; +static int *MMCurRelno; +static MMCacheTag *MMBlockTags; +static char *MMBlockCache; +static HTAB *MMCacheHT; +static HTAB *MMRelCacheHT; int mminit() { - char *mmcacheblk; - int mmsize = 0; - bool found; - HASHCTL info; + char *mmcacheblk; + int mmsize = 0; + bool found; + HASHCTL info; - SpinAcquire(MMCacheLock); + SpinAcquire(MMCacheLock); - mmsize += MAXALIGN(BLCKSZ * MMNBUFFERS); - mmsize += MAXALIGN(sizeof(*MMCurTop)); - mmsize += MAXALIGN(sizeof(*MMCurRelno)); - mmsize += MAXALIGN((MMNBUFFERS * sizeof(MMCacheTag))); - mmcacheblk = (char *) ShmemInitStruct("Main memory smgr", mmsize, &found); + mmsize += MAXALIGN(BLCKSZ * MMNBUFFERS); + mmsize += MAXALIGN(sizeof(*MMCurTop)); + mmsize += MAXALIGN(sizeof(*MMCurRelno)); + mmsize += MAXALIGN((MMNBUFFERS * sizeof(MMCacheTag))); + mmcacheblk = (char *) ShmemInitStruct("Main memory smgr", mmsize, &found); - if (mmcacheblk == (char *) NULL) { - SpinRelease(MMCacheLock); - return (SM_FAIL); - } + if (mmcacheblk == (char *) NULL) + { + SpinRelease(MMCacheLock); + return (SM_FAIL); + } - info.keysize = sizeof(MMCacheTag); - info.datasize = sizeof(int); - info.hash = tag_hash; + info.keysize = sizeof(MMCacheTag); + info.datasize = sizeof(int); + info.hash = tag_hash; - MMCacheHT = (HTAB *) ShmemInitHash("Main memory store HT", - MMNBUFFERS, MMNBUFFERS, - &info, (HASH_ELEM|HASH_FUNCTION)); + MMCacheHT = (HTAB *) ShmemInitHash("Main memory store HT", + MMNBUFFERS, MMNBUFFERS, + &info, (HASH_ELEM | HASH_FUNCTION)); - if (MMCacheHT == (HTAB *) NULL) { - SpinRelease(MMCacheLock); - return (SM_FAIL); - } + if (MMCacheHT == (HTAB *) NULL) + { + SpinRelease(MMCacheLock); + return (SM_FAIL); + } - info.keysize = sizeof(MMRelTag); - info.datasize = sizeof(int); - info.hash = tag_hash; + info.keysize = sizeof(MMRelTag); + info.datasize = sizeof(int); + info.hash = tag_hash; - MMRelCacheHT = (HTAB *) ShmemInitHash("Main memory rel HT", - MMNRELATIONS, MMNRELATIONS, - &info, (HASH_ELEM|HASH_FUNCTION)); + MMRelCacheHT = (HTAB *) ShmemInitHash("Main memory rel HT", + MMNRELATIONS, MMNRELATIONS, + &info, (HASH_ELEM | HASH_FUNCTION)); - if (MMRelCacheHT == (HTAB *) NULL) { - SpinRelease(MMCacheLock); - return (SM_FAIL); - } + if (MMRelCacheHT == (HTAB *) NULL) + { + SpinRelease(MMCacheLock); + return (SM_FAIL); + } - if (IsPostmaster) { - memset(mmcacheblk, 0, mmsize); - SpinRelease(MMCacheLock); - return (SM_SUCCESS); - } + if (IsPostmaster) + { + memset(mmcacheblk, 0, mmsize); + SpinRelease(MMCacheLock); + return (SM_SUCCESS); + } - SpinRelease(MMCacheLock); + SpinRelease(MMCacheLock); - MMCurTop = (int *) mmcacheblk; - mmcacheblk += sizeof(int); - MMCurRelno = (int *) mmcacheblk; - mmcacheblk += sizeof(int); - MMBlockTags = (MMCacheTag *) mmcacheblk; - mmcacheblk += (MMNBUFFERS * sizeof(MMCacheTag)); - MMBlockCache = mmcacheblk; + MMCurTop = (int *) mmcacheblk; + mmcacheblk += sizeof(int); + MMCurRelno = (int *) mmcacheblk; + mmcacheblk += sizeof(int); + MMBlockTags = (MMCacheTag *) mmcacheblk; + mmcacheblk += (MMNBUFFERS * sizeof(MMCacheTag)); + MMBlockCache = mmcacheblk; - return (SM_SUCCESS); + return (SM_SUCCESS); } int mmshutdown() { - return (SM_SUCCESS); + return (SM_SUCCESS); } int mmcreate(Relation reln) { - MMRelHashEntry *entry; - bool found; - MMRelTag tag; + MMRelHashEntry *entry; + bool found; + MMRelTag tag; - SpinAcquire(MMCacheLock); + SpinAcquire(MMCacheLock); - if (*MMCurRelno == MMNRELATIONS) { - SpinRelease(MMCacheLock); - return (SM_FAIL); - } + if (*MMCurRelno == MMNRELATIONS) + { + SpinRelease(MMCacheLock); + return (SM_FAIL); + } - (*MMCurRelno)++; + (*MMCurRelno)++; - tag.mmrt_relid = reln->rd_id; - if (reln->rd_rel->relisshared) - tag.mmrt_dbid = (Oid) 0; - else - tag.mmrt_dbid = MyDatabaseId; + tag.mmrt_relid = reln->rd_id; + if (reln->rd_rel->relisshared) + tag.mmrt_dbid = (Oid) 0; + else + tag.mmrt_dbid = MyDatabaseId; - entry = (MMRelHashEntry *) hash_search(MMRelCacheHT, - (char *) &tag, HASH_ENTER, &found); + entry = (MMRelHashEntry *) hash_search(MMRelCacheHT, + (char *) &tag, HASH_ENTER, &found); - if (entry == (MMRelHashEntry *) NULL) { - SpinRelease(MMCacheLock); - elog(FATAL, "main memory storage mgr rel cache hash table corrupt"); - } + if (entry == (MMRelHashEntry *) NULL) + { + SpinRelease(MMCacheLock); + elog(FATAL, "main memory storage mgr rel cache hash table corrupt"); + } - if (found) { - /* already exists */ - SpinRelease(MMCacheLock); - return (SM_FAIL); - } + if (found) + { + /* already exists */ + SpinRelease(MMCacheLock); + return (SM_FAIL); + } - entry->mmrhe_nblocks = 0; + entry->mmrhe_nblocks = 0; - SpinRelease(MMCacheLock); + SpinRelease(MMCacheLock); - return (SM_SUCCESS); + return (SM_SUCCESS); } /* - * mmunlink() -- Unlink a relation. + * mmunlink() -- Unlink a relation. */ int mmunlink(Relation reln) { - int i; - Oid reldbid; - MMHashEntry *entry; - MMRelHashEntry *rentry; - bool found; - MMRelTag rtag; - - if (reln->rd_rel->relisshared) - reldbid = (Oid) 0; - else - reldbid = MyDatabaseId; - - SpinAcquire(MMCacheLock); - - for (i = 0; i < MMNBUFFERS; i++) { - if (MMBlockTags[i].mmct_dbid == reldbid - && MMBlockTags[i].mmct_relid == reln->rd_id) { - entry = (MMHashEntry *) hash_search(MMCacheHT, - (char *) &MMBlockTags[i], - HASH_REMOVE, &found); - if (entry == (MMHashEntry *) NULL || !found) { - SpinRelease(MMCacheLock); - elog(FATAL, "mmunlink: cache hash table corrupted"); - } - MMBlockTags[i].mmct_dbid = (Oid) 0; - MMBlockTags[i].mmct_relid = (Oid) 0; - MMBlockTags[i].mmct_blkno = (BlockNumber) 0; + int i; + Oid reldbid; + MMHashEntry *entry; + MMRelHashEntry *rentry; + bool found; + MMRelTag rtag; + + if (reln->rd_rel->relisshared) + reldbid = (Oid) 0; + else + reldbid = MyDatabaseId; + + SpinAcquire(MMCacheLock); + + for (i = 0; i < MMNBUFFERS; i++) + { + if (MMBlockTags[i].mmct_dbid == reldbid + && MMBlockTags[i].mmct_relid == reln->rd_id) + { + entry = (MMHashEntry *) hash_search(MMCacheHT, + (char *) &MMBlockTags[i], + HASH_REMOVE, &found); + if (entry == (MMHashEntry *) NULL || !found) + { + SpinRelease(MMCacheLock); + elog(FATAL, "mmunlink: cache hash table corrupted"); + } + MMBlockTags[i].mmct_dbid = (Oid) 0; + MMBlockTags[i].mmct_relid = (Oid) 0; + MMBlockTags[i].mmct_blkno = (BlockNumber) 0; + } } - } - rtag.mmrt_dbid = reldbid; - rtag.mmrt_relid = reln->rd_id; + rtag.mmrt_dbid = reldbid; + rtag.mmrt_relid = reln->rd_id; - rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT, (char *) &rtag, - HASH_REMOVE, &found); + rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT, (char *) &rtag, + HASH_REMOVE, &found); - if (rentry == (MMRelHashEntry *) NULL || !found) { - SpinRelease(MMCacheLock); - elog(FATAL, "mmunlink: rel cache hash table corrupted"); - } + if (rentry == (MMRelHashEntry *) NULL || !found) + { + SpinRelease(MMCacheLock); + elog(FATAL, "mmunlink: rel cache hash table corrupted"); + } - (*MMCurRelno)--; + (*MMCurRelno)--; - SpinRelease(MMCacheLock); - return 1; + SpinRelease(MMCacheLock); + return 1; } /* - * mmextend() -- Add a block to the specified relation. + * mmextend() -- Add a block to the specified relation. * - * This routine returns SM_FAIL or SM_SUCCESS, with errno set as - * appropriate. + * This routine returns SM_FAIL or SM_SUCCESS, with errno set as + * appropriate. */ int mmextend(Relation reln, char *buffer) { - MMRelHashEntry *rentry; - MMHashEntry *entry; - int i; - Oid reldbid; - int offset; - bool found; - MMRelTag rtag; - MMCacheTag tag; - - if (reln->rd_rel->relisshared) - reldbid = (Oid) 0; - else - reldbid = MyDatabaseId; - - tag.mmct_dbid = rtag.mmrt_dbid = reldbid; - tag.mmct_relid = rtag.mmrt_relid = reln->rd_id; - - SpinAcquire(MMCacheLock); - - if (*MMCurTop == MMNBUFFERS) { - for (i = 0; i < MMNBUFFERS; i++) { - if (MMBlockTags[i].mmct_dbid == 0 && - MMBlockTags[i].mmct_relid == 0) - break; + MMRelHashEntry *rentry; + MMHashEntry *entry; + int i; + Oid reldbid; + int offset; + bool found; + MMRelTag rtag; + MMCacheTag tag; + + if (reln->rd_rel->relisshared) + reldbid = (Oid) 0; + else + reldbid = MyDatabaseId; + + tag.mmct_dbid = rtag.mmrt_dbid = reldbid; + tag.mmct_relid = rtag.mmrt_relid = reln->rd_id; + + SpinAcquire(MMCacheLock); + + if (*MMCurTop == MMNBUFFERS) + { + for (i = 0; i < MMNBUFFERS; i++) + { + if (MMBlockTags[i].mmct_dbid == 0 && + MMBlockTags[i].mmct_relid == 0) + break; + } + if (i == MMNBUFFERS) + { + SpinRelease(MMCacheLock); + return (SM_FAIL); + } } - if (i == MMNBUFFERS) { - SpinRelease(MMCacheLock); - return (SM_FAIL); + else + { + i = *MMCurTop; + (*MMCurTop)++; } - } else { - i = *MMCurTop; - (*MMCurTop)++; - } - - rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT, (char *) &rtag, - HASH_FIND, &found); - if (rentry == (MMRelHashEntry *) NULL || !found) { - SpinRelease(MMCacheLock); - elog(FATAL, "mmextend: rel cache hash table corrupt"); - } - tag.mmct_blkno = rentry->mmrhe_nblocks; + rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT, (char *) &rtag, + HASH_FIND, &found); + if (rentry == (MMRelHashEntry *) NULL || !found) + { + SpinRelease(MMCacheLock); + elog(FATAL, "mmextend: rel cache hash table corrupt"); + } - entry = (MMHashEntry *) hash_search(MMCacheHT, (char *) &tag, - HASH_ENTER, &found); - if (entry == (MMHashEntry *) NULL || found) { - SpinRelease(MMCacheLock); - elog(FATAL, "mmextend: cache hash table corrupt"); - } + tag.mmct_blkno = rentry->mmrhe_nblocks; - entry->mmhe_bufno = i; - MMBlockTags[i].mmct_dbid = reldbid; - MMBlockTags[i].mmct_relid = reln->rd_id; - MMBlockTags[i].mmct_blkno = rentry->mmrhe_nblocks; + entry = (MMHashEntry *) hash_search(MMCacheHT, (char *) &tag, + HASH_ENTER, &found); + if (entry == (MMHashEntry *) NULL || found) + { + SpinRelease(MMCacheLock); + elog(FATAL, "mmextend: cache hash table corrupt"); + } - /* page numbers are zero-based, so we increment this at the end */ - (rentry->mmrhe_nblocks)++; + entry->mmhe_bufno = i; + MMBlockTags[i].mmct_dbid = reldbid; + MMBlockTags[i].mmct_relid = reln->rd_id; + MMBlockTags[i].mmct_blkno = rentry->mmrhe_nblocks; - /* write the extended page */ - offset = (i * BLCKSZ); - memmove(&(MMBlockCache[offset]), buffer, BLCKSZ); + /* page numbers are zero-based, so we increment this at the end */ + (rentry->mmrhe_nblocks)++; - SpinRelease(MMCacheLock); + /* write the extended page */ + offset = (i * BLCKSZ); + memmove(&(MMBlockCache[offset]), buffer, BLCKSZ); - return (SM_SUCCESS); + SpinRelease(MMCacheLock); + + return (SM_SUCCESS); } /* - * mmopen() -- Open the specified relation. + * mmopen() -- Open the specified relation. */ int mmopen(Relation reln) { - /* automatically successful */ - return (0); + /* automatically successful */ + return (0); } /* - * mmclose() -- Close the specified relation. + * mmclose() -- Close the specified relation. * - * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate. + * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate. */ int mmclose(Relation reln) { - /* automatically successful */ - return (SM_SUCCESS); + /* automatically successful */ + return (SM_SUCCESS); } /* - * mmread() -- Read the specified block from a relation. + * mmread() -- Read the specified block from a relation. * - * Returns SM_SUCCESS or SM_FAIL. + * Returns SM_SUCCESS or SM_FAIL. */ int mmread(Relation reln, BlockNumber blocknum, char *buffer) { - MMHashEntry *entry; - bool found; - int offset; - MMCacheTag tag; + MMHashEntry *entry; + bool found; + int offset; + MMCacheTag tag; - if (reln->rd_rel->relisshared) - tag.mmct_dbid = (Oid) 0; - else - tag.mmct_dbid = MyDatabaseId; + if (reln->rd_rel->relisshared) + tag.mmct_dbid = (Oid) 0; + else + tag.mmct_dbid = MyDatabaseId; - tag.mmct_relid = reln->rd_id; - tag.mmct_blkno = blocknum; + tag.mmct_relid = reln->rd_id; + tag.mmct_blkno = blocknum; - SpinAcquire(MMCacheLock); - entry = (MMHashEntry *) hash_search(MMCacheHT, (char *) &tag, - HASH_FIND, &found); + SpinAcquire(MMCacheLock); + entry = (MMHashEntry *) hash_search(MMCacheHT, (char *) &tag, + HASH_FIND, &found); - if (entry == (MMHashEntry *) NULL) { - SpinRelease(MMCacheLock); - elog(FATAL, "mmread: hash table corrupt"); - } + if (entry == (MMHashEntry *) NULL) + { + SpinRelease(MMCacheLock); + elog(FATAL, "mmread: hash table corrupt"); + } - if (!found) { - /* reading nonexistent pages is defined to fill them with zeroes */ - SpinRelease(MMCacheLock); - memset(buffer, 0, BLCKSZ); - return (SM_SUCCESS); - } + if (!found) + { + /* reading nonexistent pages is defined to fill them with zeroes */ + SpinRelease(MMCacheLock); + memset(buffer, 0, BLCKSZ); + return (SM_SUCCESS); + } - offset = (entry->mmhe_bufno * BLCKSZ); - memmove(buffer, &MMBlockCache[offset], BLCKSZ); + offset = (entry->mmhe_bufno * BLCKSZ); + memmove(buffer, &MMBlockCache[offset], BLCKSZ); - SpinRelease(MMCacheLock); + SpinRelease(MMCacheLock); - return (SM_SUCCESS); + return (SM_SUCCESS); } /* - * mmwrite() -- Write the supplied block at the appropriate location. + * mmwrite() -- Write the supplied block at the appropriate location. * - * Returns SM_SUCCESS or SM_FAIL. + * Returns SM_SUCCESS or SM_FAIL. */ int mmwrite(Relation reln, BlockNumber blocknum, char *buffer) { - MMHashEntry *entry; - bool found; - int offset; - MMCacheTag tag; + MMHashEntry *entry; + bool found; + int offset; + MMCacheTag tag; - if (reln->rd_rel->relisshared) - tag.mmct_dbid = (Oid) 0; - else - tag.mmct_dbid = MyDatabaseId; + if (reln->rd_rel->relisshared) + tag.mmct_dbid = (Oid) 0; + else + tag.mmct_dbid = MyDatabaseId; - tag.mmct_relid = reln->rd_id; - tag.mmct_blkno = blocknum; + tag.mmct_relid = reln->rd_id; + tag.mmct_blkno = blocknum; - SpinAcquire(MMCacheLock); - entry = (MMHashEntry *) hash_search(MMCacheHT, (char *) &tag, - HASH_FIND, &found); + SpinAcquire(MMCacheLock); + entry = (MMHashEntry *) hash_search(MMCacheHT, (char *) &tag, + HASH_FIND, &found); - if (entry == (MMHashEntry *) NULL) { - SpinRelease(MMCacheLock); - elog(FATAL, "mmread: hash table corrupt"); - } + if (entry == (MMHashEntry *) NULL) + { + SpinRelease(MMCacheLock); + elog(FATAL, "mmread: hash table corrupt"); + } - if (!found) { - SpinRelease(MMCacheLock); - elog(FATAL, "mmwrite: hash table missing requested page"); - } + if (!found) + { + SpinRelease(MMCacheLock); + elog(FATAL, "mmwrite: hash table missing requested page"); + } - offset = (entry->mmhe_bufno * BLCKSZ); - memmove(&MMBlockCache[offset], buffer, BLCKSZ); + offset = (entry->mmhe_bufno * BLCKSZ); + memmove(&MMBlockCache[offset], buffer, BLCKSZ); - SpinRelease(MMCacheLock); + SpinRelease(MMCacheLock); - return (SM_SUCCESS); + return (SM_SUCCESS); } /* - * mmflush() -- Synchronously write a block to stable storage. + * mmflush() -- Synchronously write a block to stable storage. * - * For main-memory relations, this is exactly equivalent to mmwrite(). + * For main-memory relations, this is exactly equivalent to mmwrite(). */ int mmflush(Relation reln, BlockNumber blocknum, char *buffer) { - return (mmwrite(reln, blocknum, buffer)); + return (mmwrite(reln, blocknum, buffer)); } /* - * mmblindwrt() -- Write a block to stable storage blind. + * mmblindwrt() -- Write a block to stable storage blind. * - * We have to be able to do this using only the name and OID of - * the database and relation in which the block belongs. + * We have to be able to do this using only the name and OID of + * the database and relation in which the block belongs. */ int mmblindwrt(char *dbstr, - char *relstr, - Oid dbid, - Oid relid, - BlockNumber blkno, - char *buffer) + char *relstr, + Oid dbid, + Oid relid, + BlockNumber blkno, + char *buffer) { - return (SM_FAIL); + return (SM_FAIL); } /* - * mmnblocks() -- Get the number of blocks stored in a relation. + * mmnblocks() -- Get the number of blocks stored in a relation. * - * Returns # of blocks or -1 on error. + * Returns # of blocks or -1 on error. */ int mmnblocks(Relation reln) { - MMRelTag rtag; - MMRelHashEntry *rentry; - bool found; - int nblocks; + MMRelTag rtag; + MMRelHashEntry *rentry; + bool found; + int nblocks; - if (reln->rd_rel->relisshared) - rtag.mmrt_dbid = (Oid) 0; - else - rtag.mmrt_dbid = MyDatabaseId; + if (reln->rd_rel->relisshared) + rtag.mmrt_dbid = (Oid) 0; + else + rtag.mmrt_dbid = MyDatabaseId; - rtag.mmrt_relid = reln->rd_id; + rtag.mmrt_relid = reln->rd_id; - SpinAcquire(MMCacheLock); + SpinAcquire(MMCacheLock); - rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT, (char *) &rtag, - HASH_FIND, &found); + rentry = (MMRelHashEntry *) hash_search(MMRelCacheHT, (char *) &rtag, + HASH_FIND, &found); - if (rentry == (MMRelHashEntry *) NULL) { - SpinRelease(MMCacheLock); - elog(FATAL, "mmnblocks: rel cache hash table corrupt"); - } + if (rentry == (MMRelHashEntry *) NULL) + { + SpinRelease(MMCacheLock); + elog(FATAL, "mmnblocks: rel cache hash table corrupt"); + } - if (found) - nblocks = rentry->mmrhe_nblocks; - else - nblocks = -1; + if (found) + nblocks = rentry->mmrhe_nblocks; + else + nblocks = -1; - SpinRelease(MMCacheLock); + SpinRelease(MMCacheLock); - return (nblocks); + return (nblocks); } /* - * mmcommit() -- Commit a transaction. + * mmcommit() -- Commit a transaction. * - * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate. + * Returns SM_SUCCESS or SM_FAIL with errno set as appropriate. */ int mmcommit() { - return (SM_SUCCESS); + return (SM_SUCCESS); } /* - * mmabort() -- Abort a transaction. + * mmabort() -- Abort a transaction. */ int mmabort() { - return (SM_SUCCESS); + return (SM_SUCCESS); } /* - * MMShmemSize() -- Declare amount of shared memory we require. + * MMShmemSize() -- Declare amount of shared memory we require. * - * The shared memory initialization code creates a block of shared - * memory exactly big enough to hold all the structures it needs to. - * This routine declares how much space the main memory storage - * manager will use. + * The shared memory initialization code creates a block of shared + * memory exactly big enough to hold all the structures it needs to. + * This routine declares how much space the main memory storage + * manager will use. */ int MMShmemSize() { - int size = 0; - int nbuckets; - int nsegs; - int tmp; - - /* - * first compute space occupied by the (dbid,relid,blkno) hash table - */ - - nbuckets = 1 << (int)my_log2((MMNBUFFERS - 1) / DEF_FFACTOR + 1); - nsegs = 1 << (int)my_log2((nbuckets - 1) / DEF_SEGSIZE + 1); - - size += MAXALIGN(my_log2(MMNBUFFERS) * sizeof(void *)); - size += MAXALIGN(sizeof(HHDR)); - size += nsegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT)); - tmp = (int)ceil((double)MMNBUFFERS/BUCKET_ALLOC_INCR); - size += tmp * BUCKET_ALLOC_INCR * - (MAXALIGN(sizeof(BUCKET_INDEX)) + - MAXALIGN(sizeof(MMHashEntry))); /* contains hash key */ - - /* - * now do the same for the rel hash table - */ - - size += MAXALIGN(my_log2(MMNRELATIONS) * sizeof(void *)); - size += MAXALIGN(sizeof(HHDR)); - size += nsegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT)); - tmp = (int)ceil((double)MMNRELATIONS/BUCKET_ALLOC_INCR); - size += tmp * BUCKET_ALLOC_INCR * - (MAXALIGN(sizeof(BUCKET_INDEX)) + - MAXALIGN(sizeof(MMRelHashEntry))); /* contains hash key */ - - /* - * finally, add in the memory block we use directly - */ - - size += MAXALIGN(BLCKSZ * MMNBUFFERS); - size += MAXALIGN(sizeof(*MMCurTop)); - size += MAXALIGN(sizeof(*MMCurRelno)); - size += MAXALIGN(MMNBUFFERS * sizeof(MMCacheTag)); - - return (size); + int size = 0; + int nbuckets; + int nsegs; + int tmp; + + /* + * first compute space occupied by the (dbid,relid,blkno) hash table + */ + + nbuckets = 1 << (int) my_log2((MMNBUFFERS - 1) / DEF_FFACTOR + 1); + nsegs = 1 << (int) my_log2((nbuckets - 1) / DEF_SEGSIZE + 1); + + size += MAXALIGN(my_log2(MMNBUFFERS) * sizeof(void *)); + size += MAXALIGN(sizeof(HHDR)); + size += nsegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT)); + tmp = (int) ceil((double) MMNBUFFERS / BUCKET_ALLOC_INCR); + size += tmp * BUCKET_ALLOC_INCR * + (MAXALIGN(sizeof(BUCKET_INDEX)) + + MAXALIGN(sizeof(MMHashEntry))); /* contains hash key */ + + /* + * now do the same for the rel hash table + */ + + size += MAXALIGN(my_log2(MMNRELATIONS) * sizeof(void *)); + size += MAXALIGN(sizeof(HHDR)); + size += nsegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT)); + tmp = (int) ceil((double) MMNRELATIONS / BUCKET_ALLOC_INCR); + size += tmp * BUCKET_ALLOC_INCR * + (MAXALIGN(sizeof(BUCKET_INDEX)) + + MAXALIGN(sizeof(MMRelHashEntry))); /* contains hash key */ + + /* + * finally, add in the memory block we use directly + */ + + size += MAXALIGN(BLCKSZ * MMNBUFFERS); + size += MAXALIGN(sizeof(*MMCurTop)); + size += MAXALIGN(sizeof(*MMCurRelno)); + size += MAXALIGN(MMNBUFFERS * sizeof(MMCacheTag)); + + return (size); } -#endif /* MAIN_MEMORY */ +#endif /* MAIN_MEMORY */ diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c index 89ac5e92cb7..9fc395da0d9 100644 --- a/src/backend/storage/smgr/smgr.c +++ b/src/backend/storage/smgr/smgr.c @@ -1,16 +1,16 @@ /*------------------------------------------------------------------------- * * smgr.c-- - * public interface routines to storage manager switch. + * public interface routines to storage manager switch. * - * All file system operations in POSTGRES dispatch through these - * routines. + * All file system operations in POSTGRES dispatch through these + * routines. * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgr.c,v 1.8 1997/08/19 21:33:38 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgr.c,v 1.9 1997/09/07 04:49:25 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -23,380 +23,390 @@ #include "utils/rel.h" #include "utils/palloc.h" -static void smgrshutdown(int dummy); - -typedef struct f_smgr { - int (*smgr_init)(); /* may be NULL */ - int (*smgr_shutdown)(); /* may be NULL */ - int (*smgr_create)(); - int (*smgr_unlink)(); - int (*smgr_extend)(); - int (*smgr_open)(); - int (*smgr_close)(); - int (*smgr_read)(); - int (*smgr_write)(); - int (*smgr_flush)(); - int (*smgr_blindwrt)(); - int (*smgr_nblocks)(); - int (*smgr_truncate)(); - int (*smgr_commit)(); /* may be NULL */ - int (*smgr_abort)(); /* may be NULL */ -} f_smgr; +static void smgrshutdown(int dummy); + +typedef struct f_smgr +{ + int (*smgr_init) (); /* may be NULL */ + int (*smgr_shutdown) (); /* may be NULL */ + int (*smgr_create) (); + int (*smgr_unlink) (); + int (*smgr_extend) (); + int (*smgr_open) (); + int (*smgr_close) (); + int (*smgr_read) (); + int (*smgr_write) (); + int (*smgr_flush) (); + int (*smgr_blindwrt) (); + int (*smgr_nblocks) (); + int (*smgr_truncate) (); + int (*smgr_commit) (); /* may be NULL */ + int (*smgr_abort) (); /* may be NULL */ +} f_smgr; /* - * The weird placement of commas in this init block is to keep the compiler - * happy, regardless of what storage managers we have (or don't have). + * The weird placement of commas in this init block is to keep the compiler + * happy, regardless of what storage managers we have (or don't have). */ -static f_smgr smgrsw[] = { +static f_smgr smgrsw[] = { - /* magnetic disk */ - { mdinit, NULL, mdcreate, mdunlink, mdextend, mdopen, mdclose, - mdread, mdwrite, mdflush, mdblindwrt, mdnblocks, mdtruncate, - mdcommit, mdabort }, + /* magnetic disk */ + {mdinit, NULL, mdcreate, mdunlink, mdextend, mdopen, mdclose, + mdread, mdwrite, mdflush, mdblindwrt, mdnblocks, mdtruncate, + mdcommit, mdabort}, #ifdef MAIN_MEMORY - /* main memory */ - { mminit, mmshutdown, mmcreate, mmunlink, mmextend, mmopen, mmclose, - mmread, mmwrite, mmflush, mmblindwrt, mmnblocks, NULL, - mmcommit, mmabort }, + /* main memory */ + {mminit, mmshutdown, mmcreate, mmunlink, mmextend, mmopen, mmclose, + mmread, mmwrite, mmflush, mmblindwrt, mmnblocks, NULL, + mmcommit, mmabort}, -#endif /* MAIN_MEMORY */ +#endif /* MAIN_MEMORY */ }; /* - * This array records which storage managers are write-once, and which - * support overwrite. A 'true' entry means that the storage manager is - * write-once. In the best of all possible worlds, there would be no - * write-once storage managers. + * This array records which storage managers are write-once, and which + * support overwrite. A 'true' entry means that the storage manager is + * write-once. In the best of all possible worlds, there would be no + * write-once storage managers. */ -static bool smgrwo[] = { - false, /* magnetic disk */ +static bool smgrwo[] = { + false, /* magnetic disk */ #ifdef MAIN_MEMORY - false, /* main memory*/ -#endif /* MAIN_MEMORY */ + false, /* main memory */ +#endif /* MAIN_MEMORY */ }; -static int NSmgr = lengthof(smgrsw); +static int NSmgr = lengthof(smgrsw); /* - * smgrinit(), smgrshutdown() -- Initialize or shut down all storage - * managers. + * smgrinit(), smgrshutdown() -- Initialize or shut down all storage + * managers. * */ int smgrinit() { - int i; - - for (i = 0; i < NSmgr; i++) { - if (smgrsw[i].smgr_init) { - if ((*(smgrsw[i].smgr_init))() == SM_FAIL) - elog(FATAL, "initialization failed on %s", smgrout(i)); + int i; + + for (i = 0; i < NSmgr; i++) + { + if (smgrsw[i].smgr_init) + { + if ((*(smgrsw[i].smgr_init)) () == SM_FAIL) + elog(FATAL, "initialization failed on %s", smgrout(i)); + } } - } - /* register the shutdown proc */ - on_exitpg(smgrshutdown, 0); + /* register the shutdown proc */ + on_exitpg(smgrshutdown, 0); - return (SM_SUCCESS); + return (SM_SUCCESS); } static void smgrshutdown(int dummy) { - int i; - - for (i = 0; i < NSmgr; i++) { - if (smgrsw[i].smgr_shutdown) { - if ((*(smgrsw[i].smgr_shutdown))() == SM_FAIL) - elog(FATAL, "shutdown failed on %s", smgrout(i)); + int i; + + for (i = 0; i < NSmgr; i++) + { + if (smgrsw[i].smgr_shutdown) + { + if ((*(smgrsw[i].smgr_shutdown)) () == SM_FAIL) + elog(FATAL, "shutdown failed on %s", smgrout(i)); + } } - } } /* - * smgrcreate() -- Create a new relation. + * smgrcreate() -- Create a new relation. * - * This routine takes a reldesc, creates the relation on the appropriate - * device, and returns a file descriptor for it. + * This routine takes a reldesc, creates the relation on the appropriate + * device, and returns a file descriptor for it. */ int smgrcreate(int16 which, Relation reln) { - int fd; + int fd; - if ((fd = (*(smgrsw[which].smgr_create))(reln)) < 0) - elog(WARN, "cannot open %s", - &(reln->rd_rel->relname.data[0])); + if ((fd = (*(smgrsw[which].smgr_create)) (reln)) < 0) + elog(WARN, "cannot open %s", + &(reln->rd_rel->relname.data[0])); - return (fd); + return (fd); } /* - * smgrunlink() -- Unlink a relation. + * smgrunlink() -- Unlink a relation. * - * The relation is removed from the store. + * The relation is removed from the store. */ int smgrunlink(int16 which, Relation reln) { - int status; + int status; - if ((status = (*(smgrsw[which].smgr_unlink))(reln)) == SM_FAIL) - elog(WARN, "cannot unlink %s", - &(reln->rd_rel->relname.data[0])); + if ((status = (*(smgrsw[which].smgr_unlink)) (reln)) == SM_FAIL) + elog(WARN, "cannot unlink %s", + &(reln->rd_rel->relname.data[0])); - return (status); + return (status); } /* - * smgrextend() -- Add a new block to a file. + * smgrextend() -- Add a new block to a file. * - * Returns SM_SUCCESS on success; aborts the current transaction on - * failure. + * Returns SM_SUCCESS on success; aborts the current transaction on + * failure. */ int smgrextend(int16 which, Relation reln, char *buffer) { - int status; + int status; - status = (*(smgrsw[which].smgr_extend))(reln, buffer); + status = (*(smgrsw[which].smgr_extend)) (reln, buffer); - if (status == SM_FAIL) - elog(WARN, "%s: cannot extend", - &(reln->rd_rel->relname.data[0])); + if (status == SM_FAIL) + elog(WARN, "%s: cannot extend", + &(reln->rd_rel->relname.data[0])); - return (status); + return (status); } /* - * smgropen() -- Open a relation using a particular storage manager. + * smgropen() -- Open a relation using a particular storage manager. * - * Returns the fd for the open relation on success, aborts the - * transaction on failure. + * Returns the fd for the open relation on success, aborts the + * transaction on failure. */ int smgropen(int16 which, Relation reln) { - int fd; + int fd; - if ((fd = (*(smgrsw[which].smgr_open))(reln)) < 0) - elog(WARN, "cannot open %s", - &(reln->rd_rel->relname.data[0])); + if ((fd = (*(smgrsw[which].smgr_open)) (reln)) < 0) + elog(WARN, "cannot open %s", + &(reln->rd_rel->relname.data[0])); - return (fd); + return (fd); } /* - * smgrclose() -- Close a relation. + * smgrclose() -- Close a relation. * - * NOTE: mdclose frees fd vector! It may be re-used for other relation! - * reln should be flushed from cache after closing !.. - * Currently, smgrclose is calling by - * relcache.c:RelationPurgeLocalRelation() only. - * It would be nice to have smgrfree(), but because of - * smgrclose is called from single place... - vadim 05/22/97 + * NOTE: mdclose frees fd vector! It may be re-used for other relation! + * reln should be flushed from cache after closing !.. + * Currently, smgrclose is calling by + * relcache.c:RelationPurgeLocalRelation() only. + * It would be nice to have smgrfree(), but because of + * smgrclose is called from single place... - vadim 05/22/97 * - * Returns SM_SUCCESS on success, aborts on failure. + * Returns SM_SUCCESS on success, aborts on failure. */ int smgrclose(int16 which, Relation reln) { - if ((*(smgrsw[which].smgr_close))(reln) == SM_FAIL) - elog(WARN, "cannot close %s", - &(reln->rd_rel->relname.data[0])); + if ((*(smgrsw[which].smgr_close)) (reln) == SM_FAIL) + elog(WARN, "cannot close %s", + &(reln->rd_rel->relname.data[0])); - return (SM_SUCCESS); + return (SM_SUCCESS); } /* - * smgrread() -- read a particular block from a relation into the supplied - * buffer. + * smgrread() -- read a particular block from a relation into the supplied + * buffer. * - * This routine is called from the buffer manager in order to - * instantiate pages in the shared buffer cache. All storage managers - * return pages in the format that POSTGRES expects. This routine - * dispatches the read. On success, it returns SM_SUCCESS. On failure, - * the current transaction is aborted. + * This routine is called from the buffer manager in order to + * instantiate pages in the shared buffer cache. All storage managers + * return pages in the format that POSTGRES expects. This routine + * dispatches the read. On success, it returns SM_SUCCESS. On failure, + * the current transaction is aborted. */ int smgrread(int16 which, Relation reln, BlockNumber blocknum, char *buffer) { - int status; + int status; - status = (*(smgrsw[which].smgr_read))(reln, blocknum, buffer); + status = (*(smgrsw[which].smgr_read)) (reln, blocknum, buffer); - if (status == SM_FAIL) - elog(WARN, "cannot read block %d of %s", - blocknum, &(reln->rd_rel->relname.data[0])); + if (status == SM_FAIL) + elog(WARN, "cannot read block %d of %s", + blocknum, &(reln->rd_rel->relname.data[0])); - return (status); + return (status); } /* - * smgrwrite() -- Write the supplied buffer out. + * smgrwrite() -- Write the supplied buffer out. * - * This is not a synchronous write -- the interface for that is - * smgrflush(). The buffer is written out via the appropriate - * storage manager. This routine returns SM_SUCCESS or aborts - * the current transaction. + * This is not a synchronous write -- the interface for that is + * smgrflush(). The buffer is written out via the appropriate + * storage manager. This routine returns SM_SUCCESS or aborts + * the current transaction. */ int smgrwrite(int16 which, Relation reln, BlockNumber blocknum, char *buffer) { - int status; + int status; - status = (*(smgrsw[which].smgr_write))(reln, blocknum, buffer); + status = (*(smgrsw[which].smgr_write)) (reln, blocknum, buffer); - if (status == SM_FAIL) - elog(WARN, "cannot write block %d of %s", - blocknum, &(reln->rd_rel->relname.data[0])); + if (status == SM_FAIL) + elog(WARN, "cannot write block %d of %s", + blocknum, &(reln->rd_rel->relname.data[0])); - return (status); + return (status); } /* - * smgrflush() -- A synchronous smgrwrite(). + * smgrflush() -- A synchronous smgrwrite(). */ int smgrflush(int16 which, Relation reln, BlockNumber blocknum, char *buffer) { - int status; + int status; - status = (*(smgrsw[which].smgr_flush))(reln, blocknum, buffer); + status = (*(smgrsw[which].smgr_flush)) (reln, blocknum, buffer); - if (status == SM_FAIL) - elog(WARN, "cannot flush block %d of %s to stable store", - blocknum, &(reln->rd_rel->relname.data[0])); + if (status == SM_FAIL) + elog(WARN, "cannot flush block %d of %s to stable store", + blocknum, &(reln->rd_rel->relname.data[0])); - return (status); + return (status); } /* - * smgrblindwrt() -- Write a page out blind. + * smgrblindwrt() -- Write a page out blind. * - * In some cases, we may find a page in the buffer cache that we - * can't make a reldesc for. This happens, for example, when we - * want to reuse a dirty page that was written by a transaction - * that has not yet committed, which created a new relation. In - * this case, the buffer manager will call smgrblindwrt() with - * the name and OID of the database and the relation to which the - * buffer belongs. Every storage manager must be able to force - * this page down to stable storage in this circumstance. + * In some cases, we may find a page in the buffer cache that we + * can't make a reldesc for. This happens, for example, when we + * want to reuse a dirty page that was written by a transaction + * that has not yet committed, which created a new relation. In + * this case, the buffer manager will call smgrblindwrt() with + * the name and OID of the database and the relation to which the + * buffer belongs. Every storage manager must be able to force + * this page down to stable storage in this circumstance. */ int smgrblindwrt(int16 which, - char *dbname, - char *relname, - Oid dbid, - Oid relid, - BlockNumber blkno, - char *buffer) + char *dbname, + char *relname, + Oid dbid, + Oid relid, + BlockNumber blkno, + char *buffer) { - char *dbstr; - char *relstr; - int status; + char *dbstr; + char *relstr; + int status; - dbstr = pstrdup(dbname); - relstr = pstrdup(relname); + dbstr = pstrdup(dbname); + relstr = pstrdup(relname); - status = (*(smgrsw[which].smgr_blindwrt))(dbstr, relstr, dbid, relid, - blkno, buffer); + status = (*(smgrsw[which].smgr_blindwrt)) (dbstr, relstr, dbid, relid, + blkno, buffer); - if (status == SM_FAIL) - elog(WARN, "cannot write block %d of %s [%s] blind", - blkno, relstr, dbstr); + if (status == SM_FAIL) + elog(WARN, "cannot write block %d of %s [%s] blind", + blkno, relstr, dbstr); - pfree(dbstr); - pfree(relstr); + pfree(dbstr); + pfree(relstr); - return (status); + return (status); } /* - * smgrnblocks() -- Calculate the number of POSTGRES blocks in the - * supplied relation. + * smgrnblocks() -- Calculate the number of POSTGRES blocks in the + * supplied relation. * - * Returns the number of blocks on success, aborts the current - * transaction on failure. + * Returns the number of blocks on success, aborts the current + * transaction on failure. */ int smgrnblocks(int16 which, Relation reln) { - int nblocks; + int nblocks; - if ((nblocks = (*(smgrsw[which].smgr_nblocks))(reln)) < 0) - elog(WARN, "cannot count blocks for %s", - &(reln->rd_rel->relname.data[0])); + if ((nblocks = (*(smgrsw[which].smgr_nblocks)) (reln)) < 0) + elog(WARN, "cannot count blocks for %s", + &(reln->rd_rel->relname.data[0])); - return (nblocks); + return (nblocks); } /* - * smgrtruncate() -- Truncate supplied relation to a specified number - * of blocks + * smgrtruncate() -- Truncate supplied relation to a specified number + * of blocks * - * Returns the number of blocks on success, aborts the current - * transaction on failure. + * Returns the number of blocks on success, aborts the current + * transaction on failure. */ int smgrtruncate(int16 which, Relation reln, int nblocks) { - int newblks; - - newblks = nblocks; - if (smgrsw[which].smgr_truncate) - { - if ((newblks = (*(smgrsw[which].smgr_truncate))(reln, nblocks)) < 0) - elog(WARN, "cannot truncate %s to %d blocks", - &(reln->rd_rel->relname.data[0]), nblocks); - } - - return (newblks); + int newblks; + + newblks = nblocks; + if (smgrsw[which].smgr_truncate) + { + if ((newblks = (*(smgrsw[which].smgr_truncate)) (reln, nblocks)) < 0) + elog(WARN, "cannot truncate %s to %d blocks", + &(reln->rd_rel->relname.data[0]), nblocks); + } + + return (newblks); } /* - * smgrcommit(), smgrabort() -- Commit or abort changes made during the - * current transaction. + * smgrcommit(), smgrabort() -- Commit or abort changes made during the + * current transaction. */ int smgrcommit() { - int i; - - for (i = 0; i < NSmgr; i++) { - if (smgrsw[i].smgr_commit) { - if ((*(smgrsw[i].smgr_commit))() == SM_FAIL) - elog(FATAL, "transaction commit failed on %s", smgrout(i)); + int i; + + for (i = 0; i < NSmgr; i++) + { + if (smgrsw[i].smgr_commit) + { + if ((*(smgrsw[i].smgr_commit)) () == SM_FAIL) + elog(FATAL, "transaction commit failed on %s", smgrout(i)); + } } - } - return (SM_SUCCESS); + return (SM_SUCCESS); } #ifdef NOT_USED int smgrabort() { - int i; - - for (i = 0; i < NSmgr; i++) { - if (smgrsw[i].smgr_abort) { - if ((*(smgrsw[i].smgr_abort))() == SM_FAIL) - elog(FATAL, "transaction abort failed on %s", smgrout(i)); + int i; + + for (i = 0; i < NSmgr; i++) + { + if (smgrsw[i].smgr_abort) + { + if ((*(smgrsw[i].smgr_abort)) () == SM_FAIL) + elog(FATAL, "transaction abort failed on %s", smgrout(i)); + } } - } - return (SM_SUCCESS); + return (SM_SUCCESS); } + #endif bool smgriswo(int16 smgrno) { - if (smgrno < 0 || smgrno >= NSmgr) - elog(WARN, "illegal storage manager number %d", smgrno); + if (smgrno < 0 || smgrno >= NSmgr) + elog(WARN, "illegal storage manager number %d", smgrno); - return (smgrwo[smgrno]); + return (smgrwo[smgrno]); } diff --git a/src/backend/storage/smgr/smgrtype.c b/src/backend/storage/smgr/smgrtype.c index cb32d458b82..64fb53c9c2e 100644 --- a/src/backend/storage/smgr/smgrtype.c +++ b/src/backend/storage/smgr/smgrtype.c @@ -1,81 +1,83 @@ /*------------------------------------------------------------------------- * * smgrtype.c-- - * storage manager type + * storage manager type * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgrtype.c,v 1.2 1996/11/03 05:08:01 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgrtype.c,v 1.3 1997/09/07 04:49:26 momjian Exp $ * *------------------------------------------------------------------------- */ #include <string.h> #include "postgres.h" -#include "utils/builtins.h" /* where the declarations go */ +#include "utils/builtins.h" /* where the declarations go */ #include "utils/palloc.h" #include "storage/smgr.h" -typedef struct smgrid { - char *smgr_name; -} smgrid; +typedef struct smgrid +{ + char *smgr_name; +} smgrid; /* - * StorageManager[] -- List of defined storage managers. + * StorageManager[] -- List of defined storage managers. * - * The weird comma placement is to keep compilers happy no matter - * which of these is (or is not) defined. + * The weird comma placement is to keep compilers happy no matter + * which of these is (or is not) defined. */ -static smgrid StorageManager[] = { +static smgrid StorageManager[] = { {"magnetic disk"}, #ifdef MAIN_MEMORY {"main memory"} -#endif /* MAIN_MEMORY */ +#endif /* MAIN_MEMORY */ }; -static int NStorageManagers = lengthof(StorageManager); +static int NStorageManagers = lengthof(StorageManager); int2 smgrin(char *s) { - int i; + int i; - for (i = 0; i < NStorageManagers; i++) { - if (strcmp(s, StorageManager[i].smgr_name) == 0) - return((int2) i); - } - elog(WARN, "smgrin: illegal storage manager name %s", s); - return 0; + for (i = 0; i < NStorageManagers; i++) + { + if (strcmp(s, StorageManager[i].smgr_name) == 0) + return ((int2) i); + } + elog(WARN, "smgrin: illegal storage manager name %s", s); + return 0; } -char * +char * smgrout(int2 i) { - char *s; + char *s; - if (i >= NStorageManagers || i < 0) - elog(WARN, "Illegal storage manager id %d", i); + if (i >= NStorageManagers || i < 0) + elog(WARN, "Illegal storage manager id %d", i); - s = (char *) palloc(strlen(StorageManager[i].smgr_name) + 1); - strcpy(s, StorageManager[i].smgr_name); - return (s); + s = (char *) palloc(strlen(StorageManager[i].smgr_name) + 1); + strcpy(s, StorageManager[i].smgr_name); + return (s); } bool smgreq(int2 a, int2 b) { - if (a == b) - return (true); - return (false); + if (a == b) + return (true); + return (false); } bool smgrne(int2 a, int2 b) { - if (a == b) - return (false); - return (true); + if (a == b) + return (false); + return (true); } |