IV. Initialisation d'un module de filesystem▲
Nous allons présenter ici quelques lignes de code correspondant aux actions élémentaires que tout module de filesystem effectue.
IV-A. Initialisation du module▲
Avant toute chose, il est nécessaire de rédiger l'entry point du module, qui correspond au code appelé au chargement du module.
Voici donc un exemple simple et plutôt minimaliste.
//Module Entry point
int
yfs_init_module
(
void
)
{
int
err;
printk
(
"
YFS-fs: init_module
\n
"
);
//Allocate inode cache
yfs_inode_cache =
kmem_cache_create
(
"
yfs_inode_cache
"
,
sizeof
(
struct
yfs_inode_info),
0
,
0
,
yfs_init_once);
if
(!
yfs_inode_cache)
return
-
ENOMEM;
//Register filesystem
err =
register_filesystem
(&
yfs_fs_type);
return
(
err);
}
//...
module_init
(
yfs_init_module);
On notera la création d'un cache (yfs_inode_cache est une globale) afin de disposer d'un pool mémoire pour l'allocation des inodes du filesystem. yfs_inode_info est une structure qui englobe une struct inode*, car comme précisé plus haut, nous pourrions nécessiter des données supplémentaires, telle que la position des bloques d'un fichier sur le disque.
La fonction yfs_init_once sera appelée à l'allocation d'une inode. Ici, elle se contente d'appeler inode_init_once(&inode->vfs_inode) où vfs_inode est une struct inode.
IV-B. Libération du module▲
Une fois son devoir accompli, le module doit libérer les ressources allouées, et supprimer le filesystem de la liste des fs disponibles.
Ce que font ces quelques lignes :
//Module Exit
static
void
sfs_cleanup_module
(
void
)
{
printk
(
"
SFS-fs: cleanup_module
\n
"
);
//Free inode cache
kmem_cache_destroy
(
sfs_inode_cache);
//Unregister FS
unregister_filesystem
(&
sfs_fs_type);
}
module_exit
(
sfs_cleanup_module);
IV-C. Allouer une inode▲
Afin d'illustrer une utilisation du cache créé dans l'exemple précédent, voici quelques lignes de deux fonctions d'une structure super_opérations.
struct
inode*
sfs_alloc_inode
(
struct
super_block *
sb)
{
struct
yfs_inode_info *
ii;
printk
(
KERN_DEBUG "
YFS: alloc_inode
\n
"
);
if
(!(
ii =
kmem_cache_alloc
(
yfs_inode_cache, GFP_KERNEL)))
return
NULL
;
return
&
ii->
vfs_inode;
}
static
void
yfs_destroy_inode
(
struct
inode *
inode)
{
printk
(
KERN_DEBUG "
YFS: destroy_inode
\n
"
);
kmem_cache_free
(
yfs_inode_cache, inode);
}