GNU/Linux >> Linux Esercitazione >  >> Linux

Linux:in che modo Linux assegna numeri di inode a filesystem non basati su inode?

Questo è l'output di ls -li comando sul filesystem VFAT.

% ls -li
合計 736
1207 drwxr-xr-x 3 root root  16384  3月 10 10:42 efi
1208 -rwxr-xr-x 1 root root 721720  3月 22 14:15 kernel.bin

1207 e 1208 sono i numeri di inode della directory e del file. Tuttavia, il filesystem VFAT non ha il concetto di inode.

In che modo Linux assegna i numeri di inode ai file su un filesystem che non ha la nozione di inode?

Risposta accettata:

tl;dr:per filesystem virtuali, volatili o indipendenti dall'inode, i numeri di inode vengono generalmente generati da un contatore a 32 bit a incremento monotono quando viene creato l'inode. Il resto dell'inode (es. permessi) viene compilato dai dati equivalenti nel filesystem sottostante, o viene sostituito con valori impostati al momento del montaggio (es. {uid,gid}= ) se tale concetto non esiste.

Per rispondere alla domanda nel titolo (cioè astrattamente, come Linux alloca i numeri di inode per un filesystem che non ha il concetto di inode), dipende dal filesystem. Per alcuni filesystem virtuali o inode, il numero di inode viene estratto al momento dell'istanza da get_next_ino piscina. Questo ha una serie di problemi, però:

  1. get_next_ino() utilizza numeri di inode a 32 bit anche su un kernel a 64 bit, a causa della gestione legacy per userland a 32 bit senza _FILE_OFFSET_BITS=64;
  2. get_next_ino() è solo un contatore a incremento globale utilizzato da più filesystem, quindi il rischio di overflow è ulteriormente aumentato.

Problemi come questo sono uno dei motivi per cui ho spostato tmpfs lontano da get_next_ino-backed inodes l'anno scorso.

Per questo motivo, tmpfs in particolare è un'eccezione dalla maggior parte dei formati di filesystem volatili o "inodeless". Prese, pipe, rampe e simili usano ancora get_next_ino pool a partire dal 5.11.

Per quanto riguarda la tua domanda specifica sui filesystem FAT:fs/fat/inode.c è dove vengono assegnati i numeri di inode per i vilesystem FAT. Se guardiamo lì dentro, vediamo fat_build_inode (fonte):

struct inode *fat_build_inode(struct super_block *sb,
                              struct msdos_dir_entry *de, loff_t i_pos)
{
        struct inode *inode;
        int err;

        fat_lock_build_inode(MSDOS_SB(sb));
        inode = fat_iget(sb, i_pos);
        if (inode)
                goto out;
        inode = new_inode(sb);
        if (!inode) {
                inode = ERR_PTR(-ENOMEM);
                goto out;
        }
        inode->i_ino = iunique(sb, MSDOS_ROOT_INO);
        inode_set_iversion(inode, 1);
        err = fat_fill_inode(inode, de);
        if (err) {
                iput(inode);
                inode = ERR_PTR(err);
                goto out;
        }
        fat_attach(inode, i_pos);
        insert_inode_hash(inode);
out:
        fat_unlock_build_inode(MSDOS_SB(sb));
        return inode;
}

Ciò che in pratica dice è questo:

  1. Prendete il blocco per la creazione dell'inode FAT per questo superblocco.
  2. Verifica se l'inode esiste già in questa posizione nel superblocco. In tal caso, sblocca e restituisci quell'inode.
  3. Altrimenti, crea un nuovo inode.
  4. Ottieni il numero di inode da iunique(sb, MSDOS_ROOT_INO) (ne parleremo più in un secondo).
  5. Riempi il resto dell'inode dalle strutture dati FAT equivalenti.

inode->i_ino = iunique(sb, MSDOS_ROOT_INO); è dove è impostato il numero di inode qui. iunique (source) è una funzione fs-agnostic che fornisce numeri di inode univoci per un dato superblocco. Lo fa utilizzando una tabella hash basata su superblock + inode, con un contatore che aumenta in modo monotono:

ino_t iunique(struct super_block *sb, ino_t max_reserved)
{
        static DEFINE_SPINLOCK(iunique_lock);
        static unsigned int counter;
        ino_t res;

        rcu_read_lock();
        spin_lock(&iunique_lock);
        do {
                if (counter <= max_reserved)
                        counter = max_reserved + 1;
                res = counter++;
        } while (!test_inode_iunique(sb, res)); /* nb: this checks the hash table */
        spin_unlock(&iunique_lock);
        rcu_read_unlock();

        return res;
}

Sotto questo aspetto, è abbastanza simile al già citato get_next_ino :solo per superblocco invece di essere globale (come per tubi, prese o simili) e con una protezione rudimentale basata su tabelle hash contro le collisioni. Eredita persino get_next_ino Il comportamento di utilizzo dei numeri di inode a 32 bit come metodo per cercare di evitare EOVERFLOW su applicazioni legacy, quindi è probabile che ci saranno più filesystem che necessitano di correzioni di inode a 64 bit (come il mio già citato inode64 implementazione per tmpfs) in futuro.

Correlati:Linux – Come aggiungere a un file come sudo?

Quindi per riassumere:

  1. La maggior parte dei filesystem virtuali o inode utilizzano un contatore ad incremento monotono per il numero di inode.
  2. Quel contatore non è stabile nemmeno per i filesystem inodeless su disco*. Può cambiare senza altre modifiche al filesystem al momento del rimontaggio.
  3. La maggior parte dei filesystem in questo stato (tranne tmpfs con inode64 ) utilizzano ancora contatori a 32 bit, quindi con un uso intenso è del tutto possibile che il contatore possa traboccare e potresti ritrovarti con inode duplicati.

* ...sebbene, per essere onesti, per contratto questo è vero anche per i filesystem che fanno avere un concetto di inode quando i_generation cambia — è solo meno probabile che accada in pratica poiché spesso il numero di inode è correlato alla sua posizione fisica o simili.


Linux
  1. Come assegnare l'output di un comando Linux a una variabile

  2. Inode e il filesystem di Linux

  3. Linux – Perché Setuid non funziona??

  4. Linux:come si controllano le informazioni sulla struttura delle directory di un file Unix/linux?

  5. Linux – Ldd non trova il percorso, come aggiungere?

Come trovare file basati su timestamp in Linux

Come elencare i filesystem in Linux con lfs

Linux:come funziona il display di Linux?

Come funziona la memoria di scambio in Linux?

Cosa sono gli inode in Linux?

Come funziona il display di Linux?