Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+53-1
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

+4-4
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

+65
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

+5
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

-2
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

+2-41
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

+58
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)