亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
1234567下一頁(yè)
最近訪問板塊 發(fā)新帖
查看: 75826 | 回復(fù): 67
打印 上一主題 下一主題

[文件系統(tǒng)] 一個(gè)簡(jiǎn)單文件系統(tǒng)的實(shí)現(xiàn) [復(fù)制鏈接]

論壇徽章:
2
申猴
日期:2013-12-26 22:11:31天秤座
日期:2014-12-23 10:23:19
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2009-05-23 14:43 |只看該作者 |倒序?yàn)g覽
/*轉(zhuǎn)載請(qǐng)注明作者
author goter
email prowlman@gmail.com
*/
花了將進(jìn)兩個(gè)月的時(shí)候閱讀完內(nèi)核文件系統(tǒng),對(duì)于文件系統(tǒng)是如何運(yùn)行的還是有點(diǎn)模糊,所以想通過寫一個(gè)簡(jiǎn)單的文件系統(tǒng)來使自己對(duì)文件系統(tǒng)有個(gè)深入的了解。經(jīng)過拷貝抄襲ext2和minix文件系統(tǒng)后,寫了一個(gè)簡(jiǎn)單的文件系統(tǒng),我把這個(gè)簡(jiǎn)單的文件系統(tǒng)叫作GTFS,估計(jì)還有很多BUG,歡迎大家修正這些BUG
GTFS不支持磁盤配額和acl。鏈接,讀寫,刪除,新建,改名等都支持,有時(shí)候會(huì)有莫名其妙的錯(cuò)誤,希望大家諒解

下面先附上代碼和使用信息

使用信息
在fs/Makefile中添加一行

  1. obj-$(CONFIG_GT_FS)                += gt/
復(fù)制代碼

在fs/Kconfig中添加

  1. config GT_FS
  2.         tristate "GOTER fs support"
  3.         help
  4.            GTFS is a simple Linux file system for hard disk.
復(fù)制代碼

在include/linux/Kbuild中添加一行

  1. unifdef-y += gt_fs.h
復(fù)制代碼

在include/linux/magic.h中添加一行

  1. #define GT_SUPER_MAGIC                0x0601
復(fù)制代碼

為了迎接六一兒童節(jié),所以GTFS的魔數(shù)就設(shè)為0x0601了

然后將附件中的壓縮包解壓,可以看到有兩個(gè)目錄
一個(gè)目錄是mkfs.gt,進(jìn)入mkfs.gt目錄,里邊有4個(gè)文件,mkfs.gt為生成的二進(jìn)制文件,可以使用gcc -o mkfs.gt mkfs.gt.c生成mkfs.gt工具,這個(gè)工具用來創(chuàng)建GT文件系統(tǒng),只支持mkfs.gt /dev/sdax(設(shè)備名)命令。
另一個(gè)目錄是gtfs,進(jìn)入gtfs目錄,里邊有8個(gè)文件,將gtfs/gt_fs.h移動(dòng)到內(nèi)核include/linux/下,然后在內(nèi)核fs/ 下新建目錄gt,將剩余的7個(gè)文件移動(dòng)到gt下

然后make menuconfig,到filesystem下選中g(shù)tfs,然后編譯即可

GT-FS.tar.gz (19.69 KB, 下載次數(shù): 1816)
我會(huì)在下面為大家分析GTFS代碼的

[ 本帖最后由 goter 于 2009-5-23 20:17 編輯 ]

評(píng)分

參與人數(shù) 1可用積分 +15 收起 理由
Godbach + 15 原創(chuàng)內(nèi)容

查看全部評(píng)分

