stat.c :
Implémentation au niveau du VFS (Virtual File System) de l'appel système ``astat''.
/*
* vfs_astat effectue une résolution du nom passé en
* paramètre (en utilisant la fonction link_path_walk)
* et récupère les informations sur le fichier pour
* remplir la structure de type ``struct kstat''
*/
int vfs_astat(char __user *name, struct kstat *stat)
{ .... }
/*
* L'appel système astat fait en fait appel à la fonction
* vfs_astat avant de recopier le résultat dans le buffer en
* mémoire utilisateur.
*
* Le comportement de astat est identique à lstat sur les liens
* et fichiers non alink. Sa particularité est de ne pas suivre
* les liens alink.
* D'après nos tests le comportement de stat sur les fichiers
* alink est correcte. lstat par contre n'essaie pas du tout de
* résoudre les alink alors que le comportement correct qui
* nous a été demandé veut que lstat s'exécute sur le programme
* d'indirection.
* Un comportement correcte demande quelques modifications de la
* fonction link_path_walk du fichier namei.c, ce que nous
* n'avons pas eu le temps de faire (et pas osé modifier au
* dernier moment de peur de tout casser, cette fonction étant
* assez complexe).
*/
asmlinkage long sys_astat(char __user * filename,
struct __old_kernel_stat __user * statbuf)
{ .... }
/*
* L'appel système readalink récupère l'inode du fichier
* passé en paramètre, et si c'est bien un fichier de
* type alink (si l'opération readalink existe sur cet
* inode), alors il exécute l'opération readalink sur
* cet inode (la fonction namei.c:page_alink est alors
* appelée).
*/
asmlinkage long sys_readalink(const char __user * path,
char __user * buf, int bufsiz)
{ .... }
EXPORT_SYMBOL(vfs_astat);
namei.c :
Implémentation au niveau du VFS (Virtual File System) des appels systèmes ``alink'' et ``readalink''.
/*
* La fonction exécute_alink prend en paramètre un fichier
* qu'elle va exécuter pour nous donner dans un buffer le
* résultat de sa sortie standard. Le fonctionnement de
* cette fonction est décrit plus en détails dans le chapitre
* ``La résolution des liens actifs''.
* Cette fonction est appelée dans vfs_readalink et
* page_follow_alink.
*/
int execute_alink(struct s_readalink *li, char *buf, int buflen)
{ .... }
/*
* La fonction page_readalink est la fonction qui est appelée
* sur un inode par l'appel système readalink pour récupérer
* la chaîne de caractères renvoyée par le programme
* d'indirection sur lequel pointe le alink.
* Cette fonction récupère le nom du programme d'indirection
* sur lequel le alink pointe (à l'aide de la fonction
* page_getlink) avant de le passer en paramètre à la
* fonction vfs_readalink qui va se charger d'exécuter le
* programme d'indirection pour récupérer le résultat qu'elle
* va recopier dans un buffer en mémoire utilisateur (à l'aide
* de la fonction copy_to_user).
*/
int page_readalink(struct dentry *dentry, char __user *buffer,
int buflen, const char __user *path)
{ .... }
/*
* La fonction vfs_readalink alloue un buffer en mémoire noyau
* d'une taille identique à celle du buffer en mémoire utilisateur
* puis appelle la fonction execute_alink pour récupérer dans ce
* buffer le résultat de l'exécution du programme d'indirection.
* Le buffer en mémoire noyau est ensuite recopié dans le buffer
* en mémoire utilisateur avant d'être libérée.
*/
int vfs_readalink(struct dentry *dentry, char __user *buffer, int buflen,
const char *link, const char __user *path)
{ .... }
/*
* La fonction link_path_walk est une fonction de résolution
* permettant de récupérer une structure dentry on lui
* fournissant un nom de fichier et quelques flags pour lui
* demander ou non de résoudre les link et alink finaux
* (les appels systèmes stat, astat et lstat appellent tous
* les trois cette même fonction en fournissant des flags
* différents).
* Nous avons eu à rajouter dans cette fonction quelques
* appellent à la fonction do_follow_alink permettant de
* résoudre un alink.
*/
int fastcall link_path_walk(const char * name, struct nameidata *nd)
{ .... }
/*
* La fonction do_follow_link est chargée de résoudre un alink.
* Pour cela elle commence par incrémenter quelques compteur
* permettant de faire des testes pour éviter les boucles
* qui pourraient être crées par des link ou alink qui pointent
* sur d'autres link ou alink formant une boucle.
* Elle execute ensuite l'opération follow_alink de l'inode,
* qui est en fait un appel à la fonction page_follow_alink.
*/
static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
{ .... }
/*
* La fonction page_follow_alink récupère le nom du programme
* d'indirection à l'aide de la fonction page_getlink, alloue
* un buffer et appelle execute_alink sur ce buffer et le
* nom du programme d'indirection.
*/
int page_follow_alink(struct dentry *dentry, struct nameidata *nd)
{ .... }
/*
* Cet appel système permet de créer un alink (fonctionnement
* identique à l'appel système de création de lien.
*/
asmlinkage long sys_alink(const char __user * oldname,
const char __user * newname)
{ .... }
EXPORT_SYMBOL(vfs_alink);
EXPORT_SYMBOL(vfs_readalink);
EXPORT_SYMBOL(page_alink);
EXPORT_SYMBOL(page_follow_alink);
EXPORT_SYMBOL(page_readalink);