diff --git a/sbin/hastd/hast.h b/sbin/hastd/hast.h index 7bfef4c248f3..d82783ba0c6b 100644 --- a/sbin/hastd/hast.h +++ b/sbin/hastd/hast.h @@ -167,6 +167,8 @@ struct hast_resource { off_t hr_local_mediasize; /* Sector size of local provider. */ unsigned int hr_local_sectorsize; + /* Is flushing write cache supported by the local provider? */ + bool hr_localflush; /* Flush write cache on metadata updates? */ int hr_metaflush; diff --git a/sbin/hastd/parse.y b/sbin/hastd/parse.y index e548a858374b..15b11430a124 100644 --- a/sbin/hastd/parse.y +++ b/sbin/hastd/parse.y @@ -788,6 +788,7 @@ resource_start: STR curres->hr_provname[0] = '\0'; curres->hr_localpath[0] = '\0'; curres->hr_localfd = -1; + curres->hr_localflush = true; curres->hr_metaflush = -1; curres->hr_remoteaddr[0] = '\0'; curres->hr_sourceaddr[0] = '\0'; diff --git a/sbin/hastd/primary.c b/sbin/hastd/primary.c index 08c3329b98e6..4a3c51ff1a0f 100644 --- a/sbin/hastd/primary.c +++ b/sbin/hastd/primary.c @@ -1304,8 +1304,15 @@ local_send_thread(void *arg) } break; case BIO_FLUSH: + if (!res->hr_localflush) { + ret = -1; + errno = EOPNOTSUPP; + break; + } ret = g_flush(res->hr_localfd); if (ret < 0) { + if (errno == EOPNOTSUPP) + res->hr_localflush = false; hio->hio_errors[ncomp] = errno; reqlog(LOG_WARNING, 0, ggio, "Local request failed (%s): ", diff --git a/sbin/hastd/secondary.c b/sbin/hastd/secondary.c index 0ec4c6e28deb..c761143f9693 100644 --- a/sbin/hastd/secondary.c +++ b/sbin/hastd/secondary.c @@ -664,7 +664,7 @@ disk_thread(void *arg) struct hast_resource *res = arg; struct hio *hio; ssize_t ret; - bool clear_activemap; + bool clear_activemap, logerror; clear_activemap = true; @@ -702,6 +702,7 @@ disk_thread(void *arg) break; } reqlog(LOG_DEBUG, 2, -1, hio, "disk: (%p) Got request: ", hio); + logerror = true; /* Handle the actual request. */ switch (hio->hio_cmd) { case HIO_READ: @@ -736,14 +737,23 @@ disk_thread(void *arg) hio->hio_error = 0; break; case HIO_FLUSH: + if (!res->hr_localflush) { + ret = -1; + hio->hio_error = EOPNOTSUPP; + logerror = false; + break; + } ret = g_flush(res->hr_localfd); - if (ret < 0) + if (ret < 0) { + if (errno == EOPNOTSUPP) + res->hr_localflush = false; hio->hio_error = errno; - else + } else { hio->hio_error = 0; + } break; } - if (hio->hio_error != 0) { + if (logerror && hio->hio_error != 0) { reqlog(LOG_ERR, 0, hio->hio_error, hio, "Request failed: "); }