Direct S3 writes target the primary device and may leave the selected blob device shorter than its allocated extent.
Write objects at device-relative offsets on the selected device and extend it to the final block boundary. Assisted-by: Codex:gpt-5.6-sol Signed-off-by: Yifan Zhao <[email protected]> --- Changes since v1: - Correct the author and Signed-off-by email address. lib/remotes/s3.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/lib/remotes/s3.c b/lib/remotes/s3.c index 56ab808..feba9b4 100644 --- a/lib/remotes/s3.c +++ b/lib/remotes/s3.c @@ -15,6 +15,7 @@ #include "erofs/internal.h" #include "erofs/print.h" #include "erofs/inode.h" +#include "../liberofs_cache.h" #include "../liberofs_chunk.h" #include "erofs/diskbuf.h" #include "erofs/importer.h" @@ -1017,6 +1018,11 @@ struct s3erofs_curl_getobject_resp { erofs_off_t pos, end; }; +static bool s3erofs_could_write_directly(const struct erofs_importer *im) +{ + return !im->sbi->available_compr_algs && im->params->no_datainline; +} + static size_t s3erofs_remote_getobject_cb(void *contents, size_t size, size_t nmemb, void *userp) { @@ -1053,16 +1059,20 @@ static int s3erofs_remote_getobject(struct erofs_importer *im, return -EIO; resp.pos = 0; - if (!sbi->available_compr_algs && im->params->no_datainline) { + if (s3erofs_could_write_directly(im)) { + unsigned int device_id = im->params->ddev_id_def; + inode->datalayout = EROFS_INODE_FLAT_PLAIN; inode->idata_size = 0; ret = erofs_allocate_inode_bh_data(inode, DIV_ROUND_UP(inode->i_size, 1U << sbi->blkszbits), - im->params->ddev_id_def); + device_id); if (ret) return ret; - resp.vf = &sbi->bdev; - resp.pos = erofs_pos(inode->sbi, inode->u.i_blkaddr); + resp.vf = device_id ? + sbi->devs[device_id - 1].bmgr->vf : &sbi->bdev; + if (inode->i_size) + resp.pos = erofs_pos(sbi, erofs_inode_dev_baddr(inode)); inode->datasource = EROFS_INODE_DATA_SOURCE_NONE; } else { if (!inode->i_diskbuf) { @@ -1189,6 +1199,17 @@ int s3erofs_build_trees(struct erofs_importer *im, struct erofs_s3 *s3, goto err_iter; } + if (!fillzero && s3erofs_could_write_directly(im) && + im->params->ddev_id_def) { + struct erofs_bufmgr *bmgr = + sbi->devs[im->params->ddev_id_def - 1].bmgr; + + ret = erofs_io_ftruncate(bmgr->vf, + erofs_pos(sbi, erofs_mapbh(bmgr, NULL))); + if (ret) + goto err_iter; + } + err_iter: s3erofs_destroy_object_iterator(iter); err_global: base-commit: 65645313de60a42d6d93389a6658317f8b1e6b8e -- 2.55.0
