]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfs: move symlink target write function to libxfs
authorDarrick J. Wong <djwong@kernel.org>
Thu, 22 Feb 2024 20:48:20 +0000 (12:48 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Thu, 22 Feb 2024 20:52:37 +0000 (12:52 -0800)
Move xfs_symlink_write_target to xfs_symlink_remote.c so that kernel and
mkfs can share the same function.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/libxfs/xfs_symlink_remote.c
fs/xfs/libxfs/xfs_symlink_remote.h
fs/xfs/xfs_symlink.c

index d88af5c3c79fa1136065c372ba165fbb286d6990..ffb1317a92123c60e3faba0ef1945d5935514b99 100644 (file)
@@ -304,3 +304,79 @@ xfs_symlink_remote_read(
  out:
        return error;
 }
+
+/* Write the symlink target into the inode. */
+int
+xfs_symlink_write_target(
+       struct xfs_trans        *tp,
+       struct xfs_inode        *ip,
+       const char              *target_path,
+       int                     pathlen,
+       xfs_fsblock_t           fs_blocks,
+       uint                    resblks)
+{
+       struct xfs_bmbt_irec    mval[XFS_SYMLINK_MAPS];
+       struct xfs_mount        *mp = tp->t_mountp;
+       const char              *cur_chunk;
+       struct xfs_buf          *bp;
+       xfs_daddr_t             d;
+       int                     byte_cnt;
+       int                     nmaps;
+       int                     offset = 0;
+       int                     n;
+       int                     error;
+
+       /*
+        * If the symlink will fit into the inode, write it inline.
+        */
+       if (pathlen <= xfs_inode_data_fork_size(ip)) {
+               xfs_init_local_fork(ip, XFS_DATA_FORK, target_path, pathlen);
+
+               ip->i_disk_size = pathlen;
+               ip->i_df.if_format = XFS_DINODE_FMT_LOCAL;
+               xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE);
+               return 0;
+       }
+
+       nmaps = XFS_SYMLINK_MAPS;
+       error = xfs_bmapi_write(tp, ip, 0, fs_blocks, XFS_BMAPI_METADATA,
+                       resblks, mval, &nmaps);
+       if (error)
+               return error;
+
+       ip->i_disk_size = pathlen;
+       xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+
+       cur_chunk = target_path;
+       offset = 0;
+       for (n = 0; n < nmaps; n++) {
+               char    *buf;
+
+               d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
+               byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
+               error = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
+                               BTOBB(byte_cnt), 0, &bp);
+               if (error)
+                       return error;
+               bp->b_ops = &xfs_symlink_buf_ops;
+
+               byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
+               byte_cnt = min(byte_cnt, pathlen);
+
+               buf = bp->b_addr;
+               buf += xfs_symlink_hdr_set(mp, ip->i_ino, offset, byte_cnt,
+                               bp);
+
+               memcpy(buf, cur_chunk, byte_cnt);
+
+               cur_chunk += byte_cnt;
+               pathlen -= byte_cnt;
+               offset += byte_cnt;
+
+               xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SYMLINK_BUF);
+               xfs_trans_log_buf(tp, bp, 0, (buf + byte_cnt - 1) -
+                                               (char *)bp->b_addr);
+       }
+       ASSERT(pathlen == 0);
+       return 0;
+}
index bb83a8b8dfa66ddb3ed0b9a3a946f7dd51a32720..a63bd38ae4faf463876b2954c851cb2f1c0a3467 100644 (file)
@@ -19,5 +19,8 @@ void xfs_symlink_local_to_remote(struct xfs_trans *tp, struct xfs_buf *bp,
                                 struct xfs_inode *ip, struct xfs_ifork *ifp);
 xfs_failaddr_t xfs_symlink_shortform_verify(void *sfp, int64_t size);
 int xfs_symlink_remote_read(struct xfs_inode *ip, char *link);
+int xfs_symlink_write_target(struct xfs_trans *tp, struct xfs_inode *ip,
+               const char *target_path, int pathlen, xfs_fsblock_t fs_blocks,
+               uint resblks);
 
 #endif /* __XFS_SYMLINK_REMOTE_H */
index 3b40211f3123bf5ce5ba884b7f2e39d52b13e958..3e376d24c7c162c97881fe738dab32591dcb8b69 100644 (file)
@@ -93,15 +93,7 @@ xfs_symlink(
        int                     error = 0;
        int                     pathlen;
        bool                    unlock_dp_on_error = false;
-       xfs_fileoff_t           first_fsb;
        xfs_filblks_t           fs_blocks;
-       int                     nmaps;
-       struct xfs_bmbt_irec    mval[XFS_SYMLINK_MAPS];
-       xfs_daddr_t             d;
-       const char              *cur_chunk;
-       int                     byte_cnt;
-       int                     n;
-       struct xfs_buf          *bp;
        prid_t                  prid;
        struct xfs_dquot        *udqp = NULL;
        struct xfs_dquot        *gdqp = NULL;
@@ -189,62 +181,11 @@ xfs_symlink(
        xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
 
        resblks -= XFS_IALLOC_SPACE_RES(mp);
-       /*
-        * If the symlink will fit into the inode, write it inline.
-        */
-       if (pathlen <= xfs_inode_data_fork_size(ip)) {
-               xfs_init_local_fork(ip, XFS_DATA_FORK, target_path, pathlen);
-
-               ip->i_disk_size = pathlen;
-               ip->i_df.if_format = XFS_DINODE_FMT_LOCAL;
-               xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE);
-       } else {
-               int     offset;
-
-               first_fsb = 0;
-               nmaps = XFS_SYMLINK_MAPS;
-
-               error = xfs_bmapi_write(tp, ip, first_fsb, fs_blocks,
-                                 XFS_BMAPI_METADATA, resblks, mval, &nmaps);
-               if (error)
-                       goto out_trans_cancel;
-
-               resblks -= fs_blocks;
-               ip->i_disk_size = pathlen;
-               xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-
-               cur_chunk = target_path;
-               offset = 0;
-               for (n = 0; n < nmaps; n++) {
-                       char    *buf;
-
-                       d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
-                       byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
-                       error = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
-                                              BTOBB(byte_cnt), 0, &bp);
-                       if (error)
-                               goto out_trans_cancel;
-                       bp->b_ops = &xfs_symlink_buf_ops;
-
-                       byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
-                       byte_cnt = min(byte_cnt, pathlen);
-
-                       buf = bp->b_addr;
-                       buf += xfs_symlink_hdr_set(mp, ip->i_ino, offset,
-                                                  byte_cnt, bp);
-
-                       memcpy(buf, cur_chunk, byte_cnt);
-
-                       cur_chunk += byte_cnt;
-                       pathlen -= byte_cnt;
-                       offset += byte_cnt;
-
-                       xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SYMLINK_BUF);
-                       xfs_trans_log_buf(tp, bp, 0, (buf + byte_cnt - 1) -
-                                                       (char *)bp->b_addr);
-               }
-               ASSERT(pathlen == 0);
-       }
+       error = xfs_symlink_write_target(tp, ip, target_path, pathlen,
+                       fs_blocks, resblks);
+       if (error)
+               goto out_trans_cancel;
+       resblks -= fs_blocks;
        i_size_write(VFS_I(ip), ip->i_disk_size);
 
        /*