Differences

This shows you the differences between two versions of the page.

Link to this comparison view

so2:laboratoare:lab09 [2018/04/24 18:18]
anda.nicolae [Ștergerea unui director]
so2:laboratoare:lab09 [2021/05/03 11:06] (current)
teodor_stefan.dutu [Operații pentru inode - inode_operations]
Line 60: Line 60:
 ==== Obținerea unui inode ==== ==== Obținerea unui inode ====
  
-Una din principalele operații cu inode-uri este obținerea unui inode (a unei structuri [[http://lxr.free-electrons.com/​source/​include/​linux/​fs.h?v=4.9#L604 | struct inode]] în VFS). Până la versiunea ''​2.6.24''​ a nucleului Linux, dezvoltatorul definea o funcție ''​read_inode''​. Începând cu versiunea [[http://​lkml.org/​lkml/​2007/​10/​10/​210|2.6.25]],​ dezvoltatorul trebuie să definească o funcție ''<​fsname>​_iget''​ unde ''<​fsname>''​ este numele sistemului de fișiere. Această funcție este responsabilă cu aflarea inode-ului VFS în cazul în care acesta există sau crearea unui inode nou și completarea acestuia cu informațiile de pe disc.+Una din principalele operații cu inode-uri este obținerea unui inode (a unei structuri [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​fs.h#​L565 | struct inode]] în VFS). Până la versiunea ''​2.6.24''​ a nucleului Linux, dezvoltatorul definea o funcție ''​read_inode''​. Începând cu versiunea [[http://​lkml.org/​lkml/​2007/​10/​10/​210|2.6.25]],​ dezvoltatorul trebuie să definească o funcție ''<​fsname>​_iget''​ unde ''<​fsname>''​ este numele sistemului de fișiere. Această funcție este responsabilă cu aflarea inode-ului VFS în cazul în care acesta există sau crearea unui inode nou și completarea acestuia cu informațiile de pe disc.
  
-În general, în cadrul funcției se va apela [[http://lxr.free-electrons.com/​source/​fs/​inode.c?v=4.9#L1087 | iget_locked]] pentru obținerea structurii [[http://lxr.free-electrons.com/​source/​include/​linux/​fs.h?v=4.9#L604 | struct inode]] din VFS. În cazul în care inode-ul este nou creat, atunci va trebui citit inode-ul de pe disc (folosind [[http://lxr.free-electrons.com/​source/​include/​linux/​buffer_head.h?v=4.9#L298 | sb_bread]]) și completate informațiile utile.+În general, în cadrul funcției se va apela [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​inode.c#​L1088 | iget_locked]] pentru obținerea structurii [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​fs.h#​L565 | struct inode]] din VFS. În cazul în care inode-ul este nou creat, atunci va trebui citit inode-ul de pe disc (folosind [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​buffer_head.h#​L304 | sb_bread]]) și completate informațiile utile.
  
-Un exemplu de astfel de funcție este [[http://lxr.free-electrons.com/​source/​fs/​minix/​inode.c?v=4.9#L531 | minix_iget]]:​+Un exemplu de astfel de funcție este [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​inode.c#​L527 | minix_iget]]:​
  
 <code cpp> <code cpp>
Line 97: Line 97:
 </​code>​ </​code>​
  
-În cadrul funcției [[http://lxr.free-electrons.com/​source/​fs/​minix/​inode.c?v=4.9#L531 | minix_iget]] se obține inode-ul VFS folosind [[http://lxr.free-electrons.com/​source/​fs/​inode.c?v=4.9#L1087 | iget_locked]]. Dacă inode-ul este deja existent (nu este nou = nu este configurat flag-ul [[http://lxr.free-electrons.com/​source/​include/​linux/​fs.h?v=4.9#L1950 | I_NEW]]) funcția se întoarce. Altfel, se apelează funcția [[http://lxr.free-electrons.com/​source/​fs/​minix/​inode.c?v=4.9#L463 | V1_minix_iget]] care va citi inode-ul de pe disc folosind [[http://lxr.free-electrons.com/​source/​fs/​minix/​bitmap.c?v=4.9#L105 | minix_V1_raw_inode]] și apoi va completa inode-ul VFS cu informațiile citite.+În cadrul funcției [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​inode.c#​L527 | minix_iget]] se obține inode-ul VFS folosind [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​inode.c#​L1088 | iget_locked]]. Dacă inode-ul este deja existent (nu este nou = nu este configurat flag-ul [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​fs.h#​L1992 | I_NEW]]) funcția se întoarce. Altfel, se apelează funcția [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​inode.c#​L459 | V1_minix_iget]] care va citi inode-ul de pe disc folosind [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​bitmap.c#​L106 | minix_V1_raw_inode]] și apoi va completa inode-ul VFS cu informațiile citite.
  
 ==== Superoperații ==== ==== Superoperații ====
  
-O bună parte din superoperații (componentele structurii [[http://lxr.free-electrons.com/​source/​include/​linux/​fs.h?v=4.9#L1786 | struct super_operations]],​ utilizate de superbloc) sunt folosite în lucrul cu inode-uri. În continuare sunt prezentate acestea:+O bună parte din superoperații (componentele structurii [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​fs.h#​L1803 | struct super_operations]],​ utilizate de superbloc) sunt folosite în lucrul cu inode-uri. În continuare sunt prezentate acestea:
  
-  *''​alloc_inode'':​ alocă un inode. De obicei, în cadrul acestei structuri se alocă o structură ''​fsname_inode_info''​ și se efectuează inițializările de bază ale inode-ului VFS (folosind [[http://lxr.free-electrons.com/​source/​fs/​inode.c?v=4.9#L359 | inode_init_once]]). În [[http://lxr.free-electrons.com/​source/​fs/​minix/?​v=4.9 ​| minix]], pentru alocare este folosită funcția [[http://lxr.free-electrons.com/​source/​tools/​testing/​radix-tree/​linux/​slab.h?v=4.9#L20 | kmem_cache_alloc]] care interacționează cu subsistemul [[http://lxr.free-electrons.com/​source/​mm/​slab.c?v=4.9| SLAB]]. La fiecare alocare se apelează [[http://lxr.free-electrons.com/​source/​include/​linux/​slab_def.h#​L81| constructorul]] cache-ului, în cazul [[http://lxr.free-electrons.com/​source/​fs/​minix/?​v=4.9 ​| minix]] funcția [[http://lxr.free-electrons.com/​source/​fs/​minix/​inode.c?v=4.9#​L82|init_once]]. Alternativ, se poate folosi [[http://lxr.free-electrons.com/​source/​include/​linux/​slab.h?v=4.9#L478 | kmalloc]], caz în care va trebui apelată funcția [[http://lxr.free-electrons.com/​source/​fs/​inode.c?v=4.9#L359 | inode_init_once]]. Funcția ''​alloc_inode''​ va fi apelată de funcțiile [[http://lxr.free-electrons.com/​source/​fs/​inode.c?v=4.9#L900 | new_inode]] și [[http://lxr.free-electrons.com/​source/​fs/​inode.c?v=4.9#L1087 | iget_locked]].+  *''​alloc_inode'':​ alocă un inode. De obicei, în cadrul acestei structuri se alocă o structură ''​fsname_inode_info''​ și se efectuează inițializările de bază ale inode-ului VFS (folosind [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​inode.c#​L360 | inode_init_once]]). În [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix | minix]], pentru alocare este folosită funcția [[https://elixir.bootlin.com/​linux/​v4.15/​source/​tools/​testing/​radix-tree/​linux/​slab.h#​L14 | kmem_cache_alloc]] care interacționează cu subsistemul [[https://elixir.bootlin.com/​linux/​v4.15/​source/​mm/​slab.c| SLAB]]. La fiecare alocare se apelează [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​slab_def.h#​L39| constructorul]] cache-ului, în cazul [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix | minix]] funcția [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​inode.c#​L82|init_once]]. Alternativ, se poate folosi [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​slab.h#​L436 | kmalloc]], caz în care va trebui apelată funcția [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​inode.c#​L360 | inode_init_once]]. Funcția ''​alloc_inode''​ va fi apelată de funcțiile [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​inode.c#​L901 | new_inode]] și [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​inode.c#​L1088 | iget_locked]].
   *''​write_inode'':​ salvează/​actualizează pe disc inode-ul primit ca parametru; pentru actualizarea inode-ului, deși ineficient, pentru începători este recomandat să folosească următoarea secvență de operații:   *''​write_inode'':​ salvează/​actualizează pe disc inode-ul primit ca parametru; pentru actualizarea inode-ului, deși ineficient, pentru începători este recomandat să folosească următoarea secvență de operații:
-    *încarcă inode-ul de pe disc cu ajutorul funcției [[http://lxr.free-electrons.com/​source/​include/​linux/​buffer_head.h?v=4.9#L298 | sb_bread]];​ +    *încarcă inode-ul de pe disc cu ajutorul funcției [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​buffer_head.h#​L304 | sb_bread]];​ 
-    *modifică [[http://lxr.free-electrons.com/​source/​include/​linux/​buffer_head.h?v=4.9#L53|buffer-ul]] în concordanță cu inode-ul de salvat; +    *modifică [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​buffer_head.h#​L54|buffer-ul]] în concordanță cu inode-ul de salvat; 
-    *marchează buffer-ul murdar (dirty) cu ajutorul funcției [[http://lxr.free-electrons.com/​source/​fs/​buffer.c?v=4.9#L1136 | mark_buffer_dirty]];​ kernel-ul se va ocupa apoi de scrierea lui pe disc;  +    *marchează buffer-ul murdar (dirty) cu ajutorul funcției [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​buffer.c#​L1094 | mark_buffer_dirty]];​ kernel-ul se va ocupa apoi de scrierea lui pe disc;  
-    *un exemplu este funcția [[http://lxr.free-electrons.com/​source/​fs/​minix/​inode.c?v=4.9#L603 | minix_write_inode]] din sistemul de fișiere [[http://lxr.free-electrons.com/​source/​fs/​minix/?​v=4.9 ​| minix]]+    *un exemplu este funcția [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​inode.c#​L602 | minix_write_inode]] din sistemul de fișiere [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix | minix]]
   *''​evict_inode'':​ șterge de pe disc și din memorie orice informație referitoare la numărul inode-ului primit în câmpul ''​i_ino''​ (atât inode-ul de pe disc cât și blocurile de date asociate). Aceasta implică realizarea următoarelor operații:   *''​evict_inode'':​ șterge de pe disc și din memorie orice informație referitoare la numărul inode-ului primit în câmpul ''​i_ino''​ (atât inode-ul de pe disc cât și blocurile de date asociate). Aceasta implică realizarea următoarelor operații:
     *șterge inode-ul de pe disc;     *șterge inode-ul de pe disc;
     *actualizează hărțile de biți pe disc (în cazul în care există)     *actualizează hărțile de biți pe disc (în cazul în care există)
-    *șterge inode-ul din page cache prin apelarea funcției [[http://lxr.free-electrons.com/​source/​mm/​truncate.c?v=4.9#L387 | truncate_inode_pages]];​+    *șterge inode-ul din page cache prin apelarea funcției [[https://elixir.bootlin.com/​linux/​v4.15/​source/​mm/​truncate.c#​L468 | truncate_inode_pages]];​
     *șterge inode-ul din memorie prin apelarea funcției ''​clear_inode''​ ;     *șterge inode-ul din memorie prin apelarea funcției ''​clear_inode''​ ;
-    *un exemplu este funcția [[http://lxr.free-electrons.com/​source/​fs/​minix/​inode.c?v=4.9#L27 | minix_evict_inode]] din sistemul de fișiere [[http://lxr.free-electrons.com/​source/​fs/​minix/?​v=4.9 ​| minix]].+    *un exemplu este funcția [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​inode.c#​L27 | minix_evict_inode]] din sistemul de fișiere [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix | minix]].
   *''​destroy_inode''​ eliberează memoria ocupată de inode   *''​destroy_inode''​ eliberează memoria ocupată de inode
  
Line 121: Line 121:
 Operațiile pentru inode sunt descrise de structura [[http://​lxr.free-electrons.com/​source/​include/​linux/​fs.h?​v=4.9#​L604 | struct inode_operations]]. Operațiile pentru inode sunt descrise de structura [[http://​lxr.free-electrons.com/​source/​include/​linux/​fs.h?​v=4.9#​L604 | struct inode_operations]].
  
-Inode-urile sunt de mai multe tipuri: fișier, director, fișier special (pipe, fifo), dispozitiv de tip bloc, dispozitiv de tip caracter, link etc. Din acest motiv, operațiile pe care trebuie un inode să le implementeze sunt diferite pentru fiecare tip de inode. Mai jos vor fi prezentate în detaliu operațiile implementate pentru un [[#Inode-urile_de_tip_fi.C8.99ier|inode de tip fișier]] și un [[#Opera.C8.9Bii_asupra_inode-urilor_de_tip_director|inode de tip director]].+Inode-urile sunt de mai multe tipuri: fișier, director, fișier special (pipe, fifo), dispozitiv de tip bloc, dispozitiv de tip caracter, link etc. Din acest motiv, operațiile pe care trebuie un inode să le implementeze sunt diferite pentru fiecare tip de inode. Mai jos vor fi prezentate în detaliu operațiile implementate pentru un [[#inode-urile_de_tip_fisier|inode de tip fișier]] și un [[#operatii_asupra_inode-urilor_de_tip_director|inode de tip director]].
  
 Operațiile unui inode sunt inițializate și accesate folosind câmpul ''​i_op''​ al structurii [[http://​lxr.free-electrons.com/​source/​include/​linux/​fs.h?​v=4.9#​L604 | struct inode]]. Operațiile unui inode sunt inițializate și accesate folosind câmpul ''​i_op''​ al structurii [[http://​lxr.free-electrons.com/​source/​include/​linux/​fs.h?​v=4.9#​L604 | struct inode]].
Line 129: Line 129:
 Structura ''​file''​ corespunde unui fișier deschis de un proces și există doar în memorie, fiind asociată unui inode. Este entitatea din VFS cea mai apropiată de user-space; câmpurile structurii conțin informații familiare ale unui fișier din user-space (modul de acces, poziția în fișier, etc.), iar operațiile cu aceasta sunt apeluri de sistem cunoscute (''​read'',​ ''​write'',​ etc.). Structura ''​file''​ corespunde unui fișier deschis de un proces și există doar în memorie, fiind asociată unui inode. Este entitatea din VFS cea mai apropiată de user-space; câmpurile structurii conțin informații familiare ale unui fișier din user-space (modul de acces, poziția în fișier, etc.), iar operațiile cu aceasta sunt apeluri de sistem cunoscute (''​read'',​ ''​write'',​ etc.).
  
-Operațiile pentru ''​file''​ sunt descrise de structura [[http://lxr.free-electrons.com/​source/​include/​linux/​fs.h?v=4.9#L1696 | struct file_operations]].+Operațiile pentru ''​file''​ sunt descrise de structura [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​fs.h#​L1692 | struct file_operations]].
  
-Pentru a inițializa operațiile pe ''​file''​ pentru un sistem de fișiere, se folosește câmpul ''​i_fop''​ al structurii [[http://lxr.free-electrons.com/​source/​include/​linux/​fs.h?v=4.9#L604 | struct inode]]. La deschiderea unui fișier, VFS-ul inițializează câmpul ''​f_op''​ al structurii [[http://lxr.free-electrons.com/​source/​include/​linux/​fs.h?v=4.9#L880 | struct file]] cu adresa din ''​inode->​i_fop'',​ astfel încât apeluri de sistem ulterioare să folosească valoarea stocată în ''​file->​f_op''​.+Pentru a inițializa operațiile pe ''​file''​ pentru un sistem de fișiere, se folosește câmpul ''​i_fop''​ al structurii [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​fs.h#​L565 | struct inode]]. La deschiderea unui fișier, VFS-ul inițializează câmpul ''​f_op''​ al structurii [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​fs.h#​L852 | struct file]] cu adresa din ''​inode->​i_fop'',​ astfel încât apeluri de sistem ulterioare să folosească valoarea stocată în ''​file->​f_op''​.
  
 ===== Inode-urile de tip fișier ===== ===== Inode-urile de tip fișier =====
Line 139: Line 139:
 ==== Operații asupra inode-urilor de tip fișier ==== ==== Operații asupra inode-urilor de tip fișier ====
  
-În sistemul de fișiere [[http://lxr.free-electrons.com/​source/​fs/​minix/?​v=4.9 ​| minix]], pentru operațiile pe un inode este definită structura [[http://lxr.free-electrons.com/​source/​fs/​minix/​file.c?v=4.9#L48 | minix_file_inode_operations]],​ iar pentru operațiile pe ''​file''​ se definește structura [[http://lxr.free-electrons.com/​source/​fs/​minix/​file.c?v=4.9#L11 | minix_file_operations]]:​+În sistemul de fișiere [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix | minix]], pentru operațiile pe un inode este definită structura [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​file.c#​L49 | minix_file_inode_operations]],​ iar pentru operațiile pe ''​file''​ se definește structura [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​file.c#​L12 | minix_file_operations]]:​
  
 <code cpp> <code cpp>
Line 165: Line 165:
 </​code>​ </​code>​
  
-Funcțiile [[http://lxr.free-electrons.com/​source/​fs/​read_write.c?v=4.9#L135 | generic_file_llseek]],​ [[http://lxr.free-electrons.com/​source/​mm/​filemap.c?v=4.9#L2335 | generic_file_mmap]],​ [[http://lxr.free-electrons.com/​source/​mm/​filemap.c?v=4.9#L1912 | generic_file_read_iter]] și [[http://lxr.free-electrons.com/​source/​mm/​filemap.c?v=4.9#L2868 | generic_file_write_iter]] sunt implementate în kernel.+Funcțiile [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​read_write.c#​L134 | generic_file_llseek]],​ [[https://elixir.bootlin.com/​linux/​v4.15/​source/​mm/​filemap.c#​L2733 | generic_file_mmap]],​ [[https://elixir.bootlin.com/​linux/​v4.15/​source/​mm/​filemap.c#​L2306 | generic_file_read_iter]] și [[https://elixir.bootlin.com/​linux/​v4.15/​source/​mm/​filemap.c#​L3195 | generic_file_write_iter]] sunt implementate în kernel.
  
-Pentru sistemele de fișiere simple nu trebuie să se implementeze decât operația de trunchiere (apelul de sistem ''​truncate''​). Deși inițial exita o operație dedicată, începând cu 3.14, operația a fost înglobată în setattr: dacă dimensiunea pasată este diferită de dimensiunea curentă a inode-ului atunci va trebui efectuată o operație de trunchiere. Un exemplu de implementare a acestei verificări este prezentă în funcția [[http://lxr.free-electrons.com/​source/​fs/​minix/​file.c#​L26 | minix_setattr]]:​+Pentru sistemele de fișiere simple nu trebuie să se implementeze decât operația de trunchiere (apelul de sistem ''​truncate''​). Deși inițial exita o operație dedicată, începând cu 3.14, operația a fost înglobată în setattr: dacă dimensiunea pasată este diferită de dimensiunea curentă a inode-ului atunci va trebui efectuată o operație de trunchiere. Un exemplu de implementare a acestei verificări este prezentă în funcția [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​file.c#​L25 | minix_setattr]]:​
  
 <code c> <code c>
Line 199: Line 199:
   * actualizarea hărților de biți pe disc (în cazul în care sunt folosite);   * actualizarea hărților de biți pe disc (în cazul în care sunt folosite);
   * actualizarea inode-ului;   * actualizarea inode-ului;
-  * completarea cu zero spațiul care a rămas nefolosit din ultimul bloc cu ajutorul funcției [[http://lxr.free-electrons.com/​source/​fs/​buffer.c?v=4.9#L2864 | block_truncate_page]].+  * completarea cu zero spațiul care a rămas nefolosit din ultimul bloc cu ajutorul funcției [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​buffer.c#​L2860 | block_truncate_page]].
  
-Un exemplu de implementarea a operației de trunchiere este funcția [[http://lxr.free-electrons.com/​source/​fs/​minix/​inode.c?v=4.9#L641 | minix_truncate]] din sistemul de fișiere [[http://lxr.free-electrons.com/​source/​fs/​minix/?​v=4.9 ​| minix]].  ​+Un exemplu de implementarea a operației de trunchiere este funcția [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​inode.c#​L640 | minix_truncate]] din sistemul de fișiere [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix | minix]].  ​
  
  
Line 211: Line 211:
 Între spațiul de adrese al unui proces și fișiere există o strânsă legătură: execuția programelor se face aproape exclusiv prin maparea fișierului în spațiul de adresă al procesului. Întrucât această abordare funcționează foarte bine și este destul de generală, poate fi folosită și în cazul apelurilor de sistem obișnuite cum ar fi ''​read''​ și ''​write''​. Între spațiul de adrese al unui proces și fișiere există o strânsă legătură: execuția programelor se face aproape exclusiv prin maparea fișierului în spațiul de adresă al procesului. Întrucât această abordare funcționează foarte bine și este destul de generală, poate fi folosită și în cazul apelurilor de sistem obișnuite cum ar fi ''​read''​ și ''​write''​.
  
-Structura care descrie spațiul de adresă este [[http://lxr.free-electrons.com/​source/​include/​linux/​fs.h?v=4.9#L431 | struct address_space]] , iar operațiile cu aceasta sunt descrise de structura [[http://lxr.free-electrons.com/​source/​include/​linux/​fs.h?v=4.9#L371 | struct address_space_operations]]. Pentru inițializarea operațiilor asupra spațiului de adresă, se completează câmpul ''​%%inode->​i_mapping->​a_ops%%''​ al inode-ului de tip fișier.+Structura care descrie spațiul de adresă este [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​fs.h#​L391 | struct address_space]],​ iar operațiile cu aceasta sunt descrise de structura [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​fs.h#​L331 | struct address_space_operations]]. Pentru inițializarea operațiilor asupra spațiului de adresă, se completează câmpul ''​%%inode->​i_mapping->​a_ops%%''​ al inode-ului de tip fișier.
  
-Un exemplu este structura [[http://lxr.free-electrons.com/​source/​fs/​minix/​inode.c?v=4.9#L428 | minix_aops]] din sistemul de fișiere [[http://lxr.free-electrons.com/​source/​fs/​minix/​inode.c?v=4.9#L442| minix]]:+Un exemplu este structura [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​inode.c#​L428 | minix_aops]] din sistemul de fișiere [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​inode.c#​L441| minix]]:
  
 <code cpp> <code cpp>
Line 231: Line 231:
 </​code>​ </​code>​
   ​   ​
-Funcția [[http://lxr.free-electrons.com/​source/​fs/​buffer.c?v=4.9#L2145 | generic_write_end ]] este deja implementată. Majoritatea funcțiilor specifice sunt foarte ușor de implementat,​ după cum urmează:+Funcția [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​buffer.c#​L2144 | generic_write_end ]] este deja implementată. Majoritatea funcțiilor specifice sunt foarte ușor de implementat,​ după cum urmează:
  
 <code cpp> <code cpp>
Line 274: Line 274:
 </​code>​ </​code>​
  
-Tot ce mai trebuie făcut este să se implementeze [[http://lxr.free-electrons.com/​source/​fs/​minix/​inode.c?v=4.9#L375 | minix_get_block]],​ care trebuie să translateze un bloc al unui fișier într-un bloc de pe device. Dacă flag-ul ''​create''​ primit ca parametru este activat, trebuie alocat un nou bloc. În cazul în care se creează un bloc nou, trebuie marcată corespunzător harta de biți. Pentru a înștiința nucleul să nu mai citească blocul de pe disc, trebuie marcat ''​bh''​ cu [[http://lxr.free-electrons.com/​source/​fs/​minix/​itree_common.c#​L197|set_buffer_new]]. Trebuie asociat buffer-ul cu blocul cerut prin funcția [[http://lxr.free-electrons.com/​source/​include/​linux/​buffer_head.h?v=4.9#L335 | map_bh]].+Tot ce mai trebuie făcut este să se implementeze [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​inode.c#​L375 | minix_get_block]],​ care trebuie să translateze un bloc al unui fișier într-un bloc de pe device. Dacă flag-ul ''​create''​ primit ca parametru este activat, trebuie alocat un nou bloc. În cazul în care se creează un bloc nou, trebuie marcată corespunzător harta de biți. Pentru a înștiința nucleul să nu mai citească blocul de pe disc, trebuie marcat ''​bh''​ cu [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​itree_common.c#​L198|set_buffer_new]]. Trebuie asociat buffer-ul cu blocul cerut prin funcția [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​buffer_head.h#​L341 | map_bh]].
  
 ===== Structura dentry ===== ===== Structura dentry =====
  
-Operațiile pe directoare folosesc structura [[http://lxr.free-electrons.com/​source/​include/​linux/​dcache.h?v=4.9#L83 | struct dentry]]. Principala sarcină a acesteia este realizarea de legături între inode-uri și numele fișierelor. Câmpurile importante ale acestei structuri sunt prezentate mai jos:+Operațiile pe directoare folosesc structura [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​dcache.h#​L90 | struct dentry]]. Principala sarcină a acesteia este realizarea de legături între inode-uri și numele fișierelor. Câmpurile importante ale acestei structuri sunt prezentate mai jos:
  
 <code cpp> <code cpp>
Line 299: Line 299:
   *''​d_inode'':​ inode-ul referit de acest dentry;   *''​d_inode'':​ inode-ul referit de acest dentry;
   *''​d_parent'':​ dentry-ul asociat directorului părinte;   *''​d_parent'':​ dentry-ul asociat directorului părinte;
-  *''​d_name'':​ o structură de tip [[http://lxr.free-electrons.com/​source/​include/​linux/​dcache.h?v=4.9#L45|struct qstr]] ce conține câmpurile ''​name''​ și ''​len''​ cu numele, respectiv lungimea numelui; +  *''​d_name'':​ o structură de tip [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​dcache.h#​L40 | struct qstr]] ce conține câmpurile ''​name''​ și ''​len''​ cu numele, respectiv lungimea numelui; 
-  *''​d_op'':​ operații cu dentry-uri, reprezentate printr-o structură [[http://lxr.free-electrons.com/​source/​include/​linux/​dcache.h?v=4.9#L129 | struct dentry_operations]]. Nucleul implementează operații implicite, astfel încât nu este nevoie să fie (re)implementate. Unele sisteme de fișiere pot face optimizări legate de structura specifică a dentry-urilor;​+  *''​d_op'':​ operații cu dentry-uri, reprezentate printr-o structură [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​dcache.h#​L136 | struct dentry_operations]]. Nucleul implementează operații implicite, astfel încât nu este nevoie să fie (re)implementate. Unele sisteme de fișiere pot face optimizări legate de structura specifică a dentry-urilor;​
   *''​d_fsdata'':​ câmp rezervat sistemului de fișiere ce implementează operații dentry;   *''​d_fsdata'':​ câmp rezervat sistemului de fișiere ce implementează operații dentry;
  
Line 307: Line 307:
 Operațiile care se aplică cel mai adesea asupra dentry-urilor sunt:  Operațiile care se aplică cel mai adesea asupra dentry-urilor sunt: 
  
-  * [[http://lxr.free-electrons.com/​source/​fs/​dcache.c?v=3.13#L1789 | d_make_root]]:​ alocă dentry-ul rădăcină. Se folosește în general în funcția care este apelată pentru citirea superblocului (''​fill_super''​),​ care trebuie să inițializeze directorul rădăcină. Așadar se obține inode-ul rădăcină din superbloc și se folosește ca argument pentru această funcție, pentru a completa câmpul ''​s_root''​ din structura [[http://lxr.free-electrons.com/​source/​include/​linux/​fs.h?v=4.9#L1338|struct super_block]];​ +  * [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​dcache.c#​L1885 | d_make_root]]:​ alocă dentry-ul rădăcină. Se folosește în general în funcția care este apelată pentru citirea superblocului (''​fill_super''​),​ care trebuie să inițializeze directorul rădăcină. Așadar se obține inode-ul rădăcină din superbloc și se folosește ca argument pentru această funcție, pentru a completa câmpul ''​s_root''​ din structura [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​fs.h#​L1337 | struct super_block]];​ 
-  * [[http://lxr.free-electrons.com/​source/​fs/​dcache.c?v=4.9#L2543 | d_add]]: asociază un dentry unui inode; dentry-ul primit ca parametru în apelurile discutate mai sus, semnifică intrarea (nume, lungime nume) ce trebuie să fie creată. Se va folosi această funcție atunci când se creează / încarcă un nou inode care nu are asociat un dentry și care nu a fost introdus încă în hash (la ''​lookup''​);​ +  * [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​dcache.c#​L2582 | d_add]]: asociază un dentry unui inode; dentry-ul primit ca parametru în apelurile discutate mai sus, semnifică intrarea (nume, lungime nume) ce trebuie să fie creată. Se va folosi această funcție atunci când se creează / încarcă un nou inode care nu are asociat un dentry și care nu a fost introdus încă în hash (la ''​lookup''​);​ 
-  * [[http://lxr.free-electrons.com/​source/​fs/​dcache.c?v=4.9#L1792 | d_instantiate]]:​ versiunea mai light a apelului precedent, în care dentry-ul a fost în prealabil introdus în hash.+  * [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​dcache.c#​L1831 | d_instantiate]]:​ versiunea mai light a apelului precedent, în care dentry-ul a fost în prealabil introdus în hash.
  
 <note warning> <note warning>
Line 316: Line 316:
 ===== Operații asupra inode-urilor de tip director ===== ===== Operații asupra inode-urilor de tip director =====
  
-Operațiile de lucru cu inode-urile de tip director au un nivel de complexitate mai ridicat decât cele de tip fișier. Dezvoltatorul trebuie să definească operații pentru inode-uri și operații pentru file-uri. În [[http://lxr.free-electrons.com/​source/​fs/​minix/?​v=4.9 ​| minix]], aceste operații sunt definite în structurile [[http://lxr.free-electrons.com/​source/​fs/​minix/​namei.c?v=4.9#L262 | minix_dir_inode_operations]],​ respectiv [[http://lxr.free-electrons.com/​source/​fs/​minix/​dir.c?v=4.9#L21|minix_dir_operations]]:​+Operațiile de lucru cu inode-urile de tip director au un nivel de complexitate mai ridicat decât cele de tip fișier. Dezvoltatorul trebuie să definească operații pentru inode-uri și operații pentru file-uri. În [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix | minix]], aceste operații sunt definite în structurile [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​namei.c#​L260 | minix_dir_inode_operations]],​ respectiv [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​dir.c#​L22 | minix_dir_operations]]:​
  
 <code cpp> <code cpp>
Line 332: Line 332:
  
 struct file_operations minix_dir_operations = { struct file_operations minix_dir_operations = {
 +      .llseek = generic_file_llseek,​
       .read = generic_read_dir,​       .read = generic_read_dir,​
       .iterate = minix_readdir,​       .iterate = minix_readdir,​
Line 346: Line 347:
 </​code>​ </​code>​
  
-Singura funcție deja implementată este [[http://lxr.free-electrons.com/​source/​fs/​libfs.c?v=4.9#L210 | generic_read_dir]].+Singura funcție deja implementată este [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​libfs.c#​L211 | generic_read_dir]].
  
 Funcțiile care implementează operațiile asupra inode-urilor de tip director sunt cele descrise mai jos. Funcțiile care implementează operațiile asupra inode-urilor de tip director sunt cele descrise mai jos.
Line 352: Line 353:
 ==== Crearea unui inode ==== ==== Crearea unui inode ====
  
-Funcția de creare de inode este indicată de câmpul ''​create''​ din structura ''​inode_operations''​. În cazul minix este vorba de [[http://lxr.free-electrons.com/​source/​fs/​minix/​namei.c?v=4.9#L69 | minix_create]]. Această funcție este apelată în urma apelurilor de sistem ''​creat''​ și ''​open''​. O astfel de funcție realizează următoarele operații:+Funcția de creare de inode este indicată de câmpul ''​create''​ din structura ''​inode_operations''​. În cazul minix este vorba de [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​namei.c#​L70 | minix_create]]. Această funcție este apelată în urma apelurilor de sistem ''​creat''​ și ''​open''​. O astfel de funcție realizează următoarele operații:
   - Introduce în structura fizică a discului o nouă intrare; nu trebuie uitată actualizarea hărților de biți pe disc.   - Introduce în structura fizică a discului o nouă intrare; nu trebuie uitată actualizarea hărților de biți pe disc.
   - Configurează drepturile de acces la cele primite ca parametru.   - Configurează drepturile de acces la cele primite ca parametru.
-  - Marchează inode-ul ca murdar (dirty) cu ajutorul funcției [[http://lxr.free-electrons.com/​source/​include/​linux/​fs.h?v=4.9#L1969 | mark_inode_dirty]]. +  - Marchează inode-ul ca murdar (dirty) cu ajutorul funcției [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​fs.h#​L2012 | mark_inode_dirty]]. 
-  - Instanțiază intrarea de director (//​dentry//​) cu ajutorul funcției [[http://lxr.free-electrons.com/​source/​fs/​dcache.c?v=4.9#L1792 | d_instantiate]].+  - Instanțiază intrarea de director (//​dentry//​) cu ajutorul funcției [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​dcache.c#​L1831 | d_instantiate]].
  
 ==== Crearea unui director ==== ==== Crearea unui director ====
  
-Funcția de creare de director este indicată de câmpul ''​mkdir''​ din structura ''​inode_operations''​. În cazul minix este vorba de [[http://lxr.free-electrons.com/​source/​fs/​minix/​namei.c?v=4.9#L115 | minix_mkdir]]. Această funcție este apelată în urma apelului de sistem ''​mkdir''​. O astfel de funcție realizează următoarele operații:​ +Funcția de creare de director este indicată de câmpul ''​mkdir''​ din structura ''​inode_operations''​. În cazul minix este vorba de [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​namei.c#​L116 | minix_mkdir]]. Această funcție este apelată în urma apelului de sistem ''​mkdir''​. O astfel de funcție realizează următoarele operații:​ 
-    * Apelează [[http://lxr.free-electrons.com/​source/​fs/​minix/​namei.c?v=4.9#L69 | minix_create]].+    * Apelează [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​namei.c#​L70 | minix_create]].
     * Alocă un bloc de date pentru director.     * Alocă un bloc de date pentru director.
     * Introduce intrările "​."​ și "​.."​.     * Introduce intrările "​."​ și "​.."​.
Line 367: Line 368:
 ==== Crearea unui link ==== ==== Crearea unui link ====
  
-Funcția de creare de link (hard) este indicată de câmpul ''​link''​ din structura ''​inode_operations''​. În cazul minix este vorba de [[http://lxr.free-electrons.com/​source/​fs/​minix/​namei.c?v=4.9#L104 | minix_link]]. Această funcție este apelată în urma apelului de sistem ''​link''​. O astfel de funcție realizează următoarele operații:+Funcția de creare de link (hard) este indicată de câmpul ''​link''​ din structura ''​inode_operations''​. În cazul minix este vorba de [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​namei.c#​L105 | minix_link]]. Această funcție este apelată în urma apelului de sistem ''​link''​. O astfel de funcție realizează următoarele operații:
     * Leagă dentry-ul nou la inode.     * Leagă dentry-ul nou la inode.
     * Incrementează câmpul ''​i_nlink''​ al inode-ului.     * Incrementează câmpul ''​i_nlink''​ al inode-ului.
-    * Marchează inode-ul ca murdar (dirty) cu ajutorul funcției [[http://lxr.free-electrons.com/​source/​include/​linux/​fs.h?v=4.9#L1969 | mark_inode_dirty]].+    * Marchează inode-ul ca murdar (dirty) cu ajutorul funcției [[https://elixir.bootlin.com/​linux/​v4.15/​source/​include/​linux/​fs.h#​L2012 | mark_inode_dirty]].
  
 ==== Crearea unui link simbolic ==== ==== Crearea unui link simbolic ====
  
-Funcția de creare de link (simbolic) este indicată de câmpul ''​symlink''​ din structura ''​inode_operations''​. În cazul minix este vorba de [[http://lxr.free-electrons.com/​source/​fs/​minix/​namei.c?v=4.9#L75 | minix_symlink]]. Operațiile care trebuiesc realizate sunt similare cu cele de la [[hhttp://lxr.free-electrons.com/​source/​fs/​minix/​namei.c?v=4.9#L104 | minix_link]] cu deosebirile date de faptul că se creează o legătură simbolică.+Funcția de creare de link (simbolic) este indicată de câmpul ''​symlink''​ din structura ''​inode_operations''​. În cazul minix este vorba de [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​namei.c#​L76 | minix_symlink]]. Operațiile care trebuiesc realizate sunt similare cu cele de la [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​namei.c#​L105 | minix_link]] cu deosebirile date de faptul că se creează o legătură simbolică.
  
 ==== Ștergerea unui link === ==== Ștergerea unui link ===
  
-Funcția de ștergere a unui link (hard) este indicată de câmpul ''​unlink''​ din structura ''​inode_operations''​. În cazul minix este vorba de [[http://lxr.free-electrons.com/​source/​fs/​minix/​namei.c?v=4.9#L151 | minix_unlink]]. Această funcție este apelată în urma apelului de sistem ''​unlink''​. O astfel de funcție realizează următoarele operații:+Funcția de ștergere a unui link (hard) este indicată de câmpul ''​unlink''​ din structura ''​inode_operations''​. În cazul minix este vorba de [[https://elixir.bootlin.com/​linux/​v4.15/​source/​fs/​minix/​namei.c#​L152 | minix_unlink]]. Această funcție este apelată în urma apelului de sistem ''​unlink''​. O astfel de funcție realizează următoarele operații:
   - Șterge din structura fizică a discului intrarea dată ca parametru.   - Șterge din structura fizică a discului intrarea dată ca parametru.
   - Decrementează contorul ''​i_nlink''​ al inode-ului către care puncta intrarea (altfel inode-ul nu va fi niciodată șters).   - Decrementează contorul ''​i_nlink''​ al inode-ului către care puncta intrarea (altfel inode-ul nu va fi niciodată șters).
so2/laboratoare/lab09.1524583088.txt.gz · Last modified: 2018/04/24 18:18 by anda.nicolae
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0