2011-11-23 12 views
13

Necesito obtener el nombre de un archivo de un descriptor de archivo dado, dentro de un pequeño módulo de kernel de Linux que escribí. Probé la solución dada en Getting Filename from file descriptor in C, pero por alguna razón, imprime los valores de basura (en el uso de readlink en /proc/self/fd/NNN como se menciona en la solución). ¿Cómo puedo hacerlo?¿Cómo puedo obtener un nombre de archivo de un descriptor de archivo dentro de un módulo kernel?

+0

posible duplicado de [sys_readlink falla EFAULT - alternativa] (http://stackoverflow.com/questions/8216871/sys-readlink-fails-efault-alternative) – ephemient

Respuesta

21

No llame al SYS_readlink - utilice el mismo método que procfs cuando se lee uno de esos enlaces. Comience con el código en proc_pid_readlink() y proc_fd_link() en fs/proc/base.c.

En términos generales, dada una int fd y una struct files_struct *files de la tarea que le interesa (que usted ha tomado una referencia a), que desea hacer:

char *tmp; 
char *pathname; 
struct file *file; 
struct path *path; 

spin_lock(&files->file_lock); 
file = fcheck_files(files, fd); 
if (!file) { 
    spin_unlock(&files->file_lock); 
    return -ENOENT; 
} 

path = &file->f_path; 
path_get(path); 
spin_unlock(&files->file_lock); 

tmp = (char *)__get_free_page(GFP_KERNEL); 

if (!tmp) { 
    path_put(path); 
    return -ENOMEM; 
} 

pathname = d_path(path, tmp, PAGE_SIZE); 
path_put(path); 

if (IS_ERR(pathname)) { 
    free_page((unsigned long)tmp); 
    return PTR_ERR(pathname); 
} 

/* do something here with pathname */ 

free_page((unsigned long)tmp); 

Si el código se ejecuta en el proceso- contexto (por ejemplo, invocado a través de un syscall) y el descriptor de archivo es del proceso actual, luego puede usar current->files para la tarea actual struct files_struct *.

+0

Agradable. Eso funciono. ¡Gracias! Pregunta rápida sin embargo. ¿Para qué sirven las llamadas 'path_get' y' path_put' (porque eliminarlas no tiene mucho efecto en mi programa)? Además, ¿alguna idea de por qué no funcionaría 'sys_readlink'? – Siddhant

+1

@ Siddhant: Las llamadas 'path_get()' y 'path_put()' son necesarias para corregir, ya que fijan la ruta para que no desaparezca mientras tratas de trabajar con ella (todo el 'struct path' contains es un par de punteros, a 'struct vfsmount' y' struct dentry'). – caf

+0

Aha. ¡Gracias de nuevo! – Siddhant

Cuestiones relacionadas