CSD İŞLETİM SİSTEMİNİN SANAL DOSYA SİSTEMİNE İLİŞKİN TEMEL VERİ YAPILARI

Benzer belgeler
SANAL DOSYA SİSTEMİ. Fatih YILDIRIM

BLM-112 PROGRAMLAMA DİLLERİ II. Ders-3 İşaretçiler (Pointer) (Kısım-2)

HEAP SİSTEMİ. Oğuz Karan

BLM 112- Programlama Dilleri II. Hafta 5 İşaretçiler (Pointers)

Yrd. Doç. Dr. Caner ÖZCAN

Linux işletim sistemlerinde dosya hiyerarşisinde en üstte bulunan dizindir. Diğer bütün dizinler kök dizinin altında bulunur.

Yrd. Doç. Dr. Caner ÖZCAN

Özyineleme (Recursion)

DOSYA ORGANİZASYONU. Çarpışma çözümleme yöntemleri ÖZLEM AYDIN TRAKYA ÜNİVERSİTESİ BİLGİSAYAR MÜHENDİSLİĞİ BÖLÜMÜ

Temel Bilgisayar Programlama Final Sınavı Çalışma Notları

ALGORİTMA VE PROGRAMLAMA II

Temel Linux Eğitimi 1., 2. ve 3. Bölümler

Bilgi ve İletişim Teknolojileri (JFM 102) Ders 7. LINUX OS (Sistem Yapısı) BİLGİ & İLETİŞİM TEKNOLOJİLERİ. LINUX Yapısı

VERİ YAPILARI LİSTELER. Yrd. Doç. Dr. Murat GÖK Bilgisayar Mühendisliği Bölümü YALOVA ÜNİVERSİTESİ

Uzaktan Eğitim Uygulama ve Araştırma Merkezi

ELN1002 BİLGİSAYAR PROGRAMLAMA 2

Master boot record (MBR)

Veri Yapıları Laboratuvarı

Dosyaların Özellikleri (Attribute) Dosya İşlemleri. İki Seviyeli Katalog Sistemleri. Tek Seviyeli Katalog Sistemleri. Hiyerarşik Katalog Sistemleri

Windows Eski Sürümleri Bellek Yapısı

LİNUX. Dosyalar ve dizinler

DİSK DEPOLAMA ALANLARI

Dosya, disk üzerinde depolanmış verilerin bütününe verilen isimdir. İşletim sistemi genel olarak iki çeşit dosya içerir.

Pointer Kavramı. Veri Yapıları

Algoritma Geliştirme ve Veri Yapıları 9 Ağaç Veri Modeli ve Uygulaması. Mustafa Kemal Üniversitesi

BİLGİ İŞLEM DERS 1. Yrd Doç Dr. Ferhat ÖZOK MSGSU FİZİK BÖLÜMÜ MSGSU FİZİK BÖLÜMÜ

Yeni G/Ç (new I/O) Altuğ B. Altıntaş 2003 Java ve Yazılım Tasarımı - Bölüm 10 1

YAPILAR BİRLİKLER SAYMA SABİTLERİ/KÜMELERİ. 3. Hafta

Göstericiler (Pointers)

Bilgilerin Uzun Vadeli Saklanması

C++ Dersi: Nesne Tabanlı Programlama 2. Baskı

Dosya Saklama Ortamları (Sabit Diskler) Kütük Organizasyonu 1

Veri Yapıları. Amaçlar: Temel Veri Yapılarını Tanımlamalı Veri Yapılarını Veri Modeli ve Türlerini Öğreneceksiniz. İçindekiler:

Linux Dosya ve Dizin Yapısı

İşletim Sistemleri. Hazırlayan: M. Ali Akcayol Gazi Üniversitesi Bilgisayar Mühendisliği Bölümü

İşletim Sistemlerine Giriş

BLM-112 PROGRAMLAMA DİLLERİ II. Ders-8 Dosya İşlemleri-1. Yrd. Doç. Dr. Ümit ATİLA

Fiziksel Veritabanı Modelleme

Uzaktan Eğitim Uygulama ve Araştırma Merkezi

Konular. Hafta 5 Veri Tipleri (Devam) BLG339 PROGRAMLAMA DİLLERİ KAVRAMI

BTP 205 İŞLETİM SİSTEMLERİ

Proses. Prosesler 2. İşletim Sistemleri

Temel Veri Yapıları. (Veri Yapıları 1. Bölüm)

William Stallings Computer Organization and Architecture 9 th Edition

ELN1001 BİLGİSAYAR PROGRAMLAMA I

API(Application Programming Interface) Fonksiyonları:

Bölüm 10. Altprogramların gerçeklenmesi ISBN

PROSESLER. Proses. Proses

Yrd. Doç. Dr. Caner ÖZCAN

ALGORİTMA VE PROGRAMLAMA I

ALGORİTMA VE PROGRAMLAMA II

Algoritma Geliştirme ve Veri Yapıları 3 Veri Yapıları. Mustafa Kemal Üniversitesi

HSancak Nesne Tabanlı Programlama I Ders Notları

Algoritma Geliştirme ve Veri Yapıları 7 Liste ve Bağlantılı Liste. Mustafa Kemal Üniversitesi

VERİ YAPILARI VE PROGRAMLAMA

Linux ta komutlar hakkında yardım almak için aşağıdaki komutlar kullanılır : - man - info - whatis - apropos

