diff options
| author | Darrick J. Wong <djwong@kernel.org> | 2021-12-08 16:24:23 -0800 |
|---|---|---|
| committer | Darrick J. Wong <djwong@kernel.org> | 2021-12-15 17:29:31 -0800 |
| commit | 90d15e3e9dcd303fbb36e9a54e7c36457ff9a254 (patch) | |
| tree | 2ab32de923bf1ffc28ae7f9529d6d7c1bb5c0b63 | |
| parent | b0cad080048a93ceeae93b51a0cab55c85c5a7ec (diff) | |
| download | xfs-linux-90d15e3e9dcd303fbb36e9a54e7c36457ff9a254.tar.gz | |
xfs: move symlink target write function to libxfs
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>
| -rw-r--r-- | fs/xfs/libxfs/xfs_symlink_remote.c | 76 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_symlink_remote.h | 3 | ||||
| -rw-r--r-- | fs/xfs/xfs_symlink.c | 79 | ||||
| -rw-r--r-- | fs/xfs/xfs_symlink.h | 3 |
4 files changed, 80 insertions, 81 deletions
diff --git a/fs/xfs/libxfs/xfs_symlink_remote.c b/fs/xfs/libxfs/xfs_symlink_remote.c index e1e2bdcf64622..1fb71a52d37be 100644 --- a/fs/xfs/libxfs/xfs_symlink_remote.c +++ b/fs/xfs/libxfs/xfs_symlink_remote.c @@ -305,3 +305,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_IFORK_DSIZE(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; +} diff --git a/fs/xfs/libxfs/xfs_symlink_remote.h b/fs/xfs/libxfs/xfs_symlink_remote.h index 6df1bdc01bbea..d718c5dec0b7e 100644 --- a/fs/xfs/libxfs/xfs_symlink_remote.h +++ b/fs/xfs/libxfs/xfs_symlink_remote.h @@ -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(struct xfs_inode *ip); 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 */ diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 6df3bfac648c1..e41c8e8fcf9e6 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -67,84 +67,6 @@ xfs_readlink( 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_IFORK_DSIZE(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); - i_size_write(VFS_I(ip), ip->i_disk_size); - 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); - i_size_write(VFS_I(ip), ip->i_disk_size); - return 0; -} - int xfs_symlink( struct user_namespace *mnt_userns, @@ -254,6 +176,7 @@ xfs_symlink( fs_blocks, resblks); if (error) goto out_trans_cancel; + i_size_write(VFS_I(ip), ip->i_disk_size); /* * Create the directory entry for the symlink. diff --git a/fs/xfs/xfs_symlink.h b/fs/xfs/xfs_symlink.h index 06cde83e1c8aa..526ea98315b51 100644 --- a/fs/xfs/xfs_symlink.h +++ b/fs/xfs/xfs_symlink.h @@ -12,8 +12,5 @@ int xfs_symlink(struct user_namespace *mnt_userns, struct xfs_inode *dp, umode_t mode, struct xfs_inode **ipp); int xfs_readlink(struct xfs_inode *ip, char *link); int xfs_inactive_symlink(struct xfs_inode *ip); -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_H */ |
