
गंभीर extent tree भ्रष्टाचार के लिए कस्टम BTRFS मरम्मत उपकरण जहाँ btrfs check --repair विफल होता है (segfault, loop, या deadlock)
12TB मल्टी-डिवाइस BTRFS पूल की रिकवरी के दौरान लिखे गए कस्टम टूल्स, जिसमें गंभीर एक्सटेंट ट्री भ्रष्टाचार था, जिसे मूल कमांड (btrfs check --repair, --init-extent-tree, आदि) मरम्मत नहीं कर सके।
इस रिकवरी का संरचित केस स्टडी, मूल कारण वर्गीकरण और अपस्ट्रीम btrfs-progs में सुधारों के लिए रचनात्मक प्रस्ताव देखने के लिए INCIDENT-ANALYSIS.md देखें।
इन उपकरणों का उपयोग केवल तब करें जब btrfs check --repair सेगफॉल्ट करता है, अनंत लूप में चला जाता है, या फाइलसिस्टम को पहले से भी बदतर स्थिति में छोड़ देता है।
प्रलेखित मामले जहां ये मदद करते हैं:
btrfs check --repair [3/8] checking extents पर सेगफॉल्ट करता है (Issue #525)btrfs check --init-extent-tree डेडलॉक करता हैbtrfs check --repair समान मरम्मत दोहराते हुए अनंत लूप में चला जाता हैrescue=all,ro के साथ माउंट होता है, RW माउंट करने में विफल रहता हैये उपकरण हल्के भ्रष्टाचार के लिए नहीं हैं। सामान्य क्षति के लिए पहले btrfs check --repair का प्रयास करें।
--write वाले किसी भी उपकरण को चलाने से पहले मेटाडेटा का बैकअप लें:
for DEV in sda1 sdb1 sdc1; do
sudo dd if=/dev/$DEV of=sb_${DEV}.bin bs=4096 count=1 skip=16
done
--write ऑप्ट-इन है)उपकरण आंतरिक btrfs-progs API का उपयोग करते हैं और btrfs-progs स्रोत ट्री के अंदर बनाए जाने चाहिए:
# 1. btrfs-progs क्लोन करें
git clone --depth 1 --branch v6.19.1 https://github.com/kdave/btrfs-progs.git
cd btrfs-progs
# 2. EEXIST पैच लागू करें (बैच बैकरेफ़ इंजेक्शन के लिए आवश्यक)
patch -p1 < path/to/btrfs_fixes/patches/alloc_reserved_tree_block_eexist.patch
# 3. आधार btrfs-progs कॉन्फ़िगर और बनाएं
./autogen.sh
./configure
make -j$(nproc)
# 4. इस रेपो से .c फ़ाइलों को btrfs-progs निर्देशिका में कॉपी करें
cp path/to/btrfs_fixes/programs/*.c .
# 5. प्रत्येक प्रोग्राम के लिए Makefile में जोड़ें:
echo '
PROGNAME: PROGNAME.o $(objects) $(libs_shared)
@echo " [LD] $@"
$(Q)$(CC) -o $@ PROGNAME.o $(objects) $(libs_shared) $(LDFLAGS) $(LIBS)
' >> Makefile
# 6. बिल्ड करें
make PROGNAME
अनुशंसित निष्पादन क्रम:
scan_and_fix_all_backrefs.c (सबसे महत्वपूर्ण)सबसे महत्वपूर्ण उपकरण। फाइलसिस्टम में प्रत्येक ट्री (ROOT, CHUNK, EXTENT, FS, DEV, CSUM, UUID, FREE_SPACE) पर पुनरावर्ती रूप से चलता है और उन मेटाडेटा ब्लॉकों का पता लगाता है जिनमें एक्सटेंट ट्री में METADATA_ITEM बैकरेफ़ गायब है। एकल लेन-देन में सभी गायब बैकरेफ़ इंजेक्ट करता है ताकि "रूट ट्री कमिट के बीच स्थानांतरित होने" की समस्या से बचा जा सके।
उपयोग:
sudo ./scan_and_fix_all_backrefs /dev/sdX # केवल स्कैन
sudo ./scan_and_fix_all_backrefs /dev/sdX --write # स्कैन + इंजेक्ट
fix_owner_refs.cइनलाइन TREE_BLOCK_REF में owner को ठीक करता है जब वह ब्लॉक के वास्तविक btrfs_header_owner() से मेल नहीं खाता। विफल मरम्मत के दौरान ब्लॉकों को पेड़ों के बीच पुनः असाइन किए जाने पर बेमेल होता है।
sudo ./fix_owner_refs /dev/sdX # स्कैन
sudo ./fix_owner_refs /dev/sdX --write # ठीक करें
fix_bad_levels.cगलत स्तर वाले METADATA_ITEM और EXTENT_ITEM प्रविष्टियों को ठीक करता है। भ्रष्ट स्तर (जैसे 50, 55, 237) btrfs check --repair के लूप में प्रवेश करने के बाद छोड़े गए कचरे हैं। ब्लॉक के वास्तविक btrfs_header_level() के विरुद्ध सत्यापित किया जाता है।
sudo ./fix_bad_levels /dev/sdX # स्कैन
sudo ./fix_bad_levels /dev/sdX --write # ठीक करें
fix_duplicate_extents.cडुप्लिकेट METADATA_ITEMs (समान bytenr, कुंजी में अलग-अलग स्तर) को हटाता है। वह रखता है जिसका स्तर btrfs_header_level से मेल खाता है और दूसरे को हटा देता है।
sudo ./fix_duplicate_extents /dev/sdX # स्कैन
sudo ./fix_duplicate_extents /dev/sdX --write # डुप्लिकेट हटाएं
remove_stale_ptrs.cFS_TREE के प्रत्येक स्तर-1 नोड को स्कैन करता है। तीन जांचों का उपयोग करके पुराने चाइल्ड पॉइंटर्स का पता लगाता है: मालिक बेमेल, first_key बेमेल, या एक first_key जिसका प्रकार FS_TREE के लिए अमान्य है (जैसे BLOCK_GROUP_ITEM)। उन्हें btrfs_del_ptr से हटाता है।
sudo ./remove_stale_ptrs /dev/sdX # स्कैन
sudo ./remove_stale_ptrs /dev/sdX --write # हटाएं
fix_uuid_tree.c / fix_csum_tree.cUUID ट्री / CSUM ट्री के लिए क्रमशः एक खाली लीफ बनाता है। तब उपयोगी जब ROOT_ITEM एक ऐसे ब्लॉक की ओर इशारा करता है जिसे किसी अन्य ट्री को पुनः असाइन किया गया हो। कर्नेल RW माउंट पर UUID ट्री को स्वचालित रूप से पुनर्जीवित करता है। खाली CSUM ट्री के साथ, NODATASUM चिह्नित फ़ाइलें सत्यापन में विफल नहीं होती हैं।
sudo ./fix_uuid_tree /dev/sdX
sudo ./fix_csum_tree /dev/sdX
set_nodatasum.cनियमित फ़ाइल inodes पर BTRFS_INODE_NODATASUM फ्लैग सेट करता है। इसका उपयोग करें यदि csum ट्री खाली है लेकिन फ़ाइलों में अभी भी अपेक्षित चेकसम हैं, जिससे पढ़ने में त्रुटियां होती हैं। NODATASUM के साथ, कर्नेल csum लुकअप छोड़ देता है।
sudo ./set_nodatasum /dev/sdX # स्कैन
sudo ./set_nodatasum /dev/sdX --write # लागू करें
fix_fstree_node.cहार्डकोडेड पुराने ब्लॉकों की सूची वाला संस्करण। remove_stale_ptrs को प्राथमिकता दें, जो उन्हें स्वचालित रूप से पहचानता है। इसका उपयोग केवल तभी करें जब आपको किन विशिष्ट ब्लॉकों को हटाना है, इस पर मैन्युअल नियंत्रण की आवश्यकता हो।
add_backrefs.cगायब बैकरेफ़ की हार्डकोडेड सूची वाला प्रारंभिक संस्करण। scan_and_fix_all_backrefs को प्राथमिकता दें, जो उन्हें स्वचालित रूप से पहचानता है।
जब उपरोक्त आधार उपकरण अपर्याप्त थे (200K+ त्रुटियों वाला पूल अनेक पेड़ों में फैली हुई), तो ये अतिरिक्त उपकरण बनाए गए:
scan_fstree_extents.c + scan_extent_tree.cपास 1 और पास 2 स्कैनर जो क्रमशः FS_TREE और एक्सटेंट ट्री पर चलते हैं, प्रत्येक रेफ/एक्सटेंट मैपिंग के साथ TSV फ़ाइलें उत्पन्न करते हैं। rebuild_extent_tree_apply के लिए इनपुट बनाने के लिए उपयोग किया जाता है जब एक्सटेंट ट्री को स्क्रैच से पुनर्निर्मित करने की आवश्यकता होती है।
rebuild_extent_tree_apply.c (भारी लेखक)मुख्य चरण 3 लेखक। रेफ़ की पहले से मुड़ी हुई सूची (scan_fstree_extents + scan_extent_tree अंतर से) लेता है और 3M+ EXTENT_DATA_REFs को एक्सटेंट ट्री में प्रति लेन-देन 5000 के टुकड़ों में इंजेक्ट करता है। DM-SMR री-शिंगल स्टाल से बचने के लिए प्रत्येक 50K आइटम के बाद थ्रॉटल करता है। 3× WD40EFAX SMR डिस्क पर लगभग 34 मिनट में 3,248,617 इंसर्ट पर सफलतापूर्वक सत्यापित।
sudo ./rebuild_extent_tree_apply /dev/sdX1 refs_folded.txt to_insert.txt watermark.txt --dryrun
sudo ./rebuild_extent_tree_apply /dev/sdX1 refs_folded.txt to_insert.txt watermark.txt --write
patch_block_group_used.cBLOCK_GROUP_ITEM.used के लिए सर्जिकल सिंगल-फील्ड पैचर जब फेज 3 लेखक पूर्व-मौजूदा ओवरलैपिंग file_extent_items के कारण किसी विशिष्ट bg को ओवरशूट के साथ छोड़ देता है। btrfs_update_block_group space_info अकाउंटिंग (जो हम यहां नहीं चाहते) से बचने के लिए btrfs_set_block_group_used डायरेक्ट सेटर का उपयोग करता है। flags & BTRFS_BLOCK_GROUP_DATA को पूर्व-सत्यापित करता है।
sudo ./patch_block_group_used /dev/sdX1 <bg_bytenr> <bg_length> <new_used> --write