当前位置: 首页 > news >正文

linux scatterlist阅读三

sg_copy_buffer

函数定义:

/*** sg_copy_buffer - Copy data between a linear buffer and an SG list* @sgl:		 The SG list* @nents:		 Number of SG entries* @buf:		 Where to copy from* @buflen:		 The number of bytes to copy* @skip:		 Number of bytes to skip before copying* @to_buffer:		 transfer direction (true == from an sg list to a*			 buffer, false == from a buffer to an sg list** Returns the number of copied bytes.***/
size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents, void *buf, size_t buflen, off_t skip, bool to_buffer)
{unsigned int offset = 0;struct sg_mapping_iter miter;unsigned int sg_flags = SG_MITER_ATOMIC;if (to_buffer)sg_flags |= SG_MITER_FROM_SG;elsesg_flags |= SG_MITER_TO_SG;sg_miter_start(&miter, sgl, nents, sg_flags);if (!sg_miter_skip(&miter, skip))return false;while ((offset < buflen) && sg_miter_next(&miter)) {unsigned int len;len = min(miter.length, buflen - offset);if (to_buffer)memcpy(buf + offset, miter.addr, len);elsememcpy(miter.addr, buf + offset, len);offset += len;}sg_miter_stop(&miter);return offset;
}
EXPORT_SYMBOL(sg_copy_buffer);

函数实现比较复杂,还涉及了struct sg_mapping_iter 结构体,这里比较重要的是skip参数,是指拷贝时跳过的字节数。

sg_copy_from_buffer

函数定义:

/*** sg_copy_from_buffer - Copy from a linear buffer to an SG list* @sgl:		 The SG list* @nents:		 Number of SG entries* @buf:		 Where to copy from* @buflen:		 The number of bytes to copy* Returns the number of copied bytes.**/
size_t sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents,const void *buf, size_t buflen)
{return sg_copy_buffer(sgl, nents, (void *)buf, buflen, 0, false);
}
EXPORT_SYMBOL(sg_copy_from_buffer);

从buf缓冲区里拷贝buflen长度的数据到sgl表里,返回值是成功拷贝到字节数

sg_copy_to_buffer

/*** sg_copy_to_buffer - Copy from an SG list to a linear buffer* @sgl:		 The SG list* @nents:		 Number of SG entries* @buf:		 Where to copy to* @buflen:		 The number of bytes to copy** Returns the number of copied bytes.***/
size_t sg_copy_to_buffer(struct scatterlist *sgl, unsigned int nents,void *buf, size_t buflen)
{return sg_copy_buffer(sgl, nents, buf, buflen, 0, true);
}
EXPORT_SYMBOL(sg_copy_to_buffer);

sg_pcopy_from_buffer

/*** sg_pcopy_from_buffer - Copy from a linear buffer to an SG list* @sgl:		 The SG list* @nents:		 Number of SG entries* @buf:		 Where to copy from* @buflen:		 The number of bytes to copy* @skip:		 Number of bytes to skip before copying** Returns the number of copied bytes.***/
size_t sg_pcopy_from_buffer(struct scatterlist *sgl, unsigned int nents, const void *buf, size_t buflen, off_t skip)
{return sg_copy_buffer(sgl, nents, (void *)buf, buflen, skip, false);
}
EXPORT_SYMBOL(sg_pcopy_from_buffer);

sg_pcopy_to_buffer

/*** sg_pcopy_to_buffer - Copy from an SG list to a linear buffer* @sgl:		 The SG list* @nents:		 Number of SG entries* @buf:		 Where to copy to* @buflen:		 The number of bytes to copy* @skip:		 Number of bytes to skip before copying** Returns the number of copied bytes.***/
size_t sg_pcopy_to_buffer(struct scatterlist *sgl, unsigned int nents,void *buf, size_t buflen, off_t skip)
{return sg_copy_buffer(sgl, nents, buf, buflen, skip, true);
}
EXPORT_SYMBOL(sg_pcopy_to_buffer);

sg_zero_buffer

把skip后面的数据清0,比如sgl里面的数据是"abcde",skip等于2,调用函数以后,sgl里面的数据是"ab"

/*** sg_zero_buffer - Zero-out a part of a SG list* @sgl:		 The SG list* @nents:		 Number of SG entries* @buflen:		 The number of bytes to zero out* @skip:		 Number of bytes to skip before zeroing** Returns the number of bytes zeroed.**/
size_t sg_zero_buffer(struct scatterlist *sgl, unsigned int nents,size_t buflen, off_t skip)
{unsigned int offset = 0;struct sg_mapping_iter miter;unsigned int sg_flags = SG_MITER_ATOMIC | SG_MITER_TO_SG;sg_miter_start(&miter, sgl, nents, sg_flags);if (!sg_miter_skip(&miter, skip))return false;while (offset < buflen && sg_miter_next(&miter)) {unsigned int len;len = min(miter.length, buflen - offset);memset(miter.addr, 0, len);offset += len;}sg_miter_stop(&miter);return offset;
}
EXPORT_SYMBOL(sg_zero_buffer);

最后来个demo,看看怎么使用。

#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/hdreg.h>
#include <linux/genhd.h>
#include <linux/blkdev.h>
#include <linux/scatterlist.h>//struct sg_table sgt;struct scatterlist *sgl;
void *buf;/* 驱动出口函数 */
static int __init ramdisk_init(void)
{int i;void *buffer;struct scatterlist *sg;printk("sg init\n");sgl = (struct scatterlist *)kmalloc(sizeof(struct scatterlist) * 1, GFP_KERNEL);if(!sgl)return -1;buf = kmalloc(1000, GFP_KERNEL);if(!buf)return -1;buffer = kmalloc(100, GFP_KERNEL);if(!buffer)return -1;memset(buffer, 0, 100);memcpy(buffer, "hello world", 12);void *p;sg_init_one(sgl, buf, 1000);for_each_sg(sgl, sg, 1, i) {//sg_pcopy_from_buffer(sg, 1, buffer, 100, 5);sg_copy_from_buffer(sg, 1, buffer, 100);p = sg_virt(sg);//p = p + 5;printk("p = %s\n", (char *)p);memset(buffer, 0, 100);sg_pcopy_to_buffer(sg, 1, buffer, 100, 6);printk("buffer = %s\n", (char *)buffer);}kfree(buffer);return 0;
}/* 驱动出口函数 */
static void __exit ramdisk_exit(void)
{printk("sg exit\n");kfree(buf);kfree(sgl);
}module_init(ramdisk_init);
module_exit(ramdisk_exit);
http://www.lryc.cn/news/146055.html

相关文章:

  • 2023新,centos7安装mysql8.0.25
  • Data Rescue Professional for Mac:专业的数据恢复工具
  • 新手小白想要做好跨境电商独立站,需要考虑哪些要素?
  • Consul原理介绍
  • 【C++实战】C++实现贪吃蛇(含源代码)—基于easyx图形库
  • PHP获取两个日期之间的所有日期
  • STL之stack(适配器讲解以及双端队列的讲解)
  • JVM解密: 解构类加载与GC垃圾回收机制
  • 【Spring Boot】Spring Boot结合MyBatis简单实现学生信息管理模块
  • 【Java List与Map】List<T> Map与Map List<T>的区别(126)
  • 【FreeRTOS】常用函数总结
  • The Cherno——OpenGL
  • linux中学习控制进程的要点
  • C++Qt QSS要注意的坑
  • LeetCode每日一题:56. 合并区间(2023.8.27 C++)
  • 电视盒子什么牌子好?经销商整理线下热销电视盒子品牌排行榜
  • JavaScript关于函数的小挑战
  • 机器学习深度学习——针对序列级和词元级应用微调BERT
  • 重启Mysql时报错rm: cannot remove ‘/var/lock/subsys/mysql‘: Permission denied
  • [C/C++]指针详讲-让你不在害怕指针
  • 无涯教程-Android - Frame Layout函数
  • docker desktop安装es 并连接elasticsearch-head:5
  • 计网(第四章)(网络层)(六)
  • 科研无人机平台P600进阶版,突破科研难题!
  • Apache的简单介绍(LAMP架构+搭建Discuz论坛)
  • CDL基础原理
  • WPF基础入门-Class7-WPF-MVVN框架
  • C语言练习题第三弹!!!绝对典中典!!!
  • Jedis
  • Linux 使用TCP_INFO查询TCP连接的状态信息