88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.72 2000/06/28 03 :32:14 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.73 2000/07/10 04 :32:00 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -714,9 +714,16 @@ mdnblocks(Relation reln)
714714
715715 if (v -> mdfd_chain == (MdfdVec * ) NULL )
716716 {
717+ /*
718+ * Because we pass O_CREAT, we will create the next segment
719+ * (with zero length) immediately, if the last segment is of
720+ * length REL_SEGSIZE. This is unnecessary but harmless, and
721+ * testing for the case would take more cycles than it seems
722+ * worth.
723+ */
717724 v -> mdfd_chain = _mdfd_openseg (reln , segno , O_CREAT );
718725 if (v -> mdfd_chain == (MdfdVec * ) NULL )
719- elog (ERROR , "cannot count blocks for %s -- open failed" ,
726+ elog (ERROR , "cannot count blocks for %s -- open failed: %m " ,
720727 RelationGetRelationName (reln ));
721728 }
722729
@@ -1038,11 +1045,20 @@ _mdfd_getseg(Relation reln, int blkno)
10381045
10391046 if (v -> mdfd_chain == (MdfdVec * ) NULL )
10401047 {
1041- v -> mdfd_chain = _mdfd_openseg (reln , i , O_CREAT );
1048+ /*
1049+ * We will create the next segment only if the target block
1050+ * is within it. This prevents Sorcerer's Apprentice syndrome
1051+ * if a bug at higher levels causes us to be handed a ridiculously
1052+ * large blkno --- otherwise we could create many thousands of
1053+ * empty segment files before reaching the "target" block. We
1054+ * should never need to create more than one new segment per call,
1055+ * so this restriction seems reasonable.
1056+ */
1057+ v -> mdfd_chain = _mdfd_openseg (reln , i , (segno == 1 ) ? O_CREAT : 0 );
10421058
10431059 if (v -> mdfd_chain == (MdfdVec * ) NULL )
1044- elog (ERROR , "cannot open segment %d of relation %s" ,
1045- i , RelationGetRelationName (reln ));
1060+ elog (ERROR , "cannot open segment %d of relation %s (target block %d): %m " ,
1061+ i , RelationGetRelationName (reln ), blkno );
10461062 }
10471063 v = v -> mdfd_chain ;
10481064 }
@@ -1060,8 +1076,10 @@ _mdfd_getseg(Relation reln, int blkno)
10601076 * "blind" with no Relation struct. We assume that we are not likely to
10611077 * touch the same relation again soon, so we do not create an FD entry for
10621078 * the relation --- we just open a kernel file descriptor which will be
1063- * used and promptly closed. The return value is the kernel descriptor,
1064- * or -1 on failure.
1079+ * used and promptly closed. We also assume that the target block already
1080+ * exists, ie, we need not extend the relation.
1081+ *
1082+ * The return value is the kernel descriptor, or -1 on failure.
10651083 */
10661084
10671085static int
0 commit comments