⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inode.c

📁 linux的文件系统的部分代码的详细注释
💻 C
📖 第 1 页 / 共 5 页
字号:
	filemap_fdatasync(inode->i_mapping);/*分析一遍inode->i_mapping的dirty pages,
	                                                               *并写每一页
	                                                               */
/**
 *      filemap_fdatasync - walk the list of dirty pages of the given address space
 *     	and writepage() all of them.
 * 
 *      @mapping: address space structure to write
 *
 */

	/* Don't write the inode if only I_DIRTY_PAGES was set */
	if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC))/*判断是不只设置了I_DIRTY_PAGES 位脏*/
		write_inode(inode, sync);/*调用write_inode()写inode到设备上*/

	filemap_fdatawait(inode->i_mapping);/*分析一遍inode->i_mapping的dirty pages,
	                                                              *并等待每一页被解锁
	                                                              */
/**
 *      filemap_fdatawait - walk the list of locked pages of the given address space
 *     	and wait for all of them.
 * 
 *      @mapping: address space structure to wait for
 *
 */

	spin_lock(&inode_lock);/*持有自旋锁inode_lock*/
	inode->i_state &= ~I_LOCK;/*清除该inode上的锁*/
	if (!(inode->i_state & I_FREEING)) {/*inode不是空闲的*/
		struct list_head *to;/*声明一个链表指针to*/
		if (inode->i_state & I_DIRTY)/*inode为脏*/
			to = &inode->i_sb->s_dirty;/*to链表指针指向inode的超块的s_dirty链表头*/
		else if (atomic_read(&inode->i_count))/*inode不为脏,且原子操作读引用计数不为0*/
			to = &inode_in_use;/*to链表指针指向inode_in_use*/
		else/*inode不为脏,但原子操作读引用计数为0*/
			to = &inode_unused;/*to链表指针指向inode_unused*/
		list_del(&inode->i_list);/*将该 inode对象从原来的“类型”链表中删除*/
		list_add(&inode->i_list, to);/*并将其链入到to链表中*/
	}
	wake_up(&inode->i_wait);/*唤醒在该inode上等待的进程*/
}

/*等待被上锁的inode解锁,对未上锁的inode同步写回块设备*/
static inline void sync_one(struct inode *inode, int sync)
{
	if (inode->i_state & I_LOCK) {/*inode被上锁*/
		__iget(inode);/*增加一个inode对象的引用计数*/
		spin_unlock(&inode_lock);/*释放自旋锁inode_lock*/
		__wait_on_inode(inode);/*等待一个inode对象被解锁*/
		iput(inode); /*释放对一个inode对象的引用*/
		spin_lock(&inode_lock);/*持有自旋锁inode_lock*/
	} else {/*inode未被上锁*/
		__sync_one(inode, sync);/*将一个指定的脏inode同步写回块设备*/
	}
}

/*将一个脏inode队列中的所有inode同步写回块设备*/
static inline void sync_list(struct list_head *head)
{
	struct list_head * tmp;/*声明list_head指针tmp*/

	while ((tmp = head->prev) != head) /*tmp赋值为head->prev,并当tmp不为head时,
	                                                           *持续循环,顺序搜索队列head
	                                                           */
		__sync_one(list_entry(tmp, struct inode, i_list), 0);/*将一个指定的脏inode同步写回块设备*/
}

/*等待将一个链表上锁*/
static inline void wait_on_locked(struct list_head *head)
{
	struct list_head * tmp;/*声明一个list_head类型指针tmp*/
	while ((tmp = head->prev) != head) {/*tmp赋值为head->prev,并判断是否等于head,
		                                                      *不相等时进入循环体执行,
		                                                      *顺序搜索队列head
		                                                      */
		struct inode *inode = list_entry(tmp, struct inode, i_list);/*inode指向从list_head类型的域找到inode类型的域*/
 /*
 * list_entry - get the struct for this entry
 * @ptr:	the &struct list_head pointer.
 * @type:	the type of the struct this is embedded in.
 * @member:	the name of the list_struct within the struct.
 */
		__iget(inode);/*增加一个对inode的引用计数*/
		spin_unlock(&inode_lock);/*释放自旋锁inode_lock*/
		__wait_on_inode(inode);/*等待inode被解锁*/
		iput(inode);/*释放对inode的引用*/
		spin_lock(&inode_lock);/*持有自旋锁inode_lock*/
	}
}

