A estrutura bufinfo_t é a abstração que descreve uma solicitação de E/S. O buffer que corresponde a uma solicitação de E/S é apontado por args[0] nos testes start, done, wait-start e wait-done. A definição da estrutura bufinfo_t é a seguinte:
typedef struct bufinfo { int b_flags; /* flags */ size_t b_bcount; /* number of bytes */ caddr_t b_addr; /* buffer address */ uint64_t b_blkno; /* expanded block # on device */ uint64_t b_lblkno; /* block # on device */ size_t b_resid; /* # of bytes not transferred */ size_t b_bufsize; /* size of allocated buffer */ caddr_t b_iodone; /* I/O completion routine */ dev_t b_edev; /* extended device */ } bufinfo_t;
O membro b_flags indica o estado do buffer de E/S e consiste em um operador bit a bit de diferentes valores de estado. Os valores de estado válidos estão na Tabela 27–3.
Tabela 27–3 Valores de b_flags
B_DONE |
Indica que a transferência de dados foi concluída. |
B_ERROR |
Indica um erro de transferência de E/S. É definido junto com o campo b_error. |
B_PAGEIO |
Indica que o buffer está sendo usado em uma solicitação de E/S paginada. Veja a descrição do campo b_addr para obter mais informações. |
B_PHYS |
Indica que o buffer está sendo usado para E/S física (direta) para uma área de dados do usuário. |
B_READ |
Indica que os dados devem ser lidos a partir do dispositivo periférico para a memória principal. |
B_WRITE |
Indica que os dados devem ser transferidos a partir da memória principal para o dispositivo periférico. |
B_ASYNC |
A solicitação de E/S é assíncrona, e não será aguardada. Os testes wait-start e wait-done não são acionados em solicitações de E/S assíncronas. Observe que algumas E/Ss direcionadas para ser assíncronas podem não ter B_ASYNC definida: o subsistema de E/S assíncrona pode implementar a solicitação assíncrona fazendo com que um segmento de trabalho separado realize uma operação de E/S síncrona. |
O campo b_bcount é o número de bytes a ser transferido como parte da solicitação de E/S.
O campo b_addr é o endereço virtual da solicitação de E/S, a menos que B_PAGEIO esteja definida. O endereço é um endereço virtual do kernel a menos que B_PHYS esteja definida. Nesse caso, é um endereço virtual do usuário. Se B_PAGEIO estiver definida, o campo b_addr contém dados privados do kernel. Exatamente um de B_PHYS e B_PAGEIO pode ser definido, ou nenhum dos sinalizadores será definido.
O campo b_lblkno identifica qual bloco lógico no dispositivo será acessado. O mapeamento de um bloco lógico para um bloco físico (como o cilindro, a trilha e assim por diante) é definido pelo dispositivo.
O campo b_resid é definido como o número de bytes não transferidos devido a um erro.
O campo b_bufsize contém o tamanho do buffer alocado.
O campo b_iodone identifica uma rotina específica no kernel que é chamada quando a E/S está concluída.
O campo b_error pode conter um código de erro retornado do driver no caso de um erro de E/S. b_error é definido com o conjunto de bits B_ERROR no membro b_flags.
O campo b_edev contém os números principal e secundário do dispositivo acessado. Os consumidores podem usar as sub-rotinas de D getmajor() e getminor() para extrair os números principal e secundário do dispositivo do campo b_edev.