]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
libxfs: local to remote format support of remote symlinks
authorDave Chinner <dchinner@redhat.com>
Wed, 4 Sep 2013 22:05:19 +0000 (22:05 +0000)
committerRich Johnston <rjohnston@sgi.com>
Mon, 16 Sep 2013 20:14:41 +0000 (15:14 -0500)
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 <dchinner@redhat.com>
Review-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Rich Johnston <rjohnston@sgi.com>
include/xfs_symlink.h
libxfs/xfs_bmap.c
libxfs/xfs_symlink.c

index 55f3f2d6869ecc19db648061493d4d0016f318a2..e85dfd1945924afd630481b6a72279bbbdc3ff29 100644 (file)
@@ -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;
 
index 5234674ec170c1d70b6e4aec89aa3d8ed8e67321..ce72b87ed1be57d1df60c7385fcaba2d348321a4 100644 (file)
@@ -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
index 860b123923d001c5bbdeeba8c0dde26ccafddd83..f2e69f93a9a84bd74b8fa38f79d25982f537cb78 100644 (file)
@@ -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);
+}