home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / storage / smgr / smgr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  9.9 KB  |  438 lines

  1. /*
  2.  *  smgr.c -- public interface routines to storage manager switch.
  3.  *
  4.  *    All file system operations in POSTGRES dispatch through these
  5.  *    routines.
  6.  */
  7.  
  8. #include "tmp/c.h"
  9. #include "tmp/postgres.h"
  10.  
  11. #include "machine.h"
  12. #include "storage/ipci.h"
  13. #include "storage/smgr.h"
  14. #include "storage/block.h"
  15. #include "utils/rel.h"
  16. #include "utils/log.h"
  17.  
  18. RcsId("$Header: /private/postgres/src/storage/smgr/RCS/smgr.c,v 1.9 1992/07/04 03:50:40 mao Exp $");
  19.  
  20. typedef struct f_smgr {
  21.     int        (*smgr_init)();        /* may be NULL */
  22.     int        (*smgr_shutdown)();    /* may be NULL */
  23.     int        (*smgr_create)();
  24.     int        (*smgr_unlink)();
  25.     int        (*smgr_extend)();
  26.     int        (*smgr_open)();
  27.     int        (*smgr_close)();
  28.     int        (*smgr_read)();
  29.     int        (*smgr_write)();
  30.     int        (*smgr_flush)();
  31.     int        (*smgr_blindwrt)();
  32.     int        (*smgr_nblocks)();
  33.     int        (*smgr_commit)();    /* may be NULL */
  34.     int        (*smgr_abort)();    /* may be NULL */
  35. } f_smgr;
  36.  
  37. /* routines defined elsewhere */
  38. extern int    mdinit(), mdcreate(), mdunlink();
  39. extern int    mdextend(), mdopen(), mdclose(), mdread();
  40. extern int    mdwrite(), mdflush(), mdblindwrt(), mdnblocks();
  41. extern int    mdcommit(), mdabort();
  42.  
  43. #ifdef SONY_JUKEBOX
  44. extern int    sjinit(), sjshutdown(), sjcreate(), sjunlink();
  45. extern int    sjextend(), sjopen(), sjclose(), sjread();
  46. extern int    sjwrite(), sjflush(), sjblindwrt(), sjnblocks();
  47. extern int    sjcommit(), sjabort();
  48. #endif /* SONY_JUKEBOX */
  49.  
  50. #ifdef MAIN_MEMORY
  51. extern int    mminit(), mmshutdown(), mmcreate(), mmunlink();
  52. extern int    mmextend(), mmopen(), mmclose(), mmread();
  53. extern int    mmwrite(), mmflush(), mmblindwrt(), mmnblocks();
  54. extern int    mmcommit(), mmabort();
  55. #endif /* MAIN_MEMORY */
  56.  
  57. /*
  58.  *  The weird placement of commas in this init block is to keep the compiler
  59.  *  happy, regardless of what storage managers we have (or don't have).
  60.  */
  61.  
  62. static f_smgr smgrsw[] = {
  63.  
  64.     /* magnetic disk */
  65.     { mdinit, NULL, mdcreate, mdunlink, mdextend, mdopen, mdclose,
  66.       mdread, mdwrite, mdflush, mdblindwrt, mdnblocks, mdcommit, mdabort }
  67.  
  68. #ifdef SONY_JUKEBOX
  69.     /* sony jukebox */
  70.     , { sjinit, sjshutdown, sjcreate, sjunlink, sjextend, sjopen, sjclose,
  71.         sjread, sjwrite, sjflush, sjblindwrt, sjnblocks, sjcommit, sjabort }
  72.  
  73. #endif /* SONY_JUKEBOX */
  74.  
  75. #ifdef MAIN_MEMORY
  76.     /* main memory */
  77.     , { mminit, mmshutdown, mmcreate, mmunlink, mmextend, mmopen, mmclose,
  78.         mmread, mmwrite, mmflush, mmblindwrt, mmnblocks, mmcommit, mmabort }
  79.  
  80. #endif /* MAIN_MEMORY */
  81. };
  82.  
  83. /*
  84.  *  This array records which storage managers are write-once, and which
  85.  *  support overwrite.  A 'true' entry means that the storage manager is
  86.  *  write-once.  In the best of all possible worlds, there would be no
  87.  *  write-once storage managers.
  88.  */
  89.  
  90. static bool smgrwo[] = {
  91.     false        /* magnetic disk */
  92. #ifdef SONY_JUKEBOX
  93.     , true        /* sony jukebox */
  94. #endif /* SONY_JUKEBOX */
  95. #ifdef MAIN_MEMORY
  96.     , false        /* main memory*/
  97. #endif /* MAIN_MEMORY */
  98. };
  99. static int NSmgr = lengthof(smgrsw);
  100.  
  101. /*
  102.  *  smgrinit(), smgrshutdown() -- Initialize or shut down all storage
  103.  *                  managers.
  104.  *
  105.  */
  106.  
  107. int
  108. smgrinit()
  109. {
  110.     int i;
  111.     extern char *smgrout();
  112.  
  113.     for (i = 0; i < NSmgr; i++) {
  114.     if (smgrsw[i].smgr_init) {
  115.         if ((*(smgrsw[i].smgr_init))() == SM_FAIL)
  116.         elog(FATAL, "initialization failed on %s", smgrout(i));
  117.     }
  118.     }
  119.  
  120.     /* register the shutdown proc */
  121.     on_exitpg(smgrshutdown, 0);
  122.  
  123.     return (SM_SUCCESS);
  124. }
  125.  
  126. void
  127. smgrshutdown(dummy)
  128.     int dummy;
  129. {
  130.     int i;
  131.     extern char *smgrout();
  132.  
  133.     for (i = 0; i < NSmgr; i++) {
  134.     if (smgrsw[i].smgr_shutdown) {
  135.         if ((*(smgrsw[i].smgr_shutdown))() == SM_FAIL)
  136.         elog(FATAL, "shutdown failed on %s", smgrout(i));
  137.     }
  138.     }
  139. }
  140.  
  141. /*
  142.  *  smgrcreate() -- Create a new relation.
  143.  *
  144.  *    This routine takes a reldesc, creates the relation on the appropriate
  145.  *    device, and returns a file descriptor for it.
  146.  */
  147.  
  148. int
  149. smgrcreate(which, reln)
  150.     int16 which;
  151.     Relation reln;
  152. {
  153.     int fd;
  154.  
  155.     if ((fd = (*(smgrsw[which].smgr_create))(reln)) < 0)
  156.     elog(WARN, "cannot open %16s", &(reln->rd_rel->relname.data[0]));
  157.  
  158.     return (fd);
  159. }
  160.  
  161. /*
  162.  *  smgrunlink() -- Unlink a relation.
  163.  *
  164.  *    The relation is removed from the store.
  165.  */
  166.  
  167. int
  168. smgrunlink(which, reln)
  169.     int16 which;
  170.     Relation reln;
  171. {
  172.     int status;
  173.  
  174.     if ((status = (*(smgrsw[which].smgr_unlink))(reln)) == SM_FAIL)
  175.     elog(WARN, "cannot unlink %16s", &(reln->rd_rel->relname.data[0]));
  176.  
  177.     return (status);
  178. }
  179.  
  180. /*
  181.  *  smgrextend() -- Add a new block to a file.
  182.  *
  183.  *    Returns SM_SUCCESS on success; aborts the current transaction on
  184.  *    failure.
  185.  */
  186.  
  187. int
  188. smgrextend(which, reln, buffer)
  189.     int16 which;
  190.     Relation reln;
  191.     char *buffer;
  192. {
  193.     int status;
  194.  
  195.     /* new blocks are zero-filled */
  196.     bzero((char *) buffer, BLCKSZ);
  197.  
  198.     status = (*(smgrsw[which].smgr_extend))(reln, buffer);
  199.  
  200.     if (status == SM_FAIL)
  201.     elog(WARN, "%16s: cannot extend", &(reln->rd_rel->relname.data[0]));
  202.  
  203.     return (status);
  204. }
  205.  
  206. /*
  207.  *  smgropen() -- Open a relation using a particular storage manager.
  208.  *
  209.  *    Returns the fd for the open relation on success, aborts the
  210.  *    transaction on failure.
  211.  */
  212.  
  213. int
  214. smgropen(which, reln)
  215.     int16 which;
  216.     Relation reln;
  217. {
  218.     int fd;
  219.  
  220.     if ((fd = (*(smgrsw[which].smgr_open))(reln)) < 0)
  221.     elog(WARN, "cannot open %16s", &(reln->rd_rel->relname.data[0]));
  222.  
  223.     return (fd);
  224. }
  225.  
  226. /*
  227.  *  smgrclose() -- Close a relation.
  228.  *
  229.  *    Returns SM_SUCCESS on success, aborts on failure.
  230.  */
  231.  
  232. int
  233. smgrclose(which, reln)
  234.     int16 which;
  235.     Relation reln;
  236. {
  237.     if ((*(smgrsw[which].smgr_close))(reln) == SM_FAIL)
  238.     elog(WARN, "cannot close %16s", &(reln->rd_rel->relname.data[0]));
  239.  
  240.     return (SM_SUCCESS);
  241. }
  242.  
  243. /*
  244.  *  smgrread() -- read a particular block from a relation into the supplied
  245.  *          buffer.
  246.  *
  247.  *    This routine is called from the buffer manager in order to
  248.  *    instantiate pages in the shared buffer cache.  All storage managers
  249.  *    return pages in the format that POSTGRES expects.  This routine
  250.  *    dispatches the read.  On success, it returns SM_SUCCESS.  On failure,
  251.  *    the current transaction is aborted.
  252.  */
  253.  
  254. int
  255. smgrread(which, reln, blocknum, buffer)
  256.     int16 which;
  257.     Relation reln;
  258.     BlockNumber blocknum;
  259.     char *buffer;
  260. {
  261.     int status;
  262.  
  263.     status = (*(smgrsw[which].smgr_read))(reln, blocknum, buffer);
  264.  
  265.     if (status == SM_FAIL)
  266.     elog(WARN, "cannot read block %d of %16s",
  267.          blocknum, &(reln->rd_rel->relname.data[0]));
  268.  
  269.     return (status);
  270. }
  271.  
  272. /*
  273.  *  smgrwrite() -- Write the supplied buffer out.
  274.  *
  275.  *    This is not a synchronous write -- the interface for that is
  276.  *    smgrflush().  The buffer is written out via the appropriate
  277.  *    storage manager.  This routine returns SM_SUCCESS or aborts
  278.  *    the current transaction.
  279.  */
  280.  
  281. int
  282. smgrwrite(which, reln, blocknum, buffer)
  283.     int16 which;
  284.     Relation reln;
  285.     BlockNumber blocknum;
  286.     char *buffer;
  287. {
  288.     int status;
  289.  
  290.     status = (*(smgrsw[which].smgr_write))(reln, blocknum, buffer);
  291.  
  292.     if (status == SM_FAIL)
  293.     elog(WARN, "cannot write block %d of %16s",
  294.          blocknum, &(reln->rd_rel->relname.data[0]));
  295.  
  296.     return (status);
  297. }
  298.  
  299. /*
  300.  *  smgrflush() -- A synchronous smgrwrite().
  301.  */
  302.  
  303. int
  304. smgrflush(which, reln, blocknum, buffer)
  305.     int16 which;
  306.     Relation reln;
  307.     BlockNumber blocknum;
  308.     char *buffer;
  309. {
  310.     int status;
  311.  
  312.     status = (*(smgrsw[which].smgr_flush))(reln, blocknum, buffer);
  313.  
  314.     if (status == SM_FAIL)
  315.     elog(WARN, "cannot flush block %d of %16s to stable store",
  316.          blocknum, &(reln->rd_rel->relname.data[0]));
  317.  
  318.     return (status);
  319. }
  320.  
  321. /*
  322.  *  smgrblindwrt() -- Write a page out blind.
  323.  *
  324.  *    In some cases, we may find a page in the buffer cache that we
  325.  *    can't make a reldesc for.  This happens, for example, when we
  326.  *    want to reuse a dirty page that was written by a transaction
  327.  *    that has not yet committed, which created a new relation.  In
  328.  *    this case, the buffer manager will call smgrblindwrt() with
  329.  *    the name and OID of the database and the relation to which the
  330.  *    buffer belongs.  Every storage manager must be able to force
  331.  *    this page down to stable storage in this circumstance.
  332.  */
  333.  
  334. int
  335. smgrblindwrt(which, dbname, relname, dbid, relid, blkno, buffer)
  336.     int16 which;
  337.     Name dbname;
  338.     Name relname;
  339.     OID dbid;
  340.     OID relid;
  341.     BlockNumber blkno;
  342.     char *buffer;
  343. {
  344.     char *dbstr;
  345.     char *relstr;
  346.     int nbytes;
  347.     int status;
  348.  
  349.     /* do the postgres name dance */
  350.     nbytes = sizeof(NameData) + 1;
  351.     dbstr = (char *) palloc(nbytes);
  352.     relstr = (char *) palloc(nbytes);
  353.     strncpy(dbstr, dbname, sizeof(NameData));
  354.     strncpy(relstr, relname, sizeof(NameData));
  355.     dbstr[nbytes - 1] = '\0';
  356.     relstr[nbytes - 1] = '\0';
  357.  
  358.     status = (*(smgrsw[which].smgr_blindwrt))(dbstr, relstr, dbid, relid,
  359.                           blkno, buffer);
  360.  
  361.     if (status == SM_FAIL)
  362.     elog(WARN, "cannot write block %d of %s [%s] blind",
  363.          blkno, relstr, dbstr);
  364.  
  365.     pfree(dbstr);
  366.     pfree(relstr);
  367.  
  368.     return (status);
  369. }
  370. /*
  371.  *  smgrnblocks() -- Calculate the number of POSTGRES blocks in the
  372.  *             supplied relation.
  373.  *
  374.  *    Returns the number of blocks on success, aborts the current
  375.  *    transaction on failure.
  376.  */
  377.  
  378. int
  379. smgrnblocks(which, reln)
  380.     int16 which;
  381.     Relation reln;
  382. {
  383.     int nblocks;
  384.  
  385.     if ((nblocks = (*(smgrsw[which].smgr_nblocks))(reln)) < 0)
  386.     elog(WARN, "cannot count blocks for %16s",
  387.            &(reln->rd_rel->relname.data[0]));
  388.  
  389.     return (nblocks);
  390. }
  391.  
  392. /*
  393.  *  smgrcommit(), smgrabort() -- Commit or abort changes made during the
  394.  *                 current transaction.
  395.  */
  396.  
  397. int
  398. smgrcommit()
  399. {
  400.     int i;
  401.     extern char *smgrout();
  402.  
  403.     for (i = 0; i < NSmgr; i++) {
  404.     if (smgrsw[i].smgr_commit) {
  405.         if ((*(smgrsw[i].smgr_commit))() == SM_FAIL)
  406.         elog(FATAL, "transaction commit failed on %s", smgrout(i));
  407.     }
  408.     }
  409.  
  410.     return (SM_SUCCESS);
  411. }
  412.  
  413. int
  414. smgrabort()
  415. {
  416.     int i;
  417.     extern char *smgrout();
  418.  
  419.     for (i = 0; i < NSmgr; i++) {
  420.     if (smgrsw[i].smgr_abort) {
  421.         if ((*(smgrsw[i].smgr_abort))() == SM_FAIL)
  422.         elog(FATAL, "transaction abort failed on %s", smgrout(i));
  423.     }
  424.     }
  425.  
  426.     return (SM_SUCCESS);
  427. }
  428.  
  429. bool
  430. smgriswo(smgrno)
  431.     int16 smgrno;
  432. {
  433.     if (smgrno < 0 || smgrno >= NSmgr)
  434.     elog(WARN, "illegal storage manager number %d", smgrno);
  435.  
  436.     return (smgrwo[smgrno]);
  437. }
  438.