open函数如何查找file_operation结构体

1.open函数如何查找file_operation接口

在这里插入图片描述
文件描述符的本质:文件描述符的本质

1.1 get_unused_fd_flags

为本次操作分配一个未使用过的文件操作符

1.2 do_file_open

  • 生成一个空白的struct file结构体,并且绑定到空闲元素上
  • 从文件系中查找到文件对应的inode

1.3 do_dentry_open

static int do_dentry_open(                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       	
struct file *f,
struct inode *inode,
int (*open)(struct inode *, struct file *),
const struct cred *cred)
{
	...
	/*把inode的i_fop赋值给struct file的f_op*/
	f->f_op = fops_get(inode->i_fop);
	...
	if (!open)
		open = f->f_op->open;
	if (open) {
		error = open(inode, f);
		if (error)
			goto cleanup_all;
	}
	...
}

inode的f_op在上一章节有讲,

1.4 def_chr_fops->chrdev_open

/fs/char_dev.c

static int chrdev_open(struct inode *inode, struct file *filp)
{
	const struct file_operations *fops;
	struct cdev *p;
	struct cdev *new = NULL;
	...
	struct kobject *kobj;
	int idx;
	/*从内核哈希表cdev_map中,根据设备号查找自己注册的sturct cdev,获取cdev中的file_operation接口*/
	kobj = kobj_lookup(cdev_map, inode>i_rdev,&idx);
	new = container_of(kobj, struct cdev, kobj);
	...
	inode->i_cdev = p = new;
	...
	fops = fops_get(p->ops);
	...
	/*把cdev中的file_operation接口赋值给struct file的f_op*/
	replace_fops(filp, fops);
	
	/*调用自己实现的file_operation接口中的open函数*/
	if (filp->f_op->open) {
		ret = filp->f_op->open(inode, filp);
		if (ret)
			goto out_cdev_put;
	}
	...
}
ReadFile 函数是 Windows API 中用于读取文件的函数,它的原型如下: ```c++ BOOL ReadFile( HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped ); ``` 其中,参数 lpOverlapped 是一个指向 OVERLAPPED 结构体的指针,它可以用于异步 I/O 操作。如果你需要在异步 I/O 操作完成后执行特定的操作,就可以使用回调函数。 回调函数需要满足以下要求: 1. 回调函数的返回值为 void。 2. 回调函数的参数列表中应包含 DWORD 值,它表示异步 I/O 操作的结果。 3. 回调函数的参数列表中应包含 DWORD_PTR 值,它表示与异步 I/O 操作相关联的数据。 下面是一个使用回调函数的 ReadFile 示例: ```c++ #include <Windows.h> #include <iostream> void CALLBACK ReadCompletionRoutine(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped) { std::cout << "Read " << dwNumberOfBytesTransfered << " bytes from file." << std::endl; } int main() { HANDLE hFile = CreateFile(L"test.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if (hFile == INVALID_HANDLE_VALUE) { std::cerr << "Failed to open file." << std::endl; return 1; } char buffer[256]; OVERLAPPED overlapped = { 0 }; overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); BOOL result = ReadFile(hFile, buffer, sizeof(buffer), NULL, &overlapped); if (!result && GetLastError() == ERROR_IO_PENDING) { std::cout << "Asynchronous I/O operation is pending..." << std::endl; } result = GetOverlappedResult(hFile, &overlapped, NULL, TRUE); if (!result) { std::cerr << "Failed to read file." << std::endl; return 1; } ReadCompletionRoutine(0, overlapped.InternalHigh, &overlapped); CloseHandle(hFile); CloseHandle(overlapped.hEvent); return 0; } ``` 在这个示例中,我们创建了一个名为 ReadCompletionRoutine 的回调函数,并将它作为参数传递给了 ReadFile 函数。当异步 I/O 操作完成时,系统会自动调用这个回调函数,并传递异步 I/O 操作的结果。在这个示例中,我们手动调用了回调函数,以便在控制台输出读取的字节数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值