]> granicus.if.org Git - postgresql/commitdiff
Reset properly errno before calling write()
authorMichael Paquier <michael@paquier.xyz>
Sat, 4 Aug 2018 20:31:18 +0000 (05:31 +0900)
committerMichael Paquier <michael@paquier.xyz>
Sat, 4 Aug 2018 20:31:18 +0000 (05:31 +0900)
6cb3372 enforces errno to ENOSPC when less bytes than what is expected
have been written when it is unset, though it forgot to properly reset
errno before doing a system call to write(), causing errno to
potentially come from a previous system call.

Reported-by: Tom Lane
Author: Michael Paquier
Reviewed-by: Tom Lane
Discussion: https://postgr.es/m/31797.1533326676@sss.pgh.pa.us

src/backend/access/heap/rewriteheap.c
src/backend/access/transam/twophase.c
src/backend/replication/logical/origin.c
src/backend/replication/logical/reorderbuffer.c
src/backend/replication/logical/snapbuild.c
src/backend/replication/slot.c
src/bin/pg_basebackup/walmethods.c

index ed7ba181c79672d849a06214b5ed1116649b37be..85f92973c95cf6f05fd7139e6d2332aabd4ceebb 100644 (file)
@@ -1166,6 +1166,7 @@ heap_xlog_logical_rewrite(XLogReaderState *r)
        len = xlrec->num_mappings * sizeof(LogicalRewriteMappingData);
 
        /* write out tail end of mapping file (again) */
+       errno = 0;
        pgstat_report_wait_start(WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE);
        if (write(fd, data, len) != len)
        {
index 306861bb793bc215e7607206199a35d5148a5ad9..0ae0722794147c1909a45bbed8bd2d2999ae5b57 100644 (file)
@@ -1669,6 +1669,7 @@ RecreateTwoPhaseFile(TransactionId xid, void *content, int len)
                                 errmsg("could not recreate file \"%s\": %m", path)));
 
        /* Write content and CRC */
+       errno = 0;
        pgstat_report_wait_start(WAIT_EVENT_TWOPHASE_FILE_WRITE);
        if (write(fd, content, len) != len)
        {
index 822c96d1c2f82cd8c2548d8aa35175d5312122f6..bf97dcdee4b02f22e5386aa008b825c3b1dfad73 100644 (file)
@@ -576,6 +576,7 @@ CheckPointReplicationOrigin(void)
                                                tmppath)));
 
        /* write magic */
+       errno = 0;
        if ((write(tmpfd, &magic, sizeof(magic))) != sizeof(magic))
        {
                int                     save_errno = errno;
@@ -619,6 +620,7 @@ CheckPointReplicationOrigin(void)
                /* make sure we only write out a commit that's persistent */
                XLogFlush(local_lsn);
 
+               errno = 0;
                if ((write(tmpfd, &disk_state, sizeof(disk_state))) !=
                        sizeof(disk_state))
                {
@@ -641,6 +643,7 @@ CheckPointReplicationOrigin(void)
 
        /* write out the CRC */
        FIN_CRC32C(crc);
+       errno = 0;
        if ((write(tmpfd, &crc, sizeof(crc))) != sizeof(crc))
        {
                int                     save_errno = errno;
index 9b55b94227b09686281e347ada53cf9f78563b6d..1d43a165ad04f07d5c691d0a81f13a08c56c553c 100644 (file)
@@ -2421,6 +2421,7 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
 
        ondisk->size = sz;
 
+       errno = 0;
        pgstat_report_wait_start(WAIT_EVENT_REORDER_BUFFER_WRITE);
        if (write(fd, rb->outbuf, ondisk->size) != ondisk->size)
        {
index 1359d9b20a3578f4d59374ee68acc8d44e216925..a6cd6c67d16d8ad24bb966fbcc16f944182eed90 100644 (file)
@@ -1609,6 +1609,7 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn)
                ereport(ERROR,
                                (errmsg("could not open file \"%s\": %m", path)));
 
+       errno = 0;
        pgstat_report_wait_start(WAIT_EVENT_SNAPBUILD_WRITE);
        if ((write(fd, ondisk, needed_length)) != needed_length)
        {
index 6c3639805833992e76d43c3aff50a4bf33780d88..19978d9a9edc4429dae68b9f08342d86919467d8 100644 (file)
@@ -1275,6 +1275,7 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel)
                                SnapBuildOnDiskChecksummedSize);
        FIN_CRC32C(cp.checksum);
 
+       errno = 0;
        pgstat_report_wait_start(WAIT_EVENT_REPLICATION_SLOT_WRITE);
        if ((write(fd, &cp, sizeof(cp))) != sizeof(cp))
        {
index fbfee05a5a6b2aed88e673bc7eb486fc797e61d6..42e3f3023a0f22378c4d6a082de9b6379176bf8b 100644 (file)
@@ -122,6 +122,7 @@ dir_open_for_write(const char *pathname, const char *temp_suffix, size_t pad_to_
                zerobuf = pg_malloc0(XLOG_BLCKSZ);
                for (bytes = 0; bytes < pad_to_size; bytes += XLOG_BLCKSZ)
                {
+                       errno = 0;
                        if (write(fd, zerobuf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
                        {
                                int                     save_errno = errno;
@@ -445,6 +446,7 @@ tar_write_compressed_data(void *buf, size_t count, bool flush)
                {
                        size_t          len = ZLIB_OUT_SIZE - tar_data->zp->avail_out;
 
+                       errno = 0;
                        if (write(tar_data->fd, tar_data->zlibOut, len) != len)
                        {
                                /*
@@ -629,6 +631,7 @@ tar_open_for_write(const char *pathname, const char *temp_suffix, size_t pad_to_
 
        if (!tar_data->compression)
        {
+               errno = 0;
                if (write(tar_data->fd, tar_data->currentfile->header, 512) != 512)
                {
                        save_errno = errno;
@@ -829,6 +832,7 @@ tar_close(Walfile f, WalCloseMethod method)
                return -1;
        if (!tar_data->compression)
        {
+               errno = 0;
                if (write(tar_data->fd, tf->header, 512) != 512)
                {
                        /* if write didn't set errno, assume problem is no disk space */
@@ -901,6 +905,7 @@ tar_finish(void)
        MemSet(zerobuf, 0, sizeof(zerobuf));
        if (!tar_data->compression)
        {
+               errno = 0;
                if (write(tar_data->fd, zerobuf, sizeof(zerobuf)) != sizeof(zerobuf))
                {
                        /* if write didn't set errno, assume problem is no disk space */
@@ -933,6 +938,7 @@ tar_finish(void)
                        {
                                size_t          len = ZLIB_OUT_SIZE - tar_data->zp->avail_out;
 
+                               errno = 0;
                                if (write(tar_data->fd, tar_data->zlibOut, len) != len)
                                {
                                        /*