بالنسبة لنظام التشغيل Windows ، يمكن أن يستخدم tr_sys_path_rename
العلامة MOVEFILE_COPY_ALLOWED
بدلاً من حلقة "القراءة والنسخ" المضمنة من util.c:tr_moveFile
ثم يمكن لإصدار Linux استخدام 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;
}
ثم يمكن لإصدار Linux استخدام 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.
(man copy_file_range)
من الناحية المثالية ، يجب أن نتأكد من قفل واستخدام sendfile () بشكل صحيح في سلسلة منفصلة.
هذا يشبه إلى حد كبير رمز "نقل الملف" الحالي عندما
فشل rename
. هذا لا يحتفظ بالأقسام المتفرقة أيضًا ، لذلك لم أفعل
تعتبر هذه مشكلة عند استبدالها.
في الأحد 14 يوليو 2019 الساعة 10:41 مساءً كتب andreygursky [email protected] :
>
ثم يمكن لإصدار Linux استخدام 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.
(man copy_file_range)
من الناحية المثالية ، يجب أن نتأكد من قفل واستخدام sendfile () بشكل صحيح في سلسلة منفصلة.
-
أنت تتلقى هذا لأنك قمت بتأليف الموضوع.
قم بالرد على هذه الرسالة الإلكترونية مباشرةً ، أو اعرضها على 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 لنسخة داخل kernel. لكنني أعتقد أن الأمر يستحق غلافًا خاصًا لكل نظام تشغيل لأنه نظرًا لأن أنظمة الملفات تصبح أكثر كفاءة في النسخ ، فإننا نريد الوصول إلى هذه الميزات تلقائيًا.
لديّ تطبيق أساسي قيد التشغيل على MacOSX و FreeBSD ولكني بحاجة إلى إعداد عدد قليل من الأنظمة الأخرى لاختباره.
أعتقد أن هذا العمل متعامد لجعل الملف يتحرك بشكل غير متزامن. لا ينبغي للمرء أن يقف في طريق الآخر. بالنسبة للمشاريع التطوعية ، فإن زحف النطاق هو عدو الإنتاجية.
التغييرات هنا: 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 (يستخدم مساحة المستخدمين الاحتياطية) ، و FreeBSD 13. في كل حالة ، قمت بالتحقق باستخدام مصحح أخطاء من أننا نجري استدعاءات النظام المناسبة. لسوء الحظ ، لم أتمكن من الحصول على الكود للبناء على OpenBSD 6.5 أو NetBSD 8.1 أو Solaris 10 بسبب بعض مشكلات libevent غير ذات الصلة ، لكنني لست متأكدًا من أن هذه الأنظمة الأساسية مدعومة لـ libtransmission بعد الآن. في أي حال ، يجب ألا يؤثر هذا التغيير على تلك الأنظمة الأساسية.
ما يزال أن أفعل:
نرحب بالتعليقات.
+1 لجعل نقل البيانات غير متزامن. يؤدي نقل ملفات التورنت الكبيرة بين أنظمة الملفات إلى قفل التطبيق بالكامل .
التعليق الأكثر فائدة
+1 لجعل نقل البيانات غير متزامن. يؤدي نقل ملفات التورنت الكبيرة بين أنظمة الملفات إلى قفل التطبيق بالكامل .