下面說一下在用戶空間調用open/close/dup跟驅動中的open和release的對應。
下面是測試驅動:
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h> static int misc_demo_open(struct inode *nodp, struct file *filp)
{
printk("%s enter, nodp: %p, filp: %p.\n", __func__, nodp, filp); return ;
} static int misc_demo_release(struct inode *nodp, struct file *filp)
{
printk("%s enter, nodp: %p, filp: %p.\n", __func__, nodp, filp); return ;
} static struct file_operations misc_demo_fops = {
.owner = THIS_MODULE,
.open = misc_demo_open,
.release = misc_demo_release,
}; static struct miscdevice misc_demo_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "misc_demo",
.fops = &misc_demo_fops
}; static __init int misc_demo_init(void)
{
int ret; ret = misc_register(&misc_demo_dev); return ret;
} static __exit void misc_demo_exit(void)
{
misc_deregister(&misc_demo_dev); return;
} module_init(misc_demo_init);
module_exit(misc_demo_exit);
MODULE_LICENSE("GPL");
下面是用戶空間測試代碼:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h> int main(int argc, const char *argv[])
{
int fd[], fd2[], i; printf("Begin open.\n");
for (i=; i<; i++) {
fd[i] = open("/dev/misc_demo", O_RDONLY);
printf("open: %d\n", fd[i]);
fd2[i] = dup(fd[i]);
printf("dup: %d\n", fd2[i]);
sleep();
} sleep(); printf("Begin close.\n");
for (i=; i<; i++) {
printf("close: %d\n", fd[i]);
close(fd[i]);
sleep();
} sleep(); printf("Begin close dup.\n");
for (i=; i<; i++) {
printf("close dup: %d\n", fd2[i]);
close(fd2[i]);
sleep();
} return ;
}
下面是輸出的log:
Begin open.
[ 4628.805135] misc_demo_open enter, nodp: c3b88a18, filp: c3859060.
open:
dup:
[ 4629.809860] misc_demo_open enter, nodp: c3b88a18, filp: c3859c40.
open:
dup:
[ 4630.814891] misc_demo_open enter, nodp: c3b88a18, filp: c3859ec0.
open:
dup: Begin close.
close:
close:
close: 7 Begin close dup.
close dup:
[ 4641.845172] misc_demo_release enter, nodp: c3b88a18, filp: c3859060.
close dup:
[ 4642.850183] misc_demo_release enter, nodp: c3b88a18, filp: c3859c40.
close dup:
[ 4643.855123] misc_demo_release enter, nodp: c3b88a18, filp: c3859ec0.
通過分析log,我們得出結論, 用戶空間每調用一次open,驅動中的open都會被執行一次,而在調用dup的時候,只是將struct file的引用計數加1,而沒有產生新的struct file,所以返回的新的fd跟老的fd對應的是同一個struct file,同時也沒用調用open。在close的時候,只有struct file對應的所有fd都被關閉或者說struct file的引用計數爲0的時候,驅動中的release纔會被執行。
此外,如果將同時執行多個test程序,會發現,inode的地址都相同,說明每個文件只有一個inode與之對應。
完。