2010-12-10 18 views
5

Me parece que tmpfs no está reutilizando números de inodo, sino que crea un nuevo número de inodo a través de una secuencia +1 cada vez que necesita un inodo libre.¿Cómo se generan los números de inodo en linux tmpfs?

¿Sabe cómo esto se implementa/me puede punta de alfiler a un cierto código fuente en el que podía comprobar el algoritmo que se utiliza en tmpfs?

Necesito comprender esto para eludir una limitación en un sistema de almacenamiento en caché que utiliza el número inodo como su clave de caché (lo que provoca colisiones raras, pero que ocurren cuando los inodos se reutilizan con demasiada frecuencia). tmpfs podría salvar mi día si puedo demostrar que sigue creando números de inodos únicos.

Gracias por su ayuda,

Jerome Wagner

Respuesta

3

La mayor parte del código tmpfs está en mm/shmem.c. Nuevos inodes son creados por

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

pero delega casi todo al código genérico del sistema de archivos.

En particular, el campo i_ino se rellena en 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; 
} 

Y en efecto, sólo tiene que utilizar un contador incremental (last_ino).

La mayoría de los otros sistemas de archivos usan la información de los archivos en el disco para anular el campo después i_ino.

Tenga en cuenta que es perfectamente posible para esto para envolver completamente. El kernel también tiene un campo de "generación" que se llena de varias maneras. mm/shmem.c usa la hora actual.

+0

Gracias por excavar esto. ¿A qué te refieres con "envolverte todo el camino"? –

+1

Volver a cero cuando se produce un desbordamiento – slezica

7

No voy a responder directamente a su pregunta, así que me disculpo de antemano por eso.

La idea de tmpfs es buena, pero no quisiera que mi programa dependiera de un detalle de implementación más o menos oscuro para generar claves. ¿Por qué no prueba otro método, como combinar el número de inodo con otra información? Tal vez la fecha de modificación: es imposible que dos archivos obtengan el mismo número de inodo Y la fecha de modificación en el momento de la generación de la clave, a menos que la fecha del sistema cambie.

¡Salud!

+0

Acepto que confiar en tal impl. los detalles no parecen razonables y a prueba de futuro. El hecho es que la clave ya se basa (inode, mtime) pero como el mtime tiene una granularidad de 1 segundo, he aprendido de la peor manera que la colisión ocurre. El uso de nombre de archivo y tamaño de archivo en la clave también reduciría la probabilidad de colisión. Lo mejor en mi opinión sería eliminar la caché cuando se libera el inodo (usando algún tipo de notificación del kernel). El 'truco' de tmpfs podría aportar una solución rápida y sucia a mi problema hasta que se desarrolle y pruebe la solución real. Gracias por el consejo –

+0

Oh, entonces, lo siento por decirte lo que ya sabías y había probado xD – slezica

Cuestiones relacionadas