/*试图同步未使用 的inode链表*/
static inline int try_to_sync_unused_list(struct list_head *head, int nr_inodes)
{
	struct list_head *tmp = head;/*声明list_head指针tmp,指向head*/
	struct inode *inode;/*声明inode指针*/

       /*当cache中的inode对象总数不为0,
         *且将tmp赋值为tmp->prev后,tmp不指向head,
         *则持续循环,搜索head
         */
	while (nr_inodes && (tmp = tmp->prev) != head) {
		inode = list_entry(tmp, struct inode, i_list);/*inode指向从list_head类型的域找到inode类型的域*/

		if (!atomic_read(&inode->i_count)) {/*原子操作读inode->i_count,inode->i_count为0*/
			__sync_one(inode, 0);/*将inode写回块设备*/
			nr_inodes--;/*参数中的inode对象数减一*/

			/* 
			 * __sync_one moved the inode to another list,
			 * so we have to start looking from the list head.
			 */
			 /*对上面注释的翻译:
			  *__sync_one将inode移到另一个链表上,
			  *所以需要从表头开始继续查找
			  */
			tmp = head;/*tmp指向head*/
		}
	}

	return nr_inodes;/*返回参数中的inode对象数*/
}

/*单个节点同步回写操作函数*/
/*执行回写操作并等待在文件系统的脏节点上*/
void sync_inodes_sb(struct super_block *sb)
{
	spin_lock(&inode_lock);/*持有自旋锁inode_lock*/

	/*sb->s_dirty不空,或sb->s_locked_inodes不空*/
	while (!list_empty(&sb->s_dirty)||!list_empty(&sb->s_locked_inodes)) {
		sync_list(&sb->s_dirty);/*将sb->s_dirty中的所有inode同步写回块设备*/
		wait_on_locked(&sb->s_locked_inodes);/*等待将sb->s_locked_inodes上锁*/
	}
	spin_unlock(&inode_lock);/*释放自旋锁inode_lock*/
}

/*
 * Note:
 * We don't need to grab a reference to superblock here. If it has non-empty
 * ->s_dirty it's hadn't been killed yet and kill_super() won't proceed
 * past sync_inodes_sb() until both ->s_dirty and ->s_locked_inodes are
 * empty. Since __sync_one() regains inode_lock before it finally moves
 * inode from superblock lists we are OK.
 */
/*同步未上锁的inode*/
void sync_unlocked_inodes(void)
{
	struct super_block * sb;/*声明super_block指针sb*/
	spin_lock(&inode_lock);/*持有自旋锁inode_lock*/
	spin_lock(&sb_lock);/*持有自旋锁sb_lock*/
	sb = sb_entry(super_blocks.next);/*sb指向从super_blocks.next的域找到super_block类型的域*/

	/*sb指向从sb->s_list.next的域找到super_block类型的域,
	  *只要它与从super_blocks的域找到super_block类型的域不符,
	  *则持续循环
	  */
	for (; sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.next)) {
		if (!list_empty(&sb->s_dirty)) {/*如果sb->s_dirty不空*/
			spin_unlock(&sb_lock);/*释放自旋锁sb_lock*/
			sync_list(&sb->s_dirty);/*将sb->s_dirty中的所有inode同步写回块设备*/
			spin_lock(&sb_lock);/*持有自旋锁sb_lock*/
		}
	}
	spin_unlock(&sb_lock);/*释放自旋锁sb_lock*/
	spin_unlock(&inode_lock);/*释放自旋锁inode_lock*/
}

/*
 * Find a superblock with inodes that need to be synced
 */
/*获得需要同步的脏的超块结构*/
static struct super_block *get_super_to_sync(void)
{
	struct list_head *p;/*声明list_head型指针p*/
restart:
	spin_lock(&inode_lock);/*持有自旋锁inode_lock*/
	spin_lock(&sb_lock);/*持有自旋锁sb_lock*/

/*
 * list_for_each	-	iterate over a list
 * @pos:	the &struct list_head to use as a loop counter.
 * @head:	the head for your list.
 
#define list_for_each(pos, head) \
	for (pos = (head)->next, prefetch(pos->next); pos != (head); \
        	pos = pos->next, prefetch(pos->next))
 */
       /*遍历一遍链表super_blocks*/
	list_for_each(p, &super_blocks) {
	
	       /*从list_head类型的域找到super_block类型的域,
	         *并赋值给super_block指针型的s
	         */
		struct super_block *s = list_entry(p,struct super_block,s_list);

	       /*如果s->s_dirty为空,且s->s_locked_inodes为空*/
		if (list_empty(&s->s_dirty) && list_empty(&s->s_locked_inodes))
			continue;/*跳过本次循环剩下的部分,直接进入下次循环*/
		s->s_count++;/*超块引用计数加一*/
		spin_unlock(&sb_lock);/*释放自旋锁sb_lock*/
		spin_unlock(&inode_lock);/*释放自旋锁inode_lock*/
		down_read(&s->s_umount);/*读模块的引用的信号量减一*/
/*
 * down_read - lock for reading
 */
 /*
 * __down_read - get a read lock on the semaphore
 */
		if (!s->s_root) {/*超块的根目录为空*/
			drop_super(s);/*卸载超块,读引用模块的信号量加一,减少一个超块的引用*/
			goto restart;/*跳转到restart程序段*/
		}
		return s;/*返回找到的需要同步的脏的超块结构*/
	}