Aynı tipten çok sayıda değişken topluluğudur. X Y Score1 Score2 (0) (1) (2)...

CSD İŞLETİM SİSTEMİNDE SİSTEM FONKSİYONLARININ ÇAĞIRILMASI

Yrd. Doç. Dr. Caner ÖZCAN

sayi=3 harf=a reelsayi=8.72 Bellek durumu 5. İşaretç iler (pointers)

BLG 312 Bilgisayar İşletim Sistemleri 2006 BLG 312. Bilgilerin Uzun Vadeli Saklanması. Dosya Sistemi Görevleri. Dosya Sistemi Özellikleri

ELN1002 BİLGİSAYAR PROGRAMLAMA 2

Dosyalarda Farklı Yaklaşımlar. Kütük Organizasyonu 1


Linux altında komut satırında...

İşletim Sistemleri (Operating Systems)

Programlama Dilleri. C Dili. Programlama Dilleri-ders08/ 1

CSD-OS İşletim Sistemi Projesi - Fonksiyon Açıklama Standardı

ALGORİTMA VE PROGRAMLAMA I

Malloc () ve Free() fonksiyonları

Pointers (İşaretçiler)

BLM-111 PROGRAMLAMA DİLLERİ I. Ders-12 Fonksiyonlar. Yrd. Doç. Dr. Ümit ATİLA

Sistem Programlama. Kesmeler(Interrupts): Kesme mikro işlemcinin üzerinde çalıştığı koda ara vererek başka bir kodu çalıştırması işlemidir.

Struct VE GÖSTERİCİLER FONKSİYONLARDA STRUCT KULLANIMI Programlama dilleri hafta -

HESAP MAKİNASI YAPIMI

Dr. Fatih AY Tel: fatihay@fatihay.net

Windows'da çalışırken pek çok durumda bir işe başlamadan önce işletim sisteminin o işe ilişkin bilgileri depolayacağı bir alan yaratması gerekir.

Elbistan Meslek Yüksek Okulu GÜZ Yarıyılı Kas Salı, Çarşamba Öğr. Gör. Murat KEÇECİOĞLU

İşletim Sistemi. BTEP205 - İşletim Sistemleri

Bölüm 8: Ana Bellek. Operating System Concepts with Java 8 th Edition

ELN1002 BİLGİSAYAR PROGRAMLAMA 2

İşletim Sistemlerine Giriş

Kütük Yönetimi. Kütük Yönetim Sisteminin İşlevleri. Hacettepe Üniversitesi Kavramsal Kütük Modeli.

İşletim Sistemleri. Dr. Binnur Kurt Omega Eğitim ve Danışmanlık İşletim Sistemleri

İşletim Sistemlerine Giriş

Multicore/Multithread Programlama

Genel Programlama II

DOSYA NEDİR? Verilerin HDD de saklanması. Verilerin HDD de saklanması DOSYA SİSTEMİ NEDİR?

İşletim Sistemlerine Giriş

Algoritma Geliştirme ve Veri Yapıları 2 Veri Modelleri. Mustafa Kemal Üniversitesi

ALGORİTMA VE PROGRAMLAMA II

Kütük Yönetimi. Kütük Yönetim Sisteminin İşlevleri. Hacettepe Üniversitesi Kavramsal Kütük Modeli.

Bilgisayar İşletim Sistemleri BLG 312

YZM VERİ YAPILARI DERS#9: HASH FONKSİYONLARI

Önemli noktalar. Paradigma Nesnelere Giriş Mesajlar / Ara bağlantılar Bilgi Gizleme (Information Hiding ) Sınıflar(Classes) Kalıtım/Inheritance

Mühendislik Fakültesi Elektrik-Elektronik Mühendisliği C Programlama 3. Bölüm Veri Tipleri ve Değişkenler

8. İŞARETCİLER (POINTERS)

BİH 605 Bilgi Teknolojisi Bahar Dönemi 2015

ALGORİTMA VE PROGRAMLAMA II

Jval tipi. Genel veri yapılarını kullanacağımız zaman Jval den faydalanırız.önemli olanlar aşağıda mevcuttur:

Transkript:

