uphysio ou uphysio_fast Kernel Service

Propósito

Executa E/S de caracteres para um dispositivo de bloco usando uma estrutura uio.

Sintaxe

#include <sys/types.h>
#include <sys/errno.h>
#include <sys/buf.h>
#include <sys/uio.h>
int uphysio (uiop, rw, buf_cnt, devno, strat, mincnt, minparms)
struct uio * uiop;
int  rw;
uint  buf_cnt;
dev_t  devno;
int (* strat)( );
int (* mincnt )( );
void * minparms;

int uphysio_fast(uiop, rw, buf_cnt, devno, strat, max_xfer, options, blk_align)
struct uio *uiop;
int rw;
uint buf_cnt;
dev_t devno;
int (* strat)( );
uint64_t max_xfer;
uint32_t options;
uint32_t blk_align;

Parâmetros

A tabela a seguir inclui os parâmetros para uphysio e uphysio_fast:

Item Descrição
uiop Aponta para o uio estrutura descrevendo o buffer de dados para transferir usando E/S de caracteres para bloquear.
rw Indica uma operação de leitura ou gravação. Um valor de B_READ para esta sinalização indica uma operação de leitura. Um valor de B_WRITE para esta sinalização indica uma operação de gravação.
buf_cnt Especifica o número máximo de buf estruturas a usar ao chamar a rotina de estratégia especificada pelo parâmetro estrat . Este parâmetro é usado para indicar a quantidade máxima de simultaneidade que o dispositivo pode suportar e minimizar o tempo de redação de E/S. O valor do parâmetro buf_cnt pode variar de 1 a 64.
devno Especifica o principais e menores números de dispositivos. Com o serviço uphysio , este parâmetro especifica o número do dispositivo a ser colocado na estrutura buf antes de chamar a rotina de estratégia especificada pelo parâmetro estrat .
estrat Representa o ponteiro da função para a rotina ddstrategy para o dispositivo.
mincnt Representa o ponteiro da função para uma rotina usada para reduzir o tamanho de transferência de dados especificado na estrutura buf , conforme requerido pelo dispositivo antes de a rotina da estratégia ser iniciada. A rotina também pode ser usada para atualizar informações de parâmetros estendidos na estrutura buf antes que as informações sejam passadas para a rotina de estratégia.
minparmos Aponta parâmetros a serem usados pelo parâmetro mincnt .
max_xfer Especifica o tamanho máximo de transferência para o dispositivo em bytes.
Opções Especifica o valor para armazenar em b_options campo de cabeçalhos de buffer.
blk_align Parâmetro opcional para impor um alinhamento de bloco mínimo em todas as transferências enviadas para a rotina de estratégia de E/S especificada. Este valor é especificado em bytes. Quando um valor diferente de zero é especificado, cada vetor de E/S será verificado para garantir que ele seja um múltiplo deste valor. A solicitação de transferência falhará se não em um limite de alinhamento. Quando um alinhamento de bloco é especificado, assume-se que o tamanho máximo de transferência, especificado pelo parâmetro max_xfer , é bloco alinhado.

Descrição

O serviço kernel uphysio ou uphysio_fast executa E/S de caracteres para um dispositivo de bloco. O serviço uphysio ou uphysio_fast tenta enviar para a rotina de estratégia especificada o número de headers buf especificados pelo parâmetro buf_cnt . Estes buf estruturas são construídos com dados de a estrutura uio especificados pelo parâmetro uiop .

O serviço uphysio ou uphysio_fast transfere inicialmente descrições de área de dados de cada umiovecelemento encontrado na estrutura uio em cabeçalhos buf individuais. Esses cabeçalhos são posteriormente enviados para a rotina de estratégia. O serviço kernel uphysio ou uphysio_fast tenta processar como muitas áreas de dados a medida que o número de cabeçalhos buf permite. Em seguida, invoca a rotina de estratégia com a lista de buf headers.

O serviço uphysio_fast usa o tamanho máximo de transferência especificado para adequar o comprimento das transferências de dados e evita o overhead de comutação de contexto encontrado com a rotina mincnt que é necessária pelo serviço uphysio . Em ambientes em que o tamanho máximo de transferência já é conhecido pelo chamador e os campos de cabeçalho do buffer não precisam ser atualizados, este serviço deve ser usado para reduzir o comprimento do I/O pathlength.

Preparando Headers de buf Individual

A rotina especificada pelo parâmetro mincnt é chamada antes do cabeçalho buf , construído a partir de umiovecelemento, é adicionado à lista de cabeçalhos buf a serem enviados para a rotina de estratégia. O parâmetro mincnt é passado um ponteiro para o cabeçalho buf juntamente com o ponteiro minparmos . Este arranjo permite que o parâmetro mincnt alfaie o comprimento da transferência de dados descrita pelo cabeçalho buf conforme requerido pelo dispositivo que executa a E/S. O parâmetro mincnt também pode modificar opcionalmente certos campos dependentes de dispositivo no cabeçalho buf .

Quando o parâmetro mincnt retorna sem erro, uma tentativa é feita para fixar o buffer de dados descrito pelo cabeçalho buf . Se a operação pin falhar devido à memória insuficiente, a área de dados descrita pelo cabeçalho buf é reduzida pela metade. O cabeçalho buf é novamente passado para o parâmetro mincnt para modificação antes de tentar fixar a área de dados reduzida.

Este processo de downsizing a transferência especificado pelo cabeçalho buf é repetido até que uma das três condições a seguir ocorra:

  • A operação pin sucede.
  • O parâmetro mincnt indica um erro.
  • O tamanho da área de dados é reduzido para 0.

Quando a memória insuficiente indica uma operação de pino falha, o número de cabeçalhos buf utilizados para o restante da operação é reduzido para 1. Isso porque tentar fixar várias áreas de dados simultaneamente sob essas condições não é desejável.

