8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -714,9 +714,16 @@ mdnblocks(Relation reln)
714
714
715
715
if (v -> mdfd_chain == (MdfdVec * ) NULL )
716
716
{
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
+ */
717
724
v -> mdfd_chain = _mdfd_openseg (reln , segno , O_CREAT );
718
725
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 " ,
720
727
RelationGetRelationName (reln ));
721
728
}
722
729
@@ -1038,11 +1045,20 @@ _mdfd_getseg(Relation reln, int blkno)
1038
1045
1039
1046
if (v -> mdfd_chain == (MdfdVec * ) NULL )
1040
1047
{
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 );
1042
1058
1043
1059
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 );
1046
1062
}
1047
1063
v = v -> mdfd_chain ;
1048
1064
}
@@ -1060,8 +1076,10 @@ _mdfd_getseg(Relation reln, int blkno)
1060
1076
* "blind" with no Relation struct. We assume that we are not likely to
1061
1077
* touch the same relation again soon, so we do not create an FD entry for
1062
1078
* 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.
1065
1083
*/
1066
1084
1067
1085
static int
0 commit comments