CSD İŞLETİM SİSTEMİNİN SANAL DOSYA SİSTEMİNE İLİŞKİN TEMEL VERİ YAPILARI Kaan Aslan 06/01/2004 Özet: Bu makale CSD İşletim Sisteminin sanal dosya sistemi üzerinde çalışacak yeni grup üyelerini desteklemek amacıyla yazılmıştır. Makalede CSD İşletim Sisteminin sanal dosya sistemini oluşturan temel veri yapıları ve fonksiyonlar ele alınmaktadır. Makale içerisinde süper blok işlemleri, aşağı seviyeli disk cache işlemleri, dizin girişi işlemleri ve inode işlemleri gözden geçirilmiştir. Burada ele alınan özet bilgiler makalenin yazıldığı tarihe ilişkindir. Geliştirme aşamasında kaynak kodlar üzerinde sürekli olarak büyük ya da küçük değişikliklerin yapıldığı unutulmamalıdır. 1. GİRİŞ CSD sanal dosya sistemi büyük ölçüde Linux sistemlerinin sanal dosya sistemine benzemektedir. Dosya sistemi grubu çeşitli UNIX türevlerinin sanal dosya mimarilerini incelemiş ve Linux sistemlerine yakın durmayı tercih etmiştir. Gelinen nokta gözönüne alındığında sanal dosya sisteminin tasarım bakımından Linux sistemlerine benzemesi yadırganmamalı ve tedirginlikle karşılanmamalıdır. Bilindiği gibi Linux sistemleri de ilk biçiminden bu yana diğer UNIX sistemlerinden oldukça büyük alıntılar yapmış, belli bir aşamadan sonra bazı özgün yaklaşımlar geliştirebilmiştir. CSD Dosya Sistemi Grubu da geliştirmenin sonraki evrelerinde özgün yenilikler yapma isteğindedir. [V: 1] 2. DOSYA SİSTEMİNE İLİŞKİN TEMEL VERİ YAPILARI CSD dosya sisteminin desteklediği tüm dosya sistemleri FILE_SYSTEM_TYPE yapılarından oluşan bir bağlı listede tutulmaktadır. Bağlı listeye elemanlar sistemin başlatılması sırasında eklenmektedir. CSD dosya sisteminde en temel işlem diğer sistemlerde olduğu gibi mount işlemidir. Mount işlemi sırasında mount edilen dosya sistemine ilişkin bilgiler çeşitli veri yapılarında biraraya getirilmektedir. Mount işlemi SYS_LINUX_mount sistem fonksiyonu tarafından yapılmaktadır: int SYS_LINUX_mount(PSTR pszdevname, PSTR pszmountdir, PSTR pszfsname, DWORD dwflags, PVOID pdata); Fonksiyonun çağırma şeması şöyledir: 1

SYS_LINUX_mount domount readsuperblock addsuperblock addmountedfs Mount işlemi sırasında mount edilen dosya sistemi addmountedfs fonksiyonu tarafından MOUNTED_FILE_SYSTEM türünden bir bağlı listeye, süper blok bilgileri de addsuperblock fonksiyonu tarafından SUPER_BLOCK türünden bağlı listeye yazılmaktadır. gs_mountedfs MFS MFS MFS MFS slink slink slink slink slinksbmounts slinksbmounts slinksbmounts slinksbmounts gs_superblocks SB SB SB dlink dlink dlink dlinkfssb dlinkfssb dlinkfssb dlistmounts dlistmounts dlistmounts gs_fstype FST FST slink slink MFS = MOUNTED_FILE_SYSTEM dlistfssb dlistfssb SB = SUPER_BLOCK FST = FILE_SYSTEM_TYPE Bir dosya sistemi birden fazla yere mount edilebilir. Yukarıdaki şekilden de görüldüğü gibi SUPER_BLOCK yapısının dlistmounts elemanı ilgili süper bloğun nerelere mount edildiğini belirlemek için kullanılan bir bağlı listedir. Benzer biçimde bir dosya sistemine ilişkin birden fazla volume söz konusu olabilir. FILE_SYSTEM_TYPE yapısının dlistfssb elemanı o dosya sistemine ilişkin SUPER_BLOCK nesnelerini tutan bağlı listedir. MOUNTED_FILE_SYSTEM listesinin ilk elemanı gs_mountedfs tarafından, SUPER_BLOCK listesinin ilk elemanı gs_superblocks tarafından, FILE_SYSTEM_TYPE yapısının ilk elemanı da gs_fstype tarafından tutulmaktadır. 2

SYS_LINUX_mount fonksiyonunun parametresi aygıt dosyasının yol ifadesidir. Fonksiyon önce yol ifadesinden hareketle aygıt dosyasının i-node bilgilerini elde eder. Erişim için gereken aygıt numarası i-node bilgilerinin içerisindedir. Bu işlemden sonra eğer aygıtın süper bloğu SUPER_BLOCK listesinde yoksa yeni bir SUPER_BLOCK nesnesi oluşturulmakta, eğer varsa eski SUPER_BLOCK nesnesi kullanılmaktadır. Aygıt dosyasından elde edilen aygıt numaraları pek çok veri yapısına da aktarılmaktadır. SUPER_BLOCK mount edilen fiziksel birime ilişkin parametrik bilgilerin tutulduğu bir veri yapısıdır. Örneğin aygıtın fiziksel adresi, aygıtın blok sayısı, blokların sektör uzunluğu gibi temel tüm parametrik bilgiler SUPER_BLOCK yapısında tutulmaktadır. Disk üzerinde gerçek okuma, yazma işlemlerinin hareket noktası SUPER_BLOCK yapısıdır. SUPER_BLOCK nesnesi FAT ve VFAT dosya sistemlerinde boot sektör BPB blgilerinden, UNIX/LINUX dosya sistemlerinde ise diskteki süper block bilgilerinden oluşturulmaktadır. 2. DİLİMLİ TAHSİSAT SİSTEMİ Dilimli tahsisat sistemi (slab allocator) ilk kez 1994 yılında Solaris 2.4 ile birlikte uygulamaya geçirilmiştir. Linux sistemleri de 2.2 uyarlamasıyla birlikte dilimli tahsisat sistemini kullanmaya başlamıştır. CSD İşletim Sisteminin çekidek yapısı içerisinde dilimli tahsisat sistemi yoğun olarak kullanılmaktadır. Dilimli tahsisat sistemi küçük nesnelerin tahsis edilmesi işlemlerinde yavaş tahisat fonksiyonlarını az çağırmak için oluşturulmuş bir cache sistemidir. Bu sisteme göre bir nesne dilimli tahsisat fonksiyonu ile tahsis edilmeye çalışıldığında dilimli tahsisat fonksiyonu bir grup nesne kadar alanı (yani bir dilimlik alanı) tahsis eder. Sonraki tahsisatlar için hızlı bir biçimde daha önce tahsis edilmiş olan dilimlerden yer verilir. Dilimli tahsisat fonksiyonları şunlardır: HCACHE CreateCache(PCSTR pszname, DWORD dwobjects, DWORD dwobjectsize); PVOID AllocObject(HCACHE hcache); void FreeObject(HCACHE hcache, PVOID pblock); CreateCache fonksiyonu kullanılacak dilim sisteminin ismini, başlangıçta tahsis edilecek nesne sayısını ve bir nesnenin byte uzunluğunu parametre olarak alır ve tahsisat işleminde kullanılacak handle değeri ile geri döner. Fonksiyon ikinci parametresinden hareketle başlangıçta kaç dilimin gerektiğini hesaplar ve bu dilimleri tahsis eder. AllocObject dilimden nesne veren fonksiyondur. Tahsis edilen alan FreeObject fonksiyonu ile serbest bırakılır. FreeObject fonksiyonu tüm dilim boşaltılmışsa dilimi işletim sistemine geri verir. CSD dilimli tahsisat sisteminde nesne uzunluğu ne olursa olsun bir dilim SLAB_SIZE (512) kadar nesne içermektedir. Örneğin: HACAHE hdirentrycache; PDIR_ENTR pentry; hdirentrycache = CreateCache("DirEntryCache", 5000, sizeof(dir_entry)); 3