論壇徽章:
2
申猴
日期:2013-12-26 22:11:31天秤座
日期:2014-12-23 10:23:19
2 [報(bào)告]
發(fā)表于 2009-05-23 14:44 |只看該作者
因?yàn)镚TFS只是用來學(xué)習(xí)而不是用于生產(chǎn)環(huán)境的,所以GTFS的設(shè)計(jì)很簡(jiǎn)單也很簡(jiǎn)陋。GTFS的主要數(shù)據(jù)結(jié)構(gòu)和其他文件系統(tǒng)相似,主要的區(qū)別是組織塊的方式
下面是GTFS的主要數(shù)據(jù)結(jié)構(gòu)
gt_inode(索引節(jié)點(diǎn),在gt_fs.h中定義)
  1. struct gt_inode {
  2. __le16 i_mode;
  3. __le16 i_uid;
  4. __le16 i_gid;
  5. __le32 i_size;
  6. __le32 i_atime;
  7. __le32 i_ctime;
  8. __le32 i_mtime;
  9. __le32 i_dtime;
  10. __le16 i_nlinks;
  11. __le32 i_flags;
  12. __le32 i_start_block;//索引節(jié)點(diǎn)開始?jí)K
  13. __le32 i_end_block;//素引節(jié)點(diǎn)結(jié)束塊
  14. __le32 i_blocks;//索引節(jié)點(diǎn)占用的塊數(shù),另外作為索引節(jié)點(diǎn)是否是最后一個(gè)的flag
  15. __le16 i_dev;
  16. __le32 i_reserved;//為該索引節(jié)點(diǎn)預(yù)留的塊數(shù)
  17. __u8 i_nouse[10];
  18. }
復(fù)制代碼
很簡(jiǎn)單是吧,i_blocks的用途有點(diǎn)特別,GTFS默認(rèn)每個(gè)索引節(jié)點(diǎn)都會(huì)占用一個(gè)塊,所以新建一個(gè)索引節(jié)點(diǎn)時(shí),i_start_block=i_end_block,但此時(shí)i_blocks和i_reserved為0,因?yàn)镚TFS對(duì)磁盤的使用是順序使用的,所以當(dāng)新建一個(gè)索引節(jié)點(diǎn)時(shí),上一個(gè)索引節(jié)點(diǎn)就需要設(shè)置下預(yù)留塊數(shù),以便文件的增長(zhǎng)。新建的索引節(jié)點(diǎn)的開始?jí)K等于結(jié)束塊,但并不需要設(shè)置預(yù)留塊數(shù),因?yàn)樗梢砸恢笔褂玫阶詈笠粋(gè)磁盤塊(它沒有下一個(gè)索引節(jié)點(diǎn),我管這叫沒有封頂),那么當(dāng)操作系統(tǒng)打開一個(gè)文件時(shí),如何判斷這個(gè)文件對(duì)應(yīng)的索引節(jié)點(diǎn)是不是新建的呢,這就是i_blocks的作用,當(dāng)i_blocks為0時(shí),說明這個(gè)索引節(jié)點(diǎn)是新建的。當(dāng)新建一個(gè)索引節(jié)點(diǎn)時(shí),會(huì)設(shè)置上一個(gè)索引節(jié)點(diǎn)的i_blocks,
  1. i_blocks=i_end_blocks-i_start_blocks+1
復(fù)制代碼
所以,每個(gè)索引節(jié)點(diǎn)都至少占用一個(gè)塊


gt_inode_info(內(nèi)存中的i節(jié)點(diǎn)信息,在gt.h中定義)
  1. struct gt_inode_info{
  2. __le32 i_start_block;
  3. __le32 i_end_block;
  4. __le32 i_blocks;
  5. __le32 i_reserved;
  6. __u32 i_flags;
  7. __u32 i_dtime;
  8. struct mutex truncate_mutex;
  9. struct inode vfs_inode;
  10. };
復(fù)制代碼
gt_super_block(超級(jí)塊,在gt_fs.h中定義)
  1. struct gt_super_block {
  2. __le32 s_inodes_count;
  3. __le16 s_inode_size;
  4. __le32 s_blocks_count;
  5. __le32 s_free_blocks_count;
  6. __le32 s_free_inodes_count;
  7. __le32 s_first_data_block;
  8. __le32 s_first_ino;
  9. __le32 s_link_max;
  10. __le32 s_log_block_size;
  11. __le32 s_mtime;
  12. __le32 s_wtime;
  13. __le16 s_magic;
  14. };
復(fù)制代碼
超級(jí)塊數(shù)據(jù)結(jié)構(gòu)沒什么特別的,超級(jí)塊的內(nèi)容在掛載文件系統(tǒng)時(shí)從磁盤超級(jí)塊讀入

gt_sb_info(內(nèi)存中的超級(jí)塊,在gt_fs.h中定義)
  1. struct  gt_sb_info{
  2. struct gt_super_block * s_gs;//指向GT文件系統(tǒng)的超級(jí)塊
  3. struct buffer_head * s_sbh;//指向超級(jí)塊所在的緩沖區(qū)
  4. };
復(fù)制代碼
gt_dir_entry(目錄項(xiàng),在gt_fs.h中定義)
  1. #define GT_NAME_LEN 60 //目錄項(xiàng)名字長(zhǎng)度
  2. struct gt_dir_entry {
  3. __le32 ino;
  4. char name[GT_NAME_LEN];
  5. };
復(fù)制代碼

論壇徽章:
2
申猴
日期:2013-12-26 22:11:31天秤座
日期:2014-12-23 10:23:19
3 [報(bào)告]
發(fā)表于 2009-05-23 14:45 |只看該作者
文件系統(tǒng)的實(shí)現(xiàn)還需要對(duì)超級(jí)塊的操作,對(duì)文件的操作,索引節(jié)點(diǎn)操作等等
我們就先從掛載一個(gè)文件系統(tǒng)開始
掛載文件系統(tǒng)時(shí)候,VFS會(huì)通過mount命令中的文件系統(tǒng)類型或超級(jí)塊魔數(shù)來尋找file_system_type結(jié)構(gòu)
下面就是GTFS的file_system_type結(jié)構(gòu)(定義在super.c中)
  1. static struct file_system_type gt_fs_type ={
  2.         .owner                =THIS_MODULE,
  3.         .name                ="gt",//文件系統(tǒng)名稱
  4.         .get_sb                =gt_get_sb,//讀取超級(jí)塊方法
  5.         .kill_sb        =kill_block_super,
  6.         .fs_flags        =FS_REQUIRES_DEV,        
  7. };
復(fù)制代碼
我們只需要完成gt_get_sb(定義在super.c中)方法即可
  1. static int gt_get_sb(struct file_system_type *fs_type,
  2. int flags,const char *dev_name,void *data,struct vfsmount *mnt){
  3.         return get_sb_bdev(fs_type,flags,dev_name,data,gt_fill_super,mnt);
  4. }
復(fù)制代碼
從gt_get_sb函數(shù)可以看出,這個(gè)函數(shù)調(diào)用了get_sb_bdev函數(shù),get_sb_bdev又調(diào)用了gt_fill_super函數(shù)
gt_fill_super函數(shù)才是正真用來讀取超級(jí)塊的方法
  1. static int gt_fill_super(struct super_block *sb,void *data,int silent){

  2.         struct buffer_head *bh;
  3.         struct gt_super_block *gs;
  4.         struct gt_sb_info *sbi;
  5.         struct inode *root;//設(shè)備的根目錄
  6.         
  7.         unsigned long sb_block=1;//超級(jí)塊的塊號(hào)為1,第0塊為啟動(dòng)塊

  8.         long ret=-EINVAL;
  9.         
  10.         int blocksize=BLOCK_SIZE;//BLOCK_SIZE為1024

  11.         sbi=kzalloc(sizeof(struct gt_sb_info),GFP_KERNEL);
  12.         if(!sbi)
  13.                 return -ENOMEM;

  14.         if(!sb_set_blocksize(sb,BLOCK_SIZE))//設(shè)置VFS超級(jí)塊的塊大小
  15.                 goto out_bad_hblock;
  16.         if(!(bh=sb_bread(sb,sb_block))){//將GTFS超級(jí)塊所在的塊讀入內(nèi)存
  17.                 printk("GT-fs:unable to read superblock\n");
  18.                 goto failed_sbi;
  19.         }

  20.         gs=(struct gt_super_block *)(bh->b_data);
  21.         sbi->s_sbh=bh;//指向從磁盤讀入的GTFS超級(jí)塊所在的緩沖區(qū)
  22.         sbi->s_gs=gs;//將內(nèi)存中的GTFS超級(jí)塊和從磁盤讀入的GTFS超級(jí)塊聯(lián)系起來
  23.         sb->s_fs_info=sbi;//將VFS超級(jí)塊和GTFS的超級(jí)塊聯(lián)系起來
  24.         sb->s_magic=gs->s_magic;//設(shè)置魔數(shù)

  25.         if(sb->s_magic !=GT_SUPER_MAGIC)
  26.                 goto cantfind_gt;

  27.         blocksize=GT_BLOCK_SIZE;

  28.         sb->s_op=&gt_sops;
  29.         
  30.         root=gt_iget(sb,GT_ROOT_INO);//GT_ROOT_INO為1,讀入文件系統(tǒng)的根目錄
  31.         if(IS_ERR(root)){
  32.                 ret=PTR_ERR(root);
  33.                 printk(KERN_ERR "GT-fs: can't find root inode\n");
  34.                 goto failed_mount;        
  35.         }
  36.         if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
  37.                 iput(root);
  38.                 printk(KERN_ERR "isdir?%d,root->i_blocks=%d,root->i_size=%d\n",S_ISDIR(root->i_mode) , root->i_blocks, root->i_size);
  39.                 printk(KERN_ERR "GT-fs: corrupt root inode\n");
  40.                 goto failed_mount;
  41.         }

  42.         sb->s_root = d_alloc_root(root);//設(shè)置超級(jí)塊的根目錄
  43.         if (!sb->s_root) {
  44.                 iput(root);
  45.                 printk(KERN_ERR "GT: get root inode failed\n");
  46.                 ret = -ENOMEM;
  47.                 goto failed_mount;
  48.         }
  49.         
  50.         return 0;
  51. cantfind_gt:
  52.         printk("VFS: Can't find an gt filesystem on dev %s.\nmagic on dev is %d and magic of GT is %d\n",sb->s_id,sb->s_magic,GT_SUPER_MAGIC);
  53. failed_mount:
  54.         brelse(bh);
  55. out_bad_hblock:
  56.         printk("GT-fs:blocksize too small for device\n");
  57. failed_sbi:
  58.         sb->s_fs_info=NULL;
  59.         kfree(sbi);
  60.         return ret;
  61. }
復(fù)制代碼
這段函數(shù)主要是從磁盤讀入文件系統(tǒng)的超級(jí)塊,用來填充內(nèi)存中的GTFS超級(jí)塊,和VFS超級(jí)塊
調(diào)用gt_iget函數(shù)讀入指定文件系統(tǒng)的根目錄。

論壇徽章:
2
申猴
日期:2013-12-26 22:11:31天秤座
日期:2014-12-23 10:23:19
4 [報(bào)告]
發(fā)表于 2009-05-23 14:45 |只看該作者
文件系統(tǒng)在kernel中被當(dāng)作一個(gè)模塊實(shí)現(xiàn)
也有module_init和module_exit(定義在super.c)
  1. module_init(init_gt_fs)
  2. module_exit(exit_gt_fs)
復(fù)制代碼
init_gt_fs(定義在super.c)
  1. static int __init init_gt_fs(void){
  2.     int err=init_inodecache();
  3.     if(err)
  4.        return err;
  5.     err=register_filesystem(&gt_fs_type);//向內(nèi)核注冊(cè)GT文件系統(tǒng)
  6.     if(err)
  7.        goto out;
  8.     return 0;
  9. out:
  10.     destroy_inodecache();
  11.     return err;
  12. }
復(fù)制代碼
init_gt_fs中調(diào)用init_inodecache創(chuàng)建GTFS的內(nèi)存索引節(jié)點(diǎn)緩沖池(我瞎猜的...對(duì)這個(gè)不了解..)

init_inodecache(定義在super.c中)
  1. static struct kmem_cache *gt_inode_cachep;
  2. static int init_inodecache(void){
  3.    gt_inode_cachep=kmem_cache_create("gt_inode_cache",sizeof(struct gt_inode_info),0,(SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD),init_once);
  4.    if(gt_inode_cachep==NULL)
  5.       return -ENOMEM;
  6.    return 0;
  7. }
復(fù)制代碼
然后就是exit_gt_fs(定義在super.c中)
  1. static void __exit exit_gt_fs(void){
  2.      unregister_filesystem(&gt_fs_type);//注銷文件系統(tǒng)
  3.      destroy_inodecache();//銷毀緩沖池
  4. }
復(fù)制代碼

[ 本帖最后由 goter 于 2009-5-23 14:49 編輯 ]