Se o usuário ainda não obteve descritores de memória cruzada, será necessário processamento adicional. (O uio_segflg campo na estrutura uio indica se o usuário já inicializou os descritores de memória cruzada. O arquivo usr/include/sys/uio.h contém informações sobre os valores possíveis para esse sinalizador.

Quando a área de dados descrita pelo cabeçalho buf foi pintada com sucesso, o serviço uphysio ou uphysio_fast verifica a autoridade de acesso do usuário para a área de dados. Ele também obtém um descritor de memória cruzada para permitir que o manipulador de dispositivos de interrupção do manipulador limpe o acesso limitado à área de dados.

Chamando a Rotina de Estratégia

Após o serviço kernel uphysio ou uphysio_fast obtiver um descritor de memória cruzada para permitir que o manipulador de interrupção do dispositivo interrompa o acesso limitado à área de dados, o cabeçalho buf é então colocado em uma lista de cabeçalhos buf a serem enviados para a rotina de estratégia especificada pelo parâmetro estrat .

A rotina de estratégia especificada pelo parâmetro estrat é chamada com a lista de cabeçalhos buf quando:

  • A lista atinge o número de estruturas buf especificadas pelo parâmetro buf_cnt .
  • A área de dados descrita pela estrutura uio foi completamente descrita por buf headers.

Os cabeçalhos buf na lista são encadeados juntos usando o av_back e av_forw campos antes de serem enviados para a rotina de estratégia.

Aguardando a Conclusão do Cabeçalho Buf

Quando todos os cabeçalhos buf disponíveis foram enviados para a rotina de estratégia, o serviço uphysio ou uphysio_fast aguarda por um ou mais dos cabeçalhos buf para ser marcado completo. O manipulador IODONE é usado para acordar o serviço uphysio ou uphysio_fast quando está esperando por completo buf headers da rotina de estratégia.

Quando o serviço uphysio ou uphysio_fast é notificado de um cabeçalho buf concluído, o buffer de dados associado é desprendido e o descritor de memória cruzada é liberado. (No entanto, o descritor de memória cruzada é liberado apenas se o usuário não o tivesse já obtido.) Um erro é detectado na transferência de dados sob as seguintes condições:

  • O cabeçalho buf concluído tem um nonzerob_resid.
  • Ob_flagscampo tem o conjunto de bandeiras B_ERROR .

Quando um erro é detectado pelo serviço uphysio ou uphysio_fast , nenhum cabeçalhos buf novos são enviados para a rotina de estratégia.

O serviço uphysio ou uphysio_fast aguarda por quaisquer cabeçalhos buf já enviados para a rotina de estratégia a ser concluído e, em seguida, retorna um código de erro para o caller. Se nenhum erro for detectado, o cabeçalho buf e quaisquer outros cabeçalhos completados buf são novamente utilizados para enviar mais pedidos de transferência de dados para a rotina de estratégia à medida que eles se tornam disponíveis. Esse processo continua até que todos os dados descritos na estrutura uio tenham sido transferidos ou até que um erro tenha sido detectado.

O serviço uphysio ou uphysio_fast retorna para o caldo quando:

  • Todos os cabeçalhos buf foram marcados por completo pela rotina de estratégia.
  • Todos os dados especificados pela estrutura uio foram transferidos.

O serviço uphysio ou uphysio_fast também retorna um código de erro para o caller se um erro for detectado.

Detecção De Erro pelo uphysio ou uphysio_fast Kernel Service

Quando detecta um erro, o serviço kernel uphysio ou uphysio_fast relata o erro detectado mais próximo do início da área de dados descrita pela estrutura uio . Nenhum cabeçalhos buf adicional é enviado para a rotina de estratégia. O serviço kernel uphysio ou uphysio_fast aguarda por todos os cabeçalhos buf enviados para a rotina de estratégia para ser marcado completo.

No entanto, cabeçalhos de buf adicionais podem ter sido enviados para a rotina de estratégia entre estes dois eventos:

  • Depois que a rotina de estratégia detecta o erro.
  • Antes que o serviço uphysio ou uphysio_fast seja notificado da condição de erro no cabeçalho buf concluído.

Quando ocorrem erros, vários campos na estrutura retornada uio podem ou não refletir o erro. Os comandosuio_ioveuio_iovcntos campos não são atualizados e contêm seus valores originais.

Os uio_resid e uio_offset campos na estrutura de uio devolvidos indicam o número de bytes transferidos pela rotina de estratégia de acordo com a soma de todos (ob_bcountcampo menos ob_residcampos) campos nos cabeçalhos buf processados pela rotina de estratégia. Esses cabeçalhos incluem o cabeçalho buf indicando o erro mais próximo do início da área de dados descrita pela estrutura original uio . Quaisquer contagens de dados em cabeçalhos buf completados após a detecção do erro não são refletidas na estrutura uio devolvida.

Ambiente de Execução

O serviço kernel uphysio ou uphysio_fast pode ser chamado a partir do ambiente de processo apenas.

Valores De Retorno

Item Descrição
0 Indica conclusão bem-sucedida.
ENOMEM Indica que nenhuma memória está disponível para os cabeçalhos buf necessários.
EAGAIN Indica que a operação falha devido a uma condição de recurso insuficiente temporária.
EFAULT Indica que ouio_segflgcampo indicado espaço do usuário e que o usuário não tem autoridade para acessar o buffer.
EIO ou o campo b_error em um cabeçalho buf Indica um erro de E/S em um cabeçalho buf processado pela rotina de estratégia.
Código de retorno do mincnt parâmetro Indica que o código de retorno do parâmetro mincnt se a rotina retornou com um código de retorno diferente de zero.