* [PATCH v2 1/3] fsstress: new writev and readv operations test @ 2017-07-18 14:37 Zorro Lang 2017-07-18 14:37 ` [PATCH v2 2/3] fsstress: add AIO read/write and fsync test Zorro Lang 2017-07-18 14:37 ` [PATCH v2 3/3] xfs/068: update golden output due to new operations in fsstress Zorro Lang 0 siblings, 2 replies; 3+ messages in thread From: Zorro Lang @ 2017-07-18 14:37 UTC (permalink / raw) To: fstests We found some bugs by writev operations recently, writev can cover different test than normal write operation, so add writev and readv operations into fsstress. Signed-off-by: Zorro Lang <zlang@redhat.com> --- V2 patchset did below things: 1) changed writev_f and readv_f, write/read exact len bytes once, not random len and offset for writev/readv. 2) don't check errno after call io_setup/io_destroy 3) drop that randomly memset patch. 4) modify the garden image of xfs/068.out Thanks, Zorro ltp/fsstress.c | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) diff --git a/ltp/fsstress.c b/ltp/fsstress.c index e9fd2769..0ecc214c 100644 --- a/ltp/fsstress.c +++ b/ltp/fsstress.c @@ -18,6 +18,7 @@ #include <linux/fs.h> #include <setjmp.h> +#include <sys/uio.h> #include "global.h" #ifdef HAVE_ATTR_XATTR_H @@ -47,6 +48,9 @@ #define XFS_ERRTAG_MAX 17 #define XFS_IDMODULO_MAX 31 /* user/group IDs (1 << x) */ #define XFS_PROJIDMODULO_MAX 16 /* project IDs (1 << x) */ +#ifndef IOV_MAX +#define IOV_MAX 1024 +#endif #define FILELEN_MAX (32*4096) @@ -78,6 +82,7 @@ typedef enum { OP_INSERT, OP_READ, OP_READLINK, + OP_READV, OP_RENAME, OP_RESVSP, OP_RMDIR, @@ -90,6 +95,7 @@ typedef enum { OP_UNLINK, OP_UNRESVSP, OP_WRITE, + OP_WRITEV, OP_LAST } opty_t; @@ -179,6 +185,7 @@ void collapse_f(int, long); void insert_f(int, long); void read_f(int, long); void readlink_f(int, long); +void readv_f(int, long); void rename_f(int, long); void resvsp_f(int, long); void rmdir_f(int, long); @@ -191,6 +198,7 @@ void truncate_f(int, long); void unlink_f(int, long); void unresvsp_f(int, long); void write_f(int, long); +void writev_f(int, long); opdesc_t ops[] = { /* { OP_ENUM, "name", function, freq, iswrite }, */ @@ -221,6 +229,7 @@ opdesc_t ops[] = { { OP_INSERT, "insert", insert_f, 1, 1 }, { OP_READ, "read", read_f, 1, 0 }, { OP_READLINK, "readlink", readlink_f, 1, 0 }, + { OP_READV, "readv", readv_f, 1, 0 }, { OP_RENAME, "rename", rename_f, 2, 1 }, { OP_RESVSP, "resvsp", resvsp_f, 1, 1 }, { OP_RMDIR, "rmdir", rmdir_f, 1, 1 }, @@ -233,6 +242,7 @@ opdesc_t ops[] = { { OP_UNLINK, "unlink", unlink_f, 1, 1 }, { OP_UNRESVSP, "unresvsp", unresvsp_f, 1, 1 }, { OP_WRITE, "write", write_f, 4, 1 }, + { OP_WRITEV, "writev", writev_f, 4, 1 }, }, *ops_end; flist_t flist[FT_nft] = { @@ -2948,6 +2958,85 @@ readlink_f(int opno, long r) } void +readv_f(int opno, long r) +{ + char *buf; + int e; + pathname_t f; + int fd; + size_t len; + __int64_t lr; + off64_t off; + struct stat64 stb; + int v; + char st[1024]; + struct iovec *iov = NULL; + int iovcnt; + size_t iovb; + size_t iovl; + int i; + + init_pathname(&f); + if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) { + if (v) + printf("%d/%d: readv - no filename\n", procid, opno); + free_pathname(&f); + return; + } + fd = open_path(&f, O_RDONLY); + e = fd < 0 ? errno : 0; + check_cwd(); + if (fd < 0) { + if (v) + printf("%d/%d: readv - open %s failed %d\n", + procid, opno, f.path, e); + free_pathname(&f); + return; + } + if (fstat64(fd, &stb) < 0) { + if (v) + printf("%d/%d: readv - fstat64 %s failed %d\n", + procid, opno, f.path, errno); + free_pathname(&f); + close(fd); + return; + } + inode_info(st, sizeof(st), &stb, v); + if (stb.st_size == 0) { + if (v) + printf("%d/%d: readv - %s%s zero size\n", procid, opno, + f.path, st); + free_pathname(&f); + close(fd); + return; + } + lr = ((__int64_t)random() << 32) + random(); + off = (off64_t)(lr % stb.st_size); + lseek64(fd, off, SEEK_SET); + len = (random() % FILELEN_MAX) + 1; + buf = malloc(len); + + iovcnt = (random() % MIN(len, IOV_MAX)) + 1; + iov = calloc(iovcnt, sizeof(struct iovec)); + iovl = len / iovcnt; + iovb = 0; + for (i=0; i<iovcnt; i++) { + (iov + i)->iov_base = (buf + iovb); + (iov + i)->iov_len = iovl; + iovb += iovl; + } + + e = readv(fd, iov, iovcnt) < 0 ? errno : 0; + free(buf); + if (v) + printf("%d/%d: readv %s%s [%lld,%d,%d] %d\n", + procid, opno, f.path, st, (long long)off, (int)iovl, + iovcnt, e); + free_pathname(&f); + close(fd); +} + +void rename_f(int opno, long r) { fent_t *dfep; @@ -3379,3 +3468,77 @@ write_f(int opno, long r) free_pathname(&f); close(fd); } + +void +writev_f(int opno, long r) +{ + char *buf; + int e; + pathname_t f; + int fd; + size_t len; + __int64_t lr; + off64_t off; + struct stat64 stb; + int v; + char st[1024]; + struct iovec *iov = NULL; + int iovcnt; + size_t iovb; + size_t iovl; + int i; + + init_pathname(&f); + if (!get_fname(FT_REGm, r, &f, NULL, NULL, &v)) { + if (v) + printf("%d/%d: writev - no filename\n", procid, opno); + free_pathname(&f); + return; + } + fd = open_path(&f, O_WRONLY); + e = fd < 0 ? errno : 0; + check_cwd(); + if (fd < 0) { + if (v) + printf("%d/%d: writev - open %s failed %d\n", + procid, opno, f.path, e); + free_pathname(&f); + return; + } + if (fstat64(fd, &stb) < 0) { + if (v) + printf("%d/%d: writev - fstat64 %s failed %d\n", + procid, opno, f.path, errno); + free_pathname(&f); + close(fd); + return; + } + inode_info(st, sizeof(st), &stb, v); + lr = ((__int64_t)random() << 32) + random(); + off = (off64_t)(lr % MIN(stb.st_size + (1024 * 1024), MAXFSIZE)); + off %= maxfsize; + lseek64(fd, off, SEEK_SET); + len = (random() % FILELEN_MAX) + 1; + buf = malloc(len); + memset(buf, nameseq & 0xff, len); + + iovcnt = (random() % MIN(len, IOV_MAX)) + 1; + iov = calloc(iovcnt, sizeof(struct iovec)); + iovl = len / iovcnt; + iovb = 0; + for (i=0; i<iovcnt; i++) { + (iov + i)->iov_base = (buf + iovb); + (iov + i)->iov_len = iovl; + iovb += iovl; + } + + e = writev(fd, iov, iovcnt) < 0 ? errno : 0; + free(buf); + free(iov); + if (v) + printf("%d/%d: writev %s%s [%lld,%d,%d] %d\n", + procid, opno, f.path, st, (long long)off, (int)iovl, + iovcnt, e); + free_pathname(&f); + close(fd); +} -- 2.13.3 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v2 2/3] fsstress: add AIO read/write and fsync test 2017-07-18 14:37 [PATCH v2 1/3] fsstress: new writev and readv operations test Zorro Lang @ 2017-07-18 14:37 ` Zorro Lang 2017-07-18 14:37 ` [PATCH v2 3/3] xfs/068: update golden output due to new operations in fsstress Zorro Lang 1 sibling, 0 replies; 3+ messages in thread From: Zorro Lang @ 2017-07-18 14:37 UTC (permalink / raw) To: fstests We found some bugs by aio read/write test, but there's not related operations in fsstress. So add AIO test into fsstress to increase AIO stress test. Due to most kernels don't support aio fsync, so set its test frequency to zero as default. Signed-off-by: Zorro Lang <zlang@redhat.com> --- ltp/fsstress.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) diff --git a/ltp/fsstress.c b/ltp/fsstress.c index 0ecc214c..7ae7fdf2 100644 --- a/ltp/fsstress.c +++ b/ltp/fsstress.c @@ -36,6 +36,10 @@ #ifdef HAVE_SYS_PRCTL_H #include <sys/prctl.h> #endif +#ifdef AIO +#include <libaio.h> +io_context_t io_ctx; +#endif #ifndef FS_IOC_GETFLAGS #define FS_IOC_GETFLAGS _IOR('f', 1, long) @@ -55,9 +59,12 @@ #define FILELEN_MAX (32*4096) typedef enum { + OP_AFSYNC, OP_ALLOCSP, + OP_AREAD, OP_ATTR_REMOVE, OP_ATTR_SET, + OP_AWRITE, OP_BULKSTAT, OP_BULKSTAT1, OP_CHOWN, @@ -158,9 +165,12 @@ struct print_string { #define MAXFSIZE ((1ULL << 63) - 1ULL) #define MAXFSIZE32 ((1ULL << 40) - 1ULL) +void afsync_f(int, long); void allocsp_f(int, long); +void aread_f(int, long); void attr_remove_f(int, long); void attr_set_f(int, long); +void awrite_f(int, long); void bulkstat_f(int, long); void bulkstat1_f(int, long); void chown_f(int, long); @@ -202,9 +212,12 @@ void writev_f(int, long); opdesc_t ops[] = { /* { OP_ENUM, "name", function, freq, iswrite }, */ + { OP_AFSYNC, "afsync", afsync_f, 0, 1 }, { OP_ALLOCSP, "allocsp", allocsp_f, 1, 1 }, + { OP_AREAD, "aread", aread_f, 1, 0 }, { OP_ATTR_REMOVE, "attr_remove", attr_remove_f, /* 1 */ 0, 1 }, { OP_ATTR_SET, "attr_set", attr_set_f, /* 2 */ 0, 1 }, + { OP_AWRITE, "awrite", awrite_f, 1, 1 }, { OP_BULKSTAT, "bulkstat", bulkstat_f, 1, 0 }, { OP_BULKSTAT1, "bulkstat1", bulkstat1_f, 1, 0 }, { OP_CHOWN, "chown", chown_f, 3, 1 }, @@ -587,8 +600,20 @@ int main(int argc, char **argv) } } procid = i; +#ifdef AIO + if (io_setup(128, &io_ctx) != 0) { + fprintf(stderr, "io_setup failed"); + exit(1); + } +#endif for (i = 0; !loops || (i < loops); i++) doproc(); +#ifdef AIO + if(io_destroy(io_ctx) != 0) { + fprintf(stderr, "io_destroy failed"); + return 1; + } +#endif return 0; } } @@ -1708,6 +1733,62 @@ void inode_info(char *str, size_t sz, struct stat64 *s, int verbose) } void +afsync_f(int opno, long r) +{ +#ifdef AIO + int e; + pathname_t f; + int fd; + int v; + struct iocb iocb; + struct iocb *iocbs[] = { &iocb }; + struct io_event event; + + init_pathname(&f); + if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) { + if (v) + printf("%d/%d: afsync - no filename\n", procid, opno); + free_pathname(&f); + return; + } + fd = open_path(&f, O_WRONLY | O_DIRECT); + e = fd < 0 ? errno : 0; + check_cwd(); + if (fd < 0) { + if (v) + printf("%d/%d: afsync - open %s failed %d\n", + procid, opno, f.path, e); + free_pathname(&f); + return; + } + + io_prep_fsync(&iocb, fd); + if ((e = io_submit(io_ctx, 1, iocbs)) != 1) { + if (v) + printf("%d/%d: afsync - io_submit %s %d\n", + procid, opno, f.path, e); + free_pathname(&f); + close(fd); + return; + } + if ((e = io_getevents(io_ctx, 1, 1, &event, NULL)) != 1) { + if (v) + printf("%d/%d: afsync - io_getevents failed %d\n", + procid, opno, e); + free_pathname(&f); + close(fd); + return; + } + + e = event.res2; + if (v) + printf("%d/%d: afsync %s %d\n", procid, opno, f.path, e); + free_pathname(&f); + close(fd); +#endif +} + +void allocsp_f(int opno, long r) { int e; @@ -1761,6 +1842,131 @@ allocsp_f(int opno, long r) close(fd); } +#ifdef AIO +void +do_aio_rw(int opno, long r, int flags) +{ + __int64_t align; + char *buf; + struct dioattr diob; + int e; + pathname_t f; + int fd; + size_t len; + __int64_t lr; + off64_t off; + struct stat64 stb; + int v; + char st[1024]; + char *dio_env; + struct iocb iocb; + struct io_event event; + struct iocb *iocbs[] = { &iocb }; + int iswrite = (flags & (O_WRONLY | O_RDWR)) ? 1 : 0; + + init_pathname(&f); + if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) { + if (v) + printf("%d/%d: do_aio_rw - no filename\n", procid, opno); + free_pathname(&f); + return; + } + fd = open_path(&f, flags|O_DIRECT); + e = fd < 0 ? errno : 0; + check_cwd(); + if (fd < 0) { + if (v) + printf("%d/%d: do_aio_rw - open %s failed %d\n", + procid, opno, f.path, e); + free_pathname(&f); + return; + } + if (fstat64(fd, &stb) < 0) { + if (v) + printf("%d/%d: do_aio_rw - fstat64 %s failed %d\n", + procid, opno, f.path, errno); + free_pathname(&f); + close(fd); + return; + } + inode_info(st, sizeof(st), &stb, v); + if (!iswrite && stb.st_size == 0) { + if (v) + printf("%d/%d: do_aio_rw - %s%s zero size\n", procid, opno, + f.path, st); + free_pathname(&f); + close(fd); + return; + } + if (xfsctl(f.path, fd, XFS_IOC_DIOINFO, &diob) < 0) { + if (v) + printf( + "%d/%d: do_aio_rw - xfsctl(XFS_IOC_DIOINFO) %s%s failed %d\n", + procid, opno, f.path, st, errno); + free_pathname(&f); + close(fd); + return; + } + dio_env = getenv("XFS_DIO_MIN"); + if (dio_env) + diob.d_mem = diob.d_miniosz = atoi(dio_env); + align = (__int64_t)diob.d_miniosz; + lr = ((__int64_t)random() << 32) + random(); + len = (random() % FILELEN_MAX) + 1; + len -= (len % align); + if (len <= 0) + len = align; + else if (len > diob.d_maxiosz) + len = diob.d_maxiosz; + buf = memalign(diob.d_mem, len); + + if (iswrite) { + off = (off64_t)(lr % MIN(stb.st_size + (1024 * 1024), MAXFSIZE)); + off -= (off % align); + off %= maxfsize; + memset(buf, nameseq & 0xff, len); + io_prep_pwrite(&iocb, fd, buf, len, off); + } else { + off = (off64_t)(lr % stb.st_size); + off -= (off % align); + io_prep_pread(&iocb, fd, buf, len, off); + } + if ((e = io_submit(io_ctx, 1, iocbs)) != 1) { + if (v) + printf("%d/%d: %s - io_submit failed %d\n", + procid, opno, iswrite ? "awrite" : "aread", e); + free_pathname(&f); + close(fd); + return; + } + if ((e = io_getevents(io_ctx, 1, 1, &event, NULL)) != 1) { + if (v) + printf("%d/%d: %s - io_getevents failed %d\n", + procid, opno, iswrite ? "awrite" : "aread", e); + free_pathname(&f); + close(fd); + return; + } + + e = event.res != len ? event.res2 : 0; + free(buf); + if (v) + printf("%d/%d: %s %s%s [%lld,%d] %d\n", + procid, opno, iswrite ? "awrite" : "aread", + f.path, st, (long long)off, (int)len, e); + free_pathname(&f); + close(fd); +} +#endif + +void +aread_f(int opno, long r) +{ +#ifdef AIO + do_aio_rw(opno, r, O_RDONLY); +#endif +} + void attr_remove_f(int opno, long r) { @@ -1865,6 +2071,14 @@ attr_set_f(int opno, long r) } void +awrite_f(int opno, long r) +{ +#ifdef AIO + do_aio_rw(opno, r, O_WRONLY); +#endif +} + +void bulkstat_f(int opno, long r) { int count; -- 2.13.3 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v2 3/3] xfs/068: update golden output due to new operations in fsstress 2017-07-18 14:37 [PATCH v2 1/3] fsstress: new writev and readv operations test Zorro Lang 2017-07-18 14:37 ` [PATCH v2 2/3] fsstress: add AIO read/write and fsync test Zorro Lang @ 2017-07-18 14:37 ` Zorro Lang 1 sibling, 0 replies; 3+ messages in thread From: Zorro Lang @ 2017-07-18 14:37 UTC (permalink / raw) To: fstests I added some new operatoins to fsstress, and it changed the total number of test operstions. xfs/068 use a fixed seed (-s) and number of operations (-n) to run fsstress, to get fixed number of files and directories. Due to my patches break these fixed things, so update its expected result in golden image. Signed-off-by: Zorro Lang <zlang@redhat.com> --- tests/xfs/068.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/xfs/068.out b/tests/xfs/068.out index b20604f7..fa3a5523 100644 --- a/tests/xfs/068.out +++ b/tests/xfs/068.out @@ -22,7 +22,7 @@ xfsrestore: session id: ID xfsrestore: media ID: ID xfsrestore: searching media for directory dump xfsrestore: reading directories -xfsrestore: 474 directories and 1592 entries processed +xfsrestore: 383 directories and 1335 entries processed xfsrestore: directory post-processing xfsrestore: restoring non-directory files xfsrestore: restore complete: SECS seconds elapsed -- 2.13.3 ^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2017-07-18 14:37 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-07-18 14:37 [PATCH v2 1/3] fsstress: new writev and readv operations test Zorro Lang 2017-07-18 14:37 ` [PATCH v2 2/3] fsstress: add AIO read/write and fsync test Zorro Lang 2017-07-18 14:37 ` [PATCH v2 3/3] xfs/068: update golden output due to new operations in fsstress Zorro Lang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox