Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
2
22b970497
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Summer2022
22b970497
Commits
0e4c0ee5
Commit
0e4c0ee5
authored
8 years ago
by
David S. Miller
Browse files
Options
Downloads
Plain Diff
Merge branch 'for-davem' of
git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
parents
ea6b1720
32786821
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
include/linux/uio.h
+5
-1
5 additions, 1 deletion
include/linux/uio.h
lib/iov_iter.c
+63
-0
63 additions, 0 deletions
lib/iov_iter.c
net/core/datagram.c
+14
-9
14 additions, 9 deletions
net/core/datagram.c
with
82 additions
and
10 deletions
include/linux/uio.h
+
5
−
1
View file @
0e4c0ee5
...
...
@@ -39,7 +39,10 @@ struct iov_iter {
};
union
{
unsigned
long
nr_segs
;
int
idx
;
struct
{
int
idx
;
int
start_idx
;
};
};
};
...
...
@@ -81,6 +84,7 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to);
size_t
iov_iter_copy_from_user_atomic
(
struct
page
*
page
,
struct
iov_iter
*
i
,
unsigned
long
offset
,
size_t
bytes
);
void
iov_iter_advance
(
struct
iov_iter
*
i
,
size_t
bytes
);
void
iov_iter_revert
(
struct
iov_iter
*
i
,
size_t
bytes
);
int
iov_iter_fault_in_readable
(
struct
iov_iter
*
i
,
size_t
bytes
);
size_t
iov_iter_single_seg_count
(
const
struct
iov_iter
*
i
);
size_t
copy_page_to_iter
(
struct
page
*
page
,
size_t
offset
,
size_t
bytes
,
...
...
This diff is collapsed.
Click to expand it.
lib/iov_iter.c
+
63
−
0
View file @
0e4c0ee5
...
...
@@ -786,6 +786,68 @@ void iov_iter_advance(struct iov_iter *i, size_t size)
}
EXPORT_SYMBOL
(
iov_iter_advance
);
void
iov_iter_revert
(
struct
iov_iter
*
i
,
size_t
unroll
)
{
if
(
!
unroll
)
return
;
i
->
count
+=
unroll
;
if
(
unlikely
(
i
->
type
&
ITER_PIPE
))
{
struct
pipe_inode_info
*
pipe
=
i
->
pipe
;
int
idx
=
i
->
idx
;
size_t
off
=
i
->
iov_offset
;
while
(
1
)
{
size_t
n
=
off
-
pipe
->
bufs
[
idx
].
offset
;
if
(
unroll
<
n
)
{
off
-=
(
n
-
unroll
);
break
;
}
unroll
-=
n
;
if
(
!
unroll
&&
idx
==
i
->
start_idx
)
{
off
=
0
;
break
;
}
if
(
!
idx
--
)
idx
=
pipe
->
buffers
-
1
;
off
=
pipe
->
bufs
[
idx
].
offset
+
pipe
->
bufs
[
idx
].
len
;
}
i
->
iov_offset
=
off
;
i
->
idx
=
idx
;
pipe_truncate
(
i
);
return
;
}
if
(
unroll
<=
i
->
iov_offset
)
{
i
->
iov_offset
-=
unroll
;
return
;
}
unroll
-=
i
->
iov_offset
;
if
(
i
->
type
&
ITER_BVEC
)
{
const
struct
bio_vec
*
bvec
=
i
->
bvec
;
while
(
1
)
{
size_t
n
=
(
--
bvec
)
->
bv_len
;
i
->
nr_segs
++
;
if
(
unroll
<=
n
)
{
i
->
bvec
=
bvec
;
i
->
iov_offset
=
n
-
unroll
;
return
;
}
unroll
-=
n
;
}
}
else
{
/* same logics for iovec and kvec */
const
struct
iovec
*
iov
=
i
->
iov
;
while
(
1
)
{
size_t
n
=
(
--
iov
)
->
iov_len
;
i
->
nr_segs
++
;
if
(
unroll
<=
n
)
{
i
->
iov
=
iov
;
i
->
iov_offset
=
n
-
unroll
;
return
;
}
unroll
-=
n
;
}
}
}
EXPORT_SYMBOL
(
iov_iter_revert
);
/*
* Return the count of just the current iov_iter segment.
*/
...
...
@@ -839,6 +901,7 @@ void iov_iter_pipe(struct iov_iter *i, int direction,
i
->
idx
=
(
pipe
->
curbuf
+
pipe
->
nrbufs
)
&
(
pipe
->
buffers
-
1
);
i
->
iov_offset
=
0
;
i
->
count
=
count
;
i
->
start_idx
=
i
->
idx
;
}
EXPORT_SYMBOL
(
iov_iter_pipe
);
...
...
This diff is collapsed.
Click to expand it.
net/core/datagram.c
+
14
−
9
View file @
0e4c0ee5
...
...
@@ -398,7 +398,7 @@ int skb_copy_datagram_iter(const struct sk_buff *skb, int offset,
struct
iov_iter
*
to
,
int
len
)
{
int
start
=
skb_headlen
(
skb
);
int
i
,
copy
=
start
-
offset
;
int
i
,
copy
=
start
-
offset
,
start_off
=
offset
,
n
;
struct
sk_buff
*
frag_iter
;
trace_skb_copy_datagram_iovec
(
skb
,
len
);
...
...
@@ -407,11 +407,12 @@ int skb_copy_datagram_iter(const struct sk_buff *skb, int offset,
if
(
copy
>
0
)
{
if
(
copy
>
len
)
copy
=
len
;
if
(
copy_to_iter
(
skb
->
data
+
offset
,
copy
,
to
)
!=
copy
)
n
=
copy_to_iter
(
skb
->
data
+
offset
,
copy
,
to
);
offset
+=
n
;
if
(
n
!=
copy
)
goto
short_copy
;
if
((
len
-=
copy
)
==
0
)
return
0
;
offset
+=
copy
;
}
/* Copy paged appendix. Hmm... why does this look so complicated? */
...
...
@@ -425,13 +426,14 @@ int skb_copy_datagram_iter(const struct sk_buff *skb, int offset,
if
((
copy
=
end
-
offset
)
>
0
)
{
if
(
copy
>
len
)
copy
=
len
;
if
(
copy_page_to_iter
(
skb_frag_page
(
frag
),
n
=
copy_page_to_iter
(
skb_frag_page
(
frag
),
frag
->
page_offset
+
offset
-
start
,
copy
,
to
)
!=
copy
)
start
,
copy
,
to
);
offset
+=
n
;
if
(
n
!=
copy
)
goto
short_copy
;
if
(
!
(
len
-=
copy
))
return
0
;
offset
+=
copy
;
}
start
=
end
;
}
...
...
@@ -463,6 +465,7 @@ int skb_copy_datagram_iter(const struct sk_buff *skb, int offset,
*/
fault:
iov_iter_revert
(
to
,
offset
-
start_off
);
return
-
EFAULT
;
short_copy:
...
...
@@ -613,7 +616,7 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
__wsum
*
csump
)
{
int
start
=
skb_headlen
(
skb
);
int
i
,
copy
=
start
-
offset
;
int
i
,
copy
=
start
-
offset
,
start_off
=
offset
;
struct
sk_buff
*
frag_iter
;
int
pos
=
0
;
int
n
;
...
...
@@ -623,11 +626,11 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
if
(
copy
>
len
)
copy
=
len
;
n
=
csum_and_copy_to_iter
(
skb
->
data
+
offset
,
copy
,
csump
,
to
);
offset
+=
n
;
if
(
n
!=
copy
)
goto
fault
;
if
((
len
-=
copy
)
==
0
)
return
0
;
offset
+=
copy
;
pos
=
copy
;
}
...
...
@@ -649,12 +652,12 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
offset
-
start
,
copy
,
&
csum2
,
to
);
kunmap
(
page
);
offset
+=
n
;
if
(
n
!=
copy
)
goto
fault
;
*
csump
=
csum_block_add
(
*
csump
,
csum2
,
pos
);
if
(
!
(
len
-=
copy
))
return
0
;
offset
+=
copy
;
pos
+=
copy
;
}
start
=
end
;
...
...
@@ -687,6 +690,7 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
return
0
;
fault:
iov_iter_revert
(
to
,
offset
-
start_off
);
return
-
EFAULT
;
}
...
...
@@ -771,6 +775,7 @@ int skb_copy_and_csum_datagram_msg(struct sk_buff *skb,
}
return
0
;
csum_error:
iov_iter_revert
(
&
msg
->
msg_iter
,
chunk
);
return
-
EINVAL
;
fault:
return
-
EFAULT
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment