]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
mkfs: use file write helper to populate files
authorDarrick J. Wong <djwong@kernel.org>
Tue, 9 Jan 2024 17:40:23 +0000 (09:40 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Wed, 10 Apr 2024 00:21:45 +0000 (17:21 -0700)
Use the file write helper to write files into the filesystem.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
include/libxfs.h
libxfs/util.c
mkfs/proto.c

index 88112bb7839d2f8a45d6c30297ab5670e42c3d44..20d50e7ae0b44cf7726c631cc3badb15ad5ad9ac 100644 (file)
@@ -180,6 +180,8 @@ extern int  libxfs_log_header(char *, uuid_t *, int, int, int, xfs_lsn_t,
 
 extern int     libxfs_alloc_file_space(struct xfs_inode *ip, xfs_off_t offset,
                                        xfs_off_t len, uint32_t bmapi_flags);
+extern int     libxfs_file_write(struct xfs_trans *tp, struct xfs_inode *ip,
+                                 void *buf, size_t len, bool logit);
 
 /* XXX: this is messy and needs fixing */
 #ifndef __LIBXFS_INTERNAL_XFS_H__
index aec7798a8149c099fe91259e242fa96f502628f6..f2be9dbf4a278c09cd2cbf7396ac9d278b71e490 100644 (file)
@@ -537,3 +537,72 @@ get_random_u32(void)
        return ret;
 }
 #endif
+
+/*
+ * Write a buffer to a file on the data device.  We assume there are no holes
+ * and no unwritten extents.
+ */
+int
+libxfs_file_write(
+       struct xfs_trans        *tp,
+       struct xfs_inode        *ip,
+       void                    *buf,
+       size_t                  len,
+       bool                    logit)
+{
+       struct xfs_bmbt_irec    map;
+       struct xfs_mount        *mp = ip->i_mount;
+       struct xfs_buf          *bp;
+       xfs_fileoff_t           bno = 0;
+       xfs_fileoff_t           end_bno = XFS_B_TO_FSB(mp, len);
+       size_t                  count;
+       size_t                  bcount;
+       int                     nmap;
+       int                     error = 0;
+
+       /* Write up to 1MB at a time. */
+       while (bno < end_bno) {
+               xfs_filblks_t   maplen;
+
+               maplen = min(end_bno - bno, XFS_B_TO_FSBT(mp, 1048576));
+               nmap = 1;
+               error = libxfs_bmapi_read(ip, bno, maplen, &map, &nmap, 0);
+               if (error)
+                       return error;
+               if (nmap != 1)
+                       return -ENOSPC;
+
+               if (map.br_startblock == HOLESTARTBLOCK ||
+                   map.br_state == XFS_EXT_UNWRITTEN)
+                       return -EINVAL;
+
+               error = libxfs_trans_get_buf(tp, mp->m_dev,
+                               XFS_FSB_TO_DADDR(mp, map.br_startblock),
+                               XFS_FSB_TO_BB(mp, map.br_blockcount),
+                               0, &bp);
+               if (error)
+                       break;
+               bp->b_ops = NULL;
+
+               count = min(len, XFS_FSB_TO_B(mp, map.br_blockcount));
+               memmove(bp->b_addr, buf, count);
+               bcount = BBTOB(bp->b_length);
+               if (count < bcount)
+                       memset((char *)bp->b_addr + count, 0, bcount - count);
+
+               if (tp) {
+                       libxfs_trans_log_buf(tp, bp, 0, bcount - 1);
+               } else {
+                       libxfs_buf_mark_dirty(bp);
+                       libxfs_buf_relse(bp);
+               }
+               if (error)
+                       break;
+
+               buf += count;
+               len -= count;
+               bno += map.br_blockcount;
+       }
+
+       return error;
+}
index ec74281d8ccfd9d7f984e1396603ee909043823f..4e627b430c0b5d5966b9fe293e223b3b83ebfd44 100644 (file)
@@ -271,16 +271,12 @@ writefile(
 {
        struct xfs_bmbt_irec    map;
        struct xfs_mount        *mp;
-       struct xfs_buf          *bp;
-       xfs_daddr_t             d;
        xfs_extlen_t            nb;
        int                     nmap;
        int                     error;
 
        mp = ip->i_mount;
        if (len > 0) {
-               int     bcount;
-
                nb = XFS_B_TO_FSB(mp, len);
                nmap = 1;
                error = -libxfs_bmapi_write(tp, ip, 0, nb, 0, nb, &map, &nmap);
@@ -290,30 +286,18 @@ writefile(
                                        progname);
                        exit(1);
                }
-               if (error) {
+               if (error)
                        fail(_("error allocating space for a file"), error);
-               }
                if (nmap != 1) {
                        fprintf(stderr,
                                _("%s: cannot allocate space for file\n"),
                                progname);
                        exit(1);
                }
-               d = XFS_FSB_TO_DADDR(mp, map.br_startblock);
-               error = -libxfs_trans_get_buf(NULL, mp->m_dev, d,
-                               nb << mp->m_blkbb_log, 0, &bp);
-               if (error) {
-                       fprintf(stderr,
-                               _("%s: cannot allocate buffer for file\n"),
-                               progname);
-                       exit(1);
-               }
-               memmove(bp->b_addr, buf, len);
-               bcount = BBTOB(bp->b_length);
-               if (len < bcount)
-                       memset((char *)bp->b_addr + len, 0, bcount - len);
-               libxfs_buf_mark_dirty(bp);
-               libxfs_buf_relse(bp);
+
+               error = -libxfs_file_write(tp, ip, buf, len, false);
+               if (error)
+                       fail(_("error writing file"), error);
        }
        ip->i_disk_size = len;
 }