日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux 块设备驱动(二)——块设备数据结构

發(fā)布時間:2025/3/21 linux 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux 块设备驱动(二)——块设备数据结构 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

linux 塊設(shè)備驅(qū)動(二)——塊設(shè)備數(shù)據(jù)結(jié)構(gòu)

本文來源于:

1.?http://www.cnblogs.com/dyllove98/archive/2013/07/01/3165567.html

塊設(shè)備相關(guān)的數(shù)據(jù)結(jié)構(gòu)以及接口:

????? 塊設(shè)備接口則相對復(fù)雜,讀寫API沒有直接到塊設(shè)備層,而是直接到文件系統(tǒng)層,然后再由文件系統(tǒng)層發(fā)起讀寫請求。

一: block_device:? block_device結(jié)構(gòu)代表了內(nèi)核中的一個塊設(shè)備。它可以表示整個磁盤或一個特定的分區(qū)。當(dāng)這個結(jié)構(gòu)代表一個分區(qū)時,它的bd_contains成員指向包含這個分區(qū)的設(shè)備,bd_part成員指向設(shè)備的分區(qū)結(jié)構(gòu)。當(dāng)這個結(jié)構(gòu)代表一個塊設(shè)備時,bd_disk成員指向設(shè)備的gendisk結(jié)構(gòu)。

struct block_device { dev_t bd_dev; struct inode * bd_inode; /*分區(qū)結(jié)點*/ int bd_openers; struct semaphore bd_sem; /*打開/關(guān)閉鎖*/ struct semaphore bd_mount_sem; /* 加載互斥鎖*/ struct list_head bd_inodes; void * bd_holder; int bd_holders; struct block_device * bd_contains; unsigned bd_block_size;//分區(qū)塊大小 struct hd_struct * bd_part; unsigned bd_part_count;//打開次數(shù) int bd_invalidated; struct gendisk * bd_disk; struct list_head bd_list; struct backing_dev_info *bd_inode_backing_dev_info; unsigned long bd_private; }; ? ? 二:gendisk是一個單獨的磁盤驅(qū)動器的內(nèi)核表示。內(nèi)核還使用gendisk來表示分區(qū)。 struct gendisk { int major; //主設(shè)備號 int first_minor; int minors; //最大的次設(shè)備號數(shù)量,如果設(shè)備不能分區(qū),該值為1 char disk_name[32]; //主設(shè)備名 struct hd_struct **part; //分區(qū)信息,有minors個 struct block_device_operations *fops;//設(shè)備操作 struct request_queue *queue; //設(shè)備管理I/O請求 void *private_data; sector_t capacity; int flags; char devfs_name[64]; int number; struct device *driverfs_dev; struct kobject kobj; struct timer_rand_state *random; int policy; atomic_t sync_io; unsigned long stamp, stamp_idle; int in_flight; #ifdef CONFIG_SMP struct disk_stats *dkstats; #else struct disk_stats dkstats; #endif }; gendisk結(jié)構(gòu)的操作函數(shù)包括以下幾個: struct gendisk *alloc_disk(int minors); //分配磁盤 void add_disk(struct gendisk *disk); //增加磁盤信息 void unlink_gendisk(struct gendisk *disk) //刪除磁盤信息 void delete_partition(struct gendisk *disk, int part); //刪除分區(qū) void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len, int flags);//添加分區(qū) ? ? 三: block_device_operations結(jié)構(gòu)是塊設(shè)備對應(yīng)的操作接口,是連接抽象的塊設(shè)備操作與具體塊設(shè)備操作之間的樞紐。 ? struct block_device_operations { int (*open) (struct inode *, struct file *); int (*release) (struct inode *, struct file *); int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long); long (*unlocked_ioctl) (struct file *, unsigned, unsigned long); long (*compat_ioctl) (struct file *, unsigned, unsigned long); int (*direct_access) (struct block_device *, sector_t, unsigned long *); int (*media_changed) (struct gendisk *); int (*revalidate_disk) (struct gendisk *); int (*getgeo)(struct block_device *, struct hd_geometry *); struct module *owner; }; block_device_operations并不能完全提供文件操作全部的API,實際上只提供了open、release等函數(shù),其他的文件操作依賴于def_blk_fops: const struct file_operations def_blk_fops = { .open = blkdev_open, .release = blkdev_close, .llseek = block_llseek, .read = do_sync_read, .write = do_sync_write, .aio_read = generic_file_aio_read, .aio_write= generic_file_aio_write_nolock, .mmap = generic_file_mmap, .fsync = block_fsync, .unlocked_ioctl = block_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = compat_blkdev_ioctl, #endif .splice_read = generic_file_splice_read, .splice_write = generic_file_splice_write, };

?

四: 系統(tǒng)對塊設(shè)備進(jìn)行讀寫操作時,通過塊設(shè)備通用的讀寫操作函數(shù)將一個請求保存在該設(shè)備的操作請求隊列(request queue)中,然后調(diào)用這個塊設(shè)備的底層處理函數(shù),對請求隊列中的操作請求進(jìn)行逐一執(zhí)行。request_queue結(jié)構(gòu)描述了塊設(shè)備的請求隊列,該結(jié)構(gòu)定義如下:

struct request_queue { struct list_head queue_head; struct request *last_merge; elevator_t elevator; /*請求隊列列表*/ struct request_list rq; request_fn_proc *request_fn; merge_request_fn *back_merge_fn; merge_request_fn *front_merge_fn; merge_requests_fn *merge_requests_fn; make_request_fn *make_request_fn; prep_rq_fn *prep_rq_fn; unplug_fn *unplug_fn; merge_bvec_fn *merge_bvec_fn; activity_fn *activity_fn; /*自動卸載狀態(tài)*/ struct timer_list unplug_timer; int unplug_thresh; unsigned long unplug_delay; /*自動卸載延時*/ struct work_struct unplug_work; struct backing_dev_info backing_dev_info; void *queuedata; void *activity_data; unsigned long bounce_pfn; int bounce_gfp; unsigned long queue_flags;//各種隊列標(biāo)志 /*保護(hù)隊列結(jié)構(gòu),避免重入*/ spinlock_t *queue_lock; /* 請求的核心結(jié)構(gòu)*/ struct kobject kobj; /*請求的配置*/ unsigned long nr_requests; /* 請求的最大數(shù)*/ unsigned int nr_congestion_on; unsigned int nr_congestion_off; unsigned short max_sectors; unsigned short max_phys_segments; unsigned short max_hw_segments; unsigned short hardsect_size; unsigned int max_segment_size; unsigned long seg_boundary_mask; unsigned int dma_alignment; struct blk_queue_tag *queue_tags; atomic_t refcnt; unsigned int in_flight; /*sg 參數(shù)配置*/ unsigned int sg_timeout; unsigned int sg_reserved_size; }; 請求隊列相關(guān)的處理函數(shù)包括: //創(chuàng)建隊列時提供了一個自旋鎖。 request_queue_t *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock); //獲得隊列中第一個未完成的請求。 struct request *elv_next_request(request_queue_t *q); void end_request(struct request *req, int uptodate);//請求完成 void blk_stop_queue(request_queue_t *queue); //停止請求 void blk_start_queue(request_queue_t *queue); //開始請求 void blk_cleanup_queue(request_queue_t *);//清除請求隊列

?

五:向內(nèi)核注冊和注銷一個塊設(shè)備可使用如下函數(shù):

int register_blkdev(unsigned int major, const char *name); int unregister_blkdev(unsigned int major, const char *name);

總結(jié)

以上是生活随笔為你收集整理的linux 块设备驱动(二)——块设备数据结构的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。