From ddb5cce2a51e764621a1fa893360697a61fb438c Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Wed, 18 Jan 2023 10:27:47 -0800 Subject: [PATCH] Add quick utils flush_device helper Add a quick helper that just calls cache flushing ioctls on different kinds of files. Signed-off-by: Zach Brown --- utils/src/dev.c | 42 ++++++++++++++++++++++++++++++++++++++++++ utils/src/dev.h | 1 + 2 files changed, 43 insertions(+) diff --git a/utils/src/dev.c b/utils/src/dev.c index af1e91f6..2a0c9eb6 100644 --- a/utils/src/dev.c +++ b/utils/src/dev.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -103,3 +104,44 @@ char *size_str(u64 nr, unsigned size) return suffixes[i]; } + +/* + * Try to flush the local read cache for a device. This is only a best + * effort as these interfaces don't block waiting to fully purge the + * cache. This is OK because it's used by cached readers that are known + * to be racy anyway. + */ +int flush_device(int fd) +{ + struct stat st; + int ret; + + ret = fstat(fd, &st); + if (ret < 0) { + ret = -errno; + fprintf(stderr, "fstat failed: %s (%d)\n", strerror(errno), errno); + goto out; + } + + if (S_ISREG(st.st_mode)) { + ret = posix_fadvise(fd, 0, st.st_size, POSIX_FADV_DONTNEED); + if (ret < 0) { + ret = -errno; + fprintf(stderr, "POSIX_FADV_DONTNEED failed: %s (%d)\n", + strerror(errno), errno); + goto out; + } + + } else if (S_ISBLK(st.st_mode)) { + ret = ioctl(fd, BLKFLSBUF, 0); + if (ret < 0) { + ret = -errno; + fprintf(stderr, "BLKFLSBUF, failed: %s (%d)\n", strerror(errno), errno); + goto out; + } + } + + ret = 0; +out: + return ret; +} diff --git a/utils/src/dev.h b/utils/src/dev.h index df79fe4c..d483f70b 100644 --- a/utils/src/dev.h +++ b/utils/src/dev.h @@ -14,5 +14,6 @@ int device_size(char *path, int fd, char *use_type, u64 *size_ret); float size_flt(u64 nr, unsigned size); char *size_str(u64 nr, unsigned size); +int flush_device(int fd); #endif