GNU/Linux >> Znalost Linux >  >> Linux

Vysvětlení loff_t *offp pro file_operations

"loff_t" je "dlouhý offset", tj. pozice hledání, která sjednocuje šílenou rozmanitost off_t , off64_t , a tak dále, aby řidiči mohli používat loff_t a nemuseli se o to starat.

Samotný ukazatel v okamžiku, kdy se dostanete do ovladače, ukazuje na offset poskytnutý uživatelem (za předpokladu, že je to uživatelský kód, který přistupuje k ovladači – technicky může jádro poskytnout svůj vlastní, ale je třeba myslet na případ uživatele) přes lseek nebo llseek nebo lseek64 atd. a poté běžnými operacemi čtení a zápisu. Zvažte případ běžného souboru na disku:když poprvé open souboru, získáte (jako uživatel) jádro, které poskytne datovou strukturu, která sleduje vaši aktuální pozici v souboru, takže pokud read nebo write několik bajtů, dalších read nebo write pokračuje od místa, kde jste skončili.

Navíc, pokud dup deskriptor souboru nebo proveďte ekvivalent (např.) fork a exec z hlediska spouštění posloupnosti příkazů je tato pozice hledání sdílena všemi dědícími procesy. Proto na příkazovém řádku shellu příkaz:

(prog1; prog2; prog3) > outputfile

vytvoří výstupní soubor a poté dup je deskriptor tří programů, takže výstup je prog2 zápisy jde do souboru ihned po výstupu z prog1 a výstup z prog3 následuje další dva – to vše proto, že všechny tři samostatné procesy sdílejí stejnou základní datovou strukturu jádra se stejnou interní loff_t .

Totéž platí pro soubory ovladače zařízení. Když jsou volány vaše funkce čtení a zápisu, obdržíte „aktuální offset“, jak je poskytnuto uživatelem, a můžete (a měli byste) jej aktualizovat podle potřeby... za předpokladu, že je to potřeba (např. chcete uživatelům poskytnout vzhled běžného souboru, včetně skutečnosti, že offsety vyhledávání se pohybují při čtení a zápisu). Pokud má zařízení nějakou logickou aplikaci offsetu hledání, můžete to použít zde.

Ovladačů zařízení je toho samozřejmě mnohem víc, a proto jsou o těchto věcech celé knihy (q.v.). :-)


Torekova odpověď je skvělá. Jen přidávám trochu dalších detailů/kontextu... Z dřívějšího linuxového jádra (2.6.28), zde je příklad offsetu používaného v systémovém volání... zkopíruje offset z uživatelského prostoru do dočasné proměnné, než získá do mechanismu vyvolání ovladače jádra a poté jej zkopíruje zpět do uživatelského souboru. Tímto způsobem je offset, který ovladač vidí, oddělen od uživatelského pohledu na něj a usnadňuje situace, kdy je offset v systémovém volání NULL, takže nedochází k žádnému SEGVIO.

SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, loff_t __user *, offset, size_t, count)
{
    loff_t pos;
    ssize_t ret;

    if (offset) {
        if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
            return -EFAULT;
        ret = do_sendfile(out_fd, in_fd, &pos, count, 0);
        if (unlikely(put_user(pos, offset)))
            return -EFAULT;
        return ret;
    }

    return do_sendfile(out_fd, in_fd, NULL, count, 0);
}

Linux
  1. 20 základních příkazů Linuxu pro každého uživatele

  2. Pochopení paměti RAM pro váš cloudový server

  3. Jak zakázat konkrétní příkaz pro konkrétního uživatele v Linuxu

  1. Pochopení YAML pro Ansible

  2. Správa uživatelského hesla pro linux v puppetu

  3. určit ulimit pro uživatele root

  1. Řízení přístupu k rootless Podman pro uživatele

  2. Zakázat uživatelské prostředí z bezpečnostních důvodů?

  3. Vysvětlení souboru /etc/login.defs