Avoid using raw FDs for the upcoming directory data compression.

Signed-off-by: Gao Xiang <[email protected]>
---
 lib/compress.c           | 21 ++++++++------
 lib/fragments.c          | 62 ++++++++++++++++++----------------------
 lib/liberofs_fragments.h | 10 ++++---
 3 files changed, 47 insertions(+), 46 deletions(-)

diff --git a/lib/compress.c b/lib/compress.c
index 20f511e..74d40b1 100644
--- a/lib/compress.c
+++ b/lib/compress.c
@@ -1258,13 +1258,14 @@ int z_erofs_compress_segment(struct 
z_erofs_compress_sctx *ctx,
        bool frag = params->fragments && !erofs_is_packed_inode(inode) &&
                !erofs_is_metabox_inode(inode) &&
                ctx->seg_idx >= ictx->seg_num - 1;
-       int fd = ictx->fd;
+       struct erofs_vfile vf = { .fd = ictx->fd };
        int ret;
 
        DBG_BUGON(offset != -1 && frag && inode->fragment_size);
        if (offset != -1 && frag && !inode->fragment_size &&
            params->fragdedupe != EROFS_FRAGDEDUPE_OFF) {
-               ret = erofs_fragment_findmatch(inode, fd, ictx->tofh);
+               ret = erofs_fragment_findmatch(inode,
+                                              &vf, ictx->fpos, ictx->tofh);
                if (ret < 0)
                        return ret;
                if (inode->fragment_size > ctx->remaining)
@@ -1280,9 +1281,9 @@ int z_erofs_compress_segment(struct z_erofs_compress_sctx 
*ctx,
                int ret;
 
                ret = (offset == -1 ?
-                       read(fd, ctx->queue + ctx->tail, rx) :
-                       pread(fd, ctx->queue + ctx->tail, rx,
-                             ictx->fpos + offset));
+                       erofs_io_read(&vf, ctx->queue + ctx->tail, rx) :
+                       erofs_io_pread(&vf, ctx->queue + ctx->tail, rx,
+                                      ictx->fpos + offset));
                if (ret != rx)
                        return -errno;
 
@@ -1848,14 +1849,17 @@ void *erofs_begin_compressed_file(struct erofs_importer 
*im,
                inode->z_advise |= Z_EROFS_ADVISE_INTERLACED_PCLUSTER;
 
        if (frag) {
-               ictx->tofh = z_erofs_fragments_tofh(inode, fd, fpos);
+               struct erofs_vfile vf = { .fd = fd };
+
+               ictx->tofh = z_erofs_fragments_tofh(inode, &vf, fpos);
                if (ictx == &g_ictx &&
                    params->fragdedupe != EROFS_FRAGDEDUPE_OFF) {
                        /*
                         * Handle tails in advance to avoid writing duplicated
                         * parts into the packed inode.
                         */
-                       ret = erofs_fragment_findmatch(inode, fd, ictx->tofh);
+                       ret = erofs_fragment_findmatch(inode,
+                                                      &vf, fpos, ictx->tofh);
                        if (ret < 0)
                                goto err_free_ictx;
 
@@ -1874,7 +1878,8 @@ void *erofs_begin_compressed_file(struct erofs_importer 
*im,
        ictx->dedupe = false;
 
        if (all_fragments && !inode->fragment_size) {
-               ret = erofs_pack_file_from_fd(inode, fd, ictx->tofh);
+               ret = erofs_pack_file_from_fd(inode,
+                       &((struct erofs_vfile){ .fd = fd }), fpos, ictx->tofh);
                if (ret)
                        goto err_free_idata;
        }
diff --git a/lib/fragments.c b/lib/fragments.c
index 244608f..15092e1 100644
--- a/lib/fragments.c
+++ b/lib/fragments.c
@@ -53,7 +53,8 @@ struct erofs_packed_inode {
 
 const char *erofs_frags_packedname = "packed_file";
 
-u32 z_erofs_fragments_tofh(struct erofs_inode *inode, int fd, erofs_off_t fpos)
+u32 z_erofs_fragments_tofh(struct erofs_inode *inode,
+                          struct erofs_vfile *vf, erofs_off_t fpos)
 {
        u8 data_to_hash[EROFS_TOF_HASHLEN];
        u32 hash;
@@ -62,10 +63,10 @@ u32 z_erofs_fragments_tofh(struct erofs_inode *inode, int 
fd, erofs_off_t fpos)
        if (inode->i_size <= EROFS_TOF_HASHLEN)
                return ~0U;
 
-       ret = pread(fd, data_to_hash, EROFS_TOF_HASHLEN,
-                   fpos + inode->i_size - EROFS_TOF_HASHLEN);
+       ret = erofs_io_pread(vf, data_to_hash, EROFS_TOF_HASHLEN,
+                            fpos + inode->i_size - EROFS_TOF_HASHLEN);
        if (ret < 0)
-               return -errno;
+               return ret;
        if (ret != EROFS_TOF_HASHLEN) {
                DBG_BUGON(1);
                return -EIO;
@@ -76,7 +77,9 @@ u32 z_erofs_fragments_tofh(struct erofs_inode *inode, int fd, 
erofs_off_t fpos)
 
 static erofs_off_t erofs_fragment_longmatch(struct erofs_inode *inode,
                                            struct erofs_fragmentitem *fi,
-                                           erofs_off_t matched, int fd)
+                                           erofs_off_t matched,
+                                           struct erofs_vfile *vf,
+                                           erofs_off_t fpos)
 {
        struct erofs_packed_inode *epi = inode->sbi->packedinode;
        erofs_off_t total = min_t(erofs_off_t, fi->length, inode->i_size);
@@ -99,7 +102,8 @@ static erofs_off_t erofs_fragment_longmatch(struct 
erofs_inode *inode,
                        return matched;
                }
                sz = min_t(u64, total - matched, sizeof(buf[0]));
-               if (pread(fd, buf[0], sz, inode->i_size - matched - sz) != sz)
+               if (erofs_io_pread(vf, buf[0], sz,
+                                  fpos + inode->i_size - matched - sz) != sz)
                        break;
 
                if (!inmem) {
@@ -116,7 +120,8 @@ static erofs_off_t erofs_fragment_longmatch(struct 
erofs_inode *inode,
        return matched;
 }
 
-int erofs_fragment_findmatch(struct erofs_inode *inode, int fd, u32 tofh)
+int erofs_fragment_findmatch(struct erofs_inode *inode,
+                            struct erofs_vfile *vf, erofs_off_t fpos, u32 tofh)
 {
        struct erofs_packed_inode *epi = inode->sbi->packedinode;
        struct erofs_fragmentitem *cur, *fi = NULL;
@@ -136,7 +141,7 @@ int erofs_fragment_findmatch(struct erofs_inode *inode, int 
fd, u32 tofh)
        if (!data)
                return -ENOMEM;
 
-       ret = pread(fd, data, s1, inode->i_size - s1);
+       ret = erofs_io_pread(vf, data, s1, fpos + inode->i_size - s1);
        if (ret != s1) {
                free(data);
                return -errno;
@@ -167,7 +172,7 @@ int erofs_fragment_findmatch(struct erofs_inode *inode, int 
fd, u32 tofh)
                i += EROFS_TOF_HASHLEN;
                if (i >= s1) {          /* full short match */
                        DBG_BUGON(i > s1);
-                       i = erofs_fragment_longmatch(inode, cur, s1, fd);
+                       i = erofs_fragment_longmatch(inode, cur, s1, vf, fpos);
                }
 
                if (i <= deduped)
@@ -229,7 +234,8 @@ int erofs_fragment_pack(struct erofs_inode *inode, void 
*data,
        return 0;
 }
 
-int erofs_pack_file_from_fd(struct erofs_inode *inode, int fd, u32 tofh)
+int erofs_pack_file_from_fd(struct erofs_inode *inode,
+                           struct erofs_vfile *vf, erofs_off_t fpos, u32 tofh)
 {
        struct erofs_packed_inode *epi = inode->sbi->packedinode;
        s64 offset, rc, sz;
@@ -243,33 +249,27 @@ int erofs_pack_file_from_fd(struct erofs_inode *inode, 
int fd, u32 tofh)
        if (offset < 0)
                return -errno;
 
-       memblock = mmap(NULL, inode->i_size, PROT_READ, MAP_SHARED, fd, 0);
+       if (vf->ops)
+               memblock = NULL;
+       else
+               memblock = mmap(NULL, inode->i_size, PROT_READ,
+                               MAP_SHARED, vf->fd, fpos);
        if (memblock == MAP_FAILED || !memblock) {
                erofs_off_t remaining = inode->i_size;
-               struct erofs_vfile vin = { .fd = fd };
+               struct erofs_vfile vout = { .fd = epi->fd };
+               off_t pos = fpos;
 
-#if defined(HAVE_SYS_SENDFILE_H) && defined(HAVE_SENDFILE)
                do {
                        sz = min_t(u64, remaining, UINT_MAX);
-                       rc = sendfile(epi->fd, fd, NULL, sz);
+                       rc = erofs_io_sendfile(&vout, vf, &pos, sz);
                        if (rc <= 0)
                                break;
                        remaining -= rc;
                } while (remaining);
-#endif
-               while (remaining) {
-                       char buf[32768];
-
-                       sz = min_t(u64, remaining, sizeof(buf));
-                       rc = erofs_io_read(&vin, buf, sz);
-                       if (rc < 0)
-                               goto out;
-                       if (rc > 0) {
-                               rc = write(epi->fd, buf, rc);
-                               if (rc < 0)
-                                       goto out;
-                       }
-                       remaining -= rc;
+
+               if (remaining && rc >= 0) {
+                       rc = -EIO;
+                       goto out;
                }
 
                sz = min_t(u64, inode->i_size, EROFS_FRAGMENT_INMEM_SZ_MAX);
@@ -288,12 +288,6 @@ int erofs_pack_file_from_fd(struct erofs_inode *inode, int 
fd, u32 tofh)
                        }
                        goto out;
                }
-
-               rc = lseek(fd, 0, SEEK_SET);
-               if (rc < 0) {
-                       rc = -errno;
-                       goto out;
-               }
        } else {
                rc = __erofs_io_write(epi->fd, memblock, inode->i_size);
                if (rc != inode->i_size) {
diff --git a/lib/liberofs_fragments.h b/lib/liberofs_fragments.h
index ca71e52..11833eb 100644
--- a/lib/liberofs_fragments.h
+++ b/lib/liberofs_fragments.h
@@ -10,10 +10,12 @@
 
 struct erofs_importer;
 
-u32 z_erofs_fragments_tofh(struct erofs_inode *inode, int fd, erofs_off_t 
fpos);
-int erofs_fragment_findmatch(struct erofs_inode *inode, int fd, u32 tofh);
-
-int erofs_pack_file_from_fd(struct erofs_inode *inode, int fd, u32 tofcrc);
+u32 z_erofs_fragments_tofh(struct erofs_inode *inode,
+                          struct erofs_vfile *vf, erofs_off_t fpos);
+int erofs_fragment_findmatch(struct erofs_inode *inode,
+                            struct erofs_vfile *vf, erofs_off_t fpos, u32 
tofh);
+int erofs_pack_file_from_fd(struct erofs_inode *inode,
+                           struct erofs_vfile *vf, erofs_off_t fpos, u32 tofh);
 int erofs_fragment_pack(struct erofs_inode *inode, void *data,
                        erofs_off_t pos, erofs_off_t len, u32 tofh, bool tail);
 int erofs_fragment_commit(struct erofs_inode *inode, u32 tofh);
-- 
2.43.5


Reply via email to