1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-27 07:42:10 +03:00

Move our p{read,write}v replacements into their own files.

macOS's ranlib issued a warning about an empty pread.o file with the
previous arrangement, on systems new enough to require no replacement
functions.  Let's go back to using configure's AC_REPLACE_FUNCS system
to build and include each .o in the library only if it's needed, which
requires moving the *v() functions to their own files.

Also move the _with_retry() wrapper to a more permanent home.

Reported-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/1283127.1610554395%40sss.pgh.pa.us
This commit is contained in:
Thomas Munro
2021-01-14 11:10:24 +13:00
parent 5a6f9bce8d
commit 0d56acfbaa
10 changed files with 248 additions and 154 deletions

View File

@@ -92,6 +92,7 @@
#include "common/file_utils.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "port/pg_iovec.h"
#include "portability/mem.h"
#include "storage/fd.h"
#include "storage/ipc.h"
@@ -3635,3 +3636,67 @@ data_sync_elevel(int elevel)
{
return data_sync_retry ? elevel : PANIC;
}
/*
* A convenience wrapper for pg_pwritev() that retries on partial write. If an
* error is returned, it is unspecified how much has been written.
*/
ssize_t
pg_pwritev_with_retry(int fd, const struct iovec *iov, int iovcnt, off_t offset)
{
struct iovec iov_copy[PG_IOV_MAX];
ssize_t sum = 0;
ssize_t part;
/* We'd better have space to make a copy, in case we need to retry. */
if (iovcnt > PG_IOV_MAX)
{
errno = EINVAL;
return -1;
}
for (;;)
{
/* Write as much as we can. */
part = pg_pwritev(fd, iov, iovcnt, offset);
if (part < 0)
return -1;
#ifdef SIMULATE_SHORT_WRITE
part = Min(part, 4096);
#endif
/* Count our progress. */
sum += part;
offset += part;
/* Step over iovecs that are done. */
while (iovcnt > 0 && iov->iov_len <= part)
{
part -= iov->iov_len;
++iov;
--iovcnt;
}
/* Are they all done? */
if (iovcnt == 0)
{
/* We don't expect the kernel to write more than requested. */
Assert(part == 0);
break;
}
/*
* Move whatever's left to the front of our mutable copy and adjust
* the leading iovec.
*/
Assert(iovcnt > 0);
memmove(iov_copy, iov, sizeof(*iov) * iovcnt);
Assert(iov->iov_len > part);
iov_copy[0].iov_base = (char *) iov_copy[0].iov_base + part;
iov_copy[0].iov_len -= part;
iov = iov_copy;
}
return sum;
}