* [f2fs-dev] [PATCH 0/2] f2fs-tools: add 'copy' command to f2fs_io @ 2019-10-04 22:43 Eric Biggers 2019-10-04 22:43 ` [f2fs-dev] [PATCH 1/2] f2fs_io: add helper functions for handling errors Eric Biggers 2019-10-04 22:43 ` [f2fs-dev] [PATCH 2/2] f2fs_io: add copy command Eric Biggers 0 siblings, 2 replies; 4+ messages in thread From: Eric Biggers @ 2019-10-04 22:43 UTC (permalink / raw) To: linux-f2fs-devel, Jaegeuk Kim Add a copy command to f2fs_io, to allow testing direct I/O writes where the source page is from a different file (mmap) or an internal kernel page (sendfile). It could be useful for other tests in the future too. Eric Biggers (2): f2fs_io: add helper functions for handling errors f2fs_io: add copy command tools/f2fs_io/f2fs_io.c | 363 +++++++++++++++++++++++++--------------- 1 file changed, 229 insertions(+), 134 deletions(-) -- 2.23.0.581.g78d2f28ef7-goog _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel ^ permalink raw reply [flat|nested] 4+ messages in thread
* [f2fs-dev] [PATCH 1/2] f2fs_io: add helper functions for handling errors 2019-10-04 22:43 [f2fs-dev] [PATCH 0/2] f2fs-tools: add 'copy' command to f2fs_io Eric Biggers @ 2019-10-04 22:43 ` Eric Biggers 2019-10-15 7:03 ` Chao Yu 2019-10-04 22:43 ` [f2fs-dev] [PATCH 2/2] f2fs_io: add copy command Eric Biggers 1 sibling, 1 reply; 4+ messages in thread From: Eric Biggers @ 2019-10-04 22:43 UTC (permalink / raw) To: linux-f2fs-devel, Jaegeuk Kim From: Eric Biggers <ebiggers@google.com> Add and use helper functions for: - Printing an error message (optionally with errno) and exiting. - Allocating memory, exiting on error. - Opening a file, exiting on error. Signed-off-by: Eric Biggers <ebiggers@google.com> --- tools/f2fs_io/f2fs_io.c | 255 +++++++++++++++++++--------------------- 1 file changed, 121 insertions(+), 134 deletions(-) diff --git a/tools/f2fs_io/f2fs_io.c b/tools/f2fs_io/f2fs_io.c index add40c4..f5493ff 100644 --- a/tools/f2fs_io/f2fs_io.c +++ b/tools/f2fs_io/f2fs_io.c @@ -19,18 +19,21 @@ #define O_LARGEFILE 0 #endif -#include <stdio.h> +#include <errno.h> #include <fcntl.h> +#include <inttypes.h> +#include <signal.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> -#include <unistd.h> -#include <time.h> -#include <inttypes.h> #include <string.h> -#include <signal.h> -#include <termios.h> -#include <sys/types.h> #include <sys/stat.h> +#include <sys/types.h> +#include <termios.h> +#include <time.h> +#include <unistd.h> #ifdef HAVE_CONFIG_H #include "config.h" @@ -45,6 +48,63 @@ struct cmd_desc { int cmd_flags; }; +static void __attribute__((noreturn)) +do_die(const char *format, va_list va, int err) +{ + vfprintf(stderr, format, va); + if (err) + fprintf(stderr, ": %s", strerror(err)); + putc('\n', stderr); + exit(1); +} + +static void __attribute__((noreturn, format(printf, 1, 2))) +die_errno(const char *format, ...) +{ + va_list va; + + va_start(va, format); + do_die(format, va, errno); + va_end(va); +} + +static void __attribute__((noreturn, format(printf, 1, 2))) +die(const char *format, ...) +{ + va_list va; + + va_start(va, format); + do_die(format, va, 0); + va_end(va); +} + +static void *xmalloc(size_t size) +{ + void *p = malloc(size); + + if (!p) + die("Memory alloc failed (requested %zu bytes)", size); + return p; +} + +static void *aligned_xalloc(size_t alignment, size_t size) +{ + void *p = aligned_alloc(alignment, size); + + if (!p) + die("Memory alloc failed (requested %zu bytes)", size); + return p; +} + +static int xopen(const char *pathname, int flags, mode_t mode) +{ + int fd = open(pathname, flags, mode); + + if (fd < 0) + die_errno("Failed to open %s", pathname); + return fd; +} + #define getflags_desc "getflags ioctl" #define getflags_help \ "f2fs_io getflags [file]\n\n" \ @@ -66,12 +126,7 @@ static void do_getflags(int argc, char **argv, const struct cmd_desc *cmd) exit(1); } - fd = open(argv[1], O_RDONLY); - if (fd == -1) { - fputs("Open failed\n\n", stderr); - fputs(cmd->cmd_help, stderr); - exit(1); - } + fd = xopen(argv[1], O_RDONLY, 0); ret = ioctl(fd, F2FS_IOC_GETFLAGS, &flag); printf("get a flag on %s ret=%d, flags=", argv[1], ret); @@ -117,17 +172,12 @@ static void do_setflags(int argc, char **argv, const struct cmd_desc *cmd) exit(1); } - fd = open(argv[2], O_RDONLY); - if (fd == -1) { - fputs("Open failed\n\n", stderr); - fputs(cmd->cmd_help, stderr); - exit(1); - } + fd = xopen(argv[2], O_RDONLY, 0); ret = ioctl(fd, F2FS_IOC_GETFLAGS, &flag); printf("get a flag on %s ret=%d, flags=%lx\n", argv[1], ret, flag); if (ret) - exit(1); + die_errno("F2FS_IOC_GETFLAGS failed"); if (!strcmp(argv[1], "casefold")) flag |= FS_CASEFOLD_FL; @@ -169,18 +219,12 @@ static void do_shutdown(int argc, char **argv, const struct cmd_desc *cmd) fputs(cmd->cmd_help, stderr); exit(1); } - fd = open(argv[2], O_RDONLY); - if (fd == -1) { - fputs("Open failed\n\n", stderr); - fputs(cmd->cmd_help, stderr); - exit(1); - } + fd = xopen(argv[2], O_RDONLY, 0); ret = ioctl(fd, F2FS_IOC_SHUTDOWN, &flag); - if (ret < 0) { - perror("F2FS_IOC_SHUTDOWN"); - exit(1); - } + if (ret < 0) + die_errno("F2FS_IOC_SHUTDOWN failed"); + printf("Shutdown %s with level=%d\n", argv[2], flag); exit(0); } @@ -201,35 +245,26 @@ static void do_pinfile(int argc, char **argv, const struct cmd_desc *cmd) exit(1); } - fd = open(argv[2], O_RDWR); - if (fd == -1) { - fputs("Open failed\n\n", stderr); - fputs(cmd->cmd_help, stderr); - exit(1); - } + fd = xopen(argv[2], O_RDWR, 0); ret = -1; if (!strcmp(argv[1], "set")) { pin = 1; ret = ioctl(fd, F2FS_IOC_SET_PIN_FILE, &pin); - if (ret != 0) { - perror("set_pin_file failed"); - exit(1); - } + if (ret != 0) + die_errno("F2FS_IOC_SET_PIN_FILE failed"); printf("set_pin_file: %u blocks moved in %s\n", ret, argv[2]); } else if (!strcmp(argv[1], "get")) { unsigned int flags; ret = ioctl(fd, F2FS_IOC_GET_PIN_FILE, &pin); - if (ret < 0) { - perror("pin_file failed"); - exit(1); - } + if (ret < 0) + die_errno("F2FS_IOC_GET_PIN_FILE failed"); + ret = ioctl(fd, F2FS_IOC_GETFLAGS, &flags); - if (ret < 0) { - perror("get flags failed"); - exit(1); - } + if (ret < 0) + die_errno("F2FS_IOC_GETFLAGS failed"); + printf("get_pin_file: %s with %u blocks moved in %s\n", (flags & F2FS_NOCOW_FL) ? "pinned" : "un-pinned", pin, argv[2]); @@ -262,21 +297,14 @@ static void do_fallocate(int argc, char **argv, const struct cmd_desc *cmd) offset = atoi(argv[2]); length = atoi(argv[3]); - fd = open(argv[4], O_RDWR); - if (fd == -1) { - fputs("Open failed\n\n", stderr); - fputs(cmd->cmd_help, stderr); - exit(1); - } + fd = xopen(argv[4], O_RDWR, 0); + + if (fallocate(fd, mode, offset, length) != 0) + die_errno("fallocate failed"); + + if (fstat(fd, &sb) != 0) + die_errno("fstat failed"); - if (fallocate(fd, mode, offset, length)) { - fputs("fallocate failed\n\n", stderr); - exit(1); - } - if (fstat(fd, &sb) == -1) { - fputs("Stat failed\n\n", stderr); - exit(1); - } printf("fallocated a file: i_size=%"PRIu64", i_blocks=%"PRIu64"\n", sb.st_size, sb.st_blocks); exit(0); } @@ -311,41 +339,27 @@ static void do_write(int argc, char **argv, const struct cmd_desc *cmd) } bs = atoi(argv[1]); - if (bs > 1024) { - fputs("Too big chunk size - limit: 4MB\n\n", stderr); - exit(1); - } + if (bs > 1024) + die("Too big chunk size - limit: 4MB"); + buf_size = bs * 4096; offset = atoi(argv[2]) * buf_size; - buf = aligned_alloc(4096, buf_size); - if (!buf) { - fputs("Memory alloc failed\n\n", stderr); - exit(1); - } + buf = aligned_xalloc(4096, buf_size); count = atoi(argv[3]); - if (!strcmp(argv[4], "zero")) { + if (!strcmp(argv[4], "zero")) memset(buf, 0, buf_size); - } else if (strcmp(argv[4], "inc_num") && - strcmp(argv[4], "rand")) { - fputs("Wrong pattern type\n\n", stderr); - exit(1); - } + else if (strcmp(argv[4], "inc_num") && strcmp(argv[4], "rand")) + die("Wrong pattern type"); - if (!strcmp(argv[5], "dio")) { + if (!strcmp(argv[5], "dio")) flags |= O_DIRECT; - } else if (strcmp(argv[5], "buffered")) { - fputs("Wrong IO type\n\n", stderr); - exit(1); - } + else if (strcmp(argv[5], "buffered")) + die("Wrong IO type"); - fd = open(argv[6], O_CREAT | O_WRONLY | flags, 0755); - if (fd == -1) { - fputs("Open failed\n\n", stderr); - exit(1); - } + fd = xopen(argv[6], O_CREAT | O_WRONLY | flags, 0755); for (i = 0; i < count; i++) { if (!strcmp(argv[4], "inc_num")) @@ -389,43 +403,27 @@ static void do_read(int argc, char **argv, const struct cmd_desc *cmd) } bs = atoi(argv[1]); - if (bs > 1024) { - fputs("Too big chunk size - limit: 4MB\n\n", stderr); - exit(1); - } + if (bs > 1024) + die("Too big chunk size - limit: 4MB"); buf_size = bs * 4096; offset = atoi(argv[2]) * buf_size; - buf = aligned_alloc(4096, buf_size); - if (!buf) { - fputs("Memory alloc failed\n\n", stderr); - exit(1); - } + buf = aligned_xalloc(4096, buf_size); + count = atoi(argv[3]); - if (!strcmp(argv[4], "dio")) { + if (!strcmp(argv[4], "dio")) flags |= O_DIRECT; - } else if (strcmp(argv[4], "buffered")) { - fputs("Wrong IO type\n\n", stderr); - exit(1); - } + else if (strcmp(argv[4], "buffered")) + die("Wrong IO type"); print_bytes = atoi(argv[5]); - if (print_bytes > buf_size) { - fputs("Print_nbytes should be less then chunk_size in kb\n\n", stderr); - exit(1); - } - print_buf = malloc(print_bytes); - if (!print_buf) { - fputs("Memory alloc failed\n\n", stderr); - exit(1); - } + if (print_bytes > buf_size) + die("Print_nbytes should be less then chunk_size in kb"); - fd = open(argv[6], O_RDONLY | flags); - if (fd == -1) { - fputs("Open failed\n\n", stderr); - exit(1); - } + print_buf = xmalloc(print_bytes); + + fd = xopen(argv[6], O_RDONLY | flags, 0); for (i = 0; i < count; i++) { ret = pread(fd, buf, buf_size, offset + buf_size * i); @@ -480,20 +478,15 @@ static void do_fiemap(int argc, char **argv, const struct cmd_desc *cmd) offset = atoi(argv[1]); count = atoi(argv[2]); - fd = open(argv[3], O_RDONLY | O_LARGEFILE); - if (fd == -1) { - fputs("Open failed\n\n", stderr); - exit(1); - } + fd = xopen(argv[3], O_RDONLY | O_LARGEFILE, 0); printf("Fiemap: offset = %08"PRIx64" len = %d\n", offset, count); for (i = 0; i < count; i++) { blknum = offset + i; - if (ioctl(fd, FIBMAP, &blknum) < 0) { - fputs("FIBMAP failed\n\n", stderr); - exit(1); - } + if (ioctl(fd, FIBMAP, &blknum) < 0) + die_errno("FIBMAP failed"); + printf("%u ", blknum); } printf("\n"); @@ -559,18 +552,12 @@ static void do_defrag_file(int argc, char **argv, const struct cmd_desc *cmd) df.start = atoll(argv[1]); df.len = len = atoll(argv[2]); - fd = open(argv[3], O_RDWR); - if (fd == -1) { - fputs("Open failed\n\n", stderr); - fputs(cmd->cmd_help, stderr); - exit(1); - } + fd = xopen(argv[3], O_RDWR, 0); ret = ioctl(fd, F2FS_IOC_DEFRAGMENT, &df); - if (ret < 0) { - perror("F2FS_IOC_DEFRAGMENT"); - exit(1); - } + if (ret < 0) + die_errno("F2FS_IOC_DEFRAGMENT failed"); + printf("defrag %s in region[%"PRIu64", %"PRIu64"]\n", argv[3], df.start, df.start + len); exit(0); -- 2.23.0.581.g78d2f28ef7-goog _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [f2fs-dev] [PATCH 1/2] f2fs_io: add helper functions for handling errors 2019-10-04 22:43 ` [f2fs-dev] [PATCH 1/2] f2fs_io: add helper functions for handling errors Eric Biggers @ 2019-10-15 7:03 ` Chao Yu 0 siblings, 0 replies; 4+ messages in thread From: Chao Yu @ 2019-10-15 7:03 UTC (permalink / raw) To: Eric Biggers, linux-f2fs-devel, Jaegeuk Kim On 2019/10/5 6:43, Eric Biggers wrote: > From: Eric Biggers <ebiggers@google.com> > > Add and use helper functions for: > > - Printing an error message (optionally with errno) and exiting. > - Allocating memory, exiting on error. > - Opening a file, exiting on error. > > Signed-off-by: Eric Biggers <ebiggers@google.com> > --- > tools/f2fs_io/f2fs_io.c | 255 +++++++++++++++++++--------------------- > 1 file changed, 121 insertions(+), 134 deletions(-) > > diff --git a/tools/f2fs_io/f2fs_io.c b/tools/f2fs_io/f2fs_io.c > index add40c4..f5493ff 100644 > --- a/tools/f2fs_io/f2fs_io.c > +++ b/tools/f2fs_io/f2fs_io.c > @@ -19,18 +19,21 @@ > #define O_LARGEFILE 0 > #endif > > -#include <stdio.h> > +#include <errno.h> > #include <fcntl.h> > +#include <inttypes.h> > +#include <signal.h> > +#include <stdarg.h> > +#include <stdbool.h> > +#include <stdio.h> > #include <stdlib.h> > #include <string.h> > -#include <unistd.h> > -#include <time.h> > -#include <inttypes.h> > #include <string.h> > -#include <signal.h> > -#include <termios.h> > -#include <sys/types.h> > #include <sys/stat.h> > +#include <sys/types.h> > +#include <termios.h> > +#include <time.h> > +#include <unistd.h> > > #ifdef HAVE_CONFIG_H > #include "config.h" > @@ -45,6 +48,63 @@ struct cmd_desc { > int cmd_flags; > }; > > +static void __attribute__((noreturn)) > +do_die(const char *format, va_list va, int err) > +{ > + vfprintf(stderr, format, va); > + if (err) > + fprintf(stderr, ": %s", strerror(err)); > + putc('\n', stderr); > + exit(1); > +} > + > +static void __attribute__((noreturn, format(printf, 1, 2))) > +die_errno(const char *format, ...) > +{ > + va_list va; > + > + va_start(va, format); > + do_die(format, va, errno); > + va_end(va); > +} > + > +static void __attribute__((noreturn, format(printf, 1, 2))) > +die(const char *format, ...) > +{ > + va_list va; > + > + va_start(va, format); > + do_die(format, va, 0); > + va_end(va); > +} > + > +static void *xmalloc(size_t size) Hi Eric, How do you think of renaming wrapped functions to do_malloc(), do_open(), do_aligned_alloc() instead of adding a 'x' prefix? Thanks, > +{ > + void *p = malloc(size); > + > + if (!p) > + die("Memory alloc failed (requested %zu bytes)", size); > + return p; > +} > + > +static void *aligned_xalloc(size_t alignment, size_t size) > +{ > + void *p = aligned_alloc(alignment, size); > + > + if (!p) > + die("Memory alloc failed (requested %zu bytes)", size); > + return p; > +} > + > +static int xopen(const char *pathname, int flags, mode_t mode) > +{ > + int fd = open(pathname, flags, mode); > + > + if (fd < 0) > + die_errno("Failed to open %s", pathname); > + return fd; > +} > + > #define getflags_desc "getflags ioctl" > #define getflags_help \ > "f2fs_io getflags [file]\n\n" \ > @@ -66,12 +126,7 @@ static void do_getflags(int argc, char **argv, const struct cmd_desc *cmd) > exit(1); > } > > - fd = open(argv[1], O_RDONLY); > - if (fd == -1) { > - fputs("Open failed\n\n", stderr); > - fputs(cmd->cmd_help, stderr); > - exit(1); > - } > + fd = xopen(argv[1], O_RDONLY, 0); > > ret = ioctl(fd, F2FS_IOC_GETFLAGS, &flag); > printf("get a flag on %s ret=%d, flags=", argv[1], ret); > @@ -117,17 +172,12 @@ static void do_setflags(int argc, char **argv, const struct cmd_desc *cmd) > exit(1); > } > > - fd = open(argv[2], O_RDONLY); > - if (fd == -1) { > - fputs("Open failed\n\n", stderr); > - fputs(cmd->cmd_help, stderr); > - exit(1); > - } > + fd = xopen(argv[2], O_RDONLY, 0); > > ret = ioctl(fd, F2FS_IOC_GETFLAGS, &flag); > printf("get a flag on %s ret=%d, flags=%lx\n", argv[1], ret, flag); > if (ret) > - exit(1); > + die_errno("F2FS_IOC_GETFLAGS failed"); > > if (!strcmp(argv[1], "casefold")) > flag |= FS_CASEFOLD_FL; > @@ -169,18 +219,12 @@ static void do_shutdown(int argc, char **argv, const struct cmd_desc *cmd) > fputs(cmd->cmd_help, stderr); > exit(1); > } > - fd = open(argv[2], O_RDONLY); > - if (fd == -1) { > - fputs("Open failed\n\n", stderr); > - fputs(cmd->cmd_help, stderr); > - exit(1); > - } > + fd = xopen(argv[2], O_RDONLY, 0); > > ret = ioctl(fd, F2FS_IOC_SHUTDOWN, &flag); > - if (ret < 0) { > - perror("F2FS_IOC_SHUTDOWN"); > - exit(1); > - } > + if (ret < 0) > + die_errno("F2FS_IOC_SHUTDOWN failed"); > + > printf("Shutdown %s with level=%d\n", argv[2], flag); > exit(0); > } > @@ -201,35 +245,26 @@ static void do_pinfile(int argc, char **argv, const struct cmd_desc *cmd) > exit(1); > } > > - fd = open(argv[2], O_RDWR); > - if (fd == -1) { > - fputs("Open failed\n\n", stderr); > - fputs(cmd->cmd_help, stderr); > - exit(1); > - } > + fd = xopen(argv[2], O_RDWR, 0); > > ret = -1; > if (!strcmp(argv[1], "set")) { > pin = 1; > ret = ioctl(fd, F2FS_IOC_SET_PIN_FILE, &pin); > - if (ret != 0) { > - perror("set_pin_file failed"); > - exit(1); > - } > + if (ret != 0) > + die_errno("F2FS_IOC_SET_PIN_FILE failed"); > printf("set_pin_file: %u blocks moved in %s\n", ret, argv[2]); > } else if (!strcmp(argv[1], "get")) { > unsigned int flags; > > ret = ioctl(fd, F2FS_IOC_GET_PIN_FILE, &pin); > - if (ret < 0) { > - perror("pin_file failed"); > - exit(1); > - } > + if (ret < 0) > + die_errno("F2FS_IOC_GET_PIN_FILE failed"); > + > ret = ioctl(fd, F2FS_IOC_GETFLAGS, &flags); > - if (ret < 0) { > - perror("get flags failed"); > - exit(1); > - } > + if (ret < 0) > + die_errno("F2FS_IOC_GETFLAGS failed"); > + > printf("get_pin_file: %s with %u blocks moved in %s\n", > (flags & F2FS_NOCOW_FL) ? "pinned" : "un-pinned", > pin, argv[2]); > @@ -262,21 +297,14 @@ static void do_fallocate(int argc, char **argv, const struct cmd_desc *cmd) > offset = atoi(argv[2]); > length = atoi(argv[3]); > > - fd = open(argv[4], O_RDWR); > - if (fd == -1) { > - fputs("Open failed\n\n", stderr); > - fputs(cmd->cmd_help, stderr); > - exit(1); > - } > + fd = xopen(argv[4], O_RDWR, 0); > + > + if (fallocate(fd, mode, offset, length) != 0) > + die_errno("fallocate failed"); > + > + if (fstat(fd, &sb) != 0) > + die_errno("fstat failed"); > > - if (fallocate(fd, mode, offset, length)) { > - fputs("fallocate failed\n\n", stderr); > - exit(1); > - } > - if (fstat(fd, &sb) == -1) { > - fputs("Stat failed\n\n", stderr); > - exit(1); > - } > printf("fallocated a file: i_size=%"PRIu64", i_blocks=%"PRIu64"\n", sb.st_size, sb.st_blocks); > exit(0); > } > @@ -311,41 +339,27 @@ static void do_write(int argc, char **argv, const struct cmd_desc *cmd) > } > > bs = atoi(argv[1]); > - if (bs > 1024) { > - fputs("Too big chunk size - limit: 4MB\n\n", stderr); > - exit(1); > - } > + if (bs > 1024) > + die("Too big chunk size - limit: 4MB"); > + > buf_size = bs * 4096; > > offset = atoi(argv[2]) * buf_size; > > - buf = aligned_alloc(4096, buf_size); > - if (!buf) { > - fputs("Memory alloc failed\n\n", stderr); > - exit(1); > - } > + buf = aligned_xalloc(4096, buf_size); > count = atoi(argv[3]); > > - if (!strcmp(argv[4], "zero")) { > + if (!strcmp(argv[4], "zero")) > memset(buf, 0, buf_size); > - } else if (strcmp(argv[4], "inc_num") && > - strcmp(argv[4], "rand")) { > - fputs("Wrong pattern type\n\n", stderr); > - exit(1); > - } > + else if (strcmp(argv[4], "inc_num") && strcmp(argv[4], "rand")) > + die("Wrong pattern type"); > > - if (!strcmp(argv[5], "dio")) { > + if (!strcmp(argv[5], "dio")) > flags |= O_DIRECT; > - } else if (strcmp(argv[5], "buffered")) { > - fputs("Wrong IO type\n\n", stderr); > - exit(1); > - } > + else if (strcmp(argv[5], "buffered")) > + die("Wrong IO type"); > > - fd = open(argv[6], O_CREAT | O_WRONLY | flags, 0755); > - if (fd == -1) { > - fputs("Open failed\n\n", stderr); > - exit(1); > - } > + fd = xopen(argv[6], O_CREAT | O_WRONLY | flags, 0755); > > for (i = 0; i < count; i++) { > if (!strcmp(argv[4], "inc_num")) > @@ -389,43 +403,27 @@ static void do_read(int argc, char **argv, const struct cmd_desc *cmd) > } > > bs = atoi(argv[1]); > - if (bs > 1024) { > - fputs("Too big chunk size - limit: 4MB\n\n", stderr); > - exit(1); > - } > + if (bs > 1024) > + die("Too big chunk size - limit: 4MB"); > buf_size = bs * 4096; > > offset = atoi(argv[2]) * buf_size; > > - buf = aligned_alloc(4096, buf_size); > - if (!buf) { > - fputs("Memory alloc failed\n\n", stderr); > - exit(1); > - } > + buf = aligned_xalloc(4096, buf_size); > + > count = atoi(argv[3]); > - if (!strcmp(argv[4], "dio")) { > + if (!strcmp(argv[4], "dio")) > flags |= O_DIRECT; > - } else if (strcmp(argv[4], "buffered")) { > - fputs("Wrong IO type\n\n", stderr); > - exit(1); > - } > + else if (strcmp(argv[4], "buffered")) > + die("Wrong IO type"); > > print_bytes = atoi(argv[5]); > - if (print_bytes > buf_size) { > - fputs("Print_nbytes should be less then chunk_size in kb\n\n", stderr); > - exit(1); > - } > - print_buf = malloc(print_bytes); > - if (!print_buf) { > - fputs("Memory alloc failed\n\n", stderr); > - exit(1); > - } > + if (print_bytes > buf_size) > + die("Print_nbytes should be less then chunk_size in kb"); > > - fd = open(argv[6], O_RDONLY | flags); > - if (fd == -1) { > - fputs("Open failed\n\n", stderr); > - exit(1); > - } > + print_buf = xmalloc(print_bytes); > + > + fd = xopen(argv[6], O_RDONLY | flags, 0); > > for (i = 0; i < count; i++) { > ret = pread(fd, buf, buf_size, offset + buf_size * i); > @@ -480,20 +478,15 @@ static void do_fiemap(int argc, char **argv, const struct cmd_desc *cmd) > offset = atoi(argv[1]); > count = atoi(argv[2]); > > - fd = open(argv[3], O_RDONLY | O_LARGEFILE); > - if (fd == -1) { > - fputs("Open failed\n\n", stderr); > - exit(1); > - } > + fd = xopen(argv[3], O_RDONLY | O_LARGEFILE, 0); > > printf("Fiemap: offset = %08"PRIx64" len = %d\n", offset, count); > for (i = 0; i < count; i++) { > blknum = offset + i; > > - if (ioctl(fd, FIBMAP, &blknum) < 0) { > - fputs("FIBMAP failed\n\n", stderr); > - exit(1); > - } > + if (ioctl(fd, FIBMAP, &blknum) < 0) > + die_errno("FIBMAP failed"); > + > printf("%u ", blknum); > } > printf("\n"); > @@ -559,18 +552,12 @@ static void do_defrag_file(int argc, char **argv, const struct cmd_desc *cmd) > df.start = atoll(argv[1]); > df.len = len = atoll(argv[2]); > > - fd = open(argv[3], O_RDWR); > - if (fd == -1) { > - fputs("Open failed\n\n", stderr); > - fputs(cmd->cmd_help, stderr); > - exit(1); > - } > + fd = xopen(argv[3], O_RDWR, 0); > > ret = ioctl(fd, F2FS_IOC_DEFRAGMENT, &df); > - if (ret < 0) { > - perror("F2FS_IOC_DEFRAGMENT"); > - exit(1); > - } > + if (ret < 0) > + die_errno("F2FS_IOC_DEFRAGMENT failed"); > + > printf("defrag %s in region[%"PRIu64", %"PRIu64"]\n", > argv[3], df.start, df.start + len); > exit(0); > _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel ^ permalink raw reply [flat|nested] 4+ messages in thread
* [f2fs-dev] [PATCH 2/2] f2fs_io: add copy command 2019-10-04 22:43 [f2fs-dev] [PATCH 0/2] f2fs-tools: add 'copy' command to f2fs_io Eric Biggers 2019-10-04 22:43 ` [f2fs-dev] [PATCH 1/2] f2fs_io: add helper functions for handling errors Eric Biggers @ 2019-10-04 22:43 ` Eric Biggers 1 sibling, 0 replies; 4+ messages in thread From: Eric Biggers @ 2019-10-04 22:43 UTC (permalink / raw) To: linux-f2fs-devel, Jaegeuk Kim From: Eric Biggers <ebiggers@google.com> Add a copy command to f2fs_io, to allow testing direct I/O writes where the source page is from a different file (mmap) or an internal kernel page (sendfile). It could be useful for other tests in the future too. Signed-off-by: Eric Biggers <ebiggers@google.com> --- tools/f2fs_io/f2fs_io.c | 108 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/tools/f2fs_io/f2fs_io.c b/tools/f2fs_io/f2fs_io.c index f5493ff..0d90835 100644 --- a/tools/f2fs_io/f2fs_io.c +++ b/tools/f2fs_io/f2fs_io.c @@ -21,7 +21,9 @@ #include <errno.h> #include <fcntl.h> +#include <getopt.h> #include <inttypes.h> +#include <limits.h> #include <signal.h> #include <stdarg.h> #include <stdbool.h> @@ -29,6 +31,8 @@ #include <stdlib.h> #include <string.h> #include <string.h> +#include <sys/mman.h> +#include <sys/sendfile.h> #include <sys/stat.h> #include <sys/types.h> #include <termios.h> @@ -105,6 +109,27 @@ static int xopen(const char *pathname, int flags, mode_t mode) return fd; } +static ssize_t xread(int fd, void *buf, size_t count) +{ + ssize_t ret = read(fd, buf, count); + + if (ret < 0) + die_errno("read failed"); + return ret; +} + +static void full_write(int fd, const void *buf, size_t count) +{ + while (count) { + ssize_t ret = write(fd, buf, count); + + if (ret < 0) + die_errno("write failed"); + buf = (char *)buf + ret; + count -= ret; + } +} + #define getflags_desc "getflags ioctl" #define getflags_help \ "f2fs_io getflags [file]\n\n" \ @@ -563,6 +588,88 @@ static void do_defrag_file(int argc, char **argv, const struct cmd_desc *cmd) exit(0); } +#define copy_desc "copy a file" +#define copy_help \ +"f2fs_io copy [-d] [-m] [-s] src_path dst_path\n\n" \ +" src_path : path to source file\n" \ +" dst_path : path to destination file\n" \ +" -d : use direct I/O\n" \ +" -m : mmap the source file\n" \ +" -s : use sendfile\n" \ + +static void do_copy(int argc, char **argv, const struct cmd_desc *cmd) +{ + int c; + int src_fd; + int dst_fd; + int open_flags = 0; + bool mmap_source_file = false; + bool use_sendfile = false; + ssize_t ret; + + while ((c = getopt(argc, argv, "dms")) != -1) { + switch (c) { + case 'd': + open_flags |= O_DIRECT; + break; + case 'm': + mmap_source_file = true; + break; + case 's': + use_sendfile = true; + break; + default: + fputs(cmd->cmd_help, stderr); + exit(2); + } + } + argc -= optind; + argv += optind; + if (argc != 2) { + fputs("Wrong number of arguments\n\n", stderr); + fputs(cmd->cmd_help, stderr); + exit(2); + } + if (mmap_source_file && use_sendfile) + die("-m and -s are mutually exclusive"); + + src_fd = xopen(argv[0], O_RDONLY | open_flags, 0); + dst_fd = xopen(argv[1], O_WRONLY | O_CREAT | O_TRUNC | open_flags, 0644); + + if (mmap_source_file) { + struct stat stbuf; + void *src_addr; + + if (fstat(src_fd, &stbuf) != 0) + die_errno("fstat of source file failed"); + + if ((size_t)stbuf.st_size != stbuf.st_size) + die("Source file is too large"); + + src_addr = mmap(NULL, stbuf.st_size, PROT_READ, MAP_SHARED, + src_fd, 0); + if (src_addr == MAP_FAILED) + die("mmap of source file failed"); + + full_write(dst_fd, src_addr, stbuf.st_size); + + munmap(src_addr, stbuf.st_size); + } else if (use_sendfile) { + while ((ret = sendfile(dst_fd, src_fd, NULL, INT_MAX)) > 0) + ; + if (ret < 0) + die_errno("sendfile failed"); + } else { + char *buf = aligned_xalloc(4096, 4096); + + while ((ret = xread(src_fd, buf, 4096)) > 0) + full_write(dst_fd, buf, ret); + free(buf); + } + close(src_fd); + close(dst_fd); +} + #define CMD_HIDDEN 0x0001 #define CMD(name) { #name, do_##name, name##_desc, name##_help, 0 } @@ -581,6 +688,7 @@ const struct cmd_desc cmd_list[] = { CMD(fiemap), CMD(gc_urgent), CMD(defrag_file), + CMD(copy), { NULL, NULL, NULL, NULL, 0 } }; -- 2.23.0.581.g78d2f28ef7-goog _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel ^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2019-10-15 7:03 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2019-10-04 22:43 [f2fs-dev] [PATCH 0/2] f2fs-tools: add 'copy' command to f2fs_io Eric Biggers 2019-10-04 22:43 ` [f2fs-dev] [PATCH 1/2] f2fs_io: add helper functions for handling errors Eric Biggers 2019-10-15 7:03 ` Chao Yu 2019-10-04 22:43 ` [f2fs-dev] [PATCH 2/2] f2fs_io: add copy command Eric Biggers
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).