ďťż

IPUT.HTML

Lemur zaprasza

Do spisu treści tematu 

6.4.2 Algorytm iput 



Spis treści



 Wprowadzenie


 Skomentowany kod


 Funkcje pomocnicze


 Bibliografia 





Wprowadzenie
Jeżeli proces zakończył operację z plikiem (a więc także z i węzłem ),
musi on zwolnić
kopię pamięciową i-węzła, aby inne procesy mogły pobrać wolny i-węzeł.
Generalnie algorytm polega na zmniejszeniu licznika otwarć pliku(i_count),
oraz wykonaniu specjalnych czynności w przypadku, gdy proces jest ostatnim
zamykającym plik(i_count==0). Czynności te to:


nagranie i-węzla, jeżeli kopia pamięciowa różni się od dyskowej(specjalna
flaga)


umieszczenie i-węzła na liście wolnych i-węzłów


w razie potrzeby zwolnienie bloków dyskowych związanych z plikem

lub zwolnienie i-węzła na dysku
Algorytm ten w Linuxie 2.0.32 jest realizowany przez funkcję iput, znajdującą
się
w pliku inode.c.







 Skomentowany Kod
void iput(struct inode * inode)
{
               
if (!inode)
                       
return;
                   
Wykonaj test blokady
                  
wait_on_inode(inode);
                     
Jeżeli licznik otwarć(i_count) = 0 wyjdź;
                  
if (!inode->i_count) {
                        
printk("VFS: iput: trying to free free inode\n");
                       
printk("VFS: device %s, inode %lu, mode=0%07o\n",
                       
kdevname(inode->i_rdev), inode->i_ino, inode->i_mode);
                        
return;
                   
}
                   
Jeżeli inode jest typu PIPE, obudż wszystkie przerywalne procesy
                    
z kolejki PIPE_WAIT(*inode)
                  
if (inode->i_pipe)
                         
wake_up_interruptible(&PIPE_WAIT(*inode));
repeat:
                   
Jeżeli licznik otwarć jest > 1 to zmniejsz go o 1 i wyjdz;
               
if (inode->i_count>1) {
                    
inode->i_count--;
                    
return;
               
}
                 
Zwolnij procesy czekające na wolny i-węzel w kolejce inode_wait;
               
wake_up(&inode_wait);

                 
Jeżeli inode byl typu PIPE, zwolnij związana z nim stronę pamięci
               
if (inode->i_pipe) {
               
unsigned long page = (unsigned long) PIPE_BASE(*inode);
               
PIPE_BASE(*inode) = NULL;
                 
free_page(page);
               
}
               
Jeżeli wskaźniki do funkcji put_inode i pośrednie są OK
              
if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->put_inode)
{
                 
wykonaj  funkcje put_inode odpowiednią do systemu plików;
               
inode->i_sb->s_op->put_inode(inode);
                  
jeżeli liczba dowiązań do pliku wynosi 0, wyjdź
               
if (!inode->i_nlink)
                       
return;
        }

         Jeżeli i-węzel należy
zaktualizować
        if (inode->i_dirt) {
                
nagraj i-węzel
               
write_inode(inode);     /* we can sleep - so do again
*/
                 
wykonaj test na blokadę
               
wait_on_inode(inode);
               
goto repeat;
        }
         Jeżeli i-węzel
ma charakter nagrywalny(plik,katalog lub link) i
         są zdefiniowane
operacje na quota
        if (IS_WRITABLE(inode))
{
               
if (inode->i_sb && inode->i_sb->dq_op) {
                       
/* Here we can sleep also. Let's do it again
                        
* Dmitry Gorodchanin 02/11/96 */
                         
zalóż blokadę na inode
                       
inode->i_lock = 1;
                          
uaktualnij quotę
                       
inode->i_sb->dq_op->drop(inode);
                          
zdejmij blokadę
                       
unlock_inode(inode);
                       
goto repeat;
               
}
        }
          zmniejsz
licznik otwarć pliku
        inode->i_count--;

        if (inode->i_count)
        /*
         * Huoh, we were supposed
to be the last user, but someone has
         * grabbed it while
we were sleeping. Dont destroy inode VM
         * mappings, it might
cause a memory leak.
         */
               
return;

        if (inode->i_mmap) {
               
printk("iput: inode %lu on device %s still has mappings.\n",
                       
inode->i_ino, kdevname(inode->i_dev));
               
inode->i_mmap = NULL;
        }
          zwiększ licznik
wolnych i-węzlow
        nr_free_inodes++;
        return;
}







Funkcje pomocnicze
wait_on_inode()
jezeli flaga i_lock jest ustawiona zaśnij w kolejce zwiazanej z i-węzlem
(wait_queue)

write_inode() ( w ext2 - ext_write_inode
),
drop_inode,
put_inode (w ext2 ext2_put_inode),
są to operacje wykonywane fizycznie na dysku, zależne od konkretnego
systemu plikow,
zazwyczaj wykonywane przez super block. Czasami znajdują sie w nich
także uaktualnienia pól struktury inode, np. czasu zmian itp.


 


 Bibliografia
    1.Pliki zrodlowe Linuxa:


 /include/linux/fs.h


 /fs/inode.c


 /include/linux/ext2_fs.h


/fs/ext2/inode.c

    2.Projekt Linux
    3.Maurice J. Bach "Budowa systemu operacyjnego UNIX"
- rozdzial 4
    4.  Linux
Kernel Hackers Guide




Autor:  Tomasz Sawicki
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • teen-mushing.xlx.pl
  • Wątki
    Powered by wordpress | Theme: simpletex | © Lemur zaprasza