рд╡рд┐рдВрдбреЛрдЬрд╝ рдХреЗ рд▓рд┐рдП, tr_sys_path_rename
рдзреНрд╡рдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ MOVEFILE_COPY_ALLOWED
рдмрдЬрд╛рдп util.c:tr_moveFile
рддрдм рд▓рд┐рдирдХреНрд╕ рд╕рдВрд╕реНрдХрд░рдг рдкреНрд░рддреНрдпреЗрдХ рдкрд░ рд▓реВрдкрд┐рдВрдЧ рдХреЗ рдмрдЬрд╛рдп рдЕрдзрд┐рдХ рдЖрдзреБрдирд┐рдХ copy_file_range
рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рдерд╛ред
рд╢рд╛рдпрдж рдХреБрдЫ рдРрд╕рд╛:
size_t tr_sys_file_copy(tr_sys_file_t infile, tr_sys_file_t outfile, size_t len, tr_error** error )
{
TR_ASSERT(outfile != NULL);
TR_ASSERT(infile != NULL);
bool ret = false;
unsigned int flags = 0;
size_t res;
res = copy_file_range(infile, NULL, outfile, NULL, &len, flags);
if (res) {
return res;
}
else {
set_system_error(error, errno);
return res;
}
}
рдФрд░ рд╢рд╛рдпрдж рдПрдХ:
tr_sys_file_copy_fallback(tr_sys_file_t infile, tr_sys_file_t outfile, size_t len, tr_error** error ) {
TR_ASSERT(outfile != NULL);
TR_ASSERT(infile != NULL);
uint64_t bytesLeft = len;
size_t const buflen = 1024 * 128; /* 128 KiB buffer */
tr_sys_path_info info;
while (bytesLeft > 0)
{
uint64_t const bytesThisPass = MIN(bytesLeft, buflen);
uint64_t numRead;
uint64_t bytesWritten;
if (!tr_sys_file_read(infile, buf, bytesThisPass, &numRead, error))
{
break;
}
if (!tr_sys_file_write(outfile, buf, numRead, &bytesWritten, error))
{
break;
}
TR_ASSERT(numRead == bytesWritten);
TR_ASSERT(bytesWritten <= bytesLeft);
bytesLeft -= bytesWritten;
}
return bytesLeft;
}
рддрдм рд▓рд┐рдирдХреНрд╕ рд╕рдВрд╕реНрдХрд░рдг рдкреНрд░рддреНрдпреЗрдХ рдкрд░ рд▓реВрдкрд┐рдВрдЧ рдХреЗ рдмрдЬрд╛рдп рдЕрдзрд┐рдХ рдЖрдзреБрдирд┐рдХ copy_file_range рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рдерд╛ред
рдпрд╣ рдХреЗрд╡рд▓ рдПрдХ рдХреЙрд▓ (рдпрд╛ рд╕рд╛рдзрд╛рд░рдг рд▓реВрдк рдореЗрдВ) рдХреЗ рд╕рд╛рде рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
If file_in is a sparse file, then copy_file_range() may expand any
holes existing in the requested range. Users may benefit from calling
copy_file_range() in a loop, and using the lseek(2) SEEK_DATA and
SEEK_HOLE operations to find the locations of data segments.
(рдЖрджрдореА copy_file_range)
рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ рд╣рдореЗрдВ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдареАрдХ рд╕реЗ рд▓реЙрдХ рд╣реЛ рдФрд░ рдПрдХ рдЕрд▓рдЧ рдереНрд░реЗрдб рдореЗрдВ рд╕реЗрдВрдбрдлрд╛рдЗрд▓ () рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред
рдпрд╣ рдХрд╛рдлреА рд╣рдж рддрдХ рд╡рд░реНрддрдорд╛рди "рдореВрд╡ рдлрд╛рдЗрд▓" рдХреЛрдб рдЬреИрд╕рд╛ рд╣реА рд╣реИ рдЬрдм
rename
рд╡рд┐рдлрд▓ рд░рд╣рддрд╛ рд╣реИред рдпрд╣ рд╡рд┐рд░рд▓ рд╡рд░реНрдЧреЛрдВ рдХреЛ рднреА рдирд╣реАрдВ рд░рдЦрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдирд╣реАрдВ рдХрд┐рдпрд╛
рдЗрд╕реЗ рдмрджрд▓рддреЗ рд╕рдордп рдПрдХ рд╕рдорд╕реНрдпрд╛ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред
рд╕реВрд░реНрдп, 14 рдЬреБрд▓рд╛рдИ, 2019 рдкрд░ 10:41 pm рдкрд░ andreygursky [email protected] рд▓рд┐рдЦрд╛ рд╣реИ:
>
рддрдм рд▓рд┐рдирдХреНрд╕ рд╕рдВрд╕реНрдХрд░рдг рдкреНрд░рддреНрдпреЗрдХ рдкрд░ рд▓реВрдкрд┐рдВрдЧ рдХреЗ рдмрдЬрд╛рдп рдЕрдзрд┐рдХ рдЖрдзреБрдирд┐рдХ copy_file_range рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рдерд╛ред
рдпрд╣ рдХреЗрд╡рд▓ рдПрдХ рдХреЙрд▓ (рдпрд╛ рд╕рд╛рдзрд╛рд░рдг рд▓реВрдк рдореЗрдВ) рдХреЗ рд╕рд╛рде рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
If file_in is a sparse file, then copy_file_range() may expand any holes existing in the requested range. Users may benefit from calling copy_file_range() in a loop, and using the lseek(2) SEEK_DATA and SEEK_HOLE operations to find the locations of data segments.
(рдЖрджрдореА copy_file_range)
рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ рд╣рдореЗрдВ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдареАрдХ рд╕реЗ рд▓реЙрдХ рд╣реЛ рдФрд░ рдПрдХ рдЕрд▓рдЧ рдереНрд░реЗрдб рдореЗрдВ рд╕реЗрдВрдбрдлрд╛рдЗрд▓ () рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред
-
рдЖрдк рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдиреЗ рд╕реВрддреНрд░ рдХреЛ рд▓рд┐рдЦрд╛ рд╣реИред
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ, рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ, рдпрд╛ рдереНрд░реЗрдб рдХреЛ рдореНрдпреВрдЯ рдХрд░реЗрдВред
рд╡рд░реНрддрдорд╛рди "рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдлрд╝рд╛рдЗрд▓" рдПрдХ рд╕рдВрджрд░реНрдн рдХреЗ рд░реВрдк рдореЗрдВ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ
рд╡рд░реНрддрдорд╛рди рдХрд╛рд░реНрдп:
https://github.com/transmission/transmission/blob/master/libtransmission/utils.c#L1682
https://github.com/transmission/transmission/blob/master/libtransmission/utils.c#L1744
рдпрд╣ рд╡рд┐рд░рд▓ рд╡рд░реНрдЧреЛрдВ рдХреЛ рднреА рдирд╣реАрдВ рд░рдЦрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдирд╣реАрдВ рдХрд┐рдпрд╛
рдЗрд╕реЗ рдмрджрд▓рддреЗ рд╕рдордп рдПрдХ рд╕рдорд╕реНрдпрд╛ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред
рдФрд░ рдЗрд╕рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдп рдлрд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░реАрдЖрд▓реЛрдХреЗрд╢рди рдЧреБрдо рд╣реИред
рд╣рд╛рдВред рдУ рднреАред "рдлрд╝рд╛рдЗрд▓ рд▓реЗ рдЬрд╛рдПрдБ" рдХрд╛ рд╡рд░реНрддрдорд╛рди рдЦрд░рд╛рдм рд╡реНрдпрд╡рд╣рд╛рд░ рдХреБрдЫ рд╕реЗрдЯ рдЕрдк рдореЗрдВ рдмреЗрддреБрдХреЗ рднрд╛рд░ рдХрд╛ рдХрд╛рд░рдг рдмрдирдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред рдпрджрд┐ рд╕рдВрднрд╡ рд╣реЛ, рддреЛ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ glibc copy_file_range рдореЗрдВ рдлрд╝реЙрд▓-рдмреИрдХ рд╕рдорд╛рдзрд╛рди рдПрдХ рдмреЗрд╣рддрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рднреА рд╣реИред
рдореИрдВрдиреЗ рдЗрд╕рдХреЗ рд╕рд╛рде рдПрдХ рдирд╛рдЯрдХ рдХрд┐рдпрд╛ рд╣реИред рдХреНрд░реЙрд╕ рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рддрд░реАрдХреЗ рд╕реЗ рд╕рд╣реА рд╣реЛрдирд╛ рдХрдард┐рди рд╣реИ: рдЗрди-рдХрд░реНрдиреЗрд▓ рдХреЙрдкреА рдХреЗ рд▓рд┐рдП рдХреЛрдИ POSIX рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреНрд░рддреАрдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдкреНрд░рддреНрдпреЗрдХ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖ рдЖрд╡рд░рдг рдХреЗ рд▓рд╛рдпрдХ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЬреИрд╕реЗ-рдЬреИрд╕реЗ рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдкреНрд░рддрд┐рдпреЛрдВ рдореЗрдВ рдЕрдзрд┐рдХ рдХреБрд╢рд▓ рд╣реЛрддреЗ рд╣реИрдВ рд╣рдо рдЙрди рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред
рдореЗрд░реЗ рдкрд╛рд╕ рдореИрдХреЛрдЬрд╝рдХреНрд╕ рдФрд░ рдлреНрд░реАрдмреАрдПрд╕рдбреА рдкрд░ рдПрдХ рдмреБрдирд┐рдпрд╛рджреА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ рдФрд░ рдЪрд▓ рд░рд╣рд╛ рд╣реИ рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдЗрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдФрд░ рд╕рд┐рд╕реНрдЯрдо рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХрд╛рдо рдлрд╝рд╛рдЗрд▓ рдХреЛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдСрд░реНрдереЛрдЧреЛрдирд▓ рд╣реИред рдПрдХ рдХреЛ рджреВрд╕рд░реЗ рдХреЗ рд░рд╛рд╕реНрддреЗ рдореЗрдВ рдирд╣реАрдВ рдЦрдбрд╝рд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рд╕реНрд╡рдпрдВрд╕реЗрд╡реА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП, рдЧреБрдВрдЬрд╛рдЗрд╢ рд░реЗрдВрдЧрдирд╛ рдЙрддреНрдкрд╛рджрдХрддрд╛ рдХрд╛ рджреБрд╢реНрдорди рд╣реИред
рдкрд░рд┐рд╡рд░реНрддрди рдпрд╣рд╛рдБ рд╣реИрдВ: https://github.com/transmission/transmission/compare/master...RobCrowston:kernelcopy-wip
рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдореИрдВ tr_sys_path_copy() рдирд╛рдордХ рдПрдХ рдирдпрд╛ рдЕрдореВрд░реНрдд рдмрдирд╛рддрд╛ рд╣реВрдВред (рдореИрдВ рдПрдХ рдЪрд╛рд▓ рдХреЗ рдмрдЬрд╛рдп рдПрдХ рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдХреЗ рд╕рд╛рде рдЧрдпрд╛ рдерд╛ рдХреНрдпреЛрдВрдХрд┐ рдЬрдм рд╣рдо рдЗрд╕реЗ рдПрдХ рдПрд╕рд┐рдВрдХ рдСрдкрд░реЗрд╢рди рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рдЕрдиреНрдп рдзрд╛рдЧреЗ рдореЗрдВ рдлрд╝рд╛рдЗрд▓ рд╣реИрдВрдбрд▓ рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдкреВрд░реНрдг рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдореВрд▓ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдХреБрдЫ рдЕрдирд┐рд╢реНрдЪрд┐рдд рдЕрд╡рдзрд┐ рдХреЗ рд▓рд┐рдП рд░рдЦрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред)
рдЖрдЬ рддрдХ, рдореИрдВрдиреЗ MacOS 10.15.1, Windows Server 2016, Linux 5.0 (Ubuntu 19.05), Linux 5.3 (Arch 2019-12-03), FreeBSD 12.1 рдкрд░ рдирдпрд╛ рдкрд░реАрдХреНрд╖рдг (рдЯреНрд░рд╛рдВрд╕рдорд┐рд╢рди-рдЯреЗрд╕реНрдЯ-рдХреЙрдкреА) рд╕рдВрдХрд▓рд┐рдд рдФрд░ рдЪрд▓рд╛рдпрд╛ рд╣реИред (рдпреВрдЬрд░рд╕реНрдкреЗрд╕ рдлрд╝реЙрд▓рдмреИрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ), рдФрд░ рдлреНрд░реАрдмреАрдПрд╕рдбреА 13. рдкреНрд░рддреНрдпреЗрдХ рдорд╛рдорд▓реЗ рдореЗрдВ рдореИрдВрдиреЗ рдбреАрдмрдЧрд░ рд╕реЗ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдХрд┐ рд╣рдо рдЙрдкрдпреБрдХреНрдд рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ рдореИрдВ рдХреБрдЫ рдЕрд╕рдВрдмрдВрдзрд┐рдд libevent рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рдХрд╛рд░рдг OpenBSD 6.5, NetBSD 8.1, рдпрд╛ Solaris 10 рдкрд░ рдХреЛрдб рдмрдирд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рдерд╛, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпреЗ рдЕрдм libtransmission рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерд┐рдд рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рд╣реИрдВред рдХрд┐рд╕реА рднреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдпрд╣ рдкрд░рд┐рд╡рд░реНрддрди рдЙрди рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдЕрднреА рднреА рдХрд░рдирд╛ рд╣реИ:
рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИред
рдбреЗрдЯрд╛ рдХреЛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП +1ред рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдмреАрдЪ рдмрдбрд╝реЗ рдЯреЛрд░реЗрдВрдЯ рдХреЛ рд▓реЗ рдЬрд╛рдирд╛ рдкреВрд░реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд▓реЙрдХ рдХрд░ рджреЗрддрд╛ рд╣реИ ред
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
рдбреЗрдЯрд╛ рдХреЛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП +1ред рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдмреАрдЪ рдмрдбрд╝реЗ рдЯреЛрд░реЗрдВрдЯ рдХреЛ рд▓реЗ рдЬрд╛рдирд╛ рдкреВрд░реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд▓реЙрдХ рдХрд░ рджреЗрддрд╛ рд╣реИ ред