Skip to content

Commit

Permalink
fsx/fsstress: round blocksize properly
Browse files Browse the repository at this point in the history
The block sizes reported by stat and DIOINFO aren't required to be
powers of two.  This can happen on an XFS filesystem with a realtime
extent size that isn't a power of two; on such filesystems, certain IO
calls will fail due to alignment issues.  Fix that by providing rounding
helpers that work for all sizes.

Signed-off-by: Darrick J. Wong <[email protected]>
Reviewed-by: Christoph Hellwig <[email protected]>
Signed-off-by: Eryu Guan <[email protected]>
  • Loading branch information
Darrick J. Wong authored and guaneryu committed May 23, 2021
1 parent b77d5da commit 0049872
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 23 deletions.
24 changes: 12 additions & 12 deletions ltp/fsstress.c
Original file line number Diff line number Diff line change
Expand Up @@ -2140,7 +2140,7 @@ do_aio_rw(int opno, long r, int flags)
" fallback to stat()\n",
procid, opno, f.path, st, errno);
diob.d_mem = diob.d_miniosz = stb.st_blksize;
diob.d_maxiosz = INT_MAX & ~(diob.d_miniosz - 1);
diob.d_maxiosz = rounddown_64(INT_MAX, diob.d_miniosz);
}
dio_env = getenv("XFS_DIO_MIN");
if (dio_env)
Expand Down Expand Up @@ -2608,7 +2608,7 @@ clonerange_f(

/* Calculate offsets */
len = (random() % FILELEN_MAX) + 1;
len &= ~(stat1.st_blksize - 1);
len = rounddown_64(len, stat1.st_blksize);
if (len == 0)
len = stat1.st_blksize;
if (len > stat1.st_size)
Expand All @@ -2620,7 +2620,7 @@ clonerange_f(
else
off1 = (off64_t)(lr % MIN(stat1.st_size - len, MAXFSIZE));
off1 %= maxfsize;
off1 &= ~(stat1.st_blksize - 1);
off1 = rounddown_64(off1, stat1.st_blksize);

/*
* If srcfile == destfile, randomly generate destination ranges
Expand All @@ -2631,7 +2631,7 @@ clonerange_f(
lr = ((int64_t)random() << 32) + random();
off2 = (off64_t)(lr % max_off2);
off2 %= maxfsize;
off2 &= ~(stat2.st_blksize - 1);
off2 = rounddown_64(off2, stat2.st_blksize);
} while (stat1.st_ino == stat2.st_ino && llabs(off2 - off1) < len);

/* Clone data blocks */
Expand Down Expand Up @@ -2968,7 +2968,7 @@ deduperange_f(

/* Never try to dedupe more than half of the src file. */
len = (random() % FILELEN_MAX) + 1;
len &= ~(stat[0].st_blksize - 1);
len = rounddown_64(len, stat[0].st_blksize);
if (len == 0)
len = stat[0].st_blksize / 2;
if (len > stat[0].st_size / 2)
Expand All @@ -2981,7 +2981,7 @@ deduperange_f(
else
off[0] = (off64_t)(lr % MIN(stat[0].st_size - len, MAXFSIZE));
off[0] %= maxfsize;
off[0] &= ~(stat[0].st_blksize - 1);
off[0] = rounddown_64(off[0], stat[0].st_blksize);

/*
* If srcfile == destfile[i], randomly generate destination ranges
Expand All @@ -2997,7 +2997,7 @@ deduperange_f(
else
off[i] = (off64_t)(lr % MIN(stat[i].st_size - len, MAXFSIZE));
off[i] %= maxfsize;
off[i] &= ~(stat[i].st_blksize - 1);
off[i] = rounddown_64(off[i], stat[i].st_blksize);
} while (stat[0].st_ino == stat[i].st_ino &&
llabs(off[i] - off[0]) < len &&
tries++ < 10);
Expand Down Expand Up @@ -3406,7 +3406,7 @@ dread_f(int opno, long r)
" fallback to stat()\n",
procid, opno, f.path, st, errno);
diob.d_mem = diob.d_miniosz = stb.st_blksize;
diob.d_maxiosz = INT_MAX & ~(diob.d_miniosz - 1);
diob.d_maxiosz = rounddown_64(INT_MAX, diob.d_miniosz);
}

dio_env = getenv("XFS_DIO_MIN");
Expand Down Expand Up @@ -3483,7 +3483,7 @@ dwrite_f(int opno, long r)
" %s%s return %d, fallback to stat()\n",
procid, opno, f.path, st, errno);
diob.d_mem = diob.d_miniosz = stb.st_blksize;
diob.d_maxiosz = INT_MAX & ~(diob.d_miniosz - 1);
diob.d_maxiosz = rounddown_64(INT_MAX, diob.d_miniosz);
}

dio_env = getenv("XFS_DIO_MIN");
Expand Down Expand Up @@ -3579,8 +3579,8 @@ do_fallocate(int opno, long r, int mode)
*/
if ((mode & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE)) &&
(opno % 2)) {
off = ((off + stb.st_blksize - 1) & ~(stb.st_blksize - 1));
len = ((len + stb.st_blksize - 1) & ~(stb.st_blksize - 1));
off = roundup_64(off, stb.st_blksize);
len = roundup_64(len, stb.st_blksize);
}
mode |= FALLOC_FL_KEEP_SIZE & random();
e = fallocate(fd, mode, (loff_t)off, (loff_t)len) < 0 ? errno : 0;
Expand Down Expand Up @@ -4186,7 +4186,7 @@ do_mmap(int opno, long r, int prot)

lr = ((int64_t)random() << 32) + random();
off = (off64_t)(lr % stb.st_size);
off &= (off64_t)(~(sysconf(_SC_PAGE_SIZE) - 1));
off = rounddown_64(off, sysconf(_SC_PAGE_SIZE));
len = (size_t)(random() % MIN(stb.st_size - off, FILELEN_MAX)) + 1;

flags = (random() % 2) ? MAP_SHARED : MAP_PRIVATE;
Expand Down
22 changes: 11 additions & 11 deletions ltp/fsx.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ static void *round_ptr_up(void *ptr, unsigned long align, unsigned long offset)
{
unsigned long ret = (unsigned long)ptr;

ret = ((ret + align - 1) & ~(align - 1));
ret = roundup_64(ret, align);
ret += offset;
return (void *)ret;
}
Expand Down Expand Up @@ -1948,12 +1948,12 @@ static void generate_dest_range(bool bdy_align,

TRIM_OFF_LEN(*src_offset, *size, file_size);
if (bdy_align) {
*src_offset -= *src_offset % readbdy;
*src_offset = rounddown_64(*src_offset, readbdy);
if (o_direct)
*size -= *size % readbdy;
*size = rounddown_64(*size, readbdy);
} else {
*src_offset = *src_offset & ~(block_size - 1);
*size = *size & ~(block_size - 1);
*src_offset = rounddown_64(*src_offset, block_size);
*size = rounddown_64(*size, block_size);
}

do {
Expand All @@ -1964,9 +1964,9 @@ static void generate_dest_range(bool bdy_align,
*dst_offset = random();
TRIM_OFF(*dst_offset, max_range_end);
if (bdy_align)
*dst_offset -= *dst_offset % writebdy;
*dst_offset = rounddown_64(*dst_offset, writebdy);
else
*dst_offset = *dst_offset & ~(block_size - 1);
*dst_offset = rounddown_64(*dst_offset, block_size);
} while (range_overlaps(*src_offset, *dst_offset, *size) ||
*dst_offset + *size > max_range_end);
}
Expand Down Expand Up @@ -2156,8 +2156,8 @@ test(void)
break;
case OP_COLLAPSE_RANGE:
TRIM_OFF_LEN(offset, size, file_size - 1);
offset = offset & ~(block_size - 1);
size = size & ~(block_size - 1);
offset = rounddown_64(offset, block_size);
size = rounddown_64(size, block_size);
if (size == 0) {
log4(OP_COLLAPSE_RANGE, offset, size, FL_SKIPPED);
goto out;
Expand All @@ -2167,8 +2167,8 @@ test(void)
case OP_INSERT_RANGE:
TRIM_OFF(offset, file_size);
TRIM_LEN(file_size, size, maxfilelen);
offset = offset & ~(block_size - 1);
size = size & ~(block_size - 1);
offset = rounddown_64(offset, block_size);
size = rounddown_64(size, block_size);
if (size == 0) {
log4(OP_INSERT_RANGE, offset, size, FL_SKIPPED);
goto out;
Expand Down
13 changes: 13 additions & 0 deletions src/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,17 @@
#include <sys/mman.h>
#endif

static inline unsigned long long
rounddown_64(unsigned long long x, unsigned int y)
{
x /= y;
return x * y;
}

static inline unsigned long long
roundup_64(unsigned long long x, unsigned int y)
{
return rounddown_64(x + y - 1, y);
}

#endif /* GLOBAL_H */

0 comments on commit 0049872

Please sign in to comment.