Wie das Einhängen und Aushängen funktioniert

Block-Geräte können im Gegensatz zu Zeichen-Geräten und normalen Dateien in das Dateisystem des Rechners eingehängt werden. Das Einhängen bringt eine weitere Abstraktionsebene mit sich, die bei Zeichen-Geräten nicht bekannt ist, wo der Zugriff über einen struct file-Zeiger erfolgt, der zu einem bestimmten Prozeß gehört. Wenn ein Dateisystem eingehängt ist, gibt es keinen Prozeß, der einen filp hält.

Wenn der Kernel ein Gerät in das Dateisystem einhängt, ruft er die normale open-Methode auf, um auf den Treiber zuzugreifen. In diesem Fall sind aber sowohl das filp-Argument als auch das inode-Argument von open nur Dummies. In der file-Struktur haben nur die Felder f_mode und f_flags eine Bedeutung; in der inode-Struktur darf nur i_rdev benutzt werden. Die anderen Felder enthalten zufällige Werte und sollten nicht verwendet werden. Der Wert von f_mode teilt dem Treiber mit, ob das Gerät nur zum Lesen (f_mode == FMODE_READ) oder zum Lesen und Schreiben (f_mode == (FMODE_READ|FMODE_WRITE)) eingehängt werden soll.

Diese Schnittstelle mag etwas merkwürdig aussehen, hat aber zwei Gründe. Zunächst kann die open-Methode weiterhin normal von einem Prozeß aufgerufen werden, der direkt auf das Gerät zugreift, wie etwa das Hilfsprogramm mkfs. Der andere Grund ist historisch bedingt: Block-Geräte benutzten früher die gleiche file_operations-Struktur wie Zeichen-Geräte und mußten daher die gleiche Schnittstelle verwenden.

Abgesehen von den Einschränkungen bezüglich der Argumente der open-Methode sieht der Treiber nichts Besonderes, wenn ein Dateisystem eingehängt wird. Das Gerät wird geöffnet, und die request-Methode wird aufgerufen, um Blocks hin- und herzutransportieren. Der Treiber kann den Unterschied zwischen Operationen, die als Antwort auf einen individuellen Prozeß (wie etwa fsck) gestartet werden, und solchen, die aus den Dateisystem-Schichten des Kernels stammen, nicht erkennen.

umount schreibt lediglich den Buffer-Cache heraus und ruft die release-Methode des Treibers auf. Weil es keinen sinnvollen filp gibt, den der Kernel an die release-Methode übergeben könnte, wird hierfür NULL verwendet. Da die release-Implementation eines Block-Treibers filp->private_data nicht verwenden kann, um auf die Geräte-Informationen zuzugreifen, wird zur Unterscheidung der Geräte inode->i_rdev verwendet. Die release-Implementation in sbull sieht wie folgt aus:


 
int sbull_release (struct inode *inode, struct file *filp)
{
    Sbull_Dev *dev = sbull_devices + MINOR(inode->i_rdev);

    spin_lock(&dev->lock);
    dev->usage--;
    MOD_DEC_USE_COUNT;
    spin_unlock(&dev->lock);
    return 0;
}

Andere Treiberfunktionen sind vom flip-Problem nicht betroffen, weil sie nichts mit dem Ein- oder Aushängen von Dateisystemen zu tun haben. Beispielsweise wird ioctl nur von Prozessen verwendet, die das Gerät explizit mit open geöffnet haben.