8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -130,6 +130,7 @@ mdcreate(Relation reln)
130
130
char * path ;
131
131
132
132
Assert (reln -> rd_unlinked && reln -> rd_fd < 0 );
133
+
133
134
path = relpath (RelationGetPhysicalRelationName (reln ));
134
135
#ifndef __CYGWIN32__
135
136
fd = FileNameOpenFile (path ,O_RDWR |O_CREAT |O_EXCL ,0600 );
@@ -138,19 +139,21 @@ mdcreate(Relation reln)
138
139
#endif
139
140
140
141
/*
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
146
143
* record with the same relname by the unique index. So we are able to
147
- * reuse existent files for newcatloged relations. Currently we reuse
144
+ * reuse existent files for newcataloged relations. Currently we reuse
148
145
* them in the following cases. 1. they are empty. 2. they are used
149
146
* 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.
150
151
*/
151
152
152
153
if (fd < 0 )
153
154
{
155
+ int save_errno = errno ;
156
+
154
157
if (!IsBootstrapProcessingMode ()&&
155
158
reln -> rd_rel -> relkind == RELKIND_UNCATALOGED )
156
159
return -1 ;
@@ -161,11 +164,15 @@ mdcreate(Relation reln)
161
164
fd = FileNameOpenFile (path ,O_RDWR |O_BINARY ,0600 );
162
165
#endif
163
166
if (fd < 0 )
167
+ {
168
+ /* be sure to return the error reported by create, not open */
169
+ errno = save_errno ;
164
170
return -1 ;
171
+ }
165
172
if (!IsBootstrapProcessingMode ())
166
173
{
167
174
bool reuse = false;
168
- int len = FileSeek (fd ,0L ,SEEK_END );
175
+ long len = FileSeek (fd ,0L ,SEEK_END );
169
176
170
177
if (len == 0 )
171
178
reuse = true;
@@ -175,9 +182,12 @@ mdcreate(Relation reln)
175
182
if (!reuse )
176
183
{
177
184
FileClose (fd );
185
+ /* be sure to return the error reported by create */
186
+ errno = save_errno ;
178
187
return -1 ;
179
188
}
180
189
}
190
+ errno = 0 ;
181
191
}
182
192
reln -> rd_unlinked = false;
183
193
@@ -733,9 +743,16 @@ mdnblocks(Relation reln)
733
743
734
744
if (v -> mdfd_chain == (MdfdVec * )NULL )
735
745
{
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
+ */
736
753
v -> mdfd_chain = _mdfd_openseg (reln ,segno ,O_CREAT );
737
754
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 " ,
739
756
RelationGetRelationName (reln ));
740
757
}
741
758
@@ -1075,11 +1092,20 @@ _mdfd_getseg(Relation reln, int blkno)
1075
1092
1076
1093
if (v -> mdfd_chain == (MdfdVec * )NULL )
1077
1094
{
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 );
1079
1105
1080
1106
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 );
1083
1109
}
1084
1110
v = v -> mdfd_chain ;
1085
1111
}
@@ -1097,8 +1123,10 @@ _mdfd_getseg(Relation reln, int blkno)
1097
1123
* "blind" with no Relation struct. We assume that we are not likely to
1098
1124
* touch the same relation again soon, so we do not create an FD entry for
1099
1125
* 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.
1102
1130
*/
1103
1131
1104
1132
static int