mirror of
https://git.savannah.gnu.org/git/coreutils.git
synced 2025-09-10 07:59:52 +02:00
dd: support iflag=direct with arbitrary sized files
* src/dd.c (iread): Handle read error with a non-aligned file offset in the O_DIRECT case. This is not an issue on XFS at least, but on EXT4 the final read will return EINVAL rather than the expected 0 to indicate EOF. * tests/dd/direct.sh: Test the iflag=direct case also. * NEWS: Mention the improvement.
This commit is contained in:
2
NEWS
2
NEWS
@@ -37,6 +37,8 @@ GNU coreutils NEWS -*- outline -*-
|
||||
|
||||
** Improvements
|
||||
|
||||
dd now supports iflag=direct with arbitrary sized files on all file systems.
|
||||
|
||||
tail --bytes=NUM will efficiently seek to the end of block devices,
|
||||
rather than reading from the start.
|
||||
|
||||
|
||||
15
src/dd.c
15
src/dd.c
@@ -1108,11 +1108,21 @@ static ssize_t
|
||||
iread (int fd, char *buf, size_t size)
|
||||
{
|
||||
ssize_t nread;
|
||||
static ssize_t prev_nread;
|
||||
|
||||
do
|
||||
{
|
||||
process_signals ();
|
||||
nread = read (fd, buf, size);
|
||||
/* Ignore final read error with iflag=direct as that
|
||||
returns EINVAL due to the non aligned file offset. */
|
||||
if (nread == -1 && errno == EINVAL
|
||||
&& 0 < prev_nread && prev_nread < size
|
||||
&& (input_flags & O_DIRECT))
|
||||
{
|
||||
errno = 0;
|
||||
nread = 0;
|
||||
}
|
||||
}
|
||||
while (nread < 0 && errno == EINTR);
|
||||
|
||||
@@ -1122,8 +1132,6 @@ iread (int fd, char *buf, size_t size)
|
||||
|
||||
if (0 < nread && warn_partial_read)
|
||||
{
|
||||
static ssize_t prev_nread;
|
||||
|
||||
if (0 < prev_nread && prev_nread < size)
|
||||
{
|
||||
uintmax_t prev = prev_nread;
|
||||
@@ -1136,10 +1144,9 @@ iread (int fd, char *buf, size_t size)
|
||||
prev);
|
||||
warn_partial_read = false;
|
||||
}
|
||||
|
||||
prev_nread = nread;
|
||||
}
|
||||
|
||||
prev_nread = nread;
|
||||
return nread;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# ensure that dd's oflag=direct works
|
||||
# ensure that dd's iflag=direct and oflag=direct work
|
||||
|
||||
# Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
@@ -29,7 +29,7 @@ truncate -s 8193 p1 || framework_failure_
|
||||
|
||||
for i in short m1 p1; do
|
||||
rm -f out
|
||||
dd if=$i oflag=direct of=out || fail=1
|
||||
dd if=$i iflag=direct oflag=direct of=out || fail=1
|
||||
done
|
||||
|
||||
Exit $fail
|
||||
|
||||
Reference in New Issue
Block a user