       /*遍历super_blocks都没有找到需要同步的脏块,则执行下面语句*/
	spin_unlock(&sb_lock);/*释放自旋锁sb_lock*/
	spin_unlock(&inode_lock);/*释放自旋锁inode_lock*/
	return NULL;/*返回空*/
}

/**
 *	sync_inodes
 *	@dev: device to sync the inodes from.
 *
 *	sync_inodes goes through the super block's dirty list, 
 *	writes them out, and puts them back on the normal list.
 */
/*多个节点同步回写操作函数*/
/*遍历每个超级块的脏节点链表,把节点写回到块设备,
  *并等待回写的完成,写完成后把节点放回到正常的链表中*/
void sync_inodes(kdev_t dev)
{
	struct super_block * s;/*声明一个super_block型指针s*/

	/*
	 * Search the super_blocks array for the device(s) to sync.
	 */
	if (dev) {/*dev不等于0,同步回写一个设备的超块*/
		if ((s = get_super(dev)) != NULL) {/*从块设备上获得了超块*/
			sync_inodes_sb(s);/*对单个节点同步回写操作*/
			drop_super(s);/*卸载超块,读引用模块的信号量加一,减少一个超块的引用*/
		}
	} else {/*dev等于0,同步所有需要同步的超块*/
	       /*当可以得到脏的超块结构,持续循环*/
		while ((s = get_super_to_sync()) != NULL) {
			sync_inodes_sb(s);/*对单个节点同步回写操作*/
			drop_super(s);/*卸载超块,读引用模块的信号量加一,减少一个超块的引用*/
		}
	}
}

/*试图同步未使用的inode*/
static void try_to_sync_unused_inodes(void * arg)
{
	struct super_block * sb;/*声明super_block指针sb*/
	int nr_inodes = inodes_stat.nr_unused;/*声明int型nr_inodes ,赋值为inodes_stat.nr_unused
	                                                               *cache中未使用的inode个数
	                                                               */

	spin_lock(&inode_lock);/*持有自旋锁inode_lock*/
	spin_lock(&sb_lock);/*持有自旋锁sb_lock*/
	sb = sb_entry(super_blocks.next);/*sb赋值为从super_blocks.next的域找到super_block类型的域*/

	/*sb指向从sb->s_list.next的域找到super_block类型的域,
	  *只要它与从super_blocks的域找到super_block类型的域不符,
	  *且cache中总的inode个数不为0
	  *则持续循环
	  */
	for (; nr_inodes && sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.next)) {
		if (list_empty(&sb->s_dirty))/*如果sb->s_dirty为空*/
			continue;/*跳过本次循环的剩余部分,继续下次循环*/
		spin_unlock(&sb_lock);/*释放自旋锁sb_lock*/
		nr_inodes = try_to_sync_unused_list(&sb->s_dirty, nr_inodes);/*试图同步未使用 的inode链表sb->s_dirty*/
		spin_lock(&sb_lock);/*持有自旋锁sb_lock*/
	}
	spin_unlock(&sb_lock);/*释放自旋锁sb_lock*/
	spin_unlock(&inode_lock);/*释放自旋锁inode_lock*/
}

/*定义静态tq_struct型结构体unused_inodes_flush_task,
 *用于链接需要刷新的未使用的inode
 */
static struct tq_struct unused_inodes_flush_task;
/*
struct tq_struct {
	struct list_head list;		linked list of active bh's 
	unsigned long sync;		must be initialized to zero 
	void (*routine)(void *);   	function to call 
	void *data;			       argument to function 
};
*/

/**

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -