xfs_symlink_remote.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * Copyright (c) 2000-2006 Silicon Graphics, Inc.
  3. * Copyright (c) 2012-2013 Red Hat, Inc.
  4. * All rights reserved.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it would be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write the Free Software Foundation,
  17. * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18. */
  19. #include "xfs.h"
  20. #include "xfs_fs.h"
  21. #include "xfs_format.h"
  22. #include "xfs_log_format.h"
  23. #include "xfs_shared.h"
  24. #include "xfs_trans_resv.h"
  25. #include "xfs_mount.h"
  26. #include "xfs_bmap_btree.h"
  27. #include "xfs_inode.h"
  28. #include "xfs_error.h"
  29. #include "xfs_trace.h"
  30. #include "xfs_symlink.h"
  31. #include "xfs_cksum.h"
  32. #include "xfs_trans.h"
  33. #include "xfs_buf_item.h"
  34. #include "xfs_log.h"
  35. /*
  36. * Each contiguous block has a header, so it is not just a simple pathlen
  37. * to FSB conversion.
  38. */
  39. int
  40. xfs_symlink_blocks(
  41. struct xfs_mount *mp,
  42. int pathlen)
  43. {
  44. int buflen = XFS_SYMLINK_BUF_SPACE(mp, mp->m_sb.sb_blocksize);
  45. return (pathlen + buflen - 1) / buflen;
  46. }
  47. int
  48. xfs_symlink_hdr_set(
  49. struct xfs_mount *mp,
  50. xfs_ino_t ino,
  51. uint32_t offset,
  52. uint32_t size,
  53. struct xfs_buf *bp)
  54. {
  55. struct xfs_dsymlink_hdr *dsl = bp->b_addr;
  56. if (!xfs_sb_version_hascrc(&mp->m_sb))
  57. return 0;
  58. memset(dsl, 0, sizeof(struct xfs_dsymlink_hdr));
  59. dsl->sl_magic = cpu_to_be32(XFS_SYMLINK_MAGIC);
  60. dsl->sl_offset = cpu_to_be32(offset);
  61. dsl->sl_bytes = cpu_to_be32(size);
  62. uuid_copy(&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid);
  63. dsl->sl_owner = cpu_to_be64(ino);
  64. dsl->sl_blkno = cpu_to_be64(bp->b_bn);
  65. bp->b_ops = &xfs_symlink_buf_ops;
  66. return sizeof(struct xfs_dsymlink_hdr);
  67. }
  68. /*
  69. * Checking of the symlink header is split into two parts. the verifier does
  70. * CRC, location and bounds checking, the unpacking function checks the path
  71. * parameters and owner.
  72. */
  73. bool
  74. xfs_symlink_hdr_ok(
  75. xfs_ino_t ino,
  76. uint32_t offset,
  77. uint32_t size,
  78. struct xfs_buf *bp)
  79. {
  80. struct xfs_dsymlink_hdr *dsl = bp->b_addr;
  81. if (offset != be32_to_cpu(dsl->sl_offset))
  82. return false;
  83. if (size != be32_to_cpu(dsl->sl_bytes))
  84. return false;
  85. if (ino != be64_to_cpu(dsl->sl_owner))
  86. return false;
  87. /* ok */
  88. return true;
  89. }
  90. static bool
  91. xfs_symlink_verify(
  92. struct xfs_buf *bp)
  93. {
  94. struct xfs_mount *mp = bp->b_target->bt_mount;
  95. struct xfs_dsymlink_hdr *dsl = bp->b_addr;
  96. if (!xfs_sb_version_hascrc(&mp->m_sb))
  97. return false;
  98. if (dsl->sl_magic != cpu_to_be32(XFS_SYMLINK_MAGIC))
  99. return false;
  100. if (!uuid_equal(&dsl->sl_uuid, &mp->m_sb.sb_meta_uuid))
  101. return false;
  102. if (bp->b_bn != be64_to_cpu(dsl->sl_blkno))
  103. return false;
  104. if (be32_to_cpu(dsl->sl_offset) +
  105. be32_to_cpu(dsl->sl_bytes) >= MAXPATHLEN)
  106. return false;
  107. if (dsl->sl_owner == 0)
  108. return false;
  109. if (!xfs_log_check_lsn(mp, be64_to_cpu(dsl->sl_lsn)))
  110. return false;
  111. return true;
  112. }
  113. static void
  114. xfs_symlink_read_verify(
  115. struct xfs_buf *bp)
  116. {
  117. struct xfs_mount *mp = bp->b_target->bt_mount;
  118. /* no verification of non-crc buffers */
  119. if (!xfs_sb_version_hascrc(&mp->m_sb))
  120. return;
  121. if (!xfs_buf_verify_cksum(bp, XFS_SYMLINK_CRC_OFF))
  122. xfs_buf_ioerror(bp, -EFSBADCRC);
  123. else if (!xfs_symlink_verify(bp))
  124. xfs_buf_ioerror(bp, -EFSCORRUPTED);
  125. if (bp->b_error)
  126. xfs_verifier_error(bp);
  127. }
  128. static void
  129. xfs_symlink_write_verify(
  130. struct xfs_buf *bp)
  131. {
  132. struct xfs_mount *mp = bp->b_target->bt_mount;
  133. struct xfs_buf_log_item *bip = bp->b_fspriv;
  134. /* no verification of non-crc buffers */
  135. if (!xfs_sb_version_hascrc(&mp->m_sb))
  136. return;
  137. if (!xfs_symlink_verify(bp)) {
  138. xfs_buf_ioerror(bp, -EFSCORRUPTED);
  139. xfs_verifier_error(bp);
  140. return;
  141. }
  142. if (bip) {
  143. struct xfs_dsymlink_hdr *dsl = bp->b_addr;
  144. dsl->sl_lsn = cpu_to_be64(bip->bli_item.li_lsn);
  145. }
  146. xfs_buf_update_cksum(bp, XFS_SYMLINK_CRC_OFF);
  147. }
  148. const struct xfs_buf_ops xfs_symlink_buf_ops = {
  149. .name = "xfs_symlink",
  150. .verify_read = xfs_symlink_read_verify,
  151. .verify_write = xfs_symlink_write_verify,
  152. };
  153. void
  154. xfs_symlink_local_to_remote(
  155. struct xfs_trans *tp,
  156. struct xfs_buf *bp,
  157. struct xfs_inode *ip,
  158. struct xfs_ifork *ifp)
  159. {
  160. struct xfs_mount *mp = ip->i_mount;
  161. char *buf;
  162. xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SYMLINK_BUF);
  163. if (!xfs_sb_version_hascrc(&mp->m_sb)) {
  164. bp->b_ops = NULL;
  165. memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes);
  166. xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1);
  167. return;
  168. }
  169. /*
  170. * As this symlink fits in an inode literal area, it must also fit in
  171. * the smallest buffer the filesystem supports.
  172. */
  173. ASSERT(BBTOB(bp->b_length) >=
  174. ifp->if_bytes + sizeof(struct xfs_dsymlink_hdr));
  175. bp->b_ops = &xfs_symlink_buf_ops;
  176. buf = bp->b_addr;
  177. buf += xfs_symlink_hdr_set(mp, ip->i_ino, 0, ifp->if_bytes, bp);
  178. memcpy(buf, ifp->if_u1.if_data, ifp->if_bytes);
  179. xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsymlink_hdr) +
  180. ifp->if_bytes - 1);
  181. }