Do spisu tresci tematu 6

6.8 Funkcja Mknod()




Spis tresci


Wywolanie

#include 
#include 

int mknod(sciezka, tryb, nrurz)
   char *sciezka;    /* nazwa pliku
   char *tryb;       /* tryb pliku
   int  nrurz;       /* numer urzadzenia

/* W przypadku powodzenia zwraca 0, bledu -1 */

Informacje ogolne

Funkcja systemowa mknod umozliwia tworzenie plikow dowolnego rodzaju. Bieze sie pod uwage wszystkich 16 bitow trybu tego pliku, okreslonego parametrem tryb. Tworzac plik specjalny nalezy okreslic numer urzadzenia bedacy indeksem tablicy jadra systemu, ktora zawiera inforacje o podprogramach obslugi urzadzen. Numer urzadzenia sklada sie z drugorzednego i glownego numeru urzadzenia.
Funkcji mknod uzywa sie do stworzenia pliku specjalnego tylko wowczas, gdy w systemie jest instalowany nowy podprogram obslugi urzadzen lub gdy nowy drugorzedny numer urzadzenia staje sie aktywny. Wraz z ustaleniem konfiguracji systemu funkcja mknod przestaje miec znaczenie w odniesieniu do plikow specjalnych.
Z wyjatkiem tworzenia kolejek FIFO, wylacznie nadzorca moze wykonywac funkcje mknod.

W odroznieniu do Unix'a, gdzie funkcja mknod jest wykorzystywana do tworzenia katalogow. W systemie Linux jest zdefiniowana oddzielna funkcja do tworzenia katalogow.



Struktury danych


Wprowadzenie

Glowna struktura danych na ktorej dokonywane sa operacje dla funkcji mknod jest sturktura i-wezla (inode).


Struktura inode (przypomnienie)

Oto dokladna definicja struktury inode z pliku include/linux/fs.h:

struct inode {
	kdev_t		i_dev;
	unsigned long	i_ino;
	umode_t		i_mode;
	nlink_t		i_nlink;
	uid_t		i_uid;
	gid_t		i_gid;
	kdev_t		i_rdev;
	off_t		i_size;
	time_t		i_atime;
	time_t		i_mtime;
	time_t		i_ctime;
	unsigned long	i_blksize;
	unsigned long	i_blocks;
	unsigned long	i_version;
	unsigned long	i_nrpages;
	struct semaphore i_sem;
	struct inode_operations *i_op;
	struct super_block *i_sb;
	struct wait_queue *i_wait;
	struct file_lock *i_flock;
	struct vm_area_struct *i_mmap;
	struct page *i_pages;
	struct dquot *i_dquot[MAXQUOTAS];
	struct inode *i_next, *i_prev;
	struct inode *i_hash_next, *i_hash_prev;
	struct inode *i_bound_to, *i_bound_by;
	struct inode *i_mount;
	unsigned short i_count;
	unsigned short i_flags;
	unsigned char i_lock;
	unsigned char i_dirt;
	unsigned char i_pipe;
	unsigned char i_sock;
	unsigned char i_seek;
	unsigned char i_update;
	unsigned short i_writecount;
	union {
		struct pipe_inode_info pipe_i;
		struct minix_inode_info minix_i;
		struct ext_inode_info ext_i;
		struct ext2_inode_info ext2_i;
		struct hpfs_inode_info hpfs_i;
		struct msdos_inode_info msdos_i;
		struct umsdos_inode_info umsdos_i;
		struct iso_inode_info isofs_i;
		struct nfs_inode_info nfs_i;
		struct xiafs_inode_info xiafs_i;
		struct sysv_inode_info sysv_i;
		struct affs_inode_info affs_i;
		struct ufs_inode_info ufs_i;
		struct socket socket_i;
		void * generic_ip;
	} u;
};


Implementacja


Wprowadzenie

