diff --git a/CHANGELOG.md b/CHANGELOG.md index 5501276fa..05f348b1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -87,6 +87,11 @@ IOAT for copy engine is disabled by default. It can be enabled by specifying the option with "Yes" in `[Ioat]` section of the configuration file. The Disable option is now deprecated and will be removed in a future release. +### blobfs + +Change the return type of spdk_file_truncate from void to int. The purpose is to catch +the `NOMEM` error condition. + ## v18.04: Logical Volume Snapshot/Clone, iSCSI Initiator, Bdev QoS, VPP Userspace TCP/IP ### vhost diff --git a/include/spdk/blobfs.h b/include/spdk/blobfs.h index d3aba0c8e..b8c521166 100644 --- a/include/spdk/blobfs.h +++ b/include/spdk/blobfs.h @@ -301,9 +301,11 @@ spdk_fs_iter spdk_fs_iter_next(spdk_fs_iter iter); * \param file File to truncate. * \param channel The I/O channel used to allocate file request. * \param length New size in bytes of the file. + * + * \return 0 on success, negative errno on failure. */ -void spdk_file_truncate(struct spdk_file *file, struct spdk_io_channel *channel, - uint64_t length); +int spdk_file_truncate(struct spdk_file *file, struct spdk_io_channel *channel, + uint64_t length); /** * Get file name. diff --git a/lib/blobfs/blobfs.c b/lib/blobfs/blobfs.c index 200b428ff..0eabb2816 100644 --- a/lib/blobfs/blobfs.c +++ b/lib/blobfs/blobfs.c @@ -1501,7 +1501,7 @@ __truncate(void *arg) args->fn.file_op, args->arg); } -void +int spdk_file_truncate(struct spdk_file *file, struct spdk_io_channel *_channel, uint64_t length) { @@ -1510,7 +1510,9 @@ spdk_file_truncate(struct spdk_file *file, struct spdk_io_channel *_channel, struct spdk_fs_cb_args *args; req = alloc_fs_request(channel); - assert(req != NULL); + if (req == NULL) { + return -ENOMEM; + } args = &req->args; @@ -1522,6 +1524,8 @@ spdk_file_truncate(struct spdk_file *file, struct spdk_io_channel *_channel, channel->send_request(__truncate, req); sem_wait(&channel->sem); free_fs_request(req); + + return 0; } static void diff --git a/lib/rocksdb/env_spdk.cc b/lib/rocksdb/env_spdk.cc index 0fe3a3639..7fde91a01 100644 --- a/lib/rocksdb/env_spdk.cc +++ b/lib/rocksdb/env_spdk.cc @@ -207,9 +207,15 @@ public: virtual Status Truncate(uint64_t size) override { - spdk_file_truncate(mFile, g_sync_args.channel, size); - mSize = size; - return Status::OK(); + int rc; + rc = spdk_file_truncate(mFile, g_sync_args.channel, size); + if (!rc) { + mSize = size; + return Status::OK(); + } else { + errno = -rc; + return Status::IOError(spdk_file_get_name(mFile), strerror(errno)); + } } virtual Status Close() override { @@ -246,8 +252,15 @@ public: } virtual Status Allocate(uint64_t offset, uint64_t len) override { - spdk_file_truncate(mFile, g_sync_args.channel, offset + len); - return Status::OK(); + int rc; + + rc = spdk_file_truncate(mFile, g_sync_args.channel, offset + len); + if (!rc) { + return Status::OK(); + } else { + errno = -rc; + return Status::IOError(spdk_file_get_name(mFile), strerror(errno)); + } } virtual Status RangeSync(uint64_t offset, uint64_t nbytes) override { diff --git a/test/blobfs/fuse/fuse.c b/test/blobfs/fuse/fuse.c index 2cdaa5a22..9d11dfa07 100644 --- a/test/blobfs/fuse/fuse.c +++ b/test/blobfs/fuse/fuse.c @@ -143,7 +143,11 @@ spdk_fuse_truncate(const char *path, off_t size, struct fuse_file_info *fi) return -rc; } - spdk_file_truncate(file, g_channel, size); + rc = spdk_file_truncate(file, g_channel, size); + if (rc != 0) { + return -rc; + } + spdk_file_close(file, g_channel); return 0; diff --git a/test/unit/lib/blobfs/blobfs_sync_ut/blobfs_sync_ut.c b/test/unit/lib/blobfs/blobfs_sync_ut/blobfs_sync_ut.c index e85154b65..b7f9261e3 100644 --- a/test/unit/lib/blobfs/blobfs_sync_ut/blobfs_sync_ut.c +++ b/test/unit/lib/blobfs/blobfs_sync_ut/blobfs_sync_ut.c @@ -180,13 +180,15 @@ cache_write(void) SPDK_CU_ASSERT_FATAL(g_file != NULL); length = (4 * 1024 * 1024); - spdk_file_truncate(g_file, channel, length); + rc = spdk_file_truncate(g_file, channel, length); + CU_ASSERT(rc == 0); spdk_file_write(g_file, channel, buf, 0, sizeof(buf)); CU_ASSERT(spdk_file_get_length(g_file) == length); - spdk_file_truncate(g_file, channel, sizeof(buf)); + rc = spdk_file_truncate(g_file, channel, sizeof(buf)); + CU_ASSERT(rc == 0); spdk_file_close(g_file, channel); rc = spdk_fs_delete_file(g_fs, channel, "testfile"); @@ -218,7 +220,8 @@ cache_write_null_buffer(void) SPDK_CU_ASSERT_FATAL(g_file != NULL); length = 0; - spdk_file_truncate(g_file, channel, length); + rc = spdk_file_truncate(g_file, channel, length); + CU_ASSERT(rc == 0); rc = spdk_file_write(g_file, channel, NULL, 0, 0); CU_ASSERT(rc == 0);