uphysio oder uphysio_fast Kernel Service

Zweck

Führt Zeichen-E/A für eine Blockeinheit mit UIO -Strukturaus.

Syntax

#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;

Parameter

Die folgende Tabelle enthält die Parameter für Uphysio und uphysio_schnell:

Element Beschreibung
Uiop Verweist auf den UIO -Struktur , der den Puffer der Daten beschreibt, die mithilfe der Zeichen-zu-Block-E/A übertragen werden sollen.
rw Gibt eine Lese-oder Schreiboperation an. Der Wert B_READ (FEHLERHAFT) für dieses Flag gibt eine Leseoperation an. Der Wert B_Schreiben für dieses Flag gibt eine Schreiboperation an.
Buf_cnt Gibt die maximale Anzahl von Buf -Strukturen an, die verwendet werden soll, wenn die im Parameter Strat angegebene Strategieroutine aufgerufen wird. Dieser Parameter wird verwendet, um den maximalen Umfang des gemeinsamen Zugriffs anzugeben, den die Einheit unterstützen kann, und um die Zeit für das erneute E/A-Laufwerk zu minimieren. Der Wert des Parameters Buf_cnt kann zwischen 1 und 64 liegen.
Devno Gibt die Major-und Minor-Einheitennummernan. Beim Service Uphysio gibt dieser Parameter die Einheitennummer an, die in die Struktur Buf eingefügt werden soll, bevor die durch den Parameter Strat angegebene StrategiRoutine aufgerufen wird.
Strat Stellt den Funktionszeiger auf die Datendefinitionsstrategie -Routine für die Einheit dar
Mindestzahl Stellt den Funktionszeiger auf eine Routine dar, die verwendet wird, um die in der Buf -Struktur angegebene Datenübertragungsgröße zu reduzieren, wie von der Einheit gefordert, bevor die Strategioutine gestartet wird. Die Routine kann auch verwendet werden, um erweiterte Parameterinformationen in der Struktur Buf zu aktualisieren, bevor die Informationen an die Strategioutine übergeben werden.
Minparms Verweist auf Parameter, die vom Parameter Mindestzahl verwendet werden.
max_xfer Gibt die maximale Übertragungsgröße für die Einheit in Byte an
Optionen Gibt den Wert an, der im Feld b_optionen der Pufferheader gespeichert werden soll.
Blk_align Optionaler Parameter zum Erzwingen einer minimalen Blockausrichtung für alle Übertragungen, die an die angegebene E/A-Strategieroutine gesendet werden. Dieser Wert wird in Byte angegeben. Wenn ein Wert ungleich null angegeben wird, wird jeder E/A-Vektor überprüft, um sicherzustellen, dass er ein Vielfaches dieses Werts ist. Die Übertragungsanforderung schlägt fehl, wenn sie sich nicht an einer Ausrichtungsgrenze befindet. Wenn eine Blockausrichtung angegeben wird, wird davon ausgegangen, dass die mit dem Parameter max_xfer angegebene maximale Übertragungsgröße blockorientiert ist.

Beschreibung

Der Kernel-Service Uphysio oder uphysio_schnell führt Zeichenorientierte Ein-/Ausgabe für eine Blockeinheit aus. Der Service Uphysio oder uphysio_schnell versucht, die mit dem Parameter Buf_cnt angegebene Anzahl von Buf -Headern an die angegebene Strategieroutine zu senden. Diese Buf -Strukturen werden mit Daten aus Struktur UIO erstellt, die durch den Parameter Uiop angegeben werden.

Der Uphysio -oder uphysio_schnell -Service überträgt anfänglich Datenbereichsbeschreibungen von jedemiovecElement in der Struktur UIO in einzelnen Buf -Headern gefunden. Diese Header werden später an die Strategioutine gesendet. Der Kernel-Service Uphysio oder uphysio_schnell versucht, so viele Datenbereiche zu verarbeiten, wie die Anzahl der Buf -Header zulässt. Anschließend ruft er die Strategieroutine mit der Liste der Buf -Header auf.

Der uphysio_schnell -Service verwendet die angegebene maximale Übertragungsgröße, um die Länge von Datenübertragungen anzupassen, und vermeidet den Aufwand für Kontextwechsel, der bei der Mindestzahl -Routine auftritt, die für den Uphysio -Service erforderlich ist. In Umgebungen, in denen die maximale Übertragungsgröße dem aufrufenden Programm bereits bekannt ist und die Pufferheaderfelder nicht aktualisiert werden müssen, sollte dieser Service verwendet werden, um die E/A-Pfadlänge zu reduzieren.

