Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
3a654f97
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
3a654f97
编写于
6月 19, 2014
作者:
A
Al Viro
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
new helpers: skb_copy_datagram_from_iter() and zerocopy_sg_from_iter()
Signed-off-by:
N
Al Viro
<
viro@zeniv.linux.org.uk
>
上级
3af0bfe5
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
119 addition
and
0 deletion
+119
-0
include/linux/skbuff.h
include/linux/skbuff.h
+3
-0
net/core/datagram.c
net/core/datagram.c
+116
-0
未找到文件。
include/linux/skbuff.h
浏览文件 @
3a654f97
...
...
@@ -2659,10 +2659,13 @@ static inline int skb_copy_and_csum_datagram_msg(struct sk_buff *skb, int hlen,
int
skb_copy_datagram_from_iovec
(
struct
sk_buff
*
skb
,
int
offset
,
const
struct
iovec
*
from
,
int
from_offset
,
int
len
);
int
skb_copy_datagram_from_iter
(
struct
sk_buff
*
skb
,
int
offset
,
struct
iov_iter
*
from
,
int
len
);
int
zerocopy_sg_from_iovec
(
struct
sk_buff
*
skb
,
const
struct
iovec
*
frm
,
int
offset
,
size_t
count
);
int
skb_copy_datagram_iter
(
const
struct
sk_buff
*
from
,
int
offset
,
struct
iov_iter
*
to
,
int
size
);
int
zerocopy_sg_from_iter
(
struct
sk_buff
*
skb
,
struct
iov_iter
*
frm
);
void
skb_free_datagram
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
);
void
skb_free_datagram_locked
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
);
int
skb_kill_datagram
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
,
unsigned
int
flags
);
...
...
net/core/datagram.c
浏览文件 @
3a654f97
...
...
@@ -572,6 +572,78 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
}
EXPORT_SYMBOL
(
skb_copy_datagram_from_iovec
);
int
skb_copy_datagram_from_iter
(
struct
sk_buff
*
skb
,
int
offset
,
struct
iov_iter
*
from
,
int
len
)
{
int
start
=
skb_headlen
(
skb
);
int
i
,
copy
=
start
-
offset
;
struct
sk_buff
*
frag_iter
;
/* Copy header. */
if
(
copy
>
0
)
{
if
(
copy
>
len
)
copy
=
len
;
if
(
copy_from_iter
(
skb
->
data
+
offset
,
copy
,
from
)
!=
copy
)
goto
fault
;
if
((
len
-=
copy
)
==
0
)
return
0
;
offset
+=
copy
;
}
/* Copy paged appendix. Hmm... why does this look so complicated? */
for
(
i
=
0
;
i
<
skb_shinfo
(
skb
)
->
nr_frags
;
i
++
)
{
int
end
;
const
skb_frag_t
*
frag
=
&
skb_shinfo
(
skb
)
->
frags
[
i
];
WARN_ON
(
start
>
offset
+
len
);
end
=
start
+
skb_frag_size
(
frag
);
if
((
copy
=
end
-
offset
)
>
0
)
{
size_t
copied
;
if
(
copy
>
len
)
copy
=
len
;
copied
=
copy_page_from_iter
(
skb_frag_page
(
frag
),
frag
->
page_offset
+
offset
-
start
,
copy
,
from
);
if
(
copied
!=
copy
)
goto
fault
;
if
(
!
(
len
-=
copy
))
return
0
;
offset
+=
copy
;
}
start
=
end
;
}
skb_walk_frags
(
skb
,
frag_iter
)
{
int
end
;
WARN_ON
(
start
>
offset
+
len
);
end
=
start
+
frag_iter
->
len
;
if
((
copy
=
end
-
offset
)
>
0
)
{
if
(
copy
>
len
)
copy
=
len
;
if
(
skb_copy_datagram_from_iter
(
frag_iter
,
offset
-
start
,
from
,
copy
))
goto
fault
;
if
((
len
-=
copy
)
==
0
)
return
0
;
offset
+=
copy
;
}
start
=
end
;
}
if
(
!
len
)
return
0
;
fault:
return
-
EFAULT
;
}
EXPORT_SYMBOL
(
skb_copy_datagram_from_iter
);
/**
* zerocopy_sg_from_iovec - Build a zerocopy datagram from an iovec
* @skb: buffer to copy
...
...
@@ -643,6 +715,50 @@ int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from,
}
EXPORT_SYMBOL
(
zerocopy_sg_from_iovec
);
int
zerocopy_sg_from_iter
(
struct
sk_buff
*
skb
,
struct
iov_iter
*
from
)
{
int
len
=
iov_iter_count
(
from
);
int
copy
=
min_t
(
int
,
skb_headlen
(
skb
),
len
);
int
frag
=
0
;
/* copy up to skb headlen */
if
(
skb_copy_datagram_from_iter
(
skb
,
0
,
from
,
copy
))
return
-
EFAULT
;
while
(
iov_iter_count
(
from
))
{
struct
page
*
pages
[
MAX_SKB_FRAGS
];
size_t
start
;
ssize_t
copied
;
unsigned
long
truesize
;
int
n
=
0
;
if
(
frag
==
MAX_SKB_FRAGS
)
return
-
EMSGSIZE
;
copied
=
iov_iter_get_pages
(
from
,
pages
,
~
0U
,
MAX_SKB_FRAGS
-
frag
,
&
start
);
if
(
copied
<
0
)
return
-
EFAULT
;
iov_iter_advance
(
from
,
copied
);
truesize
=
PAGE_ALIGN
(
copied
+
start
);
skb
->
data_len
+=
copied
;
skb
->
len
+=
copied
;
skb
->
truesize
+=
truesize
;
atomic_add
(
truesize
,
&
skb
->
sk
->
sk_wmem_alloc
);
while
(
copied
)
{
int
size
=
min_t
(
int
,
copied
,
PAGE_SIZE
-
start
);
skb_fill_page_desc
(
skb
,
frag
++
,
pages
[
n
],
start
,
size
);
start
=
0
;
copied
-=
size
;
n
++
;
}
}
return
0
;
}
EXPORT_SYMBOL
(
zerocopy_sg_from_iter
);
static
int
skb_copy_and_csum_datagram
(
const
struct
sk_buff
*
skb
,
int
offset
,
u8
__user
*
to
,
int
len
,
__wsum
*
csump
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录