ASSERT(hDirEntryCache!= NULL); pentry = (PDIR_ENTRY) AllocObject(hDirEntryCache); ASSERT(pEntry!= NULL); Bu durumda CreateCache başlangıçta 10 dilim tahsis edecektir (5000 / 512 yukarı doğru yuvarlanmıştır.) Dilimli tahsisat sisteminde dilimler işletim sisteminin çekirdek heap alanından tahsisat yapan AllocMem sistem fonksiyonu ile tahsis edilmektedir. Nesne Tahsisat İşlemleri Dilimli Tahsisat Sistemi Çekirdek Heap Sistemi Sayfa Tablosu Düzeyinde Tahsisat İşlemleri 3. AŞAĞI SEVİYELİ DİSK CACHE SİSTEMİ Disk cache sistemi diskten son okunan blokların RAM de tutulmasıyla disk erişimini azaltmayı hedefleyen bir cache sistemdir. Bu sisteme UNIX/LINUX sistemlerinde İnglizce buffer cache denilmektedir. Disk cache sisteminin büyüklüğüne sistemdeki RAM miktarına bakılarak dinamik bir biçimde karar verilir. Disk cache sisteminin -iyi uygulandığı taktirde- disk erişimini %70 lerin üzerinde azalttığı (cache hit ratio) bilinmektedir. Bu nedenle disk cache sistemi dosya sisteminin performansını belirlemede kritik öneme sahiptir. Linux disk cache sistemi Maurice J. Bach ın ünlü Design of the UNIX Operating System kitabında açıklanan modelden alınmıştır. CSD İşletim Sisteminde de bu model kullanılmaktadır. Disk cache sistemi bağlı listeli bir hash tablosu olarak düzenlenmiştir. Hash tablosu BUFFER_HEAD bağlı listelerininin başlangıç adreslerinin tutulduğu bir dizi biçimindedir. DLIST_HEADER gs_hashtable[hash_table_size]; Cache teki her blok için bir BUFFER_HEAD nesnesi vardır. Bloğun tüm bilgileri bu nesnede tutulur: 4

typedef struct tagbuffer_head { KDEV kdev; DWORD dwblock; DWORD dwblocksize; DWORD dwstatus; DWORD dwlruindex; DWORD dwsector; BYTE *pblock; DLIST_NODE dlink; DLIST_NODE dlinkfree; } BUFFER_HEAD, *PBUFFER_HEAD; Görüldüğü gibi yapının içerisinde söz konusu bloğun uzuluğu, hangi aygıtın hangi bloğu olduğu gibi önemli bilgiler bulunmaktadır. Yapının pblock gösterici elemanı bloğun yerini, dwblocksize elemanı ise uzunluğunu tutar. BUFFER_HEAD nesnelerinin tuttukları bloklar farklı büyüklükte olabilmektedir. Fakat blok uzunluğu işlemcinin desteklediği sayfa uzunluğundan (örneğin Intel işlemcilerinde 4K) büyük olamaz. Cache sisteminin şekilsel gösterimi aşağıda verilmiştir: DLIST_HEADER gs_hashtable[hash_table_size]; BUFFER_HEAD... dwblock pblock Diskteki Blok Numarası dwblocksize... BUFFER_HEAD... dwblock pblock dwblocksize... Diskteki Blok Numarası RAM de tutulan disk bloğu RAM de tutulan disk bloğu 5

BUFFER_HEAD nesnelerinden oluşan hash tablosu bir bağlı liste dizisi biçimindedir. Bloğun cache içerisinde aranması için aygıt numarası ve blok numarası kullanılarak bir dizi indeksi elde edilir. Dizinin bu indeksli elemanı üzerinde doğrusal arama yapılır. Bloklar getblock fonksiyonu tarafından cache te aranır: PRIVATE PBUFFER_HEAD getblock(kdev kdev, DWORD dwblock, DWORD dwblocksize) Fonksiyon: 1) Önce istenen blok cache te var mı diye bakar. İstenen blok cache te varsa onun BUFFER_HEAD adresiyle geri döner. 2) Eğer istenen blok cache te yoksa yeni bir BUFFER_HEAD oluşturur. Onu cache e yerleştirir ve cache e yerleştirmiş olduğu BUFFER_HEAD nesnesinin adresiyle geri döner. getblock okuma işleminin kendisini yapmaz. getblock fonksiyonunun çağırma şeması şöyledir: getblock getbuffercachehash updatelru additemlists deleteitemfreelist putbuffercache getbuffercachehash additemlru setbufferclean fillfreelist additemfreelist initbufferhead getblock fonksiyonunun anlaşılmasında iki önemli nokta vardır: 1) Cache e yerleştirilecek BUFFER_HEAD nesnesinin tahsis edilmesi 2) BUFFER_HEAD nesnesinin kullandığı bloğun tahsis edilmesi Tahsisat işlemlerinin hızlı yapılabilmesi için bloğu tahsis edilmiş olan fakat diğer bilgileri geçersiz olan BUFFER_HEAD nesneleri özel bağlı listelerde saklanır. Bu bağlı listelere boş blok listeleri (free block lists) denilmektedir. Her blok büyüklüğü için toplam NR_FREE_LIST (4) kadar boş blok listesi vardır. 6

DLIST_HEADER gs_freelist[nr_free_list]; gs_freelist[0] BH BH BH gs_freelist[1] BH BH BH BH BH BH gs_freelist[2] gs_freelist[3] BH BH BH Boş blok listelerindeki BUFFER_HEAD nesneleri ve onların blokları tahsis edilmiştir. Fakat BUFFER_HEAD nesnesinin ve onun tuttuğu bloğun içeriği boştur. Bir boş blok listesi elemanını oluşturabilmek için hem bir BUFFER_HEAD nesnesine hem de tampon (buffer) olarak kullanılacak bloğa gereksinim vardır. Boş bağlı listede eleman kalmadığında ona eleman doldurmak için fillfreelist fonksiyonu çağrılmaktadır. fillfreelist fonksiyonu o bağlı listeye Sayfa uzunluğu / Block uzunluğu kadar eleman ekler. Bu fonksiyon getblock içerisinden çağrılmaktadır. fillfreelist fonksiyonunun çağırma şeması şöyledir: fillfreelist AllocPage createbuffers getunusedbufferhead AllocObject additemfreelist fillfreelist fonksiyonu boş bağlı listeye eleman ekleyebilmek için BUFFER_HEAD nesnesi elde etmeye çalışır. BUFFER_HEAD nesneleri normal olarak dilimli tahsisat sisteminden alınmaktadır. Ancak dilimli tahsisat sistemine daha az başvurmak için kullanılmayan BUFFER_HEAD nesneleri kullanılmayan nesne listesi (unused list) denilen bir bağlı listede tıutulur. fillfreelist fonksiyonu BUFFER_HEAD nesnesini önce getunusedbufferhead fonksiyonu ile buradan almaya çalışır. Kullanılmayan nesne listesinde hiç BUFFER_HEAD nesnesi kalmamışsa nesne gerçekten AllocObject dilimli tahsisat fonksiyonuyla tahsis edilir. Her blok büyüklüğü için ayrı bir boş bağlı listenin kullanıldığını görüyorsunuz. Böylece bir blok gerektiğinde onun aranması daha hızlı yapılabilmetedir. 7

fillfreelist fonksiyonu bloklar için gerekli olan tampon RAM alanlarını doğrudan AllocPage fonksiyonunu çağırarak sayfa düzeyinde tahsis eder. getblock(...) Blok cache te var mı? Hayır fillfreelist(...) AllocPage(...) Boş bağlı listeden elemanı al ve cache e yerleştir Evet Bloğu cache ten al Kullanılmayan nesne listesinde BUFFER_HEAD var mı? Evet Hayır AllocObject(...) Sistemin blok okuması yapan ana fonksiyonu ReadBlock fonksiyonudur. ReadBlock önce getblock fonksiyonunu çağırarak cache e bakar. Eğer cache te blok bulunamazsa gerçek disk okuması için ReadWriteBlock fonksiyonunu kullanır. ReadWriteBlock fonksiyonu blok aygıt sürücüsünün teemel bir fonksiyonudur. Burada ele alınmayacaktır. ReadBlock fonksiyonunun çağırma şeması şöyledir: ReadBlock getblock ReadWriteBlock Disk cache sistemi hem okuma hem de yazma amaçlı kullanılmaktadır. Yani yazma işlemi sırasında da eğer blok cache te ise yazma cache e yapılmaktadır. Cache teki blokların tazelenmesi arka planda çalışan çekirdeğe ilişkin bir thread tarafından yapılacaktır. Disk cache sisteminde kullanılan son veri yapısı LRU listesidir. Bu liste cache teki blokların en az işlem görenlerini tespit etmek amacıyla kullanılır. Cache teki bir blok üzerinde işlem yapıldığında bu bloğa ilişkin BUFFER_HEAD nesnesi LRU listesinin en önüne alınır. Böylece listenin sonunda her zaman az kullanılanlar kalır. Disk cache sisteminden eleman çıkartılacağı zaman en az kullanılan bloklar cache ten atılmaktadır. Aşağı seviyeli disk cache sisteminde kullanılan veri yapıları isimleriyle şunlardır: 1. BUFFER_HEAD bağlı listelerinin başlangıç adreslerlerini tutan hash tablosu: PRIVATE DLIST_HEADER gs_hashtable[bufcache_hash_table_size]; 8

2. BUFFER_HEAD nesnelerinin tahsis edilmesinde kullanılan dilimli tahsisat sistemi: PRIVATE HCACHE gs_hbufheadcache; 3. Bloğu tahsis edilmiş BUFFER_HEAD nesnelerinden oluşan boş bağlı listeler: PRIVATEDLIST_HEADER gs_dlistfree[bufcache_nr_free_list]; 4. Kullanılmayan BUFFER_HEAD nesnelerinin saklı olduğu kullanılmayan nesne listesi: PRIVATE DEFINE_DLIST(gs_dlistUnused); 5. Cache teki ve kullanılmayan nesne listesindeki eleman sayılarını tutan değişkenler: PRIVATE int gs_ninusebufheads; PRIVATE int gs_nunusedbufheads; Aşağı seviyeli disk cache sistemindeki alt sistemlerin amaçları da aşağıda özetlenmiştir: Genel Disk Cache Sistemi: Diskte erişilen son blokları RAM de bir cache içerisinde saklayarak disk erişimini azaltır. Böylece sistemin hızlı çalışmasını sağlar. İşletim sisteminin hızı bakımından kritik öneme sahip bir sistemdir. Dilimli Tahsisat Sistemi: İşletim sisteminin tahsisat fonksiyonları yavaştır. Bu nedenle küçük nesneler için sistemin tahsisat fonksiyonlarını ikide bir çağırmak etkin bir yöntem değildir. Bunun yerine işletim sisteminin tahsisat fonksiyonları ile büyük dilimler tahsis edip sonra o dilimlerin içerisinden hızlı bir biçimde nesneleri verme yöntemi tercih edilir. Amaç işletim sisteminin yavaş çalışan tahsisat fonksiyonlarını daha az çağırmaktır. Hash Tablosu: Erişilmeye çalışılan bir bloğun disk cache sistemi içerisinde olup olmadığının hızlı bir biçimde tespit edilmesi için kullanılır. Eğer blok cache te varsa doğrudan alınır. Blok cache te yoksa aygıt okumasyla blok aygıttan alınarak hash tablosuna yerleştirilir. Boş Blok Listeleri: Cache ten çıkartılan bloklar hemen serbest bırakılmaz. Boş blok listelerine alınarak orada bekletilir. Böylece yeni bir disk bloğu için yeniden RAM alanı tahsis edilmemiş olur. Boş blok listelerinde bulunan bir RAM bloğu yeni disk bloğu için kullanılır. (Tabii cache ten çıkartılan her blok boş blok listesinde biriktirilmez bunun bir sayısı vardır. Yani boş blok listesinde maksimum sayı kadar blok zaten varsa yeni bloklar listeye yazılmadan doğrudan sisteme iade edilir) Kullanılmayan Nesne Listesi: Bu liste BUFFER_HEAD nesneleri için cache olarak kullanılır. Yani kullanılmayan BUFFER_HEAD nesneleri bu listeye alınır. Böylece dilimli tahsisat sisteminden yapılan tahsisatlar azaltılmış olur. Bu listedeki nesnelerin blokları tahsis edilmemiştir. 9

4. YOL İFADESİNİN ÇÖZÜMLENMESİ VE DİZİN GİRİŞLERİNE İLİŞKİN CACHE SİSTEMİ Dosya işlemlerinin programcı bakımından başlangıç noktası dosyanın hangi dizinde ve hangi isimde olduğunu gösteren yol ifadesi (path name) dir. Dosya üzerinde işlem yapan pek çok sistem fonksiyonu (open, stat, mkdir, chdir, ) dosyayı tespit edebilmek için dosyanın yol ifadesini parametre olarak almaktadır. Yol ifadesini parametre olarak alan sistem fonksiyonları ilk iş olarak bu yol ifadesinden hareketle dosyanın temel bilgilerine ulaşmaya çalışırlar. Dosyanın temel bilgileri POSIX sistemlerinde i-node yapısıyla temsil edilmektedir. Verilen bir yol ifadesinden hareketle yol ifadesinin sonunda belirtilen dosyanın i-node bilgilerine erişilmesi sürecine yol ifadesinin çözümlenmesi (pathname resolution) denilmektedir. (Yol ifadesi terimi hem dosyalar için hem de dizinler için kullanılan bir kavramdır. Dizinler ve dosyalar arasında bunların ele alınma biçimleri bakımından bir fark bulunmamaktadır.) Yol ifadelerinin çözümlenmesi özyinelemeli (recursive) bir işlemdir. Çözümleme sırasında yol ifadesini oluşturan her bir yol bileşeni üzerinden teker teker geçilmek zorundadır. Çünkü her yol bileşenine ilişkin i- node bilgisi önceki bileşen ile belirtilen dizin içerisindedir. Örneğin, /home/osdev/test.c gibi bir yol ifadesinin çözümlenmesi sırasında önce kök dizinin i-node bilgilerinden home dizininin i- node bilgileri, home dizininin i-node bilgilerinden osdev dizininin i-node bilgileri, osdev dizininin i-node bilgilerinden de nihayet test.c dosyasının i-node bilgileri elde edilir. CSD dosya sisteminde yol bileşenlerine dizin girişi (directory entry) de denilmektedir. Dizin girişi bilgileri DIR_ENTRY yapısıyla temsil edilmektedir. typedef struct tagdir_entry *PDIR_ENTRY; typedef struct tagdir_entry { DWORD dwcount; DWORD dwflags; PINODE pinode; PDIR_ENTRY pparententry; DLIST_NODE dlinkhash; DLIST_NODE dlinklru; DLIST_NODE dlinkalias; DLIST_NODE dlinksibling; DLIST_HEADER dlistsubentry; PSUPER_BLOCK psb; PDIR_ENTRY_OPERATIONS pops; ENTRY_NAME entryname; char shortentryname[dentry_short_name_size]; } DIR_ENTRY; Bir dosyaya ilişkin dizin girişi bilgileri ve i-node bilgileri aslında disk üzerinde tutulan bilgilerdir. Yol ifadelerinin çözümlenmesi sırasında yol ifadelerini oluşturan dizin girişi ve i-node bilgileri diskten belleğe alınmak zorundadır. Yani yol ifadesinin çözümlenmesi işlemi aslında yol ifadesinin sonunda bulunan dosyaya ilişkin i-node bilgilerinin diskten belleğe çekilmesi işlemidir. Yol ifadelerinin çözümlenmesi daha etkin bir hale nasıl getirilebilir? Şüphesiz ilk düşünülecek yöntem bir cache sistemi kurmaktır. Böylece, bir dosyanın bilgilerine erişilirken geçilen yollara ilişkin tüm bileşenlerin dizin girişi bilgileri ve i-node bilgileri bir cache sisteminde tutulursa, ayn ı dosyalara erişildiği durumda işlemin hızlanacağı açıktır. Bu nedenle modern işletim sistemlerinde hem dizin girişleri hem de i-node elemaları için ayrı cache sistemleri kullanılmaktadır. CSD 10

