linux fat get entry,FAT文件系统学习记录一

上面的函数fat_cache_lookup从名字可以看出,它只是在cache中进行这样的查找过程中,这显然是不够的,因为cache是存在于内存中的,最初是不存在的,只能从FAT表中进行查找。

int

fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus)

//该函数输入为inode以及要查找的文件的cluster,要返回的是该cluster在磁盘上对应的dclus

{

struct super_block *sb = inode->i_sb;

const int limit = sb->s_maxbytes

>> MSDOS_SB(sb)->cluster_bits;

struct fat_entry fatent;

struct fat_cache_id cid;

int nr;

BUG_ON(MSDOS_I(inode)->i_start == 0);

*fclus = 0;

*dclus = MSDOS_I(inode)->i_start;

if (cluster == 0)

return 0;

//首先尽量从cache中进行查找,这样可以节省很多时间的。

if (fat_cache_lookup(inode, cluster,

&cid, fclus, dclus) < 0) {

/*

* dummy, always not contiguous

* This is reinitialized by cache_init(),

later.

*/

cache_init(&cid, -1, -1);

}

//剩下的工作只能从FAT表中一个一个的查找了,确实是一个一个查找,从后面的代码(*fclus)++;也可以看出来。

fatent_init(&fatent);

//这样可能会出现两种情况

//1.

*fclus = cluster即需要查找的cluster已经被包含在cache中,那么皆大欢喜,查找结束

//2.*fclus

< cluster, cache中包含不完全,其中* dclus中返回的是离cluster最近的cluster在磁盘上位置。然后根据该dclus从FAT表中查找

while (*fclus < cluster) {

/* prevent the infinite loop of

cluster chain */

if (*fclus > limit) {

fat_fs_error(sb, "%s:

detected the cluster chain loop"

" (i_pos %lld)", __func__,

MSDOS_I(inode)->i_pos);

nr = -EIO;

goto out;

}

//根据dclus中FAT表查找出,下一个cluster在磁盘上的位置。

nr = fat_ent_read(inode,

&fatent, *dclus);

if (nr < 0)

goto out;

else if (nr == FAT_ENT_FREE) {

fat_fs_error(sb, "%s:

invalid cluster chain"

" (i_pos %lld)", __func__,

MSDOS_I(inode)->i_pos);

nr = -EIO;

goto out;

} else if (nr == FAT_ENT_EOF) {

fat_cache_add(inode,

&cid);

goto out;

}

(*fclus)++;

*dclus = nr;

if (!cache_contiguous(&cid,

*dclus))

cache_init(&cid,

*fclus, *dclus);

}

nr = 0;

//查找结束,需要将相应的结果添加到cache中,便于下一次查找

fat_cache_add(inode, &cid);

out:

fatent_brelse(&fatent);

//最终返回文件cluster对应的磁盘cluster号

return nr;

}

说到fat_ent_read函数就不得不说struct

fatent_operations结构体,因为这个函数用到了很多的函数指针,因为不同的FAT类型(FAT12,FAT16,FAT32)而不同。

struct

fatent_operations {

void (*ent_blocknr)(struct super_block *,

int, int *, sector_t *);

//对应的cluster所在的FAT表中的位置

void (*ent_set_ptr)(struct fat_entry *,

int);

int (*ent_bread)(struct super_block *,

struct fat_entry *,

int, sector_t);

//用于读出一个block的内容,显然不管是数据读取还是

//在获得文件的存储位置(从FAT表中读取)都是需要

//该函数的

int (*ent_get)(struct fat_entry *);

//用于获得FAT表中的下一个cluster所在的位置

void (*ent_put)(struct fat_entry *, int);

int (*ent_next)(struct fat_entry *);

};

int

fat_ent_read(struct inode *inode, struct fat_entry *fatent, int entry)

{

struct super_block *sb = inode->i_sb;

struct msdos_sb_info *sbi =

MSDOS_SB(inode->i_sb);

struct fatent_operations *ops =

sbi->fatent_ops;

int err, offset;

sector_t blocknr;

if (entry < FAT_START_ENT ||

sbi->max_cluster <= entry) {

fatent_brelse(fatent);

fat_fs_error(sb, "invalid

access to FAT (entry 0x%08x)", entry);

return -EIO;

}

fatent_set_entry(fatent, entry);

//要获得一个文件cluster对应的磁盘cluster要分为三步:

1.算出文件cluster在FAT表中对应的位置,ent_blocknr完成

2.读出FAT表中的内容,ent_bread完成

3.获得对应的磁盘cluster,ent_get完成

ops->ent_blocknr(sb, entry,

&offset, &blocknr);

if (!fat_ent_update_ptr(sb, fatent,

offset, blocknr)) {

fatent_brelse(fatent);

err = ops->ent_bread(sb,

fatent, offset, blocknr);

if (err)

return err;

}

return ops->ent_get(fatent);

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值