Kod zrodlowy tej funkcji znajduje sie w pliku linux/fs/namei.c, a czesc zalezaca bezposrednio od konkretnego systemu plikow w jednym z podkatalogow w katalogu lunux/fs. Opisany nizej algorytm opiera sie na systemie plikow ext2. I algorytm jest zdefiniowany w pliku linux/fs/ext2/namei.c.
Procedura sys_mknod (opisana ponizej) jest wykonywana w trybie jadra systemu.

Funkcja sys_mknod()

DEFINICJA: asmlinkage int sys_mknod(filename, mode, dev)
                   const char *filename;
                   int mode;
                   dev_t dev;
    WYNIK: 0 w przypadku sukcesu, -1 wpp.

{
 Sprawdz czy plik jest katalogiem
    Jezeli tak to blad;
 Jezeli plik nie jest kolejka FIFO
  i urzytkownik nie jst super urzytkownikiem 
    to zwroc rowniez blad;
 Sprawdz czy typ pliku specjalnego jest dostepny w systemie
    (jezeli nie zostanie podany domyslnie przyjmowany jest 
     jako plik);
 Zapisz plik do pamieci jadra systemu;
 Wywolaj funkcje do_mknod();
 Zwolnij i-wezel katalogu macierzystego;
}

Funkcja do_mknod()

DEFINICJA: int do_mknod(filename, mode, dev)
                   const char *filename;
                   int mode;
                   dev_t dev;
    WYNIK: 0 w przypadku sukcesu, -1 wpp.

{
   Pobierz i-wezel katalogu macierzystego (funkcja dir_namei);
   Sprawdz czy katalog nie jest wylacznie przeznaczony do odczytu (IS_RDONLY());
   Sprawdz czy katalog posiada prawa do pisania (MAY_WRITE) 
      i wykonywania (MAY_EXEC);
   Sprawdz czy w systemie plikow katalogu macierzystego jest dostepna operacja
      mknod;
   Zwieksz licznik dowiazan plikow w katalogu macierzystym;
   Blokuj katalog macierzysty (opuszczenie semafora)(down(&dir->i_sem));
   Wywolaj funkcje ext2_mknod() (charakterystyczna dla systemu plikow);
   Odblokuj katalog macierzysty (up(&dir->i_sem));
   Zwolnij i-wezel katalogu macierzystego;
}

Funkcja ext2_mknod()

DEFINICJA: int ext2_mknod(dir, name, len, mode, rdev)
                   struct inode *dir;
                   const char *name;
                   int len;
                   int mode;
                   int rdev;

    WYNIK: 0 w przypadku sukcesu, -1 wpp.

{
 Szukaj w danym katalogu pliku o poszukiwanej nazwie 
    (ext2_find_entry). Zwroc znaleziony bufor.
   Jezeli znaleziony zwroc blad.
 Utworz i inicjuj nowy i-wezel.
  W razie bledu zwolnij i-wezel katalogu macierzystego i zwroc blad;
 Ustaw identyfikator wlasciciela pliku;
 Ustaw prawa do pliku;
 Okresl operacje w zaleznosci od pliku specjalnego;
 Dodaj plik do danego katalogu (ext2_add_entry).
 Jezeli plik jest synchronizowany zapisz informacje z bufora do
    urzadzenia;
 Zwolnij bufor;
 Zwolnij i-wezel katalogu macierzystego;
 Zwolnij nowo powstaly i-wezel;
}


Bibliografia

  1. Pliki zrodlowe Linuxa:
  2. Bach J.M., Budowa systemu operacyjnego Unix
  3. Rochkind M.J., Programowanie w systemie Unix dla zaawansowanych


Pytania i odpowiedzi

Prosze kierowac pytania pod moim adresem dotyczace danego tematu na ktore postaram sie odpowiedziec. Odpowiedzi prosze szukac wlasnie w tym miejscu.


Autor: Piotr Kawczynski