Skip to content

Commit 0d56acf

Browse files
committed
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
1 parent 5a6f9bc commit 0d56acf

File tree

10 files changed

+248
-154
lines changed

10 files changed

+248
-154
lines changed

configure

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15155,7 +15155,7 @@ fi
1515515155
LIBS_including_readline="$LIBS"
1515615156
LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
1515715157

15158-
for ac_func in backtrace_symbols clock_gettime copyfile fdatasync getifaddrs getpeerucred getrlimit kqueue mbstowcs_l memset_s poll posix_fallocate ppoll pread preadv pstat pthread_is_threaded_np pwrite pwritev readlink readv setproctitle setproctitle_fast setsid shm_open strchrnul strsignal symlink sync_file_range uselocale wcstombs_l writev
15158+
for ac_func in backtrace_symbols clock_gettime copyfile fdatasync getifaddrs getpeerucred getrlimit kqueue mbstowcs_l memset_s poll posix_fallocate ppoll pstat pthread_is_threaded_np readlink readv setproctitle setproctitle_fast setsid shm_open strchrnul strsignal symlink sync_file_range uselocale wcstombs_l writev
1515915159
do :
1516015160
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
1516115161
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -15832,6 +15832,58 @@ esac
1583215832

1583315833
fi
1583415834

15835+
ac_fn_c_check_func "$LINENO" "pread" "ac_cv_func_pread"
15836+
if test "x$ac_cv_func_pread" = xyes; then :
15837+
$as_echo "#define HAVE_PREAD 1" >>confdefs.h
15838+
15839+
else
15840+
case " $LIBOBJS " in
15841+
*" pread.$ac_objext "* ) ;;
15842+
*) LIBOBJS="$LIBOBJS pread.$ac_objext"
15843+
;;
15844+
esac
15845+
15846+
fi
15847+
15848+
ac_fn_c_check_func "$LINENO" "preadv" "ac_cv_func_preadv"
15849+
if test "x$ac_cv_func_preadv" = xyes; then :
15850+
$as_echo "#define HAVE_PREADV 1" >>confdefs.h
15851+
15852+
else
15853+
case " $LIBOBJS " in
15854+
*" preadv.$ac_objext "* ) ;;
15855+
*) LIBOBJS="$LIBOBJS preadv.$ac_objext"
15856+
;;
15857+
esac
15858+
15859+
fi
15860+
15861+
ac_fn_c_check_func "$LINENO" "pwrite" "ac_cv_func_pwrite"
15862+
if test "x$ac_cv_func_pwrite" = xyes; then :
15863+
$as_echo "#define HAVE_PWRITE 1" >>confdefs.h
15864+
15865+
else
15866+
case " $LIBOBJS " in
15867+
*" pwrite.$ac_objext "* ) ;;
15868+
*) LIBOBJS="$LIBOBJS pwrite.$ac_objext"
15869+
;;
15870+
esac
15871+
15872+
fi
15873+
15874+
ac_fn_c_check_func "$LINENO" "pwritev" "ac_cv_func_pwritev"
15875+
if test "x$ac_cv_func_pwritev" = xyes; then :
15876+
$as_echo "#define HAVE_PWRITEV 1" >>confdefs.h
15877+
15878+
else
15879+
case " $LIBOBJS " in
15880+
*" pwritev.$ac_objext "* ) ;;
15881+
*) LIBOBJS="$LIBOBJS pwritev.$ac_objext"
15882+
;;
15883+
esac
15884+
15885+
fi
15886+
1583515887
ac_fn_c_check_func "$LINENO" "random" "ac_cv_func_random"
1583615888
if test "x$ac_cv_func_random" = xyes; then :
1583715889
$as_echo "#define HAVE_RANDOM 1" >>confdefs.h