işletim sisteminde de (tıpkı Linux sistemlerinde olduğu gibi) dizin girişleri ve i-node bilgileri bu nesnelere özgü cache sistemlerinde saklanır. CSD dosya sisteminin dizin girişlerinin cache sisteminde şu veri yapıları kullanılmaktadır: 1. DIR_ENTRY türünden bağlı listelerin başlangıç adreslerinin tutulduğu bir hash tablosu: PRIVATE DLIST_HEADER gs_direntryhashtable[dentry_hash_table_size]; 2. En az kullanılan ve kullanılmayan DIR_ENTRY nesnelerinin tespit edilmesini sağlayan bir LRU bağlı listesi: PRIVATE DEFINE_DLIST(gs_dlistLRU); 3. Bir i-node a ilişkin link bilgilerini tutan bir eş giriş bağlı listesi. Bu listenin ilk elemanı i-node nesnesi içerisindedir: DLIST_HEADER dlistdirentry; /* INODE yap ısının elemanıdır */ 4. Cache teki ve kullanılmayan nesne listesindeki eleman sayınısı tutan değişkenler: PRIVATE int gs_ninuseentries; PRIVATE int gs_nunusedentries; DIR_ENTRY nesnesinin kaç kişi tarafından kullanıldığını gösteren bir dwcount elemanı vardır. Sayacı sıfıra düşen DIR_ENTRY nesnesi hash tablosundan çıkarılmaz; yalnızca LRU listesinin sonuna alınır. LRU listesinde sayacı sıfıra düşmüş olan yani kullanılmayan kaç tane DIR_ENTRY nesnesi olduğu gs_nunusedentries değişkeninde tutulmaktadır. Kullanılan DIR_ENTRY nesneleri bağlı listede öne alınır. Böylece en çok kullanılanlar önde en az kullanılanlar ve hiç kullanılmayanlar arkada kalır. Bir i-node elemanına ilişkin birden fazla DIR_ENTRY nesnesi bulunabilir. Bunlar da başlangıcı i-node nesnesinde fakat linkleri DIR_ENTRY içerisinde olan eş giriş listelerinde saklanırlar. Dizin girişlerine ilişkin cache sistemi i-node cache sisteminin kontrol merkezidir. I-node cache sistemine elemanlar DIR_ENTRY işlemleriyle alınırlar. Yani ne zaman bir yol ifadesi kullanılsa bu yol ifadesindeki dizin girişleri dizin girişi cache sistemine, i-node elemanları ise i-node cache sistemine alınmaktadır Her dizin girişi için i-node cache sistemi içerisinde bir i-node nesnesi vardır. CSD dosya sisteminde yol ifadelerinin çözümlenmesi LookupDirEntry fonksiyonu tarafından yapılmaktadır: PDIR_ENTRY LookupDirEntry(PCSTR ppathname, PDIR_ENTRY pbaseentry, DWORD dwlookupflags) 11

