Skip to content

Commit 8ae217b

Browse files
committed
[Issue #394] correctly detect ENOSPC when using write(): durable_write is implemented
1 parent 477e5bc commit 8ae217b

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

src/archive.c

+1
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@ push_file_internal_uncompressed(const char *wal_file_name, const char *pg_xlog_d
568568
}
569569

570570
/* copy content */
571+
errno = 0;
571572
for (;;)
572573
{
573574
size_t read_len = 0;

src/utils/file.c

+32-10
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,34 @@ fio_fwrite_async(FILE* f, void const* buf, size_t size)
796796
: fwrite(buf, 1, size, f);
797797
}
798798

799+
/*
800+
* Write buffer to descriptor by calling write(),
801+
* If size of written data is less than buffer size,
802+
* then try to write what is left.
803+
* We do this to get honest errno if there are some problems
804+
* with filesystem, since writing less than buffer size
805+
* is not considered an error.
806+
*/
807+
static ssize_t
808+
durable_write(int fd, const char* buf, size_t size)
809+
{
810+
off_t current_pos = 0;
811+
size_t bytes_left = size;
812+
813+
while (bytes_left > 0)
814+
{
815+
int rc = write(fd, buf + current_pos, bytes_left);
816+
817+
if (rc <= 0)
818+
return rc;
819+
820+
bytes_left -= rc;
821+
current_pos += rc;
822+
}
823+
824+
return size;
825+
}
826+
799827
/* Write data to the file */
800828
/* TODO: support async report error */
801829
ssize_t
@@ -814,27 +842,21 @@ fio_write_async(int fd, void const* buf, size_t size)
814842

815843
IO_CHECK(fio_write_all(fio_stdout, &hdr, sizeof(hdr)), sizeof(hdr));
816844
IO_CHECK(fio_write_all(fio_stdout, buf, size), size);
817-
818-
return size;
819845
}
820846
else
821-
{
822-
return write(fd, buf, size);
823-
}
847+
return durable_write(fd, buf, size);
848+
849+
return size;
824850
}
825851

826852
static void
827853
fio_write_async_impl(int fd, void const* buf, size_t size, int out)
828854
{
829-
int rc;
830-
831855
/* Quick exit if agent is tainted */
832856
if (async_errormsg)
833857
return;
834858

835-
rc = write(fd, buf, size);
836-
837-
if (rc <= 0)
859+
if (durable_write(fd, buf, size) <= 0)
838860
{
839861
async_errormsg = pgut_malloc(ERRMSG_MAX_LEN);
840862
snprintf(async_errormsg, ERRMSG_MAX_LEN, "%s", strerror(errno));

0 commit comments

Comments
 (0)