configure.ac

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1661,12 +1661,8 @@ AC_CHECK_FUNCS(m4_normalize([
16611661
poll
16621662
posix_fallocate
16631663
ppoll
1664-
pread
1665-
preadv
16661664
pstat
16671665
pthread_is_threaded_np
1668-
pwrite
1669-
pwritev
16701666
readlink
16711667
readv
16721668
setproctitle
@@ -1740,6 +1736,10 @@ AC_REPLACE_FUNCS(m4_normalize([
17401736
inet_aton
17411737
link
17421738
mkdtemp
1739+
pread
1740+
preadv
1741+
pwrite
1742+
pwritev
17431743
random
17441744
srandom
17451745
strlcat

src/backend/storage/file/fd.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
#include "common/file_utils.h"
9393
#include "miscadmin.h"
9494
#include "pgstat.h"
95+
#include "port/pg_iovec.h"
9596
#include "portability/mem.h"
9697
#include "storage/fd.h"
9798
#include "storage/ipc.h"
@@ -3635,3 +3636,67 @@ data_sync_elevel(int elevel)
36353636
{
36363637
return data_sync_retry ? elevel : PANIC;
36373638
}
3639+
3640+
/*
3641+
* A convenience wrapper for pg_pwritev() that retries on partial write. If an
3642+
* error is returned, it is unspecified how much has been written.
3643+
*/
3644+
ssize_t
3645+
pg_pwritev_with_retry(int fd, const struct iovec *iov, int iovcnt, off_t offset)
3646+
{
3647+
struct iovec iov_copy[PG_IOV_MAX];
3648+
ssize_t sum = 0;
3649+
ssize_t part;
3650+
3651+
/* We'd better have space to make a copy, in case we need to retry. */
3652+
if (iovcnt > PG_IOV_MAX)
3653+
{
3654+
errno = EINVAL;
3655+
return -1;
3656+
}
3657+
3658+
for (;;)
3659+
{
3660+
/* Write as much as we can. */
3661+
part = pg_pwritev(fd, iov, iovcnt, offset);
3662+
if (part < 0)
3663+
return -1;
3664+
3665+
#ifdef SIMULATE_SHORT_WRITE
3666+
part = Min(part, 4096);
3667+
#endif
3668+
3669+
/* Count our progress. */
3670+
sum += part;
3671+
offset += part;
3672+
3673+
/* Step over iovecs that are done. */
3674+
while (iovcnt > 0 && iov->iov_len <= part)
3675+
{
3676+
part -= iov->iov_len;
3677+
++iov;
3678+
--iovcnt;
3679+
}
3680+
3681+
/* Are they all done? */
3682+
if (iovcnt == 0)
3683+
{
3684+
/* We don't expect the kernel to write more than requested. */
3685+
Assert(part == 0);
3686+
break;
3687+
}
3688+
3689+
/*
3690+
* Move whatever's left to the front of our mutable copy and adjust
3691+
* the leading iovec.
3692+
*/
3693+
Assert(iovcnt > 0);
3694+
memmove(iov_copy, iov, sizeof(*iov) * iovcnt);
3695+
Assert(iov->iov_len > part);
3696+
iov_copy[0].iov_base = (char *) iov_copy[0].iov_base + part;
3697+
iov_copy[0].iov_len -= part;
3698+
iov = iov_copy;
3699+
}
3700+
3701+
return sum;
3702+
}

src/include/storage/fd.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545

4646
#include <dirent.h>
4747

48+
struct iovec; /* avoid including port/pg_iovec.h here */
4849

4950
typedef int File;
5051

@@ -161,6 +162,10 @@ extern int durable_unlink(const char *fname, int loglevel);
161162
extern int durable_rename_excl(const char *oldfile, const char *newfile, int loglevel);
162163
extern void SyncDataDirectory(void);
163164
extern int data_sync_elevel(int elevel);
165+
extern ssize_t pg_pwritev_with_retry(int fd,
166+
const struct iovec *iov,
167+
int iovcnt,
168+
off_t offset);
164169

165170
/* Filename components */
166171
#define PG_TEMP_FILES_DIR "pgsql_tmp"

src/port/Makefile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ OBJS = \
5353
pgstrcasecmp.o \
5454
pgstrsignal.o \
5555
pqsignal.o \
56-
pread.o \
57-
pwrite.o \
5856
qsort.o \
5957
qsort_arg.o \
6058
quotes.o \

src/port/pread.c

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
/*-------------------------------------------------------------------------
22
*
33
* pread.c
4-
* Implementation of pread[v](2) for platforms that lack one.
4+
* Implementation of pread(2) for platforms that lack one.
55
*
66
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
77
*
88
* IDENTIFICATION
99
* src/port/pread.c
1010
*
1111
* Note that this implementation changes the current file position, unlike
12-
* the POSIX function, so we use the name pg_pread(). Likewise for the
13-
* iovec version.
12+
* the POSIX function, so we use the name pg_pread().
1413
*
1514
*-------------------------------------------------------------------------
1615
*/
@@ -24,9 +23,6 @@
2423
#include <unistd.h>
2524
#endif
2625

27-
#include "port/pg_iovec.h"
28-
29-
#ifndef HAVE_PREAD
3026
ssize_t
3127
pg_pread(int fd, void *buf, size_t size, off_t offset)
3228
{
@@ -60,38 +56,3 @@ pg_pread(int fd, void *buf, size_t size, off_t offset)
6056
return read(fd, buf, size);
6157
#endif
6258
}
63-
#endif
64-
65-
#ifndef HAVE_PREADV
66-
ssize_t
67-
pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
68-
{
69-
#ifdef HAVE_READV
70-
if (iovcnt == 1)
71-
return pg_pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
72-
if (lseek(fd, offset, SEEK_SET) < 0)
73-
return -1;
74-
return readv(fd, iov, iovcnt);
75-
#else
76-
ssize_t sum = 0;
77-
ssize_t part;
78-
79-
for (int i = 0; i < iovcnt; ++i)
80-
{
81-
part = pg_pread(fd, iov[i].iov_base, iov[i].iov_len, offset);
82-
if (part < 0)
83-
{
84-
if (i == 0)
85-
return -1;
86-
else
87-
return sum;
88-
}
89-
sum += part;
90-
offset += part;
91-
if (part < iov[i].iov_len)
92-
return sum;
93-
}
94-
return sum;
95-
#endif
96-
}
97-
#endif

src/port/preadv.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* preadv.c
4+
* Implementation of preadv(2) for platforms that lack one.
5+
*
6+
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
7+
*
8+
* IDENTIFICATION
9+
* src/port/preadv.c
10+
*
11+
* Note that this implementation changes the current file position, unlike
12+
* the POSIX-like function, so we use the name pg_preadv().
13+
*
14+
*-------------------------------------------------------------------------
15+
*/
16+
17+
18+
#include "postgres.h"
19+
20+
#ifdef WIN32
21+
#include <windows.h>
22+
#else
23+
#include <unistd.h>
24+
#endif
25+
26+
#include "port/pg_iovec.h"
27+
28+
ssize_t
29+
pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
30+
{
31+
#ifdef HAVE_READV
32+
if (iovcnt == 1)
33+
return pg_pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
34+
if (lseek(fd, offset, SEEK_SET) < 0)
35+
return -1;
36+
return readv(fd, iov, iovcnt);
37+
#else
38+
ssize_t sum = 0;
39+
ssize_t part;
40+
41+
for (int i = 0; i < iovcnt; ++i)
42+
{
43+
part = pg_pread(fd, iov[i].iov_base, iov[i].iov_len, offset);
44+
if (part < 0)
45+
{
46+
if (i == 0)
47+
return -1;
48+
else
49+
return sum;
50+
}
51+
sum += part;
52+
offset += part;
53+
if (part < iov[i].iov_len)
54+
return sum;
55+
}
56+
return sum;
57+
#endif
58+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy