From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 83DDBC4332F for ; Sat, 31 Dec 2022 00:18:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235900AbiLaASP (ORCPT ); Fri, 30 Dec 2022 19:18:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56842 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235902AbiLaASO (ORCPT ); Fri, 30 Dec 2022 19:18:14 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D9B9D193DB for ; Fri, 30 Dec 2022 16:18:13 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 9144CB81E71 for ; Sat, 31 Dec 2022 00:18:12 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2697DC433D2; Sat, 31 Dec 2022 00:18:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672445891; bh=LYQsQKDp+Jj3S0IPuquQSixzvHFuFOpCnm6RUOPR+k8=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=JaTzFxFdDGlcZNYWapzZhCzCyHwHLHQ48627rNHjMUBUnhyMMdO8omR4wmKWJipI0 CUoNkn3LW1DDUrCkujw1QuJw3JIb/cUd5f6cDJqEM1K/emOmmHs8Q/DutoD7Lhmo5M twNUVW9x7VEvsy8Dor+FFZMzxrg6j8TooRff23WAEhXxzMS/2va+RxQcONPmK+p/bs Pz3gnQoULKUMhAeb1ZxwE0V7mUlbyoDCm5dPW/CEKhCG/xI97RC1pR+g7z6FF4cvTH ldP1HjI4GAByOwHBAwoWGJTzXKCtAVaF1oU+Y/UQL2E/501piwf+ei3Te+98J6k5ua M9VGvuaAdPfXQ== Subject: [PATCH 2/4] xfs: move remote symlink target read function to libxfs From: "Darrick J. Wong" To: cem@kernel.org, djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:56 -0800 Message-ID: <167243867614.713532.10935720562608290339.stgit@magnolia> In-Reply-To: <167243867587.713532.17037228277541976894.stgit@magnolia> References: <167243867587.713532.17037228277541976894.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Move xfs_readlink_bmap_ilocked to xfs_symlink_remote.c so that the swapext code can use it to convert a remote format symlink back to shortform format after a metadata repair. While we're at it, fix a broken printf modifier. Signed-off-by: Darrick J. Wong --- libxfs/xfs_symlink_remote.c | 77 +++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_symlink_remote.h | 1 + 2 files changed, 78 insertions(+) diff --git a/libxfs/xfs_symlink_remote.c b/libxfs/xfs_symlink_remote.c index e036a8f46fe..db4955adc08 100644 --- a/libxfs/xfs_symlink_remote.c +++ b/libxfs/xfs_symlink_remote.c @@ -14,6 +14,9 @@ #include "xfs_inode.h" #include "xfs_trans.h" #include "xfs_symlink_remote.h" +#include "xfs_bit.h" +#include "xfs_bmap.h" +#include "xfs_health.h" /* * Each contiguous block has a header, so it is not just a simple pathlen @@ -235,3 +238,77 @@ xfs_symlink_shortform_verify( return xfs_symlink_sf_verify_struct(ifp->if_u1.if_data, ifp->if_bytes); } + +/* Read a remote symlink target into the buffer. */ +int +xfs_symlink_remote_read( + struct xfs_inode *ip, + char *link) +{ + struct xfs_mount *mp = ip->i_mount; + struct xfs_bmbt_irec mval[XFS_SYMLINK_MAPS]; + struct xfs_buf *bp; + xfs_daddr_t d; + char *cur_chunk; + int pathlen = ip->i_disk_size; + int nmaps = XFS_SYMLINK_MAPS; + int byte_cnt; + int n; + int error = 0; + int fsblocks = 0; + int offset; + + ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); + + fsblocks = xfs_symlink_blocks(mp, pathlen); + error = xfs_bmapi_read(ip, 0, fsblocks, mval, &nmaps, 0); + if (error) + goto out; + + offset = 0; + for (n = 0; n < nmaps; n++) { + d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock); + byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount); + + error = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0, + &bp, &xfs_symlink_buf_ops); + if (xfs_metadata_is_sick(error)) + xfs_inode_mark_sick(ip, XFS_SICK_INO_SYMLINK); + if (error) + return error; + byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt); + if (pathlen < byte_cnt) + byte_cnt = pathlen; + + cur_chunk = bp->b_addr; + if (xfs_has_crc(mp)) { + if (!xfs_symlink_hdr_ok(ip->i_ino, offset, + byte_cnt, bp)) { + xfs_inode_mark_sick(ip, XFS_SICK_INO_SYMLINK); + error = -EFSCORRUPTED; + xfs_alert(mp, +"symlink header does not match required off/len/owner (0x%x/0x%x,0x%llx)", + offset, byte_cnt, ip->i_ino); + xfs_buf_relse(bp); + goto out; + + } + + cur_chunk += sizeof(struct xfs_dsymlink_hdr); + } + + memcpy(link + offset, cur_chunk, byte_cnt); + + pathlen -= byte_cnt; + offset += byte_cnt; + + xfs_buf_relse(bp); + } + ASSERT(pathlen == 0); + + link[ip->i_disk_size] = '\0'; + error = 0; + + out: + return error; +} diff --git a/libxfs/xfs_symlink_remote.h b/libxfs/xfs_symlink_remote.h index a58d536c8b8..7d3acaee0af 100644 --- a/libxfs/xfs_symlink_remote.h +++ b/libxfs/xfs_symlink_remote.h @@ -19,5 +19,6 @@ 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_sf_verify_struct(void *sfp, int64_t size); xfs_failaddr_t xfs_symlink_shortform_verify(struct xfs_inode *ip); +int xfs_symlink_remote_read(struct xfs_inode *ip, char *link); #endif /* __XFS_SYMLINK_REMOTE_H */