范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

fat文件系统查找删除创建目录

  Fat文件系统查找过程
  查找一个文件是通过文件名查找的,对于fat文件系统,可以直接从vfat_lookup函数看
  主体流程如下:  vfat_lookup     vfat_find     	fat_search_long     		while (1)     			fat_get_entry(inode, &cpos, &bh, &de)     			fat_name_match(sbi, name, name_len, bufname, len)     fat_build_inode 		inode = new_inode(sb); 			inode->i_ino = iunique(sb, MSDOS_ROOT_INO); 			fat_fill_inode(inode, de)
  vfat_lookup调了fat_search_long查找文件,其中qname->name就是文件名,比如说我们打开file.txt,就会先查找文件,这里传入的参数qname->name就是文件名,打印出来就是file.txt。  static int vfat_find(struct inode *dir, const struct qstr *qname, 		     struct fat_slot_info *sinfo) { 	unsigned int len = vfat_striptail_len(qname); 	if (len == 0) 		return -ENOENT; 	return fat_search_long(dir, qname->name, len, sinfo); }
  fat_search_long里面有个死循环,里面先调用fat_get_entry(inode, &cpos, &bh, &de)获取目录项,也就是de变量,msdos_dir_entry这个结构体,这个就是fdt表,也是fat文件系统的目录项。
  先判断文件名是否等于DELETED_FLAG,就是0xe5,如果是,代码这个是删除文件,直接continue获取下一个目录项继续解析。一般短文件名,通过fat_name_match(sbi, name, name_len, bufname, len)函数,匹配,匹配上的话,说明找到该文件,直接跳转到found,  int fat_search_long(struct inode *inode, const unsigned char *name, 		    int name_len, struct fat_slot_info *sinfo) { 	struct super_block *sb = inode->i_sb; 	struct msdos_sb_info *sbi = MSDOS_SB(sb); 	struct buffer_head *bh = NULL; 	struct msdos_dir_entry *de; 	unsigned char nr_slots; 	wchar_t *unicode = NULL; 	unsigned char bufname[FAT_MAX_SHORT_SIZE]; 	loff_t cpos = 0; 	int err, len; 	err = -ENOENT; 	while (1) { 		if (fat_get_entry(inode, &cpos, &bh, &de) == -1) 			goto end_of_dir; parse_record: 		nr_slots = 0; 		if (de->name[0] == DELETED_FLAG) 			continue; 		if (de->attr != ATTR_EXT && (de->attr & ATTR_VOLUME)) 			continue; 		if (de->attr != ATTR_EXT && IS_FREE(de->name)) 			continue; 		if (de->attr == ATTR_EXT) { 			int status = fat_parse_long(inode, &cpos, &bh, &de, 						    &unicode, &nr_slots); 			if (status < 0) { 				err = status; 				goto end_of_dir; 			} else if (status == PARSE_INVALID) 				continue; 			else if (status == PARSE_NOT_LONGNAME) 				goto parse_record; 			else if (status == PARSE_EOF) 				goto end_of_dir; 		} 		/* Never prepend "." to hidden files here. 		 * That is done only for msdos mounts (and only when 		 * "dotsOK=yes"); if we are executing here, it is in the 		 * context of a vfat mount. 		 */ 		len = fat_parse_short(sb, de, bufname, 0); 		if (len == 0) 			continue; 		/* Compare shortname */ 		if (fat_name_match(sbi, name, name_len, bufname, len)) 			goto found; 		if (nr_slots) { 			void *longname = unicode + FAT_MAX_UNI_CHARS; 			int size = PATH_MAX - FAT_MAX_UNI_SIZE; 			/* Compare longname */ 			len = fat_uni_to_x8(sb, unicode, longname, size); 			if (fat_name_match(sbi, name, name_len, longname, len)) 				goto found; 		} 	} found: 	nr_slots++;	/* include the de */ 	sinfo->slot_off = cpos - nr_slots * sizeof(*de); 	sinfo->nr_slots = nr_slots; 	sinfo->de = de; 	sinfo->bh = bh; 	sinfo->i_pos = fat_make_i_pos(sb, sinfo->bh, sinfo->de); 	err = 0; end_of_dir: 	if (unicode) 		__putname(unicode); 	return err; }
  找到文件后,会调用fat_build_inode建立索引节点信息,因为索引节点不是一直存在的,在我们嵌入式场景中,内存通常比较小,内存回收的时候会释放掉之前建立过的索引节点,所以这里大部分情况下都是走new_inode(sb)分配新的inode,然后调iunique(sb, MSDOS_ROOT_INO)查找一个没使用过的编号填充到inode->i_ino,通过都是从1开始往后分配,inode->i_ino就像是身份证一样的信息,区别每个inode,这个我们调试一些文件系统问题的时候通常会用到它。  struct inode *fat_build_inode(struct super_block *sb, 			struct msdos_dir_entry *de, loff_t i_pos) { 	struct inode *inode; 	int err; 	fat_lock_build_inode(MSDOS_SB(sb)); 	inode = fat_iget(sb, i_pos); 	if (inode) 		goto out; 	inode = new_inode(sb); 	if (!inode) { 		inode = ERR_PTR(-ENOMEM); 		goto out; 	} 	inode->i_ino = iunique(sb, MSDOS_ROOT_INO); 	inode->i_version = 1; 	err = fat_fill_inode(inode, de); 	if (err) { 		iput(inode); 		inode = ERR_PTR(err); 		goto out; 	} 	fat_attach(inode, i_pos); 	insert_inode_hash(inode); out: 	fat_unlock_build_inode(MSDOS_SB(sb)); 	return inode; }
  然后调用fat_fill_inode填充inode信息,可以看到第一个判断,如果这个目录项是目录,这里填充的一些信息,如:
  MSDOS_I(inode)->i_start = fat_get_start(sbi, de); // 就是获取簇号
  MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
  其实就是簇号,可以参考创建目录时的处理,参考函数fat_alloc_new_dir的实现。
  set_nlink的作用是设置i_nlink,它代表的是该目录的子目录数量,fat_subdirs就是计算子目录数量,一个目录至少有2个子目录,当前目录和上级目录。我的代码是4.14版本的,这里还加了个判断fat_validate_dir判断该目录是否为有效目录,据我所知,内核4.4版本是没有该函数判断的,这会导致一些问题不能及时发现。  int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de) { 	struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); 	int error; 	MSDOS_I(inode)->i_pos = 0; 	inode->i_uid = sbi->options.fs_uid; 	inode->i_gid = sbi->options.fs_gid; 	inode->i_version++; 	inode->i_generation = get_seconds(); 	if ((de->attr & ATTR_DIR) && !IS_FREE(de->name)) { 		inode->i_generation &= ~1; 		inode->i_mode = fat_make_mode(sbi, de->attr, S_IRWXUGO); 		inode->i_op = sbi->dir_ops; 		inode->i_fop = &fat_dir_operations; 		MSDOS_I(inode)->i_start = fat_get_start(sbi, de); 		MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start; 		error = fat_calc_dir_size(inode); 		if (error < 0) 			return error; 		MSDOS_I(inode)->mmu_private = inode->i_size; 		set_nlink(inode, fat_subdirs(inode)); 		error = fat_validate_dir(inode); 		if (error < 0) 			return error; 	} else { /* not a directory */ 		inode->i_generation |= 1; 		inode->i_mode = fat_make_mode(sbi, de->attr, 			((sbi->options.showexec && !is_exec(de->name + 8)) 			 ? S_IRUGO|S_IWUGO : S_IRWXUGO)); 		MSDOS_I(inode)->i_start = fat_get_start(sbi, de); 		MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start; 		inode->i_size = le32_to_cpu(de->size); 		inode->i_op = &fat_file_inode_operations; 		inode->i_fop = &fat_file_operations; 		inode->i_mapping->a_ops = &fat_aops; 		MSDOS_I(inode)->mmu_private = inode->i_size; 	} 	if (de->attr & ATTR_SYS) { 		if (sbi->options.sys_immutable) 			inode->i_flags |= S_IMMUTABLE; 	} 	fat_save_attrs(inode, de->attr); 	inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1)) 			   & ~((loff_t)sbi->cluster_size - 1)) >> 9; 	fat_time_fat2unix(sbi, &inode->i_mtime, de->time, de->date, 0); 	if (sbi->options.isvfat) { 		fat_time_fat2unix(sbi, &inode->i_ctime, de->ctime, 				  de->cdate, de->ctime_cs); 		fat_time_fat2unix(sbi, &inode->i_atime, 0, de->adate, 0); 	} else 		inode->i_ctime = inode->i_atime = inode->i_mtime; 	return 0; }
  关于fat文件系统查找就介绍这几个函数,主要是要理解几个关键的结构体、inode,目录项这几个重要的东西在查找中的作用。  fat文件系统删除
  对于文件系统删除,有2个系统调用,入口函数一个是do_unlinkat,一个是do_rmdir,它们大体流程一致,这里主要有2件事,一个是释放目录项,给fdt表文件名首字节设置成0xe5,那么查找的时候先判断de->name[0]如果是DELETED_FLAG就跳过了,不记得可以往上看回查找过程,一个是释放簇(在fat表写为0),数据区不变。  do_unlinkat     vfs_unlink         dir->i_op->unlink             vfat_unlink                 vfat_find                 fat_remove_entries                     while (nr_slots && de >= (struct msdos_dir_entry *)bh->b_data) {                         de->name[0] = DELETED_FLAG; // 删除标志0xe5                         de--;                         nr_slots--;                     }     dput         dentry_kill             __dentry_kill                 iput                     iput_final                         evict                             op->evict_inode                                 fat_evict_inode                                     // 这里进入到fat文件系统层,往下就是释放簇 fat文件系统创建目录
  fat_alloc_new_dir就是创建目录的函数,可以看到,创建的时候先在fat表找到一个未使用的簇号,分配出来,然后fat_clus_to_blknr函数通过该簇号计算出扇区编号,然后用sb_getblk对应的扇区读到内存上,紧接着就是填充fdt表,de[0]就是当前目录,de[1]就是上级目录,还有就是填充一些其他信息,如修改时间,簇号等,fat_zeroed_cluster就是把该簇其他扇区数据清0。  memcpy(de[0].name, MSDOS_DOT, MSDOS_NAME); memcpy(de[1].name, MSDOS_DOTDOT, MSDOS_NAME);int fat_alloc_new_dir(struct inode *dir, struct timespec *ts) { 	struct super_block *sb = dir->i_sb; 	struct msdos_sb_info *sbi = MSDOS_SB(sb); 	struct buffer_head *bhs[MAX_BUF_PER_PAGE]; 	struct msdos_dir_entry *de; 	sector_t blknr; 	__le16 date, time; 	u8 time_cs; 	int err, cluster; 	err = fat_alloc_clusters(dir, &cluster, 1); 	if (err) 		goto error; 	blknr = fat_clus_to_blknr(sbi, cluster); 	bhs[0] = sb_getblk(sb, blknr); 	if (!bhs[0]) { 		err = -ENOMEM; 		goto error_free; 	} 	fat_time_unix2fat(sbi, ts, &time, &date, &time_cs); 	de = (struct msdos_dir_entry *)bhs[0]->b_data; 	/* filling the new directory slots ("." and ".." entries) */ 	memcpy(de[0].name, MSDOS_DOT, MSDOS_NAME); 	memcpy(de[1].name, MSDOS_DOTDOT, MSDOS_NAME); 	de->attr = de[1].attr = ATTR_DIR; 	de[0].lcase = de[1].lcase = 0; 	de[0].time = de[1].time = time; 	de[0].date = de[1].date = date; 	if (sbi->options.isvfat) { 		/* extra timestamps */ 		de[0].ctime = de[1].ctime = time; 		de[0].ctime_cs = de[1].ctime_cs = time_cs; 		de[0].adate = de[0].cdate = de[1].adate = de[1].cdate = date; 	} else { 		de[0].ctime = de[1].ctime = 0; 		de[0].ctime_cs = de[1].ctime_cs = 0; 		de[0].adate = de[0].cdate = de[1].adate = de[1].cdate = 0; 	} 	fat_set_start(&de[0], cluster); 	fat_set_start(&de[1], MSDOS_I(dir)->i_logstart); 	de[0].size = de[1].size = 0; 	memset(de + 2, 0, sb->s_blocksize - 2 * sizeof(*de)); 	set_buffer_uptodate(bhs[0]); 	mark_buffer_dirty_inode(bhs[0], dir); 	err = fat_zeroed_cluster(dir, blknr, 1, bhs, MAX_BUF_PER_PAGE); 	if (err) 		goto error_free; 	return cluster; error_free: 	fat_free_clusters(dir, cluster); error: 	return err; }

共商大事!俄外长抵华,10国代表齐聚中国,中欧通话美也派出特使据中国国际电视台3月30日援引俄媒消息,俄外交部透露,俄外长拉夫罗夫已抵达中国安徽,以参加第3届阿富汗邻国外长会。赴华参加阿富汗邻国外长会的共有俄罗斯伊朗巴基斯坦等6国。该会议结束工薪阶层首选!高性价比家电推荐高性价比家电推荐!作为社会中的80,工薪阶层无疑是社会的中流砥柱。对于钱的态度,我想大多数人还是本着能省则省的原则。其实,节俭无可厚非,如果总是大手大脚,哪来的钱买房买车养娃?说白速食品选购攻略不止有泡面!17款优质速食品解决宅家吃饭问题本内容来源于什么值得买APP,观点仅代表作者本人作者GT7最近这段时间应该有许多朋友开始了在家办公,去市场买菜和外卖在一些地方也受到了限制,在现阶段宅家不出并且囤好食物可能算是一个东契奇35913独行侠擒骑士获三连胜!勒韦尔空砍32分NBA常规赛3月31日继续进行,本场比赛丁威迪缺阵。最终,独行侠以120112战胜骑士,独行侠获得3连胜。首节开始,布伦森和芬尼史密斯连中三分帮助独行侠104开局。随后骑士打出一波冬奥背后的故事见证历史的首钢滑雪大跳台位于首钢工业园区内的首钢滑雪大跳台,是冬奥历史上第一座与工业遗产再利用直接结合的竞赛场馆,同时也是世界上首座永久性保留和使用的滑雪大跳台,过去冬奥会的滑雪大跳台,比赛完了之后就会拆约基奇19中15砍37139!掘金3连胜超爵士升西部第五掘金客场125118击败步行者获得3连胜,排名超越爵士升至西部第五。步行者5连败。开场掘金篮下攻进6球,约基奇包办其中4球,之后杰夫格林巴顿小里弗斯连中4记三分,约基奇篮下再次打进女人老得快是缺乏雌激素吗?有女性朋友留言说我最近姨妈量特别少,觉得皮肤还特别显老,是缺少雌激素的原因吗?如果你也遇到姨妈量突然特别少,皮肤状态也不好,那么建议你到医院查一查性激素六项。如果缺乏雌激素,首先可女人最高级的活法重塑自己在青海湖有一种湟鱼,出生第一年会快速成长,一年能长一斤。然而第一年后,湟鱼几乎就停止了生长,十多岁的鱼也只有一斤重。因此,人们通常只等湟鱼长满一年,就将其打捞上岸。仔细想想,有时候篮网交易米尔斯换3D前锋!三分不准留他浪费620万纳什信任小库里纽约邮报记者布莱恩刘易斯最新消息报道,篮网队今年夏天寻求交易走帕蒂米尔斯清理620万美元空间补充一名3D前锋,他在纳什战术体系里的位置已经被塞斯库里取代,越来越被边缘化。米尔斯在篮恭喜杨鸣,辽篮获3大喜讯,赵继伟激动了,杜锋或无缘第4冠近日,关于CBA的常规赛已经全部结束了,各个球队都在二十九日准备包机前往南昌战区去参加比赛,这次的季后赛会在四月一日在南昌赛区正式开始比赛了,并且这次的季后赛和往常的比赛都不是太一不老男神苏有朋,是多少70后80后90后甚至00后的心中的偶像初识苏有朋,还得从小虎队说起,这真是一代人的记忆。三个年轻帅气的少年,朝气满满,深受人们的喜欢,是无数人心目中的偶像,当年大街小巷都放着他们的歌,年轻的男孩女孩几乎必有他们的唱片,
自驾西藏第十八天,黄龙2022年7月27日,我们进入自驾西藏第十八天。也算返程途中,昨天游览了举世闻名的九寨沟,不去游览同为国家级五A景区的黄龙似乎说不过去。于是昨晚从九寨沟出来直接睡到川主寺,今天上午老哥老姐们,走一趟西沙远方人物情景故事10小传发来一个西沙游的行程,打开一看,不禁怦然心动。这个行程最大特色击中我们这一代人的西沙情怀!年轻的时候,诵读过军旅诗人张永枚的长篇诗报告西沙之战,里面的精彩片可入住200多人!快来火车营地打卡吧!据说今年露营风火了很多营地一帐难求今天小编要隆重推荐火车营地不仅有车厢式宾馆还能学习铁路知识模拟开火车常青火车营地是共青团山东省委与中国铁路济南局集团有限公司铁路文化研学体系战略合第二届陕鼓杯西北地区机械行业班组长管理技能大赛开赛通讯员苗莹工人日报中工网记者毛浓曦7月22日,第二届陕鼓杯西北地区机械行业班组长管理技能大赛启动暨全国机械行业班组长培训基地(陕鼓集团基地)揭牌。西北五省7600余名基层班组长将在你不知道的苹果手机的那些小技能我手机是多年前买的IPhone11,手机一设置好,我就发现我的设备比我老公的10的屏幕黄很多。这部手机是我和我老公订婚的时候他送我的,还是比较有纪念意义的,再加上穷,所以一直没有换原神v3提纳里大幅加强,强化版草甘雨!草神技能猜想在今天下午,v3提纳里多莉受到了加强一提纳里大幅度加强六命巨额加强,提纳里由蓄力弓转变为速射弓天赋削弱系数由0。08削弱至0。060命提纳里演示弓箭蓄力速度快于甘雨6命提纳里演示由后羿三个技能释放顺序及出装!版本黑马还没学会吗?掌握以下几点S28赛季发育路上最大的上分黑马无非就是后羿了,但还是有很多小伙伴不熟悉后羿的英雄连招和出装,本期就给大家分享S28赛季后羿的正确连招方式和出装后羿的连招开团进场时为321aaa对花街(散文)花街吴永鑫去里运河码头,过轮埠路就到了花街。花街有梧桐树,有老房子和灯笼,就是没有花。现在去花街是看不见花的,那里没有人卖花,也没有人种花。花街似乎成为了一种历史名词,其由来说法不广西五大怪菜,都是当地人的心头爱,外地人看了直摇头自古山如画,如今画似山。广西,一个风景秀丽地方。这里桂林山水甲天下,龙脊梯田景色绮丽,这得益于它优越的地理位置,但是在我看来这里不仅风景好,美食也好。接下来我们就一起来看看这些广西陕西哪道菜最好吃?经过评选,这6道菜比较出名,你吃过几种?陕西有六朝古都之称的西安,也是丝绸之路的发源地,作为著名旅游大省的陕西,好吃的美食更是数不胜数。在陕西来一场说走就走的旅行,让灵魂与味蕾并存,当地的特色美食绝对能让你大饱口福!下面e赋能市中兴电商培育雨露计划第二期电商直播培训(新昌专场)开课7月25日,区商务和投资促进局和文化路街道办事处在新昌批发市场联合举办了雨露计划第二期电商直播培训,40余家商户参加了本次培训。此次培训为期三天,特邀阿里巴巴电商讲堂金牌讲师巨量学