2010-12-10 15 views
5

Mi sembra che tmpfs non stia riutilizzando i numeri di inode, ma invece crea un nuovo numero di inode tramite una sequenza +1 ogni volta che ha bisogno di un inode gratuito.come vengono generati i numeri di inode in linux tmpfs?

Sapete come è implementato/potete indicarmi un codice sorgente in cui posso controllare l'algoritmo utilizzato in tmpfs?

Ho bisogno di capire questo per bypassare una limitazione in un sistema di memorizzazione nella cache che utilizza il numero di inode come sua chiave di cache (quindi porta a collisioni rari, ma che si verificano quando gli inodi vengono riutilizzati troppo spesso). tmpfs potrebbe salvare la mia giornata se posso provare che continua a creare numeri di inode unici.

Grazie per il vostro aiuto,

Jerome Wagner

risposta

3

La maggior parte del codice tmpfs è in mm/shmem.c. I nuovi inode vengono creati da

static struct inode *shmem_get_inode(struct super_block *sb, const struct inode *dir, 
           int mode, dev_t dev, unsigned long flags) 

ma delega quasi tutto al codice del file system generico.

In particolare, il campo i_ino viene compilato in fs/inode.c:

/** 
*  new_inode  - obtain an inode 
*  @sb: superblock 
* 
*  Allocates a new inode for given superblock. The default gfp_mask 
*  for allocations related to inode->i_mapping is GFP_HIGHUSER_MOVABLE. 
*  If HIGHMEM pages are unsuitable or it is known that pages allocated 
*  for the page cache are not reclaimable or migratable, 
*  mapping_set_gfp_mask() must be called with suitable flags on the 
*  newly created inode's mapping 
* 
*/ 
struct inode *new_inode(struct super_block *sb) 
{ 
     /* 
     * On a 32bit, non LFS stat() call, glibc will generate an EOVERFLOW 
     * error if st_ino won't fit in target struct field. Use 32bit counter 
     * here to attempt to avoid that. 
     */ 
     static unsigned int last_ino; 
     struct inode *inode; 

     spin_lock_prefetch(&inode_lock); 

     inode = alloc_inode(sb); 
     if (inode) { 
       spin_lock(&inode_lock); 
       __inode_add_to_lists(sb, NULL, inode); 
       inode->i_ino = ++last_ino; 
       inode->i_state = 0; 
       spin_unlock(&inode_lock); 
     } 
     return inode; 
} 

Ed effettivamente basta usare un contatore di incremento (last_ino).

La maggior parte degli altri file system utilizza le informazioni dai file su disco per in seguito ignorare il campo i_ino.

Si noti che è perfettamente possibile per questo avvolgere tutto intorno. Il kernel ha anche un campo di "generazione" che viene riempito in vari modi. mm/shmem.c utilizza l'ora corrente.

+0

Grazie per averlo scoperto. Cosa intendi con "avvolgere tutto intorno"? –

+1

Torna a zero quando si verifica un overflow – slezica

7

non risponderò direttamente alla tua domanda, quindi mi scuso in anticipo per questo.

L'idea di tmpfs è buona, ma il mio programma non dovrebbe dipendere da dettagli di implementazione più o meno oscuri per la generazione di chiavi. Perché non provi un altro metodo, come la combinazione del numero di inode con altre informazioni? Forse data di modifica: è impossibile che due file ottengano lo stesso numero di inode E la data di modifica al momento della generazione della chiave, a meno che la data di sistema non cambi.

Cheers!

+0

Sono d'accordo che fare affidamento su un tale impl. i dettagli non sembrano una prova ragionevole e futura. Il fatto è che la chiave si basa già su (inode, mtime) ma dal momento che il mtime ha una granularità di 1 secondo, ho imparato a fondo che la collisione avviene. Utilizzando il nome del file e la dimensione del file nella chiave si ridurrebbe anche la probabilità di collisione. La cosa migliore a mio parere sarebbe quella di cancellare la cache quando l'inode viene rilasciato (usando qualche tipo di notifica dal kernel). L'hack di tmpfs potrebbe portare una soluzione rapida e sporca al mio problema fino a quando la correzione reale non verrà sviluppata e testata. Grazie per il consiglio –

+0

Oh bene allora, mi dispiace per avervi detto quello che sapevate già e che avevo provato xD – slezica

Problemi correlati