مساء الخير , الموضوع هيتكلم عن ال internals الخاصه بال system calls read , write
هيتكلم اذاي الدوال ديت بتشتغل , واذاي ال data بتوصلك او بتوصل لل physical media او اي كان المكان الي بتكتب
مبدئيا هنتكلم عن ال IO بشكل عام :
اي عملية IO بتتم علي ال علي ال disk بتتم علي شكل blocks of data
الي blocks ديت بتختلف في الحجم ممكن تكون 512 , 1024 , 2048 وهكذا
في فرق كبير جدا ان تقرا 1024 byte ك byte by bye وده هيكون 1024 system call لل read
بس المشكله مش في ال 1024 system call ديت ولونها هتعمل مشكله في ال performence المشكله هتكون في ال accessing the disk
ال access علي ال disk بيكون اسرع لما بيكون block aligned يعني بتقرا blocks محاذيين لبعض علي شكل خطي linear blocks
بذلك ال kernel بيقدر يقرا اسرع واسرع وده بيساعده علي تقليل ال overhead في ال access لل blocks
الكتابة على الديسك بتم على هيئة شنكس ولنقل مثلا 4 ميجا وهو ضعف حجم ال block size زي مقلنا .... اذا سواء كتبت 2 ميجا او حتى كيلو او 4 ميجا هتاخد نفس الزمن فى الكتابة ..... وهو الزمن اللى بتاخده الشنك ..... فلو انك كتبت بايت بايت هتاخد زمن 4 ميجا فى كل مرة ويبقى الكتابة مش فعالة ....... علشان كدة بتعمل بفر وبتكتب منه بعنى لو كان حجم البفر انت مظبطه على حجم الشنك
الكتابة هتكون سريعة جدا ..
كأن تقرا مثلا 1024 بايت في ال call الواحده او 2048 او 4096 بايت مثلا
Thanks hackobacko بس للاسف الكلام دوت مش بيكون موجود ديما مع ال files , لان وفي الغالب في ال file ممكن تقرا char by char او line by line ده مش بيكون block aligned علي اي شكل من الاشكال , لانك بتقرا بايت واحد في الاستدعاء او سطر واحد الله اعلم حجمه قد ايه بس مفيش سطر حجمه 512 بايت مثلا ؟
الكيرنيل اذاي بيحل الموضوع دوت , نقدر دلوقتي نتكلم عن ال internals الي ال kernel بيتعامل بيها مع ال I/O
اولا عشان نبدأ نقسم الموضوع في انظمة فرعيه في ال Kernel تكون ال I/O system في ال kernel تسمي بال I/O subsystems
التركيز هيكون علي اتنين منها حاليا وواحد كمان هيتم ذكره في الاخر للعلم بالشيئ ليس اكثر
اولهم ال : Page caching
ال page cache هو مكان في ال memory ال kernel بيتحتفظ بيه بال recently requested data , ال page cache بما انه مكان في ال memory فطبيعي انه ممكن يكبر علي حسب الاحتياج
فايدته انه بيقلل من ال disk access باستخدام "temporal locality" مش هترجمها بالعربي انما هشرح معناها , معناها ان ال disk access الي حصل في مكان ما ممكن يكون ليه احتماليه انه يحصل تاني , والاحتماليات ليها اولويات والاولويات بيتم الاستدلال عليها من اول request بتحصل disk access عشان يقدر يقلل من ال disk requests الي بتحصل لل disk
بس ليه البارانويا ديت حول ال disk access ? هو ال disk بطئ للدرجة ديت ؟
الحقيقه انه مش بطئ , انما مش سريع قد ال memory accessing
وديت لاسباب المفروض انك تكون فاهمها
بس ال page cache لزمته ايه بعد كل الكلام دوت ؟
لزمته انه بيسجل اخر data تم الحصول عليها
في حين انك لو طلبتها مرة تانيه بدل مالkernel يقوم بعمل disk access هيقوم بعمل memory access وارجاع ال data المطلوبه ليك من ال memory
وده معناه ان كل read request بتحصل بيتم الحصول علي الداتا بالتحديد من ال memory cache
في اول مرة بتحصل لما ال data مبتكنش موجوده في ال memory cache ال kernel بيقوم بقرائتها من ال disk وعمل نسخه منها في ال page cache وبعدين بيقوم بارجاع ال data من ال page cache , تاني مرة يتم طلب ال data ديت فيها بيتم ارجاعها فورا من ال page cache بدلا من عمل disk access تاني وطلب قرائه منه والانتظار.
حاجه كمان بيستخدمها ال page cache تسمي بال read ahead يعني اقرا شوية كمان قدام فوق البيانات المطلوبه , وديت بتكون نافذه حجمها ممكن يكون 16 كيلو كاقل حجم او 128 كأكبر حجم
وده نوع تاني من ال locality بيفترض ان البيانات بيتم الحصول عليها sequentially يعني تسلسليا ولذلك بيستفيد من ال read ahead , بيتم تسجيل ال read ahead في ال page cache وحجمه بيكبر او يقل علي حسب ال sequential access او علي حسب حجم ال chunks المطلوبه , يعني مثلا لو انا طلبت 4 kbyte chuck ممكن يقرا 16 kbyte كمان فوقيهم ويسجلهم في ال page cache
طبعا ديت ideal status بس مش ديما الحال بيكون كده , انك تقرا ملف بشكل تسلسي احسن بكتير من انك تقراه بشكل عشوائي , الكيرنيل لو لاحظ ذلك هيعمل disable تمام لل read ahead
بس في حاجه كمان لسه بتلعب في دماغك الا وهي ال memory ! ال memory مش كبيره للدرجة وممكن تخلص بسرعه مثلا , ولذلك لما بتحصل حاجه زي كده ال kernel بيعمل prune لل page cache
يعني بينضفه بمعني اصح , بيعمل clean لل less frequently accessed data بس برده دوت مش حل 100% , افرض ان في منهم انت محتاجهم واولوياتهم كبيره بس صغيره بالنسبه للاولويات الي في ال page cache
يعني مثلا هنا 10 وهنا 9 , 9 مش قليل بس هيتم التخلص منه , ولذلك بيستخدم swapping system , ودوت بيسمح لل kernel انه يخزن ال البيانات علي ال disk , وبذلك بيسمحه بمساحة ذاكرة اكبر من تلك الموجوده في ال ram , ال swapping موضوع تاني مش هنتكلم عنه انما حبيت اوضح الاستفاده منه
قبل منتكلم عن ال system التاني هنتكلم عن ال
read call :
ال read call بتتبع كل الكلام الي اتكلمنا عنه فوق , لو قريت data من ال disk بشكل متتابع بيتم استخدام ال page caching وال read ahead بشكل ممتاز بيسرع عملية القرائه اكتر واكتر
انما لو استخدمتها بشكل عشوائي ودوت بيحصل في بعض الاحيان بل وبيكون مطلوب ال page caching وال read ahead مش هيكونا كويسين بشكل كبير بال بالعكس ممكن يكونوا مش شغالين اساسا خاصة ال read ahead زي متكلمنا فوق
دلوقتي ال read call بتطلب data من ال مكان كذا في ال disk
الكيرنيل بيقوم بعمل read لل disk اذا كانت ال data غير موجوده في ال page cache ويقرا شوية بيانات كمان ويستخدم ال read ahead ويعمل نسخه منها في الميموري
طلبت بيانات تانيه علي نفس ال sequence بتاع البيانات الي قبل كده هيتم الحصول عليها فورا من ال page cache الي طبيعي متخزن فيه ال read ahead الي ممكن بكده حجمه يكبر ويوصل مثلا ل 128 كيلو بايت زي مقلنا قبل كده , انما سيناريو تاني ممكن يحصل انك متقراش البيانات بشكل سليم وبذلك ال performence مش هيكون علي قد كده .
نتكلم عن ال system التاني ال Page writeback:
ولكن قبل منتكلم عنها هنتكلم عن اسلوب ال write في الكتابة لل disk
رجع ضهرك لورا وهاتلك حاجه تشربها وريح شوية قبل متكمل الكلام دوت لانك محتاج تكون استوعبت الي قبل كده عشان تستوعب ده
هقلك حاجه سر , ال writes الي انت بتكتبها لل disk ممكن متكنش بتروح لل disk علي طول , صراحه مفيش حد كان عاوز يقلك كده انما ال data بتروح لل memory قبل كده وتسجل نفسها في buffer قبل متتكتب لل disk

