From 9df8ced9d19c0a62cec206735cf346fa73202d51 Mon Sep 17 00:00:00 2001 From: Hiroshi Inoue Date: Wed, 6 Oct 1999 06:38:04 +0000 Subject: [PATCH] Improve the treatment of partial(incomplete) blocks of relation files. This may solve a TODO item * Recover or force failure when disk space is exhausted --- src/backend/storage/smgr/md.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c index a2c102145b..6d8425c4bd 100644 --- a/src/backend/storage/smgr/md.c +++ b/src/backend/storage/smgr/md.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.55 1999/09/28 11:41:07 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.56 1999/10/06 06:38:04 inoue Exp $ * *------------------------------------------------------------------------- */ @@ -233,7 +233,7 @@ mdunlink(Relation reln) int mdextend(Relation reln, char *buffer) { - long pos; + long pos, nbytes; int nblocks; MdfdVec *v; @@ -243,8 +243,22 @@ mdextend(Relation reln, char *buffer) if ((pos = FileSeek(v->mdfd_vfd, 0L, SEEK_END)) < 0) return SM_FAIL; - if (FileWrite(v->mdfd_vfd, buffer, BLCKSZ) != BLCKSZ) + if (pos % BLCKSZ != 0) /* the last block is incomplete */ + { + pos -= pos % BLCKSZ; + if (FileSeek(v->mdfd_vfd, pos, SEEK_SET) < 0) + return SM_FAIL; + } + + if ((nbytes = FileWrite(v->mdfd_vfd, buffer, BLCKSZ)) != BLCKSZ) + { + if (nbytes > 0) + { + FileTruncate(v->mdfd_vfd, pos); + FileSeek(v->mdfd_vfd, pos, SEEK_SET); + } return SM_FAIL; + } /* remember that we did a write, so we can sync at xact commit */ v->mdfd_flags |= MDFD_DIRTY; @@ -432,6 +446,8 @@ mdread(Relation reln, BlockNumber blocknum, char *buffer) { if (nbytes == 0) MemSet(buffer, 0, BLCKSZ); + else if (blocknum == 0 && nbytes > 0 && mdnblocks(reln) == 0) + MemSet(buffer, 0, BLCKSZ); else status = SM_FAIL; } @@ -1067,6 +1083,7 @@ _mdnblocks(File file, Size blcksz) { long len; - len = FileSeek(file, 0L, SEEK_END) - 1; - return (BlockNumber) ((len < 0) ? 0 : 1 + len / blcksz); + len = FileSeek(file, 0L, SEEK_END); + if (len < 0) return 0; /* on failure, assume file is empty */ + return (BlockNumber) (len / blcksz); }