From: Dave Chinner Date: Wed, 4 Sep 2013 22:05:19 +0000 (+0000) Subject: libxfs: local to remote format support of remote symlinks X-Git-Tag: v3.2.0-alpha1~42 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=88b6684366b876c3b8cbcefbec80240cb619c83e;p=thirdparty%2Fxfsprogs-dev.git libxfs: local to remote format support of remote symlinks This conversion was overlooked earlier on. Now that the differences between userspace and kernel space are getting smaller this bug is obvious. Fix it. Signed-off-by: Dave Chinner Review-by: Mark Tinguely Signed-off-by: Rich Johnston --- diff --git a/include/xfs_symlink.h b/include/xfs_symlink.h index 55f3f2d68..e85dfd194 100644 --- a/include/xfs_symlink.h +++ b/include/xfs_symlink.h @@ -31,6 +31,8 @@ struct xfs_dsymlink_hdr { int xfs_symlink_blocks(struct xfs_mount *mp, int pathlen); bool xfs_symlink_hdr_ok(struct xfs_mount *mp, xfs_ino_t ino, uint32_t offset, uint32_t size, struct xfs_buf *bp); +void xfs_symlink_local_to_remote(struct xfs_trans *tp, struct xfs_buf *bp, + struct xfs_inode *ip, struct xfs_ifork *ifp); extern const struct xfs_buf_ops xfs_symlink_buf_ops; diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index 5234674ec..ce72b87ed 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -1221,18 +1221,6 @@ xfs_bmap_add_attrfork_extents( return error; } -STATIC void -xfs_symlink_local_to_remote( - struct xfs_trans *tp, - struct xfs_buf *bp, - struct xfs_inode *ip, - struct xfs_ifork *ifp) -{ - /* remote symlink blocks are not verifiable until CRCs come along */ - bp->b_ops = NULL; - memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes); -} - /* * Called from xfs_bmap_add_attrfork to handle local format files. Each * different data fork content type needs a different callout to do the diff --git a/libxfs/xfs_symlink.c b/libxfs/xfs_symlink.c index 860b12392..f2e69f93a 100644 --- a/libxfs/xfs_symlink.c +++ b/libxfs/xfs_symlink.c @@ -145,3 +145,32 @@ const struct xfs_buf_ops xfs_symlink_buf_ops = { .verify_write = xfs_symlink_write_verify, }; +void +xfs_symlink_local_to_remote( + struct xfs_trans *tp, + struct xfs_buf *bp, + struct xfs_inode *ip, + struct xfs_ifork *ifp) +{ + struct xfs_mount *mp = ip->i_mount; + char *buf; + + if (!xfs_sb_version_hascrc(&mp->m_sb)) { + bp->b_ops = NULL; + memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes); + return; + } + + /* + * As this symlink fits in an inode literal area, it must also fit in + * the smallest buffer the filesystem supports. + */ + ASSERT(BBTOB(bp->b_length) >= + ifp->if_bytes + sizeof(struct xfs_dsymlink_hdr)); + + bp->b_ops = &xfs_symlink_buf_ops; + + buf = bp->b_addr; + buf += xfs_symlink_hdr_set(mp, ip->i_ino, 0, ifp->if_bytes, bp); + memcpy(buf, ifp->if_u1.if_data, ifp->if_bytes); +}