論壇徽章:
2
申猴
日期:2013-12-26 22:11:31天秤座
日期:2014-12-23 10:23:19
5 [報(bào)告]
發(fā)表于 2009-05-23 14:49 |只看該作者
接下來是超級(jí)塊操作(定義在super.c中)
  1. static const struct super_operations gt_sops={
  2.         .alloc_inode        =gt_alloc_inode,//分配一個(gè)GTFS的索引節(jié)點(diǎn)
  3.         .destroy_inode        =gt_destroy_inode,//銷毀索引節(jié)點(diǎn)
  4.         .write_inode        =gt_write_inode,//寫入索引節(jié)點(diǎn)
  5.         .delete_inode        =gt_delete_inode,//刪除索引節(jié)點(diǎn)
  6.         .write_super    =gt_write_super,//將超級(jí)塊寫入磁盤
  7.         .put_super        =gt_put_super,//釋放超級(jí)塊
  8.         .statfs                =gt_statfs,//獲取文件系統(tǒng)狀態(tài)
  9.         .write_inode        =gt_write_inode,//將索引節(jié)點(diǎn)寫入磁盤
  10. };
復(fù)制代碼
下面我們挨個(gè)介紹
gt_alloc_inode(定義在super.c中)
  1. static struct inode *gt_alloc_inode(struct super_block *sb){
  2.         struct gt_inode_info *gi;

  3.         gi=(struct gt_inode_info *)kmem_cache_alloc(gt_inode_cachep,GFP_KERNEL);//在緩沖池分配一個(gè)GTFS的內(nèi)存索引節(jié)點(diǎn)
  4.         if(!gi)
  5.                 return NULL;
  6.         return &gi->vfs_inode;
  7. }
復(fù)制代碼
函數(shù)gt_destroy_inode(定義在super.c中)
  1. static void gt_destroy_inode(struct inode *inode){
  2.         kmem_cache_free(gt_inode_cachep,GT_I(inode));
  3. }
復(fù)制代碼
從緩沖池中釋放GTFS的內(nèi)存中索引節(jié)點(diǎn)
GT_I是定義在gt.h中的一個(gè)inline函數(shù),根據(jù)VFS索引節(jié)點(diǎn)返回GTFS的內(nèi)存索引節(jié)點(diǎn)
  1. static inline struct gt_inode_info *GT_I(struct inode *inode){
  2.           return container_of(inode,struct gt_inode_info,vfs_inode);
  3. }
復(fù)制代碼
然后是gt_write_inode(定義在super.c中)
  1. static int gt_write_inode(struct inode *inode,int wait){
  2.         brelse(gt_update_inode(inode));
  3.         return 0;
  4. }
復(fù)制代碼
可見,gt_write_inode函數(shù)調(diào)用gt_update_inode來將內(nèi)存中的索引節(jié)點(diǎn)寫入磁盤

