diff options
author | Hiroshi Inoue <inoue@tpf.co.jp> | 1999-10-06 06:38:04 +0000 |
---|---|---|
committer | Hiroshi Inoue <inoue@tpf.co.jp> | 1999-10-06 06:38:04 +0000 |
commit | 9df8ced9d19c0a62cec206735cf346fa73202d51 (patch) | |
tree | 97ac2fad506766ed5a245cb9b2996b7950d6bac5 | |
parent | 66fbea5041fae7c0bc4fff5ad77a21169a7ba7e7 (diff) | |
download | postgresql-9df8ced9d19c0a62cec206735cf346fa73202d51.tar.gz postgresql-9df8ced9d19c0a62cec206735cf346fa73202d51.zip |
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
-rw-r--r-- | src/backend/storage/smgr/md.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c index a2c102145b8..6d8425c4bd6 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); } |