Einzelne Buf-header Vorbereiten

Die durch den Parameter Mindestzahl angegebene Routine wird vor dem Header Buf aufgerufen, der aus einemiovecwird der Liste der Buf -Header hinzugefügt, die an die Strategieroutine gesendet werden. Der Parameter Mindestzahl wird zusammen mit dem Zeiger Minparms an den Header Buf übergeben. Diese Anordnung ermöglicht es dem Parameter Mindestzahl , die Länge der Datenübertragung anzupassen, die durch den Header Buf beschrieben wird, wie von der Einheit, die die Ein-/Ausgabe ausführt, benötigt wird. Der Parameter Mindestzahl kann optional auch bestimmte einheitenabhängige Felder im Header Buf ändern.

Wenn der Parameter Mindestzahl ohne Fehler zurückgegeben wird, wird versucht, den im Header Buf beschriebenen Datenpuffer zu fixieren. Wenn die PIN-Operation aufgrund von nicht ausreichendem Speicher fehlschlägt, wird der durch den Header Buf beschriebene Datenbereich um die Hälfte reduziert. Der Header Buf wird erneut zur Änderung an den Parameter Mindestzahl übergeben, bevor versucht wird, den reduzierten Datenbereich zu fixieren.

Dieser Prozess zum Herabstufen der im Header Buf angegebenen Übertragung wird wiederholt, bis eine der drei folgenden Bedingungen eintritt:

  • Die PIN-Operation ist erfolgreich.
  • Der Parameter Mindestzahl gibt einen Fehler an.
  • Die Größe des Datenbereichs wird auf 0 reduziert.

Wenn nicht genügend Speicher auf eine fehlgeschlagene PIN-Operation hinweist, wird die Anzahl der Buf -Header, die für den Rest der Operation verwendet werden, auf 1 reduziert. Dies liegt daran, dass es nicht wünschenswert ist, mehrere Datenbereiche gleichzeitig unter diesen Bedingungen zu fixieren.

Wenn der Benutzer noch keine speicherübergreifenden Deskriptoren abgerufen hat, ist eine weitere Verarbeitung erforderlich. (Die uio_segflgDas Feld in der Struktur UIO gibt an, ob der Benutzer die speicherübergreifenden Deskriptoren bereits initialisiert hat. Die Datei usr/include/sys/uio.h enthält Informationen zu möglichen Werten für dieses Flag.

Wenn der im Header Buf beschriebene Datenbereich erfolgreich fixiert wurde, überprüft der Service Uphysio oder uphysio_schnell die Benutzerzugriffsberechtigung für den Datenbereich. Außerdem erhält sie einen speicherübergreifenden Deskriptor, um dem Interrupt-Handler des Einheitentreibers eingeschränkten Zugriff auf den Datenbereich zu ermöglichen.

Strategieroutine aufrufen

Nachdem der Kernel-Service Uphysio oder uphysio_schnell einen speicherübergreifenden Deskriptor abgerufen hat, um dem Unterbrechungshandler des Einheitentreibers eingeschränkten Zugriff auf den Datenbereich zu ermöglichen, wird der Header Buf in eine Liste von Buf -Headern gestellt, die an die mit dem Parameter Strat angegebene Strategieroutine gesendet werden sollen.

Die im Parameter Strat angegebene Strategieroutine wird in folgenden Fällen mit der Liste der Buf -Header aufgerufen:

  • Die Liste erreicht die mit dem Parameter Buf_cnt angegebene Anzahl von Buf -Strukturen.
  • Der durch die UIO -Struktur beschriebene Datenbereich wurde vollständig durch Buf -Header beschrieben.

Die Buf -Header in der Liste werden mithilfe der av_back und av_forw -Felder, bevor sie an die Strategioutine gesendet werden.

Warten auf Abschluss des Buf-Headers

Wenn alle verfügbaren Buf -Header an die Strategieroutine gesendet wurden, wartet der Service Uphysio oder uphysio_schnell darauf, dass mindestens einer der Buf -Header als abgeschlossen markiert wird. Der Handler IODONE wird verwendet, um den Service Uphysio oder uphysio_schnell zu aktivieren, wenn er auf abgeschlossene Buf -Header aus der Strategieroutine wartet.

Wenn der Service Uphysio oder uphysio_schnell über einen abgeschlossenen Buf -Header benachrichtigt wird, wird die Fixierung des zugehörigen Datenpuffers aufgehoben und der speicherübergreifende Deskriptor freigegeben. (Der speicherübergreifende Deskriptor wird jedoch nur freigegeben, wenn er noch nicht vom Benutzer abgerufen wurde) Unter den folgenden Bedingungen wird bei der Datenübertragung ein Fehler festgestellt:

  • Der fertige Buf -Header hat einen Wert ungleich nullb_residFeld.
  • Dieb_flagshat das Flag B_FEHLER gesetzt.

Wenn der Service Uphysio oder uphysio_schnell einen Fehler feststellt, werden keine neuen Buf -Header an die Strategioutine gesendet.

Der Service Uphysio oder uphysio_schnell wartet, bis alle Buf -Header, die bereits an die Strategioutine gesendet wurden, abgeschlossen sind, und gibt dann einen Fehlercode an den Aufrufenden zurück. Wenn keine Fehler erkannt werden, werden der Header Buf und alle anderen abgeschlossenen Buf -Header erneut verwendet, um weitere Datenübertragungsanforderungen an die Strategieroutine zu senden, sobald sie verfügbar sind. Dieser Prozess wird fortgesetzt, bis alle in der Struktur UIO beschriebenen Daten übertragen wurden oder ein Fehler festgestellt wurde.

Der Service Uphysio oder uphysio_schnell kehrt in den folgenden Fällen zum Aufrufenden zurück:

  • Alle Buf Header wurden von der Strategioutine als abgeschlossen markiert.
  • Alle von der Struktur UIO angegebenen Daten wurden übertragen.

Der Service Uphysio oder uphysio_schnell gibt auch einen Fehlercode an den Aufrufenden zurück, wenn ein Fehler festgestellt wird.

Fehlererkennung durch uphysio oder uphysio_fast Kernel Service

Wenn er einen Fehler erkennt, meldet der Uphysio -oder uphysio_schnell -Kernel-Service den Fehler, der am nächsten am Anfang des Datenbereichs erkannt wurde, der von der Struktur UIO beschrieben wird. Es werden keine zusätzlichen Buf -Header an die StrategiRoutine gesendet. Der Kernel-Service Uphysio oder uphysio_schnell wartet darauf, dass alle Buf -Header, die an die Strategioutine gesendet werden, als abgeschlossen markiert werden.

Zwischen diesen beiden Ereignissen können jedoch zusätzliche Buf -Header an die Strategioutine gesendet worden sein:

  • Nachdem die Strategioutine den Fehler erkannt hat.
  • Bevor der Service Uphysio oder uphysio_schnell über die Fehlerbedingung im abgeschlossenen Header Buf benachrichtigt wird.

Wenn Fehler auftreten, können verschiedene Felder in der zurückgegebenen UIO -Struktur den Fehler widerspiegeln oder nicht. Deruio_iovunduio_iovcntFelder werden nicht aktualisiert und enthalten ihre ursprünglichen Werte.

Die uio_resid und uio_offset -Felder in der zurückgegebenen UIO -Struktur geben die Anzahl der Byte an, die von der Strategieroutine entsprechend der Summe allerb_bcountFeld minus derb_residFelder) in den Buf -Headern, die von der Strategioutine verarbeitet werden. Diese Header enthalten den Header Buf , der den Fehler angibt, der am nächsten am Anfang des Datenbereichs liegt, der von der ursprünglichen Struktur UIO beschrieben wird. Alle Datenzahlen in Buf -Headern, die nach der Erkennung des Fehlers abgeschlossen wurden, werden nicht in der zurückgegebenen UIO -Struktur wiedergegeben.

Ausführungsumgebung

Der Kernel-Service Uphysio oder uphysio_schnell kann nur über Prozessumgebung aufgerufen werden.

Rückgabewerte

Element Beschreibung
0 Erfolgreiche Ausführung.
ENOMEM Gibt an, dass für die erforderlichen Buf -Header kein Speicher verfügbar ist.
EAGAIN Gibt an, dass die Operation aufgrund einer temporären unzureichenden Ressourcenbedingung fehlschlägt.
EFAULT Gibt an, dass dieuio_segflgDas Feld zeigt den Benutzeradressbereich an und der Benutzer hat keine Berechtigung für den Zugriff auf den Puffer.
EIO oder das Feld b_error in einem Buf-Header Zeigt einen E/A-Fehler in einem Buf -Header an, der von der Strategioutine verarbeitet wurde.
Rückkehrcode von Mindestzahl Parameter Gibt den Rückkehrcode des Parameters Mindestzahl an, wenn die Routine mit einem Rückkehrcode ungleich null zurückgegeben wurde.