Dosyaları genellikle içerik barındıran nesneler olarak düşünürüz. Ancak, günlük hayatta daha çok bağlantılarla ilgileniriz. Aslında, dosyaların altında yatan nesneler inode
adı verilen yapılardır.
Bu makalede, Linux inode’ları üzerine yoğunlaşıyoruz: ne olduklarını, neden ve ne zaman kullandığımızı ele alacağız. Önce depolama konseptiyle başlıyoruz. Ardından, dosya sistemlerinin depolama aygıtlarına nasıl uygulandığını ve temel işleyişlerini tartışıyoruz. Son olarak, inode’lar üzerinden dosya sistemi nesnelerini inceliyoruz ve bazı özel durumları ele alıyoruz.
Bu makaledeki kodları Debian 11 (Bullseye) üzerinde GNU Bash 5.1.4 ile test ettik. Kod POSIX uyumlu olup, bu tür herhangi bir ortamda çalışmalıdır.
2. Depolama
Çoğu cihazda en az bir ana bellek ve bir de ikincil bellek bulunur. Ana belleği genellikle RAM (Rastgele Erişimli Bellek) olarak adlandırırken, ikincil bellek ya da depolama, sabit diskler, SSD’ler gibi aygıtlardan oluşur.
Depolama aygıtlarının türü ne olursa olsun, genellikle bir kontrolcüye sahiptirler. Bu kontrolcü, ilgili belleği cihaza sunan bir arayüz sağlar. Kontrolcüler cihazı aynı boyutta bloklar olarak sunar.
İkincil belleğin en küçük blok boyutu genellikle 512 baytlık sektörlerdir. Bu bilgi ilerleyen kısımlarda önemli olacaktır.
Depolama aygıtlarını daha verimli kullanmak için işletim sistemi (OS), kontrolcü ile iletişim kurabilen sürücülere sahiptir. Ancak, bu sürücüler belleğin oldukça ham bir yapısını sunar ve bu yapı başka bir soyutlama ile daha kullanıcı dostu hale getirilir.
3. Dosya Sistemi
Sürücüler, işletim sistemlerinin depolamayı görme ve kontrol etme yoludur; dosya sistemleri ise onları düzenleme biçimidir. Bunu yapmak için, dosya sistemi genellikle bir indeks mekanizması kullanır.
3.1. Meta Veri Düzenlemesi
Bir kitabın bölümlerinin, sayfa numaraları ve başlıklar gibi önemli özelliklerle listelendiğini düşünün. Bu bilgilerin tümü kitabın dizininde yer alır. Kitabın tüm sayfalarına sahip olmadan, dizin üzerinden kitabın ne kadar uzun olduğunu, bölümlerin sıralamasını ve özelliklerini görebiliriz. Bu yapı, bir dosya sisteminin temel fikrine benzer.
Dosya sistemleri için indeks, meta verileri temsil eder. Dosya sisteminin dizini, kitap sayfalarını nasıl düzenliyorsa, dosya sistemi de depolama alanındaki blokları düzenler.
3.2. Örnekler
Çoğu dosya sistemi, bloklara işaret eden bir tür destekleyici organizasyona sahiptir:
- FAT (File Allocation Table) kendi adıyla aynı olan bir Dosya Ayırma Tablosuna sahiptir.
- NTFS (New Technology File System) daha gelişmiş bir Ana Dosya Tablosu (MFT) kullanır.
- Linux’te ise ext ailesi dosya sistemleri (ext2, ext3 ve ext4) gibi bazı yerel dosya sistemleri yaygın olarak kullanılır. Bu tür sistemler, meta verilerinin anahtarı olan bir konsepti paylaşır:
inode
.
4. Inode
Inode
terimi “index node” (indeks düğümü) kelimelerinden türemiştir. Dosya sistem organizasyonlarının kitap dizinlerine benzetildiğini düşünürsek, inode’ların bu fikre nasıl uyduğunu görebiliriz.
Her inode, işletim sistemi tarafından atanmış benzersiz bir tam sayıya sahiptir ve bu sayede dosya sistemindeki nesneler anahtarlanır. Bir dosyanın inode bilgilerini görüntülemek için stat
komutunu kullanabiliriz:
$ stat file.ext
Bu çıktıda dosya adı, boyutu, inode numarası ve erişim hakları gibi bilgiler yer alır. Bu sayede, dosyanın inode’unda depolanan meta verilere hızlı bir erişim sağlanır.
5. Dosya Sistemi Nesneleri
Şimdiye kadar dosya sisteminin meta verilerinden bahsettik. Ancak dosya sistemlerinin var olma amacı, asıl verileri düzenlemektir. Kullanıcı olarak bizim görebildiğimiz şeyler, dosya sistemi nesneleridir.
Linux dosya sistemlerinde “dosya” terimi, inode ile ilişkilendirilmiş herhangi bir nesneyi ifade eder. Farklı türlerde olabilirler:
- Normal Dosya: Veri içeren dosyalardır.
- Dizin: Diğer nesneleri, hatta başka dizinleri de saklayabilir.
- Özel Blok: Cihazlara özel veri saklama yapısı.
- Özel Karakter: Tek tek karakterlerle iletişim kurar.
- Bağlantılar: Başka bir dosyaya kısayol sağlar.
5.1. Normal Dosya
Normal dosyalar, genellikle “dosya” dediğimiz veri koleksiyonlarıdır. debugfs
ile bir dosyanın içeriğinin nasıl dağıldığını görebiliriz:
$ debugfs /dev/sda
5.2. Dizin
Dizinler, dosya sistemlerinde nesneleri barındıran yapılardır. Kullanıcılar bu yapıyı bir ağaç yapısı gibi görürler.
6. Inode Dosya Sistemi Özel Durumları
Inode tabanlı bir dosya sistemi kullanırken, bazen bazı özel durumları göz önünde bulundurmak gerekebilir:
6.1. Maksimum Inode Sayısı
Bir dosya sistemi, depolama alanı olmasına rağmen inode’ları tükenebilir. Küçük dosyalar fazla yer kaplamasa bile toplam inode sayısını azaltabilir.
6.2. Yeniden Atama
Bir inode’u sildiğimizde, dosya sistemi onu başka bir dosya için yeniden tahsis edebilir. Bir dosyanın adını silmek, inode’u silmekle aynı şey değildir.
Dosya ve dizinleri tanımlayan veri yapıları olan inodelar, belirli bir sınıra sahip olup, dosya sistemi oluşturulurken ayarlanır. Bu limitler, disk alanı boş olsa bile yeni dosyalar oluşturamamamıza yol açabilir. Bu yazıda, inodeların ne olduğunu, neden sınırlı olduklarını ve inode sorunlarıyla nasıl başa çıkabileceğimizi inceleyeceğiz.
Inodeların Sınırlı Olmasının Sebebi
Bir inode, dosyanın sistem tarafından kullanılabilmesi için gerekli olan öznitelikler ve disk blok konumları gibi kritik bilgileri içerir. Linux tabanlı sistemlerde varsayılan olan ext dosya sistemleri gibi bazı dosya sistemlerinde inodelar sabit boyutlu bir tabloda saklanır. Bu tablonun boyutu, disk bölümü (partition) oluşturulurken belirlenir ve daha sonra değiştirilemez.
macOS gibi bazı sistemlerde kullanılan APFS gibi diğer dosya sistemleri ise sabit boyutlu tablolar yerine daha esnek veri yapıları (örneğin B-ağaçları) kullanır. Bu sayede inode sayısı daha esnek hale gelir. Yine de inode sayısı belirli bir sınırla sınırlıdır, ancak bu sınıra ulaşmak oldukça zordur.
Inode Limitini Belirlemek
Inode limiti, disk bölümü oluşturulurken belirlenir. Çoğu durumda varsayılan ayarlar yeterli olsa da, çok sayıda küçük dosya saklayacaksak inode ayarlarını manuel olarak yapabiliriz. Örneğin, sistemimizdeki ortalama dosya boyutunun yalnızca 1 kB olacağını düşünüyorsak, her bin bayt için bir inode oluşturmak üzere şu komutu kullanabiliriz:
$ sudo mkfs.ext4 -i 1000 /dev/sdev
Alternatif olarak, inodelar için aynı sınırlamaları olmayan Btrfs gibi başka bir dosya sistemi de tercih edebiliriz.
Inodeları Kontrol Etme ve Boşaltma
Kullanılabilir inodeları görmek için df
komutunu kullanabiliriz:
$ df -i
Filesystem 512-blocks Used Available Capacity iused ifree %iused Mounted on
/dev/disk1s5s1 489620264 46865488 34089872 58% 568975 2447532345 0% /
/dev/disk2s1 1953456384 727555584 1225900800 38% 2842014 4788675 37% /Volumes/T7
Buradaki “iused” sütunu kullanılan inodeların sayısını, “ifree” sütunu boşta olan inodeların sayısını ve “%iused” sütunu ise kullanılan inodeların yüzdesini gösterir.
Ne yazık ki inodeları boşaltmanın tek yolu gereksiz dosyaları silmektir. Ancak hangi dosyaların inodeları tükettiğini bulmak bazen zor olabilir. Bunu çözmenin bir yolu, dizinleri içerdikleri dosya sayısına göre sıralamaktır. Bu sayede sorunlu dizinleri kolayca bulabiliriz.
Aşağıdaki komut, belirli bir dizindeki dosyaları sayarak, hangi dizinlerin daha fazla inode kullandığını tespit etmemize yardımcı olur:
$ sudo find . -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -n
Çıktıda “Projects” gibi bazı dizinlerin çok sayıda dosya içerdiğini görebiliriz. Bu durumda daha fazla inceleme yapabilir veya bu dizini başka bir sürücüye taşımak gibi önlemler alabiliriz.
Sonuç olarak, inode’lar dosya sistemlerinin yapı taşlarıdır ve veri yönetiminde kritik bir rol oynamaktadır. Linux sistemlerinde, inode sınırlarının anlaşılması ve yönetilmesi, sistem performansını ve dosya organizasyonunu iyileştirmek için oldukça önemlidir. Depolama aygıtları ve dosya sistemleri arasındaki etkileşimi anlamak, daha verimli bir depolama çözümü sağlamaya yardımcı olur. İnode kullanımını izlemek ve düzenli olarak gereksiz dosyaları temizlemek, sistemin sağlıklı çalışmasını sağlarken, veri erişimini hızlandırır. Unutmayın ki, inode’ları etkili bir şekilde yönetmek, sistem kaynaklarınızı en iyi şekilde kullanmanın anahtarıdır.