On Mon, Aug 04, 2014 at 08:41:25AM +0200, Marcin Wolcendorf wrote:
> It is funny, because when I try to shrink it to 4269800000, the e2fsck
> complains about something
If resize2fs aborts with an error, it's not surprising that e2fsck
will have some things to clean up. So that's not at all surprising.
Looking at your strace output, the error is coming from this write:
lseek(3, 4096, SEEK_SET) = 4096
write(3,
"\366\7\0\0\6\10\0\0\26\10\0\0\0\0\365\17\2\0\4\0\0\0\0\0\0\0\0\0\365\17o\361"...,
8343552) = 8339456
8343552 == 8148k (2037 4k blocks)
8339456 == 8144k (2036 4k blocks)
This corresponds to this request:
Test_io: write_blk64(1, 2037)
which is where we are updating the block group descriptors. For some
reason, the kernel is reporting that it only successfully written 2036
blocks, instead of the 2037 blocks in the block group descriptors.
When writing to hard drives, the kernel should only report a short
write when there is an I/O error. Or at least, that's what the code
in lib/ext2fs/unix_io.c is assuming, and in general, it's always held
true.
What's interesting is that the corresponding read worked just fine at
the beginning of the strace:
read(3,
"\366\7\0\0\6\10\0\0\26\10\0\0\0\0\365\17\2\0\4\0\0\0\0\0\0\0\0\0\365\17o\361"...,
8343552) = 8343552
So it's unlikely to be a hardware error, which makes sense since you
reported that there was no problems that you found in
/var/log/messages or dmesg.
So the only thing I can think of at this point is that it's a bug in
in devicemapper, where if a write spans a stripe, it's returning the
results in two reads, instead of one.
Hmm. Ok, can you give me the outputs to the following two commands,
run as root:
vgdisplay home_move
lvdisplay --maps /dev/home_move/home_move_tmp
Also, can you try compiling and running the following program?
- Ted
/*
* test-read.c
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#define SIZE 8343552
unsigned char buf[SIZE];
int main(int argc, char **argv)
{
int fd;
ssize_t actual, left;
unsigned char *cp;
if (argc != 2) {
fprintf(stderr, "Usage: %s device\n", argv[0]);
exit(1);
}
fd = open(argv[1], O_RDWR);
if (fd < 0) {
perror("open");
exit(1);
}
if (lseek(fd, 4096, SEEK_SET) == (off_t) -1) {
perror("lseek");
exit(1);
}
actual = read(fd, buf, SIZE);
if (actual != SIZE) {
if (actual < 0)
perror("read");
else
fprintf(stderr, "%d bytes read, expected %d\n",
actual, SIZE);
exit(1);
}
if (lseek(fd, 4096, SEEK_SET) == (off_t) -1) {
perror("lseek 2");
exit(1);
}
actual = write(fd, buf, SIZE);
if (actual == SIZE) {
printf("successful write, finishing\n");
exit(0);
}
if (actual < 0) {
perror("write");
exit(1);
}
if (actual > SIZE) {
fprintf(stderr, "%d bytes written, expected %d ?!?\n",
actual, SIZE);
exit(1);
}
left = SIZE - actual;
cp = buf + actual;
actual = write(fd, cp, left);
if (actual != left) {
if (actual < 0)
perror("2nd write");
else
fprintf(stderr, "%d bytes write, expected %d (2)\n",
actual, SIZE);
exit(1);
}
printf("Secondary write succeeded\n");
exit(0);
}
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]