Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0c6be59

Browse files
committed
Provide helper for retrying partial vectored I/O.
compute_remaining_iovec() is a re-usable routine for retrying afterpg_readv() or pg_writev() reports a short transfer. This will gain newusers in a later commit, but can already replace the open-codedequivalent code in the existing pg_pwritev_with_retry() function.Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>Discussion:https://postgr.es/m/CA+hUKGJkOiOCa+mag4BF+zHo7qo=o9CFheB8=g6uT5TUm2gkvA@mail.gmail.com
1 parentbaf7c93 commit0c6be59

File tree

2 files changed

+57
-25
lines changed

2 files changed

+57
-25
lines changed

‎src/common/file_utils.c

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,52 @@ get_dirent_type(const char *path,
581581
returnresult;
582582
}
583583

584+
/*
585+
* Compute what remains to be done after a possibly partial vectored read or
586+
* write. The part of 'source' beginning after 'transferred' bytes is copied
587+
* to 'destination', and its length is returned. 'source' and 'destination'
588+
* may point to the same array, for in-place adjustment. A return value of
589+
* zero indicates completion (for callers without a cheaper way to know that).
590+
*/
591+
int
592+
compute_remaining_iovec(structiovec*destination,
593+
conststructiovec*source,
594+
intiovcnt,
595+
size_ttransferred)
596+
{
597+
Assert(iovcnt>0);
598+
599+
/* Skip wholly transferred iovecs. */
600+
while (source->iov_len <=transferred)
601+
{
602+
transferred-=source->iov_len;
603+
source++;
604+
iovcnt--;
605+
606+
/* All iovecs transferred? */
607+
if (iovcnt==0)
608+
{
609+
/*
610+
* We don't expect the kernel to transfer more than we asked it
611+
* to, or something is out of sync.
612+
*/
613+
Assert(transferred==0);
614+
return0;
615+
}
616+
}
617+
618+
/* Copy the remaining iovecs to the front of the array. */
619+
if (source!=destination)
620+
memmove(destination,source,sizeof(*source)*iovcnt);
621+
622+
/* Adjust leading iovec, which may have been partially transferred. */
623+
Assert(destination->iov_len>transferred);
624+
destination->iov_base= (char*)destination->iov_base+transferred;
625+
destination->iov_len-=transferred;
626+
627+
returniovcnt;
628+
}
629+
584630
/*
585631
* pg_pwritev_with_retry
586632
*
@@ -601,7 +647,7 @@ pg_pwritev_with_retry(int fd, const struct iovec *iov, int iovcnt, off_t offset)
601647
return-1;
602648
}
603649

604-
for (;;)
650+
do
605651
{
606652
/* Write as much as we can. */
607653
part=pg_pwritev(fd,iov,iovcnt,offset);
@@ -616,33 +662,14 @@ pg_pwritev_with_retry(int fd, const struct iovec *iov, int iovcnt, off_t offset)
616662
sum+=part;
617663
offset+=part;
618664

619-
/* Step over iovecs that are done. */
620-
while (iovcnt>0&&iov->iov_len <=part)
621-
{
622-
part-=iov->iov_len;
623-
++iov;
624-
--iovcnt;
625-
}
626-
627-
/* Are they all done? */
628-
if (iovcnt==0)
629-
{
630-
/* We don't expect the kernel to write more than requested. */
631-
Assert(part==0);
632-
break;
633-
}
634-
635665
/*
636-
* Move whatever's left to the front of our mutable copy and adjust
637-
* the leading iovec.
666+
* See what is left. On the first loop we used the caller's array,
667+
* but in later loops we'll use our local copy that we are allowed to
668+
* mutate.
638669
*/
639-
Assert(iovcnt>0);
640-
memmove(iov_copy,iov,sizeof(*iov)*iovcnt);
641-
Assert(iov->iov_len>part);
642-
iov_copy[0].iov_base= (char*)iov_copy[0].iov_base+part;
643-
iov_copy[0].iov_len-=part;
670+
iovcnt=compute_remaining_iovec(iov_copy,iov,iovcnt,part);
644671
iov=iov_copy;
645-
}
672+
}while (iovcnt>0);
646673

647674
returnsum;
648675
}

‎src/include/common/file_utils.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ extern PGFileType get_dirent_type(const char *path,
4646
boollook_through_symlinks,
4747
intelevel);
4848

49+
externintcompute_remaining_iovec(structiovec*destination,
50+
conststructiovec*source,
51+
intiovcnt,
52+
size_ttransferred);
53+
4954
externssize_tpg_pwritev_with_retry(intfd,
5055
conststructiovec*iov,
5156
intiovcnt,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp