aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dir2_data.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_dir2_data.c')
-rw-r--r--fs/xfs/xfs_dir2_data.c100
1 files changed, 70 insertions, 30 deletions
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index 8484ec4848ea..78320df3743f 100644
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -31,6 +31,8 @@
31#include "xfs_dir2_format.h" 31#include "xfs_dir2_format.h"
32#include "xfs_dir2_priv.h" 32#include "xfs_dir2_priv.h"
33#include "xfs_error.h" 33#include "xfs_error.h"
34#include "xfs_buf_item.h"
35#include "xfs_cksum.h"
34 36
35STATIC xfs_dir2_data_free_t * 37STATIC xfs_dir2_data_free_t *
36xfs_dir2_data_freefind(xfs_dir2_data_hdr_t *hdr, xfs_dir2_data_unused_t *dup); 38xfs_dir2_data_freefind(xfs_dir2_data_hdr_t *hdr, xfs_dir2_data_unused_t *dup);
@@ -41,7 +43,7 @@ xfs_dir2_data_freefind(xfs_dir2_data_hdr_t *hdr, xfs_dir2_data_unused_t *dup);
41 * Return 0 is the buffer is good, otherwise an error. 43 * Return 0 is the buffer is good, otherwise an error.
42 */ 44 */
43int 45int
44__xfs_dir2_data_check( 46__xfs_dir3_data_check(
45 struct xfs_inode *dp, /* incore inode pointer */ 47 struct xfs_inode *dp, /* incore inode pointer */
46 struct xfs_buf *bp) /* data block's buffer */ 48 struct xfs_buf *bp) /* data block's buffer */
47{ 49{
@@ -76,6 +78,7 @@ __xfs_dir2_data_check(
76 lep = xfs_dir2_block_leaf_p(btp); 78 lep = xfs_dir2_block_leaf_p(btp);
77 endp = (char *)lep; 79 endp = (char *)lep;
78 break; 80 break;
81 case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
79 case cpu_to_be32(XFS_DIR2_DATA_MAGIC): 82 case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
80 endp = (char *)hdr + mp->m_dirblksize; 83 endp = (char *)hdr + mp->m_dirblksize;
81 break; 84 break;
@@ -189,21 +192,27 @@ __xfs_dir2_data_check(
189 return 0; 192 return 0;
190} 193}
191 194
192static void 195static bool
193xfs_dir2_data_verify( 196xfs_dir3_data_verify(
194 struct xfs_buf *bp) 197 struct xfs_buf *bp)
195{ 198{
196 struct xfs_mount *mp = bp->b_target->bt_mount; 199 struct xfs_mount *mp = bp->b_target->bt_mount;
197 struct xfs_dir2_data_hdr *hdr = bp->b_addr; 200 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
198 int block_ok = 0;
199 201
200 block_ok = hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC); 202 if (xfs_sb_version_hascrc(&mp->m_sb)) {
201 block_ok = block_ok && __xfs_dir2_data_check(NULL, bp) == 0; 203 if (hdr3->magic != cpu_to_be32(XFS_DIR3_DATA_MAGIC))
202 204 return false;
203 if (!block_ok) { 205 if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_uuid))
204 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr); 206 return false;
205 xfs_buf_ioerror(bp, EFSCORRUPTED); 207 if (be64_to_cpu(hdr3->blkno) != bp->b_bn)
208 return false;
209 } else {
210 if (hdr3->magic != cpu_to_be32(XFS_DIR2_DATA_MAGIC))
211 return false;
206 } 212 }
213 if (__xfs_dir3_data_check(NULL, bp))
214 return false;
215 return true;
207} 216}
208 217
209/* 218/*
@@ -212,7 +221,7 @@ xfs_dir2_data_verify(
212 * format buffer or a data format buffer on readahead. 221 * format buffer or a data format buffer on readahead.
213 */ 222 */
214static void 223static void
215xfs_dir2_data_reada_verify( 224xfs_dir3_data_reada_verify(
216 struct xfs_buf *bp) 225 struct xfs_buf *bp)
217{ 226{
218 struct xfs_mount *mp = bp->b_target->bt_mount; 227 struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -225,7 +234,8 @@ xfs_dir2_data_reada_verify(
225 bp->b_ops->verify_read(bp); 234 bp->b_ops->verify_read(bp);
226 return; 235 return;
227 case cpu_to_be32(XFS_DIR2_DATA_MAGIC): 236 case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
228 xfs_dir2_data_verify(bp); 237 case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
238 xfs_dir3_data_verify(bp);
229 return; 239 return;
230 default: 240 default:
231 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr); 241 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr);
@@ -235,32 +245,56 @@ xfs_dir2_data_reada_verify(
235} 245}
236 246
237static void 247static void
238xfs_dir2_data_read_verify( 248xfs_dir3_data_read_verify(
239 struct xfs_buf *bp) 249 struct xfs_buf *bp)
240{ 250{
241 xfs_dir2_data_verify(bp); 251 struct xfs_mount *mp = bp->b_target->bt_mount;
252
253 if ((xfs_sb_version_hascrc(&mp->m_sb) &&
254 !xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
255 XFS_DIR3_DATA_CRC_OFF)) ||
256 !xfs_dir3_data_verify(bp)) {
257 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
258 xfs_buf_ioerror(bp, EFSCORRUPTED);
259 }
242} 260}
243 261
244static void 262static void
245xfs_dir2_data_write_verify( 263xfs_dir3_data_write_verify(
246 struct xfs_buf *bp) 264 struct xfs_buf *bp)
247{ 265{
248 xfs_dir2_data_verify(bp); 266 struct xfs_mount *mp = bp->b_target->bt_mount;
267 struct xfs_buf_log_item *bip = bp->b_fspriv;
268 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
269
270 if (!xfs_dir3_data_verify(bp)) {
271 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
272 xfs_buf_ioerror(bp, EFSCORRUPTED);
273 return;
274 }
275
276 if (!xfs_sb_version_hascrc(&mp->m_sb))
277 return;
278
279 if (bip)
280 hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn);
281
282 xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_DIR3_DATA_CRC_OFF);
249} 283}
250 284
251const struct xfs_buf_ops xfs_dir2_data_buf_ops = { 285const struct xfs_buf_ops xfs_dir3_data_buf_ops = {
252 .verify_read = xfs_dir2_data_read_verify, 286 .verify_read = xfs_dir3_data_read_verify,
253 .verify_write = xfs_dir2_data_write_verify, 287 .verify_write = xfs_dir3_data_write_verify,
254}; 288};
255 289
256static const struct xfs_buf_ops xfs_dir2_data_reada_buf_ops = { 290static const struct xfs_buf_ops xfs_dir3_data_reada_buf_ops = {
257 .verify_read = xfs_dir2_data_reada_verify, 291 .verify_read = xfs_dir3_data_reada_verify,
258 .verify_write = xfs_dir2_data_write_verify, 292 .verify_write = xfs_dir3_data_write_verify,
259}; 293};
260 294
261 295
262int 296int
263xfs_dir2_data_read( 297xfs_dir3_data_read(
264 struct xfs_trans *tp, 298 struct xfs_trans *tp,
265 struct xfs_inode *dp, 299 struct xfs_inode *dp,
266 xfs_dablk_t bno, 300 xfs_dablk_t bno,
@@ -268,18 +302,18 @@ xfs_dir2_data_read(
268 struct xfs_buf **bpp) 302 struct xfs_buf **bpp)
269{ 303{
270 return xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp, 304 return xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp,
271 XFS_DATA_FORK, &xfs_dir2_data_buf_ops); 305 XFS_DATA_FORK, &xfs_dir3_data_buf_ops);
272} 306}
273 307
274int 308int
275xfs_dir2_data_readahead( 309xfs_dir3_data_readahead(
276 struct xfs_trans *tp, 310 struct xfs_trans *tp,
277 struct xfs_inode *dp, 311 struct xfs_inode *dp,
278 xfs_dablk_t bno, 312 xfs_dablk_t bno,
279 xfs_daddr_t mapped_bno) 313 xfs_daddr_t mapped_bno)
280{ 314{
281 return xfs_da_reada_buf(tp, dp, bno, mapped_bno, 315 return xfs_da_reada_buf(tp, dp, bno, mapped_bno,
282 XFS_DATA_FORK, &xfs_dir2_data_reada_buf_ops); 316 XFS_DATA_FORK, &xfs_dir3_data_reada_buf_ops);
283} 317}
284 318
285/* 319/*
@@ -309,6 +343,7 @@ xfs_dir2_data_freefind(
309 * one we're looking for it has to be exact. 343 * one we're looking for it has to be exact.
310 */ 344 */
311 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 345 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
346 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
312 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 347 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
313 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 348 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
314 for (dfp = &bf[0], seenzero = matched = 0; 349 for (dfp = &bf[0], seenzero = matched = 0;
@@ -458,6 +493,7 @@ xfs_dir2_data_freescan(
458 char *p; /* current entry pointer */ 493 char *p; /* current entry pointer */
459 494
460 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 495 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
496 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
461 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 497 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
462 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 498 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
463 499
@@ -534,13 +570,12 @@ xfs_dir3_data_init(
534 XFS_DATA_FORK); 570 XFS_DATA_FORK);
535 if (error) 571 if (error)
536 return error; 572 return error;
537 bp->b_ops = &xfs_dir2_data_buf_ops; 573 bp->b_ops = &xfs_dir3_data_buf_ops;
538 574
539 /* 575 /*
540 * Initialize the header. 576 * Initialize the header.
541 */ 577 */
542 hdr = bp->b_addr; 578 hdr = bp->b_addr;
543
544 if (xfs_sb_version_hascrc(&mp->m_sb)) { 579 if (xfs_sb_version_hascrc(&mp->m_sb)) {
545 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; 580 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
546 581
@@ -591,6 +626,7 @@ xfs_dir2_data_log_entry(
591 xfs_dir2_data_hdr_t *hdr = bp->b_addr; 626 xfs_dir2_data_hdr_t *hdr = bp->b_addr;
592 627
593 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 628 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
629 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
594 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 630 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
595 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 631 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
596 632
@@ -610,6 +646,7 @@ xfs_dir2_data_log_header(
610 xfs_dir2_data_hdr_t *hdr = bp->b_addr; 646 xfs_dir2_data_hdr_t *hdr = bp->b_addr;
611 647
612 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 648 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
649 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
613 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 650 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
614 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 651 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
615 652
@@ -628,6 +665,7 @@ xfs_dir2_data_log_unused(
628 xfs_dir2_data_hdr_t *hdr = bp->b_addr; 665 xfs_dir2_data_hdr_t *hdr = bp->b_addr;
629 666
630 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 667 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
668 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
631 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 669 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
632 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 670 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
633 671
@@ -675,7 +713,8 @@ xfs_dir2_data_make_free(
675 /* 713 /*
676 * Figure out where the end of the data area is. 714 * Figure out where the end of the data area is.
677 */ 715 */
678 if (hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC)) 716 if (hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
717 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC))
679 endptr = (char *)hdr + mp->m_dirblksize; 718 endptr = (char *)hdr + mp->m_dirblksize;
680 else { 719 else {
681 xfs_dir2_block_tail_t *btp; /* block tail */ 720 xfs_dir2_block_tail_t *btp; /* block tail */
@@ -857,6 +896,7 @@ xfs_dir2_data_use_free(
857 896
858 hdr = bp->b_addr; 897 hdr = bp->b_addr;
859 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 898 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
899 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
860 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 900 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
861 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 901 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
862 ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG); 902 ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG);