@@ -35,23 +35,28 @@
*
* lustre/utils/llverfs.c
*
- * ext3 Filesystem Verification Tool.
- * This program tests the correct operation of ext3 filesystem.
- * This tool have two working modes
+ * ext3/4 Filesystem Verification Tool.
+ *
+ * This program tests some correctness aspects of ext3/4 filesystem
+ * operation.
+ *
+ * This tool has two working modes
* 1. full mode
* 2. fast mode
- * The full mode is basic mode in which program creates a subdirectory
- * in the test fileysytem, writes n(files_in_dir, default=16) large(4GB) files
- * to the directory with the test pattern at the start of each 4kb block.
- * The test pattern contains timestamp, relative file offset and per file
- * unique idenfifier(inode number). this continues until whole filesystem is
- * full and then this tooll verifies that the data in all of the test files
- * is correct.
- * In the fast mode the tool creates a test directories with
- * EXT3_TOPDIR_FL flag set. the number of directories equals to the number
- * of block groups in the filesystem(e.g. 65536 directories for 8TB filesystem)
- * and then writes a single 1MB file in each directory. The tool then verifies
- * that the data in each file is correct.
+ *
+ * In full mode, the program creates a subdirectory in the test
+ * fileysytem, writes n(files_in_dir, default=32) large(4GB) files to
+ * the directory with the test pattern at the start of each 4kb block.
+ * The test pattern contains timestamp, relative file offset and per
+ * file unique identifier(inode number). This continues until the
+ * whole filesystem is full and then the tool verifies that the data
+ * in all of the test files is correct.
+ * In fast mode, the tool creates test directories with the
+ * EXT3_TOPDIR_FL flag set. The number of directories equals the
+ * number of block groups in the filesystem (e.g. 65536 directories
+ * for an 8TB filesystem) and then writes a single 1MB file in each
+ * directory. The tool then verifies that the data in each file is
+ * correct.
*/
#ifndef _GNU_SOURCE
@@ -178,7 +183,7 @@ static int open_file(const char *file, int flag)
* Verify_chunk: Verifies test pattern in each 4kB (BLOCKSIZE) is correct.
* Returns 0 if test offset and timestamp is correct otherwise 1.
*/
-int verify_chunk(char *chunk_buf, size_t chunksize,unsigned long long chunk_off,
+int verify_chunk(char *chunk_buf, size_t chunksize, unsigned long long chunk_off,
unsigned long long time_st, unsigned long long inode_st,
char *file)
{
@@ -231,6 +236,7 @@ int write_chunks(int fd, unsigned long long offset,unsigned long long write_end,
ino_t inode_st, const char *file)
{
unsigned long long stride;
+ ssize_t nwritten;
stride = full ? chunksize : (ONE_GB - chunksize);
for (offset = offset & ~(chunksize - 1); offset < write_end;
@@ -245,7 +251,7 @@ int write_chunks(int fd, unsigned long long offset,unsigned long long write_end,
if (!full && offset > chunksize) {
fill_chunk(chunk_buf, chunksize, offset, time_st,
inode_st);
- if (write(fd, chunk_buf, chunksize) < 0) {
+ if ((nwritten = write(fd, chunk_buf, chunksize)) < 0) {
if (errno == ENOSPC) {
errno_local = errno;
return 0;
@@ -255,12 +261,14 @@ int write_chunks(int fd, unsigned long long offset,unsigned long long write_end,
progname, file, offset,strerror(errno));
return errno;
}
- offset += chunksize;
+ if (nwritten < chunksize)
+ fprintf(stderr, "short write: offset=%llu, requested=%ld, written=%ld\n", offset, chunksize, nwritten);
+ offset += nwritten;
if (offset + chunksize > write_end)
chunksize = write_end - offset;
}
fill_chunk(chunk_buf, chunksize, offset, time_st, inode_st);
- if (write(fd, (char *) chunk_buf, chunksize) < 0) {
+ if ((nwritten = write(fd, (char *) chunk_buf, chunksize)) < 0) {
if (errno == ENOSPC) {
errno_local = errno;
return 0;
@@ -269,6 +277,8 @@ int write_chunks(int fd, unsigned long long offset,unsigned long long write_end,
progname, file, offset, strerror(errno));
return 1;
}
+ if (nwritten < chunksize)
+ fprintf(stderr, "short write: offset=%llu, requested=%ld, written=%ld\n", offset, chunksize, nwritten);
}
return 0;
}
@@ -282,6 +292,7 @@ int read_chunks(int fd, unsigned long long offset, unsigned long long read_end,
ino_t inode_st, char *file)
{
unsigned long long stride;
+ ssize_t nread;
stride = full ? chunksize : (ONE_GB - chunksize);
for (offset = offset & ~(chunksize - 1); offset < read_end;
@@ -294,25 +305,29 @@ int read_chunks(int fd, unsigned long long offset, unsigned long long read_end,
if (offset + chunksize > read_end)
chunksize = read_end - offset;
if (!full && offset > chunksize) {
- if (read(fd, chunk_buf, chunksize) < 0) {
+ if ((nread = read(fd, chunk_buf, chunksize)) < 0) {
fprintf(stderr,
"\n%s: read %s+%llu failed: %s\n",
progname, file, offset,strerror(errno));
return 1;
}
- if (verify_chunk(chunk_buf, chunksize, offset,
+ if (nread < chunksize)
+ fprintf(stderr, "short read: offset=%llu, requested=%ld, read=%ld\n", offset, chunksize, nread);
+ if (verify_chunk(chunk_buf, nread, offset,
time_st, inode_st, file) != 0)
return 1;
- offset += chunksize;
+ offset += nread;
if (offset + chunksize >= read_end)
chunksize = read_end - offset;
}
- if (read(fd, chunk_buf, chunksize) < 0) {
+ if ((nread = read(fd, chunk_buf, chunksize)) < 0) {
fprintf(stderr, "\n%s: read %s+%llu failed: %s\n",
progname, file, offset, strerror(errno));
return 1;
}
- if (verify_chunk(chunk_buf, chunksize, offset, time_st,
+ if (nread < chunksize)
+ fprintf(stderr, "short read: offset=%llu, requested=%ld, read=%ld\n", offset, chunksize, nread);
+ if (verify_chunk(chunk_buf, nread, offset, time_st,
inode_st, file) != 0)
return 1;
}