الي بيحصل هو الاتي : بتطلب من الكيرنيل انك تكتب في disk , الكيرنيل بياخد الداتا بتاعتك ويعمل منها كوبي ويحطها في ال buffer الي هو قام بانشائه ويقلك اشطه هبقي اكتبها بعدين ياسكر ! ده بالظبت الي بيحصل
الكتابة بعدين ديت مبتحصلش الا لما بيحصل سبب من السببين :
1- ال buffers حجمها كبر فوق حجم بيتم عمله configure من ال kernel وسبب تقلص في حجم الذاكره المتاحه
2- ال buffers وقتها كتر في الذاكره ولازم تتكتب لل disk وده برده configurable في ال kernel
لما بيحصل حاجه من الاتنين دول بيتم ايقاظ kernel threads تسمي بال pdflush threads لما بيتم ايقاظه عن حدوث اي حدث من الاحداث الي اتكلمنها عنها من شوية , ومن ثم بتقوم بكتابة ال data لل disk وعمل لحد مالحدثين دول يتم ارضائهم ان ميكنش في اي buffer في ال kernel متوافق مع اي سبب من السببين دول
لكن دلوقتي انا لما بكتب مثلا data لل disk وفي نفس الوقت بطلب نفس ال data ديت ححصل عليها اذاي ؟ ده لان ال buffers ديت بيتم تسجيلها في ال page cache

ايوه بالظبت الاتنين ليهم علاقه كبيره ببعض في الحقيقه النظامين مشتركين مع بعض
ال buffers بيتم تسجيلها في ال page cache وبيتم تسجيلها علي هيئة منشئات بتحتوي علي بيانات تانيه ومن ضمنها مكان ال data في ال page cache وبكده نكون خلصنا من ال page writeback system
في حاجه مهمه لازم ننوه بيها : طالما محصلش اي error او كراش في النظام , النظامين الي اتكلمنا عنهم هيتشغلوا تمام , انما لو حصل كراش في النظام او قطع مثلا للتيار الكهربي ال buffers الخاصه بال write هيتم فقدها , والبيانات مش هتوصل ابدا لل disk الا لو عملتلها write من اول وجديد , ولذلك بيستخدم شيئ يسمي بال synchronized io
بيطلب "لاحظ بيطلب " من الكيرنل انه يكتب ال buffers بتاعته لل disk
man 2 sync
man 2 fsync
ودلوقتي نلخص معلوماتنا :
ال page cache بيتم تسجيل فيه ال recent used data سواء كانت read/write data
بيتم استخدامه للحصول علي performence احسن في الكتابه او القرائه
الكيرنيل بيقوم باخذ نسخه من البيانات التي تم قرائتها ويسجلها في ال page cache مع read ahead buffer
الكيرنيل بيقوم باخذ نسخه من ال بيانات المكتوبه ويسجلها في buffers لحين كتابتها
ال buffers بيتم كتابتها عن طريق ال kernel threads المسماه pdflush threads
يمكنك عمل flush لل data ديت اذا كان وصولها لل disk امر ولابد منه عن طريق استخدام ال synchronized i/o
وبكده نكون انتهينا من موضوعنا
بالنسبة للنظام التالت فهو ال VFS : Virtual file system
بيقدم نوع معين من التجريد متفرقش معاه نوع النظام , هو بيقدم نفس ال system calls لنفس ال file systems وال system calls مسؤولة عن استدعاء الدوال الصحيحه للقرائه او الكتابه
ده تلخيص ليه
النهايه
هقوم بعمل امثلة لاحقا