Fonksiyon çözümlenecek yol ifadesini (ppathname), arama işleminin başlatılacağı dizini (pbaseentry) ve arama planını belirten bayrakları parametre olarak alır. Başarılıysa ilgili girişin DIR_ENTRY adresiyle, başarısızsa NULL adresiyle geri döner. Fonksiyon dizin girişini önce cache te arar. Eğer cache te bulamazsa aygıttan okuyarak onu cache e yerleştirir. Birkaç durum söz konusudur: 1. Eğer ppathname mutlak yol ifadesi ve pbaseentry de NULL ise pbaseentry process in kök dizinine çekilir. Böylece arama işlemi kök dizininden itibaren yapılır. 2. Eğer ppathname mutlak yol ifadesi ve pbaseentry de NULL ise pbaseentry ile belirtilen girişin sayacı bir artırılır ve pbaseentry process in root dizinine çekilir. Yani yukarıdaki durumda olduğu gibi arama yine kök dizininden itibaren yapılacaktır. 3. ppathname göreli yol ifadesi ve pbaseentry de NULL ise pbaseentry process in çalışma dizinine çekilir. Böylece arama işlemi çalışma dizininden itibaren yapılır. 4. ppathname göreli yol ifadesi ve pbaseentry de NULL değilse pbaseentry olduğu gibi bırakılır. Yani arama işlemi pbaseentry ile belirtilen dizinden itibaren yapılır. Fonksiyonun çağırma şeması şöyledir: LookupDirEntry checkpermission (permission) lookupreservedentries (lookup_dentry) GetDirEntryCache (cached_lookup) GetDevDirEntry (real_lookup) allocdirentry (d_alloc) checkpermission her yol bileşeninin erişim iznini denetler. lookupreservedentries yol bileşeninin. ve.. gibi ayrılmış (reserved) isimler olup olmadığına bakar. GetDirEntryCache bileşeni cahe te aramaktadır. Bu fonksiyon ya bileşeni cache te bulur ya da bulamaz. Bileşen cache te bulunamadıysa aygıttan çekilecektir. Bunun için GetDevDirEntry fonksiyonu kullanılır. GetDevDirEntry bir DIR_ENTRY nesnesi tahsis eder ve aygıttan okunan bilgileri DIR_ENTRY cache içerisinde saklar. GetDevDirEntry fonksiyonu aygıttan yol bileşeni için DIR_ENTRY bilgilerini alarak dizin girişi cache sistemine yerleştirir. Bu işlem sırasında aynı zamanda DIR_ENTRY nesnesine ilişkin i-node bilgileri de i-node cache sistemine çekilir. PDIR_ENTRY GetDevDirEntry(PDIR_ENTRY pparententry, PCENTRY_NAME pentryname) Fonksiyon üst dizinin DIR_ENTRY adresini ve elde edilecek dizin girişinin ismini alır. GetDevDirEntry fonksiyonunun çağırma şeması şöyledir: GetCacheDirEntry allocdirentry pparentinode->pops->pflookup putdirentrycache PutInodeCache 12

allocdirentry yeni bir DIR_ENTRY nesnesini dilimli tahsisat sistemini kullanarak yaratır ve nesnenin bazı elemanlarını doldurur. Aygıttan DIR_ENTRY ve INODE nesnelerinin okunması tamamen INODE yapısına ilişkin pflookup sanal fonksiyonu tarafından yapılmaktadır. pflookup fonksiyonunun parametrik yapısı şöyledir: PDIR_ENTRY (*pflookup)(pcinode, PCDIR_ENTRY); Fonksiyon üst dizinin INODE nesne adresini ve bu dizinde aranacak olan bileşenin DIR_DENTRY nesne adresini parametre olarak alır. pflookup sanal fonksiyonu elde ettiği DIR_ENTRY nesnesini PutDirEntryCache ile dizin girişlerine ilişkin cache sistemi içerisine, PutInodeCache ile de i-node cache içerisine yerleştirir. 5. I-NODE CACHE SİSTEMİ Dosyalar üzerinde işlem yapılmadan önce onlara ilişkin bilgiler INODE yapısı ile temsil edilerek belleğe çekilmektedir. Belleğe çekilen i-node bilgileri etkinliği artırmak amacıyla bir cache sistemi içerisinde saklanır. Bu cache sistemine i-node cache denilmektedir. I-node cache sistemi aşağıdaki veri yapılarından oluşur: 1. INODE elemanlarını içeren bağlı listelerin başlangıç adreslerini tutan bir hash tablosu: PRIVATE DLIST_HEADER gs_inodehashtable[inode_hash_table_size]; 2. INODE nesnelerinin tahsis edildiği bir dilimli tahsisat sistemi: PRIVATE HCACHE gs_hinodecache; 3. En az kullanılan ve kullanılmayan i-node elemanlarının tutulduğu bir LRU listesi: PRIVATE DEFINE_DLIST(gs_dlistLRU); 4. Cache teki ve kullanılmayan nesne listesindeki eleman sayısını tutan değişkenler: PRIVATE int gs_ninuseinodes; PRIVATE int gs_nunusedinodes; I-node cache içerisinde getinodecache fonksiyonu ile arama yapılır. Bu fonksiyon hash fonksiyonuyla elde edilen indeksteki bağlı listeyi dolaşarak istenen i-node elemanının cache içerisinde olup olmadığına bakar. Yeni bir i-node nesnesine gereksinim duyulduğunda bu nesne allocinode fonksiyonu tarafından tahsis edilmektedir. allocinode nesneyi önce LRU listesinin sonundaki kullanılmayan elemanlardan elde etmeye çalışır. Eğer bunu başaramazsa tahsisat dilimli tahsisat sistemine ilişkin AllocObject fonksiyonu tarafından yapılmaktadır: 13

AlloInode GetUnuesInode AllocObject I-node cache sistemine eleman PutInodeCache fonksiyonuyla eklenmektedir. 14