dd: fix handling of short result of full_write(), closes 11711
$ dd bs=1G <sda1 of=/dev/sda1 dd: error writing '/dev/sda1': No space left on device 1+0 records in 0+0 records out 999292928 bytes (953.0MB) copied, 0.784617 seconds, 1.2GB/s function old new delta write_and_stats 99 102 +3 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
8c317f03f6
commit
875ce094cf
@ -192,23 +192,15 @@ static void dd_output_status(int UNUSED_PARAM cur_signal)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t full_write_or_warn(const void *buf, size_t len,
|
|
||||||
const char *const filename)
|
|
||||||
{
|
|
||||||
ssize_t n = full_write(ofd, buf, len);
|
|
||||||
if (n < 0)
|
|
||||||
bb_perror_msg("writing '%s'", filename);
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool write_and_stats(const void *buf, size_t len, size_t obs,
|
static bool write_and_stats(const void *buf, size_t len, size_t obs,
|
||||||
const char *filename)
|
const char *filename)
|
||||||
{
|
{
|
||||||
ssize_t n = full_write_or_warn(buf, len, filename);
|
ssize_t n;
|
||||||
if (n < 0)
|
|
||||||
return 1;
|
n = full_write(ofd, buf, len);
|
||||||
#if ENABLE_FEATURE_DD_THIRD_STATUS_LINE
|
#if ENABLE_FEATURE_DD_THIRD_STATUS_LINE
|
||||||
G.total_bytes += n;
|
if (n > 0)
|
||||||
|
G.total_bytes += n;
|
||||||
#endif
|
#endif
|
||||||
if ((size_t)n == obs) {
|
if ((size_t)n == obs) {
|
||||||
G.out_full++;
|
G.out_full++;
|
||||||
@ -218,6 +210,14 @@ static bool write_and_stats(const void *buf, size_t len, size_t obs,
|
|||||||
G.out_part++;
|
G.out_part++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/* n is < len (and possibly is -1).
|
||||||
|
* Even if n >= 0, errno is usually set correctly.
|
||||||
|
* For example, if writing to block device and getting ENOSPC,
|
||||||
|
* full_write() first sees a short write, then tries to write
|
||||||
|
* the remainder and gets errno set to ENOSPC.
|
||||||
|
* It returns n > 0 (the amount which it did write).
|
||||||
|
*/
|
||||||
|
bb_perror_msg("error writing '%s'", filename);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,8 @@
|
|||||||
/*
|
/*
|
||||||
* Write all of the supplied buffer out to a file.
|
* Write all of the supplied buffer out to a file.
|
||||||
* This does multiple writes as necessary.
|
* This does multiple writes as necessary.
|
||||||
* Returns the amount written, or -1 on an error.
|
* Returns the amount written, or -1 if error was seen
|
||||||
|
* on the very first write.
|
||||||
*/
|
*/
|
||||||
ssize_t FAST_FUNC full_write(int fd, const void *buf, size_t len)
|
ssize_t FAST_FUNC full_write(int fd, const void *buf, size_t len)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user