لماذا يقول df إن القرص ممتلئ وdu لا يجد المساحة؟
إذا كان df يعرض القرص ممتلئاً بينما تعجز du عن العثور على المساحة، تعرّف إلى الملف المحذوف الذي تبقيه عملية مفتوحاً وأسباب أخرى للمشكلة.
لماذا يعرض df أن القرص ممتلئ بينما يعطي du نتيجة مختلفة
يعرض df القرص على أنه ممتلئ، بينما لا يستطيع du العثور على المساحة لأن إحدى العمليات ما زالت تحتفظ بملف حُذف. يؤدي حذف الملف إلى إزالة اسمه من الدليل. ولا تُحرَّر كتل البيانات إلا بعد إغلاق آخر واصف ملف مفتوح يشير إلى ذلك الـinode. يتتبع du الأسماء، لذلك لا يحتسب شيئاً. أما df فيسأل نظام الملفات عن عدد الكتل المخصّصة، ولذلك يظل يحتسب الملف الذي لم يعد له اسم.
يعيد هذا الدليل إنتاج الحالة على Ubuntu VPS عادي باستخدام أدوات مثبتة مسبقاً، ويحدد العملية التي تحتفظ بالملف عبر /proc، ثم يحرر المساحة من دون إعادة تشغيل النظام. وتوجد أسباب أخرى للعرض نفسه، منها امتلاء جدول الـinode من دون وجود إدخالات حرة، ووجود ملفات مخفية أسفل نقطة mount، ووجود كتل محجوزة لحساب root.
نفّذ كل أمر واقرأ ناتجك بنفسك. تعتمد القيم على القرص لديك، لذلك قارن النتيجة قبل التنفيذ وبعده على جهازك، بدلاً من مقارنتها برقم مطبوع في دليل.
ما الذي يحسبه df وما الذي يحسبه du
df (المساحة الحرة على القرص) يستعلم من كل نظام ملفات مركّب عن حساباته الخاصة: عدد الكتل الموجودة، وعدد الكتل المخصّصة، وعدد الكتل الحرة. لا يفتح أي دليل. وتشمل النتيجة كل كتلة مخصّصة، بما في ذلك الكتل التابعة لملف لا يشير إليه أي إدخال في دليل.
du (استخدام القرص) يعمل بالعكس. يبدأ من المسار الذي تحدده، ويقرأ الأدلة، ويحصل على معلومات كل إدخال يجده، ثم يجمع الكتل. لا يمكنه رؤية ملف بلا اسم. وينطبق ذلك أيضاً على أي دليل لا يُسمح له بقراءته، ولذلك يحصل المستخدم العادي على إجمالي أصغر من الإجمالي الذي يحصل عليه root. شغّل du باستخدام sudo قبل أن تستنتج أي شيء من المقارنة.
يهمّ خياران في كل مرة تقارن فيها بين الأداتين.
-xيُبقيduضمن نظام ملفات واحد. من دونه، ينتقلdu /إلى كل نظام ملفات مركّب أسفل/، وينتج إجمالياً لم يكنdf /يقيسه أصلاً.-sيطبع سطر ملخص واحداً لكل وسيط بدلاً من سطر واحد لكل دليل.
وبذلك تحصل على الأمرين اللذين تشغّلهما جنباً إلى جنب على نظام الملفات الذي يهمك.
df -h /
sudo du -xhs / 2>/dev/nullيعرض df النتيجة فوراً. أما du فيستغرق دقائق على نظام ملفات كبير، لأنه يحصل على معلومات كل ملف أثناء مروره. عندما يختلف الإجماليان كثيراً، وكان du قد شُغِّل بصلاحيات root مع -x، فهذا يعني أن المساحة المفقودة مخصّصة لشيء لا اسم له.
أعِد إنتاج عدم التطابق عمداً
نفّذ ذلك على VPS اختباري. كل ما يلي يستخدم bash وcoreutils، لذلك لن يتم تثبيت أي شيء.
سجّل الحالة الأولية لنظام الملفات الذي يحتوي على /var/tmp.
cd /var/tmp
df -h .
df --output=used -B1 .يطبع الأمر الثاني عدد البايتات المستخدمة من دون تقريب، ما يجعل التحقق في النهاية دقيقاً.
أنشئ الآن ملفاً. يأتي حجمه من المساحة الحرة التي يبلّغ عنها الجهاز نفسه، لذلك يناسب العرض أي قرص لديك.
free=$(df --output=avail -B1 . | tail -n 1)
fallocate -l $((free / 10)) ghost.bin
ls -l ghost.bin
df -h .$(...) هو استبدال الأوامر: تنفّذ الصدفة الأمر الموجود بداخله، ويصبح الناتج قيمة free. إذا كانت هذه الصياغة جديدة عليك، يشرح استبدال الأوامر في bash ذلك بالتفصيل. يحجز fallocate الكتل الفعلية من دون الكتابة إليها، ولذلك ينتهي فوراً. إذا كان نظام الملفات لا يدعم ذلك، يفشل الأمر، ويؤدي head -c $((free / 10)) /dev/zero > ghost.bin المهمة نفسها بكتابة البايتات.
قارن df -h . هذا بالناتج الذي سجّلته. ازداد العمود المستخدم، وانخفض العمود المتاح.
أبقِ الملف مفتوحاً من عملية أخرى، ثم احذفه.
sleep infinity < ghost.bin &
holder=$!
rm ghost.bin
ls -l ghost.bin
df -h .
sudo du -xhs . 2>/dev/nullإعادة التوجيه هي جوهر العملية. يبدأ sleep infinity < ghost.bin & عملية في الخلفية يكون إدخالها القياسي ذلك الملف، لذلك تفتح الصدفة الملف وتمرر واصف الملف إلى sleep، الذي يبقيه مفتوحاً. يحتوي $! على معرّف العملية لمهمة الخلفية هذه. ثم يزيل rm الاسم، بينما لا يزال واصف الملف مفتوحاً.
اقرأ الناتج. لا يستطيع ls العثور على الملف لأن الاسم اختفى. عاد du إلى قيمة قريبة من قيمته الأولية لأنه يتتبع الأسماء. لم يتغير df لأن الكتل لا تزال محجوزة. أصبح نظام الملفات وشجرة الأدلة غير متطابقين، والفجوة بينهما هي الملف الذي حذفته للتو.
البحث عن العملية التي تحتفظ بالملف المحذوف
يظهر كل واصف ملف مفتوح ضمن /proc/<pid>/fd/ كرابط رمزي إلى الملف الذي يشير إليه. عند إلغاء ربط الملف، تضع النواة علامة الحذف على هدف ذلك الرابط. لذلك، يعني العثور على العملية المالكة البحث عن رابط يحمل هدفه تلك العلامة.
sudo find /proc/[0-9]*/fd -lname '*(deleted)' -printf '%p -> %l\n' 2>/dev/nullيطابق -lname هدف الرابط الرمزي بدلاً من اسمه، ويطبع %p مسار الواصف، بينما يطبع %l ما يشير إليه. معرّف العملية هو العنصر الثاني في المسار الذي يطبعه. شغّله باستخدام sudo، وإلا فلن تتمكن من قراءة /proc/<pid>/fd إلا للعمليات الخاصة بك. يؤدي توجيه stderr إلى إسقاط الرسائل الناتجة عن العمليات التي تنتهي أثناء تجوال find.
يحتفظ خادم مشغول بعدة ملفات محذوفة في أي لحظة، ومعظمها صغير وغير ضار. رتّبها حسب الحجم حتى تبقى الملفات المهمة فقط في أعلى القائمة.
sudo bash -c 'for fd in /proc/[0-9]*/fd/*; do
target=$(readlink "$fd" 2>/dev/null) || continue
case "$target" in
*"(deleted)") echo "$(stat -Lc %s "$fd" 2>/dev/null) $fd $target" ;;
esac
done' | sort -rn | headيتبع stat -L الرابط إلى inode نفسه، لذلك يعرض %s حجم الملف الذي لم يعد له اسم. يؤدي الترتيب وفق هذا الرقم إلى وضع أكبر ملف أولاً.
حدّد بعد ذلك العملية التي تقف وراء الواصف الفائز. يحتوي المسار الموجود في أعلى القائمة على الرقمين اللذين تحتاج إليهما، لذلك ضعهما أولاً في متغيرين، واستبدل PID وN بالقيم التي عرضتها قائمتك.
pid=PID
n=N
ps -o pid,user,etime,args -p "$pid"
sudo stat -L "/proc/$pid/fd/$n"يسمّي ps البرنامج ويعرض مدة تشغيله. يطبع stat -L حجم inode المحذوف وعدد الكتل المخصّصة له. يجيب هذان الأمران معاً عن السؤال المهم: ما الخدمة التي تُبقي هذا الملف قيد الاستخدام؟
إذا كان lsof موجوداً على الجهاز، فإن sudo lsof +L1 يسرد الملفات المفتوحة التي انخفض عدد روابطها إلى الصفر، ويعرض أحجامها في جدول واحد. لا يكون هذا البرنامج موجوداً في صورة Ubuntu مصغّرة، وقد يفشل تثبيت حزمة على نظام ملفات لا تتوفر فيه مساحة حرة. لذلك يظل استعراض /proc هو الطريقة التي تعمل دائماً.
حرّر المساحة دون إعادة تشغيل
إعادة التشغيل تحل المشكلة فعلاً، لكنها ليست الخطوة الأولى الصحيحة: فهي توقف الخدمة وتتلف الأدلة. توجد أربعة خيارات أقل تأثيراً، جرّبها بهذا الترتيب.
أولاً، انسخ البيانات إلى مكان آخر إذا كنت لا تزال تحتاج إليها. تؤدي قراءة مسار الواصف إلى قراءة inode الحي.
sudo cp /proc/<pid>/fd/<n> /root/recovered.logهذه هي الحالة الوحيدة التي يسهل فيها استعادة ملف محذوف، ولذلك يبدأ استرداد الملفات المحذوفة باستخدام rm -rf بالسؤال عمّا إذا كانت هناك عملية لا تزال تُبقي الملف مفتوحاً. بعد إغلاق آخر واصف، يزول هذا المسار.
ثانياً، أفرغ الملف عبر الواصف. يؤدي المسار /proc إلى inode نفسه، لذلك يؤدي اقتطاع الملف إلى تحرير الكتل مع استمرار العملية في العمل.
sudo truncate -s 0 "/proc/$pid/fd/$n"
df -h /يعمل هذا بسلاسة عندما تكون العملية الكاتبة قد فتحت الملف في وضع الإلحاق، لأن كل عملية كتابة تذهب عندها إلى نهاية الملف الحالية. أما إذا لم تكن قد فعلت ذلك، فتحتفظ العملية بموضع الكتابة القديم، ولذلك تصل كتابتها التالية إلى موضع بعيد داخل الملف وتعيد إنشاءه مع فجوة في بدايته. لا تُخصَّص الفجوة، لذلك تبقى الكتل حرة، ويحتفظ df بالمساحة التي حررها للتو. الذي يعود هو الحجم فقط: شغّل sudo stat -L "/proc/$pid/fd/$n" مرة أخرى بعد أن تكتب العملية، وسيعرض الحجم القديم إلى جانب عدد كتل لا يتطابق معه. أعد تشغيل العملية عندما تريد أن يبدأ الحجم من الصفر أيضاً.
ثالثاً، اطلب من الخدمة إعادة فتح سجلاتها. الخدمة الخفية التي حُذف ملف سجلها أثناء استمرارها في استخدامه هي الشكل العملي الشائع لهذه المشكلة. تعيد خدمات خفية كثيرة فتح ملفات السجل عند استقبال إشارة: يستخدم nginx الإشارة SIGUSR1، ويستخدم rsyslog الإشارة SIGHUP. راجع توثيق الخدمة الخفية التي تتعامل معها بدلاً من التخمين، لأن إرسال الإشارة الخاطئة إلى الخدمة الخاطئة يوقفها.
sudo systemctl kill -s USR1 nginxيرسل ذلك الإشارة إلى العملية التي يسجلها systemd بوصفها العملية الرئيسية للوحدة. لذلك، إذا أعلنت الوحدة قيمة Type= الخاطئة مقارنة بطريقة بدء الخدمة الخفية فعلياً، فقد تُرسل إشارتك إلى عملية لم تكن تملك الملف المحذوف، وتبقى المساحة في مكانها.
رابعاً، أعد تشغيل الوحدة. يؤدي sudo systemctl restart <unit> إلى إغلاق كل واصف احتفظت به العملية القديمة، فتعود الكتل بالتأكيد. في العرض السابق، كان المالك هو sleep الذي شغّلته بنفسك، ولذلك يكفي إنهاؤه.
kill $holder
df -h .
df --output=used -B1 .
sudo find /proc/[0-9]*/fd -lname '*(deleted)' -printf '%p -> %l\n' 2>/dev/nullقارن عدد البايتات المستخدمة بالقيمة التي سجلتها قبل إنشاء الملف. سيتطابقان مرة أخرى، ولن يعرض find واصفك بعد الآن. يظل التحقق باستخدام الأمر نفسه الذي اكتشف المشكلة عادةً مفيداً.
تسهّل مراقبة تغيّر هذه القيمة بدلاً من تشغيل df يدوياً مراراً. يعيد watch تشغيل أمر على فاصل زمني ثابت ويطبع الناتج في الموضع نفسه، ولذلك يعرض watch df -h / تغيّر عمود المساحة المستخدمة أثناء عودة المساحة.
عندما تتطابق الإجماليات مع بقاء القرص ممتلئاً
إذا تطابق df مع du -x الخاص بـroot، فلا يوجد ملف محذوف في الحالة. تكون الأسباب المتبقية مختلفة، ولكل سبب منها فحصه الخاص.
نفاد inodes لا يعني نفاد blocks
يحتوي inode على البيانات الوصفية لملف واحد. ينشئ ext4 عدداً ثابتاً من inodes عند إنشاء نظام الملفات، لذلك قد ينفد عدد inodes في نظام الملفات بينما لا تزال لديه blocks متاحة. عندها يفشل إنشاء ملفات جديدة، رغم أن df -h يعرض مساحة متاحة.
df -h /
df -i /يحسب الأمر الأول blocks، ويحسب الأمر الثاني inodes. قارن عمود الاستخدام في كل منهما. إذا كان استخدام blocks منخفضاً، بينما بلغ استخدام inodes الحد الأقصى، فالمشكلة هي وجود عدد كبير جداً من الملفات الصغيرة جداً.
يرفض df الخيارين -i و--output في الاستدعاء نفسه. لذلك، عندما تريد قراءة الأعداد الخام أو تمريرها إلى أمر آخر، حدّد حقول inodes بالاسم واترك -i معطلاً.
df --output=itotal,iused,iavail,ipcent /تعرض هذه الأعمدة بيانات المحاسبة نفسها التي يطبعها df -i، ولكن بصيغة يمكنك تحليلها.
اعثر على الملفات من خلال عدّ الإدخالات بدلاً من عدّ البايتات.
sudo du --inodes -x -d 1 / 2>/dev/null | sort -rn | headكرّر الأمر نفسه على مستوى أدنى واحد داخل الدليل الذي ظهر أولاً، حتى تصل إلى الشجرة التي تنشئ الملفات. إذا كان du لا يدعم --inodes، فإن sudo find /var -xdev -type f | wc -l يحسب الشجرة الفرعية بالطريقة الأبطأ.
الحل هو حذف هذه الملفات أو نقلها. لا يمكنك إضافة inodes إلى نظام ملفات ext4 موجود، لأن العدد يُثبَّت عند وقت mkfs. لذلك، رفع العدد يتطلب إعادة إنشاء نظام الملفات واستعادته من نسخة احتياطية. يخصّص XFS inodes حسب الحاجة، لذلك لا يواجه حداً ثابتاً بالطريقة نفسها. يصل الجهاز الذي يشغّل الحاويات إلى كلا الحدين أسرع من معظم الأجهزة، لأن طبقات الصور تحتوي على العديد من الملفات الصغيرة. على ذلك الجهاز، يُعد تقليص استخدام Docker للقرص على VPS الحل المحدد، ويستعيد مساحة أكبر بكثير مما يستعيده فحص عام لنظام الملفات.
مساحة مخفية أسفل نقطة تحميل
يمكن أن يحتوي دليل على ملفات قبل تحميل أي شيء عليه. حمّل نظام ملفات فوق ذلك الدليل، وستبقى الملفات الموجودة تحته في مكانها تماماً: ما زالت مخصّصة، وما زال df يحسبها، ولم يعد بالإمكان الوصول إليها بالاسم. لا يستطيع du رؤيتها لأن نقطة التحميل تحجبها.
اعرض ذلك باستخدام tmpfs، الذي لا يحتاج إلى مساحة إضافية على القرص. يتطلب هذا الجزء جهازاً يُسمح لك بإجراء عمليات التحميل عليه، ولذلك يمكن تنفيذه على KVM VPS.
sudo mkdir -p /srv/covered
sudo cp /etc/services /srv/covered/
ls /srv/covered
sudo mount -t tmpfs tmpfs /srv/covered
ls /srv/covered
sudo umount /srv/covered
ls /srv/coveredيعرض ls الأوسط دليلاً فارغاً. لم تنتقل النسخة إلى أي مكان: ما زالت على نظام الملفات الجذري، وستظهر مجدداً فور إلغاء التحميل. تخيّل الآن خدمة كتبت سجلاتها إلى ذلك المسار لمدة شهر قبل أن يحمّل أحدهم volume فوقه.
للعثور على الملفات الفعلية على خادم قيد التشغيل، حمّل نظام الملفات الجذري مرة ثانية في مكان آخر. يعرض bind mount نظام ملفات واحداً من دون أن يعرض أنظمة الملفات المحمّلة داخله.
sudo mkdir -p /mnt/rootcheck
sudo mount --bind / /mnt/rootcheck
sudo du -xhs /mnt/rootcheck/* 2>/dev/null | sort -h
sudo umount /mnt/rootcheckأي شيء يظهر في تلك القائمة ولا يظهر تحت المسار المعتاد يكون مدفوناً أسفل نقطة تحميل. ألغِ تحميل bind mount عند الانتهاء، وإلا فسيحسب du لاحقاً، من دون -x، الملفات نفسها مرتين.
الكتل المحجوزة لحساب root
يحجز ext4 نسبة من كتله لحساب root، حتى لا يمنع امتلاء القرص root من تسجيل الدخول وإصلاح الجهاز. تصل العملية التي تعمل بحساب مستخدم عادي إلى هذا الحد أولاً، بينما يظل df يعرض مساحة صغيرة متبقية. اقرأ الإعداد من نظام الملفات لديك بدلاً من افتراض القيمة الافتراضية.
dev=$(df --output=source / | tail -n 1)
sudo tune2fs -l "$dev" | grep -i 'block count'يعرض ذلك العدد الإجمالي للكتل وعدد الكتل المحجوزة بالوحدات نفسها، لذلك تكون النسبة بينهما مباشرة. يعرض df العمود المتاح باعتباره المساحة التي لا يزال بإمكان المستخدم العادي استخدامها، ولهذا يكون مجموع المساحتين المستخدمة والمتاحة أصغر من الحجم. والفرق هو المساحة المحجوزة.
غيّر الإعداد باستخدام sudo tune2fs -m <percent> "$dev". يُطبَّق التغيير فوراً ولا يحتاج إلى إعادة تركيب نظام الملفات. يكون خفض المساحة المحجوزة مناسباً في نظام ملفات منفصل مخصص للبيانات. أما في نظام الملفات الجذر، فاترك مساحة كافية ليتمكن root من الكتابة، لأن إصلاح نظام ملفات جذر لا يحتوي على أي مساحة حرة يصبح أصعب بكثير. وهذه المساحة هي أيضاً ما يحول دون منعك من الدخول: فقد تُكتب إضافة مفتاح إلى authorized_keys بشكل مبتور أو لا تُكتب إطلاقاً إذا لم يتبقَّ أي مكان في نظام الملفات، وعندها تكون نتيجة تسجيل الدخول التالية مرفوض الإذن (publickey) لسبب لا علاقة له بالمفتاح نفسه. يعمل tune2fs مع ext2 وext3 وext4. ولا يملك XFS إعداداً مماثلاً.
متى يضللك du عند استخدامه وحده
تؤدي أربع ممارسات في du إلى إجماليات تبدو غير صحيحة.
- الروابط الصلبة: يحسب
duinode مرة واحدة، حتى عندما تشير عدة أسماء إليه. لذلك يعرض الدليل المليء بالروابط الصلبة حجماً أقل من مجموع ملفاته. - الملفات المتناثرة: يعرض
duالكتل المخصّصة فعلياً، بينما يعرضls -lالحجم الظاهري. أضف--apparent-sizeلعرض القيمة الأخرى. - الصلاحيات: عند تشغيل الأمر كمستخدم عادي، يتجاوز
duما لا يستطيع قراءته، فيعرض قيمة أقل من الفعلية. الأخطاء التي يطبعها هي الأخطاء التي يعيد الأشخاص توجيهها إلى/dev/nullثم يتوقفون عن قراءتها. - حدود نظام الملفات: من دون
-x، يحسبdu /كل نظام ملفات مثبت تحت/. لذلك قد يتجاوز إجماليه القيمة التي يعرضهاdf /.
لدى df ممارسة أخرى تستحق المعرفة. فهو يعرض كل نظام ملفات على حدة. لذلك شغّله على المسار المحدد الذي تستهدفه عملية الكتابة الفاشلة. يمتلئ /boot منفصل وفق جدوله الخاص مع تراكم حزم kernel. كما أن إزالة kernels القديمة من Ubuntu تختلف عن تحرير مساحة على /.
ترتيب عملي للتعامل مع حادثة فعلية
- شغّل
df -h <path>وdf -i <path>على نظام الملفات الذي كانت عملية الكتابة الفاشلة تستهدفه، وليس على/تلقائياً. - شغّل
sudo du -xh -d 1 <mountpoint> 2>/dev/null | sort -h، ثم انتقل إلى الدليل الأكبر حجماً. - إذا تعذّر على
duتفسير المساحة التي يعرضdfأنها مستخدمة، فابحث في/procعن ملفات محذوفة ما زالت مفتوحة. - إذا تطابقت النتيجتان، اربط نظام الملفات باستخدام bind mount في موضع آخر، وابحث عن ملفات موجودة أسفل نقطة mount.
- إذا كان استخدام inodes هو الذي بلغ الحد، فأحصِ الملفات بدلاً من احتساب عدد البايتات.
كل خطوة هنا تتضمن أمراً يمكنك قراءة ناتجه. هذا هو الفرق بين إصلاح المشكلة والتخمين بشأنها.
FAQ
لماذا يعرض df القرص ممتلئاً بينما يعثر du على مساحة أقل بكثير؟
السبب المعتاد هو ملف حُذف بينما كانت عملية ما لا تزال تُبقيه مفتوحاً. يؤدي حذف الملف إلى إزالة إدخاله من الدليل، لذلك لا يملك du اسماً يتتبعه ويتوقف عن احتسابه. تبقى inode وكتل الملف مخصّصة حتى يُغلق آخر واصف، بينما يحتسب df الكتل المخصّصة. ابحث في /proc/<pid>/fd عن روابط رمزية يكون هدفها معلّماً كمحذوف، وستعرف الملف والعملية التي تُبقيه مفتوحاً. قبل الاعتماد على المقارنة، تأكد من تشغيل du بصلاحيات root ومع -x، لأن المستخدم العادي يتجاوز بصمت الأدلة التي لا يستطيع قراءتها.
كيف أعثر على ملف محذوف لا يزال مفتوحاً من دون lsof؟
استخدم السجل الخاص بالنواة للواصفات المفتوحة. يسرد sudo find /proc/[0-9]*/fd -lname '*(deleted)' -printf '%p -> %l\n' 2>/dev/null كل واصف يشير إلى ملف بلا اسم، ويظهر معرّف العملية داخل المسار الذي يطبعه. يعرض sudo stat -Lc %s حجم الملف عند استخدامه على أحد مسارات الواصفات تلك، ولذلك يمكنك ترتيب النتائج واختيار الملف المعني. لا تحتاج هذه الطريقة إلى أي حزمة، وهذا مهم لأن تثبيت حزمة على نظام ملفات لا يملك مساحة خالية قد يفشل.
هل يمكنني تحرير المساحة من دون إنهاء العملية؟
أحياناً. يصل sudo truncate -s 0 /proc/<pid>/fd/<n> إلى inode نفسها عبر الواصف ويحرر كتلها بينما تستمر العملية في العمل. يكون ذلك أنسب عندما فتحت العملية الملف في وضع الإلحاق، لأن عمليات الكتابة تذهب دائماً إلى النهاية الحالية. أما إذا لم تفعل ذلك، فيبقى إزاحة الكتابة في موضعها، وتعيد الكتابة التالية إنشاء الملف مع فجوة في بدايته، فيعود الحجم المبلّغ عنه إلى الارتفاع بينما تبقى الكتل الواقعة تحت الفجوة خالية. إعادة تشغيل الوحدة، أو إرسال إشارة إليها لإعادة فتح سجلاتها باستخدام الإشارة التي تحددها وثائقها، هو الحل الذي لا يترك ملفاً sparse.
يعرض df مساحة خالية، لكن عمليات الكتابة لا تزال تفشل. ما الأسباب الأخرى المحتملة؟
تحقق من inodes باستخدام df -i على المسار نفسه، لأن نظام الملفات الذي يملك كتل خالية ولا يملك inodes خالية يرفض إنشاء ملفات جديدة. تحقق مما إذا كانت عملية الكتابة تعمل كمستخدم غير root على نظام ملفات ext4 لم يتبقَّ فيه سوى الكتل المحجوزة؛ وسيعرض sudo tune2fs -l ذلك على الجهاز. تأكد من أنك تقرأ نظام الملفات الذي تستهدفه عملية الكتابة فعلياً، لأن /boot أو /var منفصلاً قد يمتلئ بصورة مستقلة عن /.
لماذا يعرض du إجماليًا أكبر من df؟
يعبر du، من دون -x، إلى كل نظام ملفات مركّب تحت المسار الذي قدمته له، ولذلك يجمع عدة أنظمة ملفات بينما يصف df نظام ملفات واحداً. تجعل bind mounts الأمر أسوأ، لأن الملفات نفسها تُحتسب مرة تحت كل مسار تظهر فيه. أضف -x لإبقاء du ضمن نظام ملفات واحد، ومرّر إلى df المسار نفسه، حتى يصف الأمران الشيء نفسه.