88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.68 2000/05/25 23:30:20 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.68.2.1 2000/09/23 22:11:41 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -130,6 +130,7 @@ mdcreate(Relation reln)
130130 char * path ;
131131
132132 Assert (reln -> rd_unlinked && reln -> rd_fd < 0 );
133+
133134 path = relpath (RelationGetPhysicalRelationName (reln ));
134135#ifndef __CYGWIN32__
135136 fd = FileNameOpenFile (path , O_RDWR | O_CREAT | O_EXCL , 0600 );
@@ -138,19 +139,21 @@ mdcreate(Relation reln)
138139#endif
139140
140141 /*
141- * During bootstrap processing, we skip that check, because pg_time,
142- * pg_variable, and pg_log get created before their .bki file entries
143- * are processed.
144- *
145- * For cataloged relations,pg_class is guaranteed to have an unique
142+ * For cataloged relations, pg_class is guaranteed to have a unique
146143 * record with the same relname by the unique index. So we are able to
147- * reuse existent files for new catloged relations. Currently we reuse
144+ * reuse existent files for new cataloged relations. Currently we reuse
148145 * them in the following cases. 1. they are empty. 2. they are used
149146 * for Index relations and their size == BLCKSZ * 2.
147+ *
148+ * During bootstrap processing, we skip that check, because pg_time,
149+ * pg_variable, and pg_log get created before their .bki file entries
150+ * are processed.
150151 */
151152
152153 if (fd < 0 )
153154 {
155+ int save_errno = errno ;
156+
154157 if (!IsBootstrapProcessingMode () &&
155158 reln -> rd_rel -> relkind == RELKIND_UNCATALOGED )
156159 return -1 ;
@@ -161,11 +164,15 @@ mdcreate(Relation reln)
161164 fd = FileNameOpenFile (path , O_RDWR | O_BINARY , 0600 );
162165#endif
163166 if (fd < 0 )
167+ {
168+ /* be sure to return the error reported by create, not open */
169+ errno = save_errno ;
164170 return -1 ;
171+ }
165172 if (!IsBootstrapProcessingMode ())
166173 {
167174 bool reuse = false;
168- int len = FileSeek (fd , 0L , SEEK_END );
175+ long len = FileSeek (fd , 0L , SEEK_END );
169176
170177 if (len == 0 )
171178 reuse = true;
@@ -175,9 +182,12 @@ mdcreate(Relation reln)
175182 if (!reuse )
176183 {
177184 FileClose (fd );
185+ /* be sure to return the error reported by create */
186+ errno = save_errno ;
178187 return -1 ;
179188 }
180189 }
190+ errno = 0 ;
181191 }
182192 reln -> rd_unlinked = false;
183193
@@ -733,9 +743,16 @@ mdnblocks(Relation reln)
733743
734744 if (v -> mdfd_chain == (MdfdVec * ) NULL )
735745 {
746+ /*
747+ * Because we pass O_CREAT, we will create the next segment
748+ * (with zero length) immediately, if the last segment is of
749+ * length REL_SEGSIZE. This is unnecessary but harmless, and
750+ * testing for the case would take more cycles than it seems
751+ * worth.
752+ */
736753 v -> mdfd_chain = _mdfd_openseg (reln , segno , O_CREAT );
737754 if (v -> mdfd_chain == (MdfdVec * ) NULL )
738- elog (ERROR , "cannot count blocks for %s -- open failed" ,
755+ elog (ERROR , "cannot count blocks for %s -- open failed: %m " ,
739756 RelationGetRelationName (reln ));
740757 }
741758
@@ -1075,11 +1092,20 @@ _mdfd_getseg(Relation reln, int blkno)
10751092
10761093 if (v -> mdfd_chain == (MdfdVec * ) NULL )
10771094 {
1078- v -> mdfd_chain = _mdfd_openseg (reln , i , O_CREAT );
1095+ /*
1096+ * We will create the next segment only if the target block
1097+ * is within it. This prevents Sorcerer's Apprentice syndrome
1098+ * if a bug at higher levels causes us to be handed a ridiculously
1099+ * large blkno --- otherwise we could create many thousands of
1100+ * empty segment files before reaching the "target" block. We
1101+ * should never need to create more than one new segment per call,
1102+ * so this restriction seems reasonable.
1103+ */
1104+ v -> mdfd_chain = _mdfd_openseg (reln , i , (segno == 1 ) ? O_CREAT : 0 );
10791105
10801106 if (v -> mdfd_chain == (MdfdVec * ) NULL )
1081- elog (ERROR , "cannot open segment %d of relation %s" ,
1082- i , RelationGetRelationName (reln ));
1107+ elog (ERROR , "cannot open segment %d of relation %s (target block %d): %m " ,
1108+ i , RelationGetRelationName (reln ), blkno );
10831109 }
10841110 v = v -> mdfd_chain ;
10851111 }
@@ -1097,8 +1123,10 @@ _mdfd_getseg(Relation reln, int blkno)
10971123 * "blind" with no Relation struct. We assume that we are not likely to
10981124 * touch the same relation again soon, so we do not create an FD entry for
10991125 * the relation --- we just open a kernel file descriptor which will be
1100- * used and promptly closed. The return value is the kernel descriptor,
1101- * or -1 on failure.
1126+ * used and promptly closed. We also assume that the target block already
1127+ * exists, ie, we need not extend the relation.
1128+ *
1129+ * The return value is the kernel descriptor, or -1 on failure.
11021130 */
11031131
11041132static int
0 commit comments