2011-11-23 100 views
13

我需要从给定的文件描述符中获取一个文件的名称,这个文件位于我编写的一个小型Linux内核模块中。我试着在Getting Filename from file descriptor in C给出的解决方案,但由于某种原因,它打印出垃圾值(使用解决方案中提到的/proc/self/fd/NNN上的readlink)。我该怎么做?如何从内核模块中的文件描述符获取文件名?

+0

可能重复的[sys_readlink失败EFAULT - 替代](http://stackoverflow.com/questions/8216871/sys-readlink-fails-efault-alternative) – ephemient

回答

21

不要调用SYS_readlink - 使用与procfs读取其中一个链接时相同的方法。从proc_pid_readlink()和中的代码开始fs/proc/base.c

广义上讲,给予int fd,并从你感兴趣的(你已采取的引用)的任务struct files_struct *files,你想做的事:

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); 

如果你的代码在运行过程 - 上下文(例如,通过系统调用调用)并且文件描述符来自当前进程,那么当前任务的struct files_struct *可以使用current->files

+0

不错。这工作。谢谢!尽管问题很快。 'path_get'和'path_put'调用的用途是什么(因为删除它们对我的程序没有太大影响)?另外,任何想法为什么不会'sys_readlink'工作? – Siddhant

+1

@Siddhant:'path_get()'和'path_put()'调用对于正确性是必需的,因为它们固定路径,以便在尝试使用它时不会消失(所有'struct path' contains是一对指针,指向'struct vfsmount'和'struct dentry')。 – caf

+0

啊哈。再次感谢! – Siddhant