📄 transaction.c.txt
字号:
any problems, send mails to sindybear@163.com
相关文件
************************日志的开始运行******************************
这个函数开始日志的记录工作,其中参数nblocks就是日志区申请占用的地方,如果的不到满足,
就会等待,知道日志区有这么多空闲的地方进行处理
handle_t *journal_start(journal_t *journal, int nblocks)
handle_t *handle = journal_current_handle(); //得到当前进程所处的日志
if (handle) {
J_ASSERT(handle->h_transaction->t_journal == journal); //检察是否日志是这个文件系统的日志
handle->h_ref++; //日志的reference加1
return handle; //返回这个日志
}
handle = jbd_kmalloc(sizeof (handle_t), GFP_NOFS); //如果没有,分配一个新的
memset (handle, 0, sizeof (handle_t)); //设置
handle->h_buffer_credits = nblocks; //记住这个handle所需的大小
handle->h_ref = 1; //访问计数设为1
current->journal_info = handle; //当前进程的日志区设置为新日志
err = start_this_handle(journal, handle); //运行这个日志
if (err < 0) { //如果运行失败,返回错误
kfree(handle);
current->journal_info = NULL; //当前进程的日志区设为空
return ERR_PTR(err);
}
return handle; //如果一切正常,返回日志句柄
这个函数将一个进程所属的日志handle加入到当前系统的事务中。
static int start_this_handle(journal_t *journal, handle_t *handle)
int nblocks = handle->h_buffer_credits; //也就是journal_star中的nblock
repeat:
lock_journal(journal); //锁定日志
repeat_locked:
if (!journal->j_running_transaction) //如果当前的日志没有一个transaction(事务)在运行就分配一个
get_transaction(journal, 0); //分配一个新的事务
transaction = journal->j_running_transaction; //得到当前正在处理的事务,注意,一个文件系统就一个正在运行事务
if (transaction->t_state == T_LOCKED) { //如果当前的事务处于锁定状态,说明日志正在往外写等操作
unlock_journal(journal);
sleep_on(&journal->j_wait_transaction_locked); //就等待日志处理完毕
goto repeat;
}
//计算所有等待完成的日志的大小,也就是将transaction中没有完成的credits加上新的handle的block
needed = transaction->t_outstanding_credits + nblocks;
if (needed > journal->j_max_transaction_buffers) { //如果加入到这个事务中的日志buffer太多了
log_start_commit(journal, transaction); //则提交事务当前的事务
unlock_journal(journal);
sleep_on(&journal->j_wait_transaction_locked); //等待事务提交完毕。
lock_journal(journal);
goto repeat_locked; //将这个handle提交给下一个事务进行处理
}
needed = journal->j_max_transaction_buffers; //?????
if (journal->j_committing_transaction)
needed += journal->j_committing_transaction->
t_outstanding_credits;
if (log_space_left(journal) < needed) {
log_wait_for_space(journal, needed); //等待磁盘空间
goto repeat_locked;
}
handle->h_transaction = transaction; //万事俱备,将我们的handle加入到当前事务中
transaction->t_outstanding_credits += nblocks; //当前事务的未完成日志的credit计数增加
transaction->t_updates++;
transaction->t_handle_count++;
unlock_journal(journal); //解锁
return 0; //完成,胜利返回
这个函数生成一个新的事务,将这个事务加入到日志系统中。
static transaction_t * get_transaction (journal_t * journal, int is_try)
transaction = jbd_kmalloc (sizeof (transaction_t), GFP_NOFS); //分配一个新事务
memset (transaction, 0, sizeof (transaction_t)); //初始化为0
transaction->t_journal = journal; //初始化
transaction->t_state = T_RUNNING; //初始状态为runing
transaction->t_tid = journal->j_transaction_sequence++;
transaction->t_expires = jiffies + journal->j_commit_interval;
journal->j_running_transaction = transaction; //将这个事务设置为当前系统的可运行事务
********************************************************************
这个函数将指定的jh加入到jlist所指示的transaction中的响应的链表中
void journal_file_buffer(struct journal_head *jh,transaction_t *transaction, int jlist)
__journal_file_buffer(jh, transaction, jlist); //实际的工作在这里面作
void __journal_file_buffer(struct journal_head *jh,transaction_t *transaction, int jlist)
switch (jlist) {
case BJ_Metadata:
transaction->t_nr_buffers++;
list = &transaction->t_buffers;
break;
……
}
************************元数据的写日志**********************************
#这个函数将传入的buffer_head,这个buffer_head中包含metadata数据,
#将它加入到transaction中的t_buffers队列中
int journal_dirty_metadata (handle_t *handle, struct buffer_head *bh)
transaction_t *transaction = handle->h_transaction; //得到一定的结构
journal_t *journal = transaction->t_journal; //得到一定的结构
struct journal_head *jh = bh2jh(bh); //得到一定的结构
if (jh->b_transaction != transaction) {
…… //如果这个jh已经在另外的一个transaction中就不做什么了
}
__journal_file_buffer(jh, handle->h_transaction, BJ_Metadata); //否则就加入到t_buffers中
************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -