正在更新的内容都放到这篇文章中,等到有些知识点达到一定量时,会把这些知识点整理成专门的一章。
请求处理过程:
// 请求是struct smb_rqst *rqst->rq_iov, 回复是struct kvec *resp_iov
compound_send_recv// ses->server->ops->setup_request
smb2_setup_request
smb2_get_mid_entry
smb2_mid_entry_alloc// 加到队列中
list_add_tail(&(*mid)->qhead, &server->pending_mid_q);// 状态设置成已提交
midQ[i]->mid_state = MID_REQUEST_SUBMITTED
smb_send_rqst
__smb_send_rqst
smb_send_kvec
wait_for_response// 状态要为已接收,在dequeue_mid()中设置
midQ->mid_state != MID_RESPONSE_RECEIVED// 回复的内容
char *)midQ[i]->resp_buf buf = (
回复处理过程:
kthread
cifs_demultiplex_thread// server->ops->find_mid
smb2_find_mid
__smb2_find_mid// 从pending_mid_q链表中找
list_for_each_entry
standard_receive3
cifs_handle_standard
handle_mid
dequeue_mid// 状态设置成已接收
mid->mid_state = MID_RESPONSE_RECEIVED// 在锁的保护下从链表中删除(可能是pending_mid_q链表也可能是retry_list链表)
list_del_init(&mid->qhead)
打开文件处理过程:
// vfs的流程
openat
do_sys_open
do_sys_openat2
do_filp_open
path_openat
open_last_lookups
lookup_open
atomic_open
// smb流程
atomic_open
cifs_atomic_open
cifs_lookup
cifs_get_inode_info
cifs_get_fattr
smb2_query_path_info
smb2_compound_op
cifs_do_create
smb2_open_file
SMB2_open cifs_send_recv
读文件处理过程:
read_pages
netfs_readahead
netfs_begin_read
netfs_rreq_submit_slice
netfs_read_from_server
cifs_req_issue_read
smb2_async_readv
cifs_call_async
mid->receive = receive
mid->callback = callback
kthread
cifs_demultiplex_thread// mids[0]->receive
cifs_readv_receive // mids[i]->callback smb2_readv_callback
写文件处理过程:
do_writepages
netfs_writepages
netfs_write_folio
netfs_advance_write
netfs_issue_write
netfs_do_issue_write
cifs_issue_write
smb2_async_writev
cifs_call_async
kthread
cifs_demultiplex_thread// mids[i]->callback smb2_writev_callback
挂载:
mount
do_mount
path_mount
do_new_mount
vfs_parse_fs_string
vfs_parse_fs_param
smb3_fs_context_parse_param
parse_monolithic_mount_data
smb3_fs_context_parse_monolithicwhile ((key = strsep(&options, ",")) != NULL) {
vfs_parse_fs_string
vfs_parse_fs_param smb3_fs_context_parse_param
lock.c
文件如下:
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main() {
int fd = open("/mnt/file", O_RDWR);
if (fd == -1) {
"Failed to open file");
perror(return 1;
}
struct flock fl;
// 写锁
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;0;
fl.l_start = 0; // 锁定整个文件
fl.l_len =
if (fcntl(fd, F_SETLK, &fl) == -1) {
"Failed to lock file");
perror(
close(fd);return 1;
}
"File locked. Press Enter to unlock...");
printf(
getchar();
// 解锁
fl.l_type = F_UNLCK; if (fcntl(fd, F_SETLK, &fl) == -1) {
"Failed to unlock file");
perror(
}
close(fd);return 0;
}
lock.c
文件还可以用flock()
函数:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/file.h>
int main(int argc, char *argv[]) {
const char file_path = "/mnt/file";
int fd = open(file_path, O_RDWR);
if (fd == -1) {
"Error: open %s\n", file_path);
printf(
exit(EXIT_FAILURE);
}"open succ %s\n", file_path);
printf(
int res = flock(fd, LOCK_SH);
if (res == -1) {
"Error: flock %s\n", file_path);
printf(
close(fd);
exit(EXIT_FAILURE);
}"lock succ %s\n", file_path);
printf(
"File locked. Press Enter to unlock...");
printf(
getchar();
// Unlock and close the file
flock(fd, LOCK_UN);
close(fd);
return 0;
}
gcc -o lock lock.c
./lock # client 1
./lock # client 2,这时会调用 SMB2_lock, server会调用 smb2_lock