gt_update_inode(定義在inode.c中)
  1. struct buffer_head *gt_update_inode(struct inode *inode){
  2.                
  3.         struct gt_inode_info *gi=GT_I(inode);
  4.         struct super_block *sb=inode->i_sb;
  5.         ino_t ino=inode->i_ino;
  6.         uid_t uid=inode->i_uid;
  7.         gid_t gid=inode->i_gid;
  8.         struct buffer_head *bh;
  9.         struct gt_inode *raw_inode =gt_raw_inode(sb,ino,&bh);//根據(jù)超級(jí)塊和索引節(jié)點(diǎn)號(hào)從磁盤讀入GTFS的磁盤索引節(jié)點(diǎn)

  10.         if(!raw_inode)
  11.                 return NULL;
  12.         /*更新*/
  13.         raw_inode->i_mode=inode->i_mode;
  14.         raw_inode->i_uid=uid;
  15.         raw_inode->i_gid=gid;
  16.         raw_inode->i_nlinks=inode->i_nlink;
  17.         raw_inode->i_size=inode->i_size;
  18.         raw_inode->i_atime=inode->i_atime.tv_sec;
  19.         raw_inode->i_mtime=inode->i_mtime.tv_sec;
  20.         raw_inode->i_ctime=inode->i_ctime.tv_sec;
  21.         //raw_inode->i_dtime=inode->i_dtime.tv_sec;
  22.        
  23.         if(S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
  24.                 raw_inode->i_dev=old_encode_dev(inode->i_rdev);
  25.         else{
  26.                 raw_inode->i_start_block=gi->i_start_block;
  27.                 raw_inode->i_end_block=gi->i_end_block;
  28.                 raw_inode->i_blocks=gi->i_blocks;
  29.                 raw_inode->i_reserved=gi->i_reserved;
  30.                        
  31.         }
  32.         mark_buffer_dirty(bh);//將磁盤索引節(jié)點(diǎn)所在的緩沖塊標(biāo)記為臟
  33.         return bh;
  34. }
復(fù)制代碼
gt_update_inode很簡(jiǎn)單,通過調(diào)用gt_raw_inode來讀入GTFS的磁盤索引節(jié)點(diǎn),然后根據(jù)GTFS內(nèi)存索引節(jié)點(diǎn)去設(shè)置磁盤索引節(jié)點(diǎn),最后將磁盤索引節(jié)點(diǎn)所在的緩沖塊標(biāo)記為臟,等待機(jī)會(huì)寫入磁盤。gt_raw_inode將在后面介紹,我們回到超級(jí)塊操作來

接下來是gt_delete_inode(定義在super.c中)
  1. static void gt_delete_inode(struct inode *inode){
  2.         truncate_inode_pages(&inode->i_data,0);
  3.         GT_I(inode)->i_dtime=get_seconds();
  4.         inode->i_size=0;
  5.         gt_truncate(inode);//清空文件
  6.         gt_free_inode(inode);//釋放索引節(jié)點(diǎn)
  7. }
復(fù)制代碼
讓我們來看看gt_truncate(定義在inode.c中)
  1. void gt_truncate(struct inode *inode){
  2.         if(!(S_ISREG(inode->i_mode)||S_ISDIR(inode->i_mode)||S_ISLNK(inode->i_mode)))
  3.                 return;
  4.         struct gt_inode_info *gi=GT_I(inode);
  5.         block_truncate_page(inode->i_mapping,inode->i_size,gt_get_block);

  6.         gi->i_reserved+=gi->i_end_block-gi->i_start_block+1;//設(shè)置預(yù)留塊數(shù)
  7.         gi->i_end_block=gi->i_start_block;//清空
  8.         inode->i_mtime=inode->i_ctime=CURRENT_TIME_SEC;
  9.         mark_inode_dirty(inode);
  10. }
復(fù)制代碼
這個(gè)函數(shù)主要是設(shè)置內(nèi)存索引節(jié)點(diǎn)的塊使用狀況

還有g(shù)t_free_inode(定義在inode.c中)
  1. void gt_free_inode(struct inode *inode){
  2.         struct super_block *sb=inode->i_sb;
  3.         struct gt_super_block *gs=GT_SB(inode->i_sb)->s_gs;
  4.         struct buffer_head *bh;
  5.         unsigned long ino;
  6.         ino=inode->i_ino;
  7.         struct gt_inode *raw_inode=NULL;
  8.         if(ino<1||ino>gs->s_inodes_count){
  9.                 printk("gt_free_inode: inode 0 or nonexistent inode\n");
  10.                 return;
  11.         }
  12.         raw_inode=gt_raw_inode(sb,ino,&bh);
  13.         if(raw_inode){
  14.                 raw_inode->i_nlinks=0;//設(shè)置磁盤索引節(jié)點(diǎn)的連接數(shù)
  15.                 raw_inode->i_mode=0;
  16.         }
  17.         if(bh){
  18.                 mark_buffer_dirty(bh);
  19.                 brelse(bh);
  20.         }
  21.         clear_inode(inode);//調(diào)用VFS函數(shù)清理VFS索引節(jié)點(diǎn)
  22. }
復(fù)制代碼
這個(gè)函數(shù)也很簡(jiǎn)單,只是讀取磁盤索引節(jié)點(diǎn),然后設(shè)置連接數(shù)和模式,然后標(biāo)記磁盤索引節(jié)點(diǎn)所在的緩沖塊為臟

論壇徽章:
2
申猴
日期:2013-12-26 22:11:31天秤座
日期:2014-12-23 10:23:19
6 [報(bào)告]
發(fā)表于 2009-05-23 14:51 |只看該作者
接著寫超級(jí)塊操作
接下來就是gt_write_super(定義在super.c中)
  1. static int gt_write_super(struct super_block *sb){
  2.         struct gt_super_block *gs;
  3.         lock_kernel();
  4.         gs=GT_SB(sb)->s_gs;
  5.         gs->s_free_blocks_count=cpu_to_le32(gt_count_free_blocks(sb));
  6.         gs->s_free_inodes_count=cpu_to_le32(gt_count_free_inodes(sb));
  7.         gs->s_mtime=cpu_to_le32(get_seconds());
  8.         gs->s_wtime = cpu_to_le32(get_seconds());
  9.         mark_buffer_dirty(GT_SB(sb)->s_sbh);
  10.         sync_dirty_buffer(GT_SB(sb)->s_sbh);
  11.         sb->s_dirt=0;       
  12.         unlock_kernel();
  13. }
復(fù)制代碼
這個(gè)很簡(jiǎn)單很簡(jiǎn)單,簡(jiǎn)單到我都懶的講了..
讓我們來看看gt_count_free_blocks和gt_count_free_inodes
這倆函數(shù)都定義在inode.c中
  1. unsigned long gt_count_free_inodes(struct super_block *sb){
  2.         struct buffer_head *bh;
  3.         struct gt_inode *gt;
  4.         char *p;
  5.          
  6.         unsigned long block=2; //索引節(jié)點(diǎn)表所在塊
  7.         unsigned long count=0;//使用了的索引節(jié)點(diǎn)數(shù)
  8.         //然后遍歷索引節(jié)點(diǎn)表
  9.         while(bh=sb_bread(sb,block)){
  10.                 p=bh->b_data;
  11.                 while(p<=(bh->b_data+GT_BLOCK_SIZE-GT_INODE_SIZE)){
  12.                         gt=(struct gt_inode *)p;
  13.                         if(gt->i_nlinks)
  14.                                 count++;//已經(jīng)使用的索引節(jié)點(diǎn)數(shù)加一
  15.                         p+=GT_INODE_SIZE;
  16.                 }
  17.                 brelse(bh);
  18.                 if(block>GT_INODE_BLOCK_COUNT(sb))//如果到了索引節(jié)點(diǎn)表結(jié)尾則跳出
  19.                         break;
  20.                 block++;       
  21.         }
  22.        
  23.         return GT_SB(sb)->s_gs->s_inodes_count-count;//返回未使用的索引節(jié)點(diǎn)數(shù)
  24. }
復(fù)制代碼
  1. unsigned long gt_count_free_blocks(struct super_block *sb){

  2.         struct gt_super_block *gs;
  3.         char *p;
  4.         int block=2;
  5.         gs=GT_SB(sb)->s_gs;
  6.         unsigned long used=0;//已經(jīng)使用的塊數(shù)
  7.         struct buffer_head *bh;
  8.         struct gt_inode * gt;
  9.        //遍歷索引節(jié)點(diǎn)表,已經(jīng)使用的塊數(shù)其實(shí)就等于最后一個(gè)索引節(jié)點(diǎn)的i_end_block
  10.         while(bh=sb_bread(sb,block)){
  11.                 p=bh->b_data;
  12.                 while(p<=(bh->b_data+GT_BLOCK_SIZE-GT_INODE_SIZE)){
  13.                         gt=(struct gt_inode *)p;
  14.                         if(!gt->i_blocks)
  15.                                 used=gt->i_end_block;
  16.                                
  17.                 }
  18.                 brelse(bh);
  19.         }
  20.         return GT_BLOCKS(sb)-used;
  21. }
復(fù)制代碼

論壇徽章:
2
申猴
日期:2013-12-26 22:11:31天秤座
日期:2014-12-23 10:23:19
7 [報(bào)告]
發(fā)表于 2009-05-23 14:55 |只看該作者
gt_put_super(定義在super.c中)
  1. static void gt_put_super(struct super_block *sb){
  2.         struct gt_sb_info *sbi=GT_SB(sb);
  3.         brelse(sbi->s_sbh);
  4.         sb->s_fs_info=NULL;
  5.         kfree(sbi);
  6. }
復(fù)制代碼
這個(gè)函數(shù)釋放掉磁盤超級(jí)塊所在的緩沖塊,釋放掉內(nèi)存超級(jí)塊

gt_statfs(定義在super.c中)
  1. static int gt_statfs(struct dentry *dentry,struct kstatfs *buf){
  2.         struct gt_sb_info * sbi=GT_SB(dentry->d_sb);
  3.         struct gt_super_block *gs=sbi->s_gs;
  4.         buf->f_type=dentry->d_sb->s_magic;
  5.         buf->f_bsize=dentry->d_sb->s_blocksize;
  6.         buf->f_blocks=(gs->s_blocks_count-gs->s_first_data_block);
  7.         buf->f_bfree=gt_count_free_blocks(sbi);
  8.         buf->f_bavail=buf->f_bfree;
  9.         buf->f_ffree=gt_count_free_inodes(sbi);
  10.         buf->f_namelen=GT_NAME_LEN;
  11.         return 0;
  12. }
復(fù)制代碼
這個(gè)函數(shù)獲取文件系統(tǒng)狀態(tài)

到這里超級(jí)塊的操作就完成了,接下來是普通索引節(jié)點(diǎn)操作,只需要一個(gè)清空函數(shù),其他的調(diào)用vfs默認(rèn)的函數(shù)
  1. const struct inode_operations gt_file_inode_operations ={
  2.         .truncate        =gt_truncate,
  3. };
復(fù)制代碼

[ 本帖最后由 goter 于 2009-5-23 15:03 編輯 ]

論壇徽章:
2
申猴
日期:2013-12-26 22:11:31天秤座
日期:2014-12-23 10:23:19
8 [報(bào)告]
發(fā)表于 2009-05-23 15:02 |只看該作者
普通文件操作(在file.c中定義),只需要實(shí)現(xiàn)一個(gè)gt_sync_file
  1. const struct file_operations gt_file_operations ={
  2.         .llseek                =generic_file_llseek,
  3.         .read                =do_sync_read,
  4.         .write                =do_sync_write,
  5.         .aio_read        =generic_file_aio_read,
  6.         .aio_write        =generic_file_aio_write,
  7.         .mmap                =generic_file_mmap,
  8.         .open                =generic_file_open,
  9.         .fsync                =gt_sync_file,
  10. };
復(fù)制代碼


來看看gt_sync_file(在file.c中定義)
  1. int gt_sync_file(struct file *file,struct dentry *dentry,int datasync){
  2.         struct inode *inode =dentry->d_inode;
  3.         int err,ret;
  4.         ret=sync_mapping_buffers(inode->i_mapping);
  5.         if(!(inode->i_state&I_DIRTY))
  6.                 return ret;
  7.         if(datasync && !(inode->i_state&I_DIRTY_DATASYNC))
  8.                 return ret;
  9.         err=gt_sync_inode(inode);
  10.         if(ret==0)
  11.                 ret=err;
  12.         return ret;
  13. }
復(fù)制代碼

函數(shù)調(diào)用gt_sync_inode(在inode.c中定義)
  1. int gt_sync_inode(struct inode *inode){
  2.         int ret=0;
  3.         struct buffer_head *bh;
  4.         bh=gt_update_inode(inode);//獲取到磁盤索引節(jié)點(diǎn)所在的緩沖區(qū)
  5.         if(bh && buffer_dirty(bh)){//如果為臟,則同步
  6.                 sync_dirty_buffer(bh);
  7.                 if(buffer_req(bh)&&!buffer_uptodate(bh)){
  8.                         printk("IO error syncing gt inode\n");
  9.                         ret=-1;
  10.                 }
  11.         }else if(!bh)
  12.                 ret=-1;
  13.         brelse(bh);
  14.         return ret;
  15. }
復(fù)制代碼

[ 本帖最后由 goter 于 2009-5-23 15:09 編輯 ]

論壇徽章:
2
申猴
日期:2013-12-26 22:11:31天秤座
日期:2014-12-23 10:23:19
9 [報(bào)告]
發(fā)表于 2009-05-23 15:09 |只看該作者
未完待續(xù)

論壇徽章:
36
IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
10 [報(bào)告]
發(fā)表于 2009-05-23 15:15 |只看該作者
多謝LZ分享,改天有時(shí)間編譯一下源碼,試用一下。
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP