/*   Funkcja bread() odczytuje żądany blok i zwraca wskaźnik do nagłówka    */
/*   bufora. Jeśli odczyt jest niemożliwy zwraca NULL.                      */
/*   Parametry funkcji: dev - mumer systemu plików do którego należy żądany */
/*   blok, block - numer bloku w systemie plików, size - rozmiar czytanego  */
/*   bloku.                                                                 */


 
struct buffer_head * bread(kdev_t dev, int block, int size)
{

        /* zmienna pomocnicza w której jest przechowywany wskaźnik do */
        /* nagłówka żądanego bufora                                   */
        struct buffer_head * bh;


        /* funkcja getblk() zwraca wskaźnik do nagłówka bufora,      */
        /* jeśli znajdzie go w tablicy haszującej to wypełnia bufor  */
        /* danymi, w przeciwnym wypadku bufor jest pusty             */
        if (!(bh = getblk(dev, block, size))) {

                /* to się nie powinno zdarzyć */
                printk("VFS: bread: impossible error\n"); 
                return NULL; 
        }


        /* jeśli funkcja getblk() zwróciła bufor z danymi to jest on */
        /* zwracany dalej                                            */
        if (buffer_uptodate(bh))
                return bh;


        /* jeśli funkcja getblk() zwróciła pusty bufor to następuje */
        /* inicjacja odczytu z dyku                                 */
        ll_rw_block(READ, 1, &bh);

        
        /* zaśnięcie w oczekiwaniu na zakończenie operacji dyskowej */
        wait_on_buffer(bh);

        /* sprawdzenie, czy sprowadzanie bloku przebiegło pomyślnie */
        if (buffer_uptodate(bh))
                return bh;


        /* w przypadku niepowodzenia następuje zwolnienie bufora      */
        /* ( gdyż funkcja getblk() zwracając bufor bez danych ustawia */
        /* licznik odwołań na 1) i wartością zwracaną jest NULL       */
        brelse(bh);
        return NULL;
}
/* Jaroslaw Wawszczak */