diff options
author | Dave Chinner <david@fromorbit.com> | 2016-12-07 01:42:30 -0500 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2016-12-07 01:42:30 -0500 |
commit | a444d72e609062a040ed95a50e8fccfa1d58281b (patch) | |
tree | c57054f0e2674a9a80097e48a266c505c0cddca6 /fs/xfs/libxfs | |
parent | 5f1c6d28cfcd11c9df67dad45992fd523727fe1e (diff) | |
parent | 6031e73a5b3f85ec45cac08ef90995b2d3f941c7 (diff) |
Merge branch 'xfs-4.10-misc-fixes-3' into for-next
Diffstat (limited to 'fs/xfs/libxfs')
-rw-r--r-- | fs/xfs/libxfs/xfs_alloc.c | 10 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_alloc_btree.c | 4 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_attr_leaf.h | 2 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_bmap.c | 14 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_bmap_btree.c | 1 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_btree.c | 20 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_btree.h | 43 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_cksum.h | 26 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_dir2_data.c | 2 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_ialloc.c | 13 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_ialloc_btree.c | 2 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_inode_buf.c | 10 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_refcount_btree.c | 1 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_rmap_btree.c | 1 |
14 files changed, 93 insertions, 56 deletions
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index effb64cf714f..5050056a0b06 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c | |||
@@ -2455,12 +2455,15 @@ xfs_agf_verify( | |||
2455 | be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp))) | 2455 | be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp))) |
2456 | return false; | 2456 | return false; |
2457 | 2457 | ||
2458 | if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > XFS_BTREE_MAXLEVELS || | 2458 | if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) < 1 || |
2459 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) < 1 || | ||
2460 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > XFS_BTREE_MAXLEVELS || | ||
2459 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) > XFS_BTREE_MAXLEVELS) | 2461 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) > XFS_BTREE_MAXLEVELS) |
2460 | return false; | 2462 | return false; |
2461 | 2463 | ||
2462 | if (xfs_sb_version_hasrmapbt(&mp->m_sb) && | 2464 | if (xfs_sb_version_hasrmapbt(&mp->m_sb) && |
2463 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > XFS_BTREE_MAXLEVELS) | 2465 | (be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) < 1 || |
2466 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > XFS_BTREE_MAXLEVELS)) | ||
2464 | return false; | 2467 | return false; |
2465 | 2468 | ||
2466 | /* | 2469 | /* |
@@ -2477,7 +2480,8 @@ xfs_agf_verify( | |||
2477 | return false; | 2480 | return false; |
2478 | 2481 | ||
2479 | if (xfs_sb_version_hasreflink(&mp->m_sb) && | 2482 | if (xfs_sb_version_hasreflink(&mp->m_sb) && |
2480 | be32_to_cpu(agf->agf_refcount_level) > XFS_BTREE_MAXLEVELS) | 2483 | (be32_to_cpu(agf->agf_refcount_level) < 1 || |
2484 | be32_to_cpu(agf->agf_refcount_level) > XFS_BTREE_MAXLEVELS)) | ||
2481 | return false; | 2485 | return false; |
2482 | 2486 | ||
2483 | return true;; | 2487 | return true;; |
diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index 5ba2dac5e67c..44cfcd03c451 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c | |||
@@ -428,6 +428,10 @@ xfs_allocbt_init_cursor( | |||
428 | cur->bc_btnum = btnum; | 428 | cur->bc_btnum = btnum; |
429 | cur->bc_blocklog = mp->m_sb.sb_blocklog; | 429 | cur->bc_blocklog = mp->m_sb.sb_blocklog; |
430 | cur->bc_ops = &xfs_allocbt_ops; | 430 | cur->bc_ops = &xfs_allocbt_ops; |
431 | if (btnum == XFS_BTNUM_BNO) | ||
432 | cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_abtb_2); | ||
433 | else | ||
434 | cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_abtc_2); | ||
431 | 435 | ||
432 | if (btnum == XFS_BTNUM_CNT) { | 436 | if (btnum == XFS_BTNUM_CNT) { |
433 | cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]); | 437 | cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]); |
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h index 8ef420a16f08..f7dda0c237b0 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.h +++ b/fs/xfs/libxfs/xfs_attr_leaf.h | |||
@@ -77,7 +77,7 @@ int xfs_attr3_leaf_add(struct xfs_buf *leaf_buffer, | |||
77 | struct xfs_da_args *args); | 77 | struct xfs_da_args *args); |
78 | int xfs_attr3_leaf_remove(struct xfs_buf *leaf_buffer, | 78 | int xfs_attr3_leaf_remove(struct xfs_buf *leaf_buffer, |
79 | struct xfs_da_args *args); | 79 | struct xfs_da_args *args); |
80 | int xfs_attr3_leaf_list_int(struct xfs_buf *bp, | 80 | void xfs_attr3_leaf_list_int(struct xfs_buf *bp, |
81 | struct xfs_attr_list_context *context); | 81 | struct xfs_attr_list_context *context); |
82 | 82 | ||
83 | /* | 83 | /* |
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 6f2881430c84..2760bc3b2536 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c | |||
@@ -518,7 +518,7 @@ void | |||
518 | xfs_bmap_trace_exlist( | 518 | xfs_bmap_trace_exlist( |
519 | xfs_inode_t *ip, /* incore inode pointer */ | 519 | xfs_inode_t *ip, /* incore inode pointer */ |
520 | xfs_extnum_t cnt, /* count of entries in the list */ | 520 | xfs_extnum_t cnt, /* count of entries in the list */ |
521 | int whichfork, /* data or attr fork */ | 521 | int whichfork, /* data or attr or cow fork */ |
522 | unsigned long caller_ip) | 522 | unsigned long caller_ip) |
523 | { | 523 | { |
524 | xfs_extnum_t idx; /* extent record index */ | 524 | xfs_extnum_t idx; /* extent record index */ |
@@ -527,11 +527,13 @@ xfs_bmap_trace_exlist( | |||
527 | 527 | ||
528 | if (whichfork == XFS_ATTR_FORK) | 528 | if (whichfork == XFS_ATTR_FORK) |
529 | state |= BMAP_ATTRFORK; | 529 | state |= BMAP_ATTRFORK; |
530 | else if (whichfork == XFS_COW_FORK) | ||
531 | state |= BMAP_COWFORK; | ||
530 | 532 | ||
531 | ifp = XFS_IFORK_PTR(ip, whichfork); | 533 | ifp = XFS_IFORK_PTR(ip, whichfork); |
532 | ASSERT(cnt == xfs_iext_count(ifp)); | 534 | ASSERT(cnt == xfs_iext_count(ifp)); |
533 | for (idx = 0; idx < cnt; idx++) | 535 | for (idx = 0; idx < cnt; idx++) |
534 | trace_xfs_extlist(ip, idx, whichfork, caller_ip); | 536 | trace_xfs_extlist(ip, idx, state, caller_ip); |
535 | } | 537 | } |
536 | 538 | ||
537 | /* | 539 | /* |
@@ -1151,6 +1153,10 @@ xfs_bmap_add_attrfork( | |||
1151 | goto trans_cancel; | 1153 | goto trans_cancel; |
1152 | if (XFS_IFORK_Q(ip)) | 1154 | if (XFS_IFORK_Q(ip)) |
1153 | goto trans_cancel; | 1155 | goto trans_cancel; |
1156 | if (ip->i_d.di_anextents != 0) { | ||
1157 | error = -EFSCORRUPTED; | ||
1158 | goto trans_cancel; | ||
1159 | } | ||
1154 | if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) { | 1160 | if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) { |
1155 | /* | 1161 | /* |
1156 | * For inodes coming from pre-6.2 filesystems. | 1162 | * For inodes coming from pre-6.2 filesystems. |
@@ -1158,7 +1164,6 @@ xfs_bmap_add_attrfork( | |||
1158 | ASSERT(ip->i_d.di_aformat == 0); | 1164 | ASSERT(ip->i_d.di_aformat == 0); |
1159 | ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; | 1165 | ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; |
1160 | } | 1166 | } |
1161 | ASSERT(ip->i_d.di_anextents == 0); | ||
1162 | 1167 | ||
1163 | xfs_trans_ijoin(tp, ip, 0); | 1168 | xfs_trans_ijoin(tp, ip, 0); |
1164 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 1169 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
@@ -1375,8 +1380,9 @@ xfs_bmap_read_extents( | |||
1375 | return error; | 1380 | return error; |
1376 | block = XFS_BUF_TO_BLOCK(bp); | 1381 | block = XFS_BUF_TO_BLOCK(bp); |
1377 | } | 1382 | } |
1383 | if (i != XFS_IFORK_NEXTENTS(ip, whichfork)) | ||
1384 | return -EFSCORRUPTED; | ||
1378 | ASSERT(i == xfs_iext_count(ifp)); | 1385 | ASSERT(i == xfs_iext_count(ifp)); |
1379 | ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork)); | ||
1380 | XFS_BMAP_TRACE_EXLIST(ip, i, whichfork); | 1386 | XFS_BMAP_TRACE_EXLIST(ip, i, whichfork); |
1381 | return 0; | 1387 | return 0; |
1382 | error0: | 1388 | error0: |
diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 8007d2ba9aef..94ad31d372ab 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c | |||
@@ -803,6 +803,7 @@ xfs_bmbt_init_cursor( | |||
803 | cur->bc_nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1; | 803 | cur->bc_nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1; |
804 | cur->bc_btnum = XFS_BTNUM_BMAP; | 804 | cur->bc_btnum = XFS_BTNUM_BMAP; |
805 | cur->bc_blocklog = mp->m_sb.sb_blocklog; | 805 | cur->bc_blocklog = mp->m_sb.sb_blocklog; |
806 | cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_bmbt_2); | ||
806 | 807 | ||
807 | cur->bc_ops = &xfs_bmbt_ops; | 808 | cur->bc_ops = &xfs_bmbt_ops; |
808 | cur->bc_flags = XFS_BTREE_LONG_PTRS | XFS_BTREE_ROOT_IN_INODE; | 809 | cur->bc_flags = XFS_BTREE_LONG_PTRS | XFS_BTREE_ROOT_IN_INODE; |
diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 0e80993c8a59..21e6a6ab6b9a 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c | |||
@@ -1769,8 +1769,28 @@ xfs_btree_lookup_get_block( | |||
1769 | if (error) | 1769 | if (error) |
1770 | return error; | 1770 | return error; |
1771 | 1771 | ||
1772 | /* Check the inode owner since the verifiers don't. */ | ||
1773 | if (xfs_sb_version_hascrc(&cur->bc_mp->m_sb) && | ||
1774 | (cur->bc_flags & XFS_BTREE_LONG_PTRS) && | ||
1775 | be64_to_cpu((*blkp)->bb_u.l.bb_owner) != | ||
1776 | cur->bc_private.b.ip->i_ino) | ||
1777 | goto out_bad; | ||
1778 | |||
1779 | /* Did we get the level we were looking for? */ | ||
1780 | if (be16_to_cpu((*blkp)->bb_level) != level) | ||
1781 | goto out_bad; | ||
1782 | |||
1783 | /* Check that internal nodes have at least one record. */ | ||
1784 | if (level != 0 && be16_to_cpu((*blkp)->bb_numrecs) == 0) | ||
1785 | goto out_bad; | ||
1786 | |||
1772 | xfs_btree_setbuf(cur, level, bp); | 1787 | xfs_btree_setbuf(cur, level, bp); |
1773 | return 0; | 1788 | return 0; |
1789 | |||
1790 | out_bad: | ||
1791 | *blkp = NULL; | ||
1792 | xfs_trans_brelse(cur->bc_tp, bp); | ||
1793 | return -EFSCORRUPTED; | ||
1774 | } | 1794 | } |
1775 | 1795 | ||
1776 | /* | 1796 | /* |
diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index c2b01d1c79ee..b69b947c4c1b 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h | |||
@@ -96,46 +96,10 @@ union xfs_btree_rec { | |||
96 | /* | 96 | /* |
97 | * Generic stats interface | 97 | * Generic stats interface |
98 | */ | 98 | */ |
99 | #define __XFS_BTREE_STATS_INC(mp, type, stat) \ | ||
100 | XFS_STATS_INC(mp, xs_ ## type ## _2_ ## stat) | ||
101 | #define XFS_BTREE_STATS_INC(cur, stat) \ | 99 | #define XFS_BTREE_STATS_INC(cur, stat) \ |
102 | do { \ | 100 | XFS_STATS_INC_OFF((cur)->bc_mp, (cur)->bc_statoff + __XBTS_ ## stat) |
103 | struct xfs_mount *__mp = cur->bc_mp; \ | 101 | #define XFS_BTREE_STATS_ADD(cur, stat, val) \ |
104 | switch (cur->bc_btnum) { \ | 102 | XFS_STATS_ADD_OFF((cur)->bc_mp, (cur)->bc_statoff + __XBTS_ ## stat, val) |
105 | case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(__mp, abtb, stat); break; \ | ||
106 | case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(__mp, abtc, stat); break; \ | ||
107 | case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(__mp, bmbt, stat); break; \ | ||
108 | case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(__mp, ibt, stat); break; \ | ||
109 | case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(__mp, fibt, stat); break; \ | ||
110 | case XFS_BTNUM_RMAP: __XFS_BTREE_STATS_INC(__mp, rmap, stat); break; \ | ||
111 | case XFS_BTNUM_REFC: __XFS_BTREE_STATS_INC(__mp, refcbt, stat); break; \ | ||
112 | case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ | ||
113 | } \ | ||
114 | } while (0) | ||
115 | |||
116 | #define __XFS_BTREE_STATS_ADD(mp, type, stat, val) \ | ||
117 | XFS_STATS_ADD(mp, xs_ ## type ## _2_ ## stat, val) | ||
118 | #define XFS_BTREE_STATS_ADD(cur, stat, val) \ | ||
119 | do { \ | ||
120 | struct xfs_mount *__mp = cur->bc_mp; \ | ||
121 | switch (cur->bc_btnum) { \ | ||
122 | case XFS_BTNUM_BNO: \ | ||
123 | __XFS_BTREE_STATS_ADD(__mp, abtb, stat, val); break; \ | ||
124 | case XFS_BTNUM_CNT: \ | ||
125 | __XFS_BTREE_STATS_ADD(__mp, abtc, stat, val); break; \ | ||
126 | case XFS_BTNUM_BMAP: \ | ||
127 | __XFS_BTREE_STATS_ADD(__mp, bmbt, stat, val); break; \ | ||
128 | case XFS_BTNUM_INO: \ | ||
129 | __XFS_BTREE_STATS_ADD(__mp, ibt, stat, val); break; \ | ||
130 | case XFS_BTNUM_FINO: \ | ||
131 | __XFS_BTREE_STATS_ADD(__mp, fibt, stat, val); break; \ | ||
132 | case XFS_BTNUM_RMAP: \ | ||
133 | __XFS_BTREE_STATS_ADD(__mp, rmap, stat, val); break; \ | ||
134 | case XFS_BTNUM_REFC: \ | ||
135 | __XFS_BTREE_STATS_ADD(__mp, refcbt, stat, val); break; \ | ||
136 | case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ | ||
137 | } \ | ||
138 | } while (0) | ||
139 | 103 | ||
140 | #define XFS_BTREE_MAXLEVELS 9 /* max of all btrees */ | 104 | #define XFS_BTREE_MAXLEVELS 9 /* max of all btrees */ |
141 | 105 | ||
@@ -253,6 +217,7 @@ typedef struct xfs_btree_cur | |||
253 | __uint8_t bc_nlevels; /* number of levels in the tree */ | 217 | __uint8_t bc_nlevels; /* number of levels in the tree */ |
254 | __uint8_t bc_blocklog; /* log2(blocksize) of btree blocks */ | 218 | __uint8_t bc_blocklog; /* log2(blocksize) of btree blocks */ |
255 | xfs_btnum_t bc_btnum; /* identifies which btree type */ | 219 | xfs_btnum_t bc_btnum; /* identifies which btree type */ |
220 | int bc_statoff; /* offset of btre stats array */ | ||
256 | union { | 221 | union { |
257 | struct { /* needed for BNO, CNT, INO */ | 222 | struct { /* needed for BNO, CNT, INO */ |
258 | struct xfs_buf *agbp; /* agf/agi buffer pointer */ | 223 | struct xfs_buf *agbp; /* agf/agi buffer pointer */ |
diff --git a/fs/xfs/libxfs/xfs_cksum.h b/fs/xfs/libxfs/xfs_cksum.h index fad1676ad8cd..a416c7cb23ea 100644 --- a/fs/xfs/libxfs/xfs_cksum.h +++ b/fs/xfs/libxfs/xfs_cksum.h | |||
@@ -6,10 +6,11 @@ | |||
6 | /* | 6 | /* |
7 | * Calculate the intermediate checksum for a buffer that has the CRC field | 7 | * Calculate the intermediate checksum for a buffer that has the CRC field |
8 | * inside it. The offset of the 32bit crc fields is passed as the | 8 | * inside it. The offset of the 32bit crc fields is passed as the |
9 | * cksum_offset parameter. | 9 | * cksum_offset parameter. We do not modify the buffer during verification, |
10 | * hence we have to split the CRC calculation across the cksum_offset. | ||
10 | */ | 11 | */ |
11 | static inline __uint32_t | 12 | static inline __uint32_t |
12 | xfs_start_cksum(char *buffer, size_t length, unsigned long cksum_offset) | 13 | xfs_start_cksum_safe(char *buffer, size_t length, unsigned long cksum_offset) |
13 | { | 14 | { |
14 | __uint32_t zero = 0; | 15 | __uint32_t zero = 0; |
15 | __uint32_t crc; | 16 | __uint32_t crc; |
@@ -26,6 +27,20 @@ xfs_start_cksum(char *buffer, size_t length, unsigned long cksum_offset) | |||
26 | } | 27 | } |
27 | 28 | ||
28 | /* | 29 | /* |
30 | * Fast CRC method where the buffer is modified. Callers must have exclusive | ||
31 | * access to the buffer while the calculation takes place. | ||
32 | */ | ||
33 | static inline __uint32_t | ||
34 | xfs_start_cksum_update(char *buffer, size_t length, unsigned long cksum_offset) | ||
35 | { | ||
36 | /* zero the CRC field */ | ||
37 | *(__le32 *)(buffer + cksum_offset) = 0; | ||
38 | |||
39 | /* single pass CRC calculation for the entire buffer */ | ||
40 | return crc32c(XFS_CRC_SEED, buffer, length); | ||
41 | } | ||
42 | |||
43 | /* | ||
29 | * Convert the intermediate checksum to the final ondisk format. | 44 | * Convert the intermediate checksum to the final ondisk format. |
30 | * | 45 | * |
31 | * The CRC32c calculation uses LE format even on BE machines, but returns the | 46 | * The CRC32c calculation uses LE format even on BE machines, but returns the |
@@ -40,11 +55,14 @@ xfs_end_cksum(__uint32_t crc) | |||
40 | 55 | ||
41 | /* | 56 | /* |
42 | * Helper to generate the checksum for a buffer. | 57 | * Helper to generate the checksum for a buffer. |
58 | * | ||
59 | * This modifies the buffer temporarily - callers must have exclusive | ||
60 | * access to the buffer while the calculation takes place. | ||
43 | */ | 61 | */ |
44 | static inline void | 62 | static inline void |
45 | xfs_update_cksum(char *buffer, size_t length, unsigned long cksum_offset) | 63 | xfs_update_cksum(char *buffer, size_t length, unsigned long cksum_offset) |
46 | { | 64 | { |
47 | __uint32_t crc = xfs_start_cksum(buffer, length, cksum_offset); | 65 | __uint32_t crc = xfs_start_cksum_update(buffer, length, cksum_offset); |
48 | 66 | ||
49 | *(__le32 *)(buffer + cksum_offset) = xfs_end_cksum(crc); | 67 | *(__le32 *)(buffer + cksum_offset) = xfs_end_cksum(crc); |
50 | } | 68 | } |
@@ -55,7 +73,7 @@ xfs_update_cksum(char *buffer, size_t length, unsigned long cksum_offset) | |||
55 | static inline int | 73 | static inline int |
56 | xfs_verify_cksum(char *buffer, size_t length, unsigned long cksum_offset) | 74 | xfs_verify_cksum(char *buffer, size_t length, unsigned long cksum_offset) |
57 | { | 75 | { |
58 | __uint32_t crc = xfs_start_cksum(buffer, length, cksum_offset); | 76 | __uint32_t crc = xfs_start_cksum_safe(buffer, length, cksum_offset); |
59 | 77 | ||
60 | return *(__le32 *)(buffer + cksum_offset) == xfs_end_cksum(crc); | 78 | return *(__le32 *)(buffer + cksum_offset) == xfs_end_cksum(crc); |
61 | } | 79 | } |
diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index cd75ab9f3bf8..d478065b9544 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c | |||
@@ -329,7 +329,7 @@ xfs_dir3_data_read( | |||
329 | 329 | ||
330 | err = xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp, | 330 | err = xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp, |
331 | XFS_DATA_FORK, &xfs_dir3_data_buf_ops); | 331 | XFS_DATA_FORK, &xfs_dir3_data_buf_ops); |
332 | if (!err && tp) | 332 | if (!err && tp && *bpp) |
333 | xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_DATA_BUF); | 333 | xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_DATA_BUF); |
334 | return err; | 334 | return err; |
335 | } | 335 | } |
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index c507c1b17ca1..f272abff11e1 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c | |||
@@ -2451,8 +2451,6 @@ xfs_ialloc_log_agi( | |||
2451 | ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC)); | 2451 | ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC)); |
2452 | #endif | 2452 | #endif |
2453 | 2453 | ||
2454 | xfs_trans_buf_set_type(tp, bp, XFS_BLFT_AGI_BUF); | ||
2455 | |||
2456 | /* | 2454 | /* |
2457 | * Compute byte offsets for the first and last fields in the first | 2455 | * Compute byte offsets for the first and last fields in the first |
2458 | * region and log the agi buffer. This only logs up through | 2456 | * region and log the agi buffer. This only logs up through |
@@ -2513,8 +2511,15 @@ xfs_agi_verify( | |||
2513 | if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum))) | 2511 | if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum))) |
2514 | return false; | 2512 | return false; |
2515 | 2513 | ||
2516 | if (be32_to_cpu(agi->agi_level) > XFS_BTREE_MAXLEVELS) | 2514 | if (be32_to_cpu(agi->agi_level) < 1 || |
2515 | be32_to_cpu(agi->agi_level) > XFS_BTREE_MAXLEVELS) | ||
2516 | return false; | ||
2517 | |||
2518 | if (xfs_sb_version_hasfinobt(&mp->m_sb) && | ||
2519 | (be32_to_cpu(agi->agi_free_level) < 1 || | ||
2520 | be32_to_cpu(agi->agi_free_level) > XFS_BTREE_MAXLEVELS)) | ||
2517 | return false; | 2521 | return false; |
2522 | |||
2518 | /* | 2523 | /* |
2519 | * during growfs operations, the perag is not fully initialised, | 2524 | * during growfs operations, the perag is not fully initialised, |
2520 | * so we can't use it for any useful checking. growfs ensures we can't | 2525 | * so we can't use it for any useful checking. growfs ensures we can't |
@@ -2593,6 +2598,8 @@ xfs_read_agi( | |||
2593 | XFS_FSS_TO_BB(mp, 1), 0, bpp, &xfs_agi_buf_ops); | 2598 | XFS_FSS_TO_BB(mp, 1), 0, bpp, &xfs_agi_buf_ops); |
2594 | if (error) | 2599 | if (error) |
2595 | return error; | 2600 | return error; |
2601 | if (tp) | ||
2602 | xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_AGI_BUF); | ||
2596 | 2603 | ||
2597 | xfs_buf_set_ref(*bpp, XFS_AGI_REF); | 2604 | xfs_buf_set_ref(*bpp, XFS_AGI_REF); |
2598 | return 0; | 2605 | return 0; |
diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index eab68ae2e011..e7ff8ef0e5a7 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c | |||
@@ -365,9 +365,11 @@ xfs_inobt_init_cursor( | |||
365 | if (btnum == XFS_BTNUM_INO) { | 365 | if (btnum == XFS_BTNUM_INO) { |
366 | cur->bc_nlevels = be32_to_cpu(agi->agi_level); | 366 | cur->bc_nlevels = be32_to_cpu(agi->agi_level); |
367 | cur->bc_ops = &xfs_inobt_ops; | 367 | cur->bc_ops = &xfs_inobt_ops; |
368 | cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_ibt_2); | ||
368 | } else { | 369 | } else { |
369 | cur->bc_nlevels = be32_to_cpu(agi->agi_free_level); | 370 | cur->bc_nlevels = be32_to_cpu(agi->agi_free_level); |
370 | cur->bc_ops = &xfs_finobt_ops; | 371 | cur->bc_ops = &xfs_finobt_ops; |
372 | cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_fibt_2); | ||
371 | } | 373 | } |
372 | 374 | ||
373 | cur->bc_blocklog = mp->m_sb.sb_blocklog; | 375 | cur->bc_blocklog = mp->m_sb.sb_blocklog; |
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index 54817f82212c..dd483e2767f7 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c | |||
@@ -392,6 +392,14 @@ xfs_dinode_verify( | |||
392 | if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC)) | 392 | if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC)) |
393 | return false; | 393 | return false; |
394 | 394 | ||
395 | /* don't allow invalid i_size */ | ||
396 | if (be64_to_cpu(dip->di_size) & (1ULL << 63)) | ||
397 | return false; | ||
398 | |||
399 | /* No zero-length symlinks. */ | ||
400 | if (S_ISLNK(be16_to_cpu(dip->di_mode)) && dip->di_size == 0) | ||
401 | return false; | ||
402 | |||
395 | /* only version 3 or greater inodes are extensively verified here */ | 403 | /* only version 3 or greater inodes are extensively verified here */ |
396 | if (dip->di_version < 3) | 404 | if (dip->di_version < 3) |
397 | return true; | 405 | return true; |
@@ -436,7 +444,7 @@ xfs_dinode_calc_crc( | |||
436 | return; | 444 | return; |
437 | 445 | ||
438 | ASSERT(xfs_sb_version_hascrc(&mp->m_sb)); | 446 | ASSERT(xfs_sb_version_hascrc(&mp->m_sb)); |
439 | crc = xfs_start_cksum((char *)dip, mp->m_sb.sb_inodesize, | 447 | crc = xfs_start_cksum_update((char *)dip, mp->m_sb.sb_inodesize, |
440 | XFS_DINODE_CRC_OFF); | 448 | XFS_DINODE_CRC_OFF); |
441 | dip->di_crc = xfs_end_cksum(crc); | 449 | dip->di_crc = xfs_end_cksum(crc); |
442 | } | 450 | } |
diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index 453bb2757ec2..6fb2215f8ff7 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c | |||
@@ -354,6 +354,7 @@ xfs_refcountbt_init_cursor( | |||
354 | cur->bc_btnum = XFS_BTNUM_REFC; | 354 | cur->bc_btnum = XFS_BTNUM_REFC; |
355 | cur->bc_blocklog = mp->m_sb.sb_blocklog; | 355 | cur->bc_blocklog = mp->m_sb.sb_blocklog; |
356 | cur->bc_ops = &xfs_refcountbt_ops; | 356 | cur->bc_ops = &xfs_refcountbt_ops; |
357 | cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2); | ||
357 | 358 | ||
358 | cur->bc_nlevels = be32_to_cpu(agf->agf_refcount_level); | 359 | cur->bc_nlevels = be32_to_cpu(agf->agf_refcount_level); |
359 | 360 | ||
diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index 83e672ff7577..de25771764ba 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c | |||
@@ -484,6 +484,7 @@ xfs_rmapbt_init_cursor( | |||
484 | cur->bc_blocklog = mp->m_sb.sb_blocklog; | 484 | cur->bc_blocklog = mp->m_sb.sb_blocklog; |
485 | cur->bc_ops = &xfs_rmapbt_ops; | 485 | cur->bc_ops = &xfs_rmapbt_ops; |
486 | cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]); | 486 | cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]); |
487 | cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_rmap_2); | ||
487 | 488 | ||
488 | cur->bc_private.a.agbp = agbp; | 489 | cur->bc_private.a.agbp = agbp; |
489 | cur->bc_private.a.agno = agno; | 490 | cur->bc_private.a.agno = agno; |