diff options
| author | Dave Chinner <david@fromorbit.com> | 2015-04-12 21:40:16 -0400 |
|---|---|---|
| committer | Dave Chinner <david@fromorbit.com> | 2015-04-12 21:40:16 -0400 |
| commit | 6a63ef064b2444883ce8b68b0779d0c739d27204 (patch) | |
| tree | 03414baf93943556fc492e041a389b1c9a671b6a | |
| parent | a448f8f1b744611fb1867ea811170cca2a9a6588 (diff) | |
| parent | 21c3ea18819b5f650c75f59a0457415bc05d2b17 (diff) | |
Merge branch 'xfs-misc-fixes-for-4.1-3' into for-next
Conflicts:
fs/xfs/xfs_iops.c
| -rw-r--r-- | fs/xfs/libxfs/xfs_attr_leaf.c | 150 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_attr_leaf.h | 6 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_da_format.h | 14 | ||||
| -rw-r--r-- | fs/xfs/xfs_attr_inactive.c | 3 | ||||
| -rw-r--r-- | fs/xfs/xfs_attr_list.c | 9 | ||||
| -rw-r--r-- | fs/xfs/xfs_bmap_util.c | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_file.c | 4 | ||||
| -rw-r--r-- | fs/xfs/xfs_ioctl.c | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_iops.c | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_pnfs.c | 7 | ||||
| -rw-r--r-- | fs/xfs/xfs_pnfs.h | 5 | ||||
| -rw-r--r-- | fs/xfs/xfs_super.c | 6 |
12 files changed, 159 insertions, 51 deletions
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index 15105dbc9e28..04e79d57bca6 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c | |||
| @@ -86,8 +86,83 @@ STATIC void xfs_attr3_leaf_moveents(struct xfs_da_args *args, | |||
| 86 | int move_count); | 86 | int move_count); |
| 87 | STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); | 87 | STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); |
| 88 | 88 | ||
| 89 | /* | ||
| 90 | * attr3 block 'firstused' conversion helpers. | ||
| 91 | * | ||
| 92 | * firstused refers to the offset of the first used byte of the nameval region | ||
| 93 | * of an attr leaf block. The region starts at the tail of the block and expands | ||
| 94 | * backwards towards the middle. As such, firstused is initialized to the block | ||
| 95 | * size for an empty leaf block and is reduced from there. | ||
| 96 | * | ||
| 97 | * The attr3 block size is pegged to the fsb size and the maximum fsb is 64k. | ||
| 98 | * The in-core firstused field is 32-bit and thus supports the maximum fsb size. | ||
| 99 | * The on-disk field is only 16-bit, however, and overflows at 64k. Since this | ||
| 100 | * only occurs at exactly 64k, we use zero as a magic on-disk value to represent | ||
| 101 | * the attr block size. The following helpers manage the conversion between the | ||
| 102 | * in-core and on-disk formats. | ||
| 103 | */ | ||
| 104 | |||
| 105 | static void | ||
| 106 | xfs_attr3_leaf_firstused_from_disk( | ||
| 107 | struct xfs_da_geometry *geo, | ||
| 108 | struct xfs_attr3_icleaf_hdr *to, | ||
| 109 | struct xfs_attr_leafblock *from) | ||
| 110 | { | ||
| 111 | struct xfs_attr3_leaf_hdr *hdr3; | ||
| 112 | |||
| 113 | if (from->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC)) { | ||
| 114 | hdr3 = (struct xfs_attr3_leaf_hdr *) from; | ||
| 115 | to->firstused = be16_to_cpu(hdr3->firstused); | ||
| 116 | } else { | ||
| 117 | to->firstused = be16_to_cpu(from->hdr.firstused); | ||
| 118 | } | ||
| 119 | |||
| 120 | /* | ||
| 121 | * Convert from the magic fsb size value to actual blocksize. This | ||
| 122 | * should only occur for empty blocks when the block size overflows | ||
| 123 | * 16-bits. | ||
| 124 | */ | ||
| 125 | if (to->firstused == XFS_ATTR3_LEAF_NULLOFF) { | ||
| 126 | ASSERT(!to->count && !to->usedbytes); | ||
| 127 | ASSERT(geo->blksize > USHRT_MAX); | ||
| 128 | to->firstused = geo->blksize; | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 132 | static void | ||
| 133 | xfs_attr3_leaf_firstused_to_disk( | ||
| 134 | struct xfs_da_geometry *geo, | ||
| 135 | struct xfs_attr_leafblock *to, | ||
| 136 | struct xfs_attr3_icleaf_hdr *from) | ||
| 137 | { | ||
| 138 | struct xfs_attr3_leaf_hdr *hdr3; | ||
| 139 | uint32_t firstused; | ||
| 140 | |||
| 141 | /* magic value should only be seen on disk */ | ||
| 142 | ASSERT(from->firstused != XFS_ATTR3_LEAF_NULLOFF); | ||
| 143 | |||
| 144 | /* | ||
| 145 | * Scale down the 32-bit in-core firstused value to the 16-bit on-disk | ||
| 146 | * value. This only overflows at the max supported value of 64k. Use the | ||
| 147 | * magic on-disk value to represent block size in this case. | ||
| 148 | */ | ||
| 149 | firstused = from->firstused; | ||
| 150 | if (firstused > USHRT_MAX) { | ||
| 151 | ASSERT(from->firstused == geo->blksize); | ||
| 152 | firstused = XFS_ATTR3_LEAF_NULLOFF; | ||
| 153 | } | ||
| 154 | |||
| 155 | if (from->magic == XFS_ATTR3_LEAF_MAGIC) { | ||
| 156 | hdr3 = (struct xfs_attr3_leaf_hdr *) to; | ||
| 157 | hdr3->firstused = cpu_to_be16(firstused); | ||
| 158 | } else { | ||
| 159 | to->hdr.firstused = cpu_to_be16(firstused); | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 89 | void | 163 | void |
| 90 | xfs_attr3_leaf_hdr_from_disk( | 164 | xfs_attr3_leaf_hdr_from_disk( |
| 165 | struct xfs_da_geometry *geo, | ||
| 91 | struct xfs_attr3_icleaf_hdr *to, | 166 | struct xfs_attr3_icleaf_hdr *to, |
| 92 | struct xfs_attr_leafblock *from) | 167 | struct xfs_attr_leafblock *from) |
| 93 | { | 168 | { |
| @@ -104,7 +179,7 @@ xfs_attr3_leaf_hdr_from_disk( | |||
| 104 | to->magic = be16_to_cpu(hdr3->info.hdr.magic); | 179 | to->magic = be16_to_cpu(hdr3->info.hdr.magic); |
| 105 | to->count = be16_to_cpu(hdr3->count); | 180 | to->count = be16_to_cpu(hdr3->count); |
| 106 | to->usedbytes = be16_to_cpu(hdr3->usedbytes); | 181 | to->usedbytes = be16_to_cpu(hdr3->usedbytes); |
| 107 | to->firstused = be16_to_cpu(hdr3->firstused); | 182 | xfs_attr3_leaf_firstused_from_disk(geo, to, from); |
| 108 | to->holes = hdr3->holes; | 183 | to->holes = hdr3->holes; |
| 109 | 184 | ||
| 110 | for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { | 185 | for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { |
| @@ -118,7 +193,7 @@ xfs_attr3_leaf_hdr_from_disk( | |||
| 118 | to->magic = be16_to_cpu(from->hdr.info.magic); | 193 | to->magic = be16_to_cpu(from->hdr.info.magic); |
| 119 | to->count = be16_to_cpu(from->hdr.count); | 194 | to->count = be16_to_cpu(from->hdr.count); |
| 120 | to->usedbytes = be16_to_cpu(from->hdr.usedbytes); | 195 | to->usedbytes = be16_to_cpu(from->hdr.usedbytes); |
| 121 | to->firstused = be16_to_cpu(from->hdr.firstused); | 196 | xfs_attr3_leaf_firstused_from_disk(geo, to, from); |
| 122 | to->holes = from->hdr.holes; | 197 | to->holes = from->hdr.holes; |
| 123 | 198 | ||
| 124 | for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { | 199 | for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { |
| @@ -129,10 +204,11 @@ xfs_attr3_leaf_hdr_from_disk( | |||
| 129 | 204 | ||
| 130 | void | 205 | void |
| 131 | xfs_attr3_leaf_hdr_to_disk( | 206 | xfs_attr3_leaf_hdr_to_disk( |
| 207 | struct xfs_da_geometry *geo, | ||
| 132 | struct xfs_attr_leafblock *to, | 208 | struct xfs_attr_leafblock *to, |
| 133 | struct xfs_attr3_icleaf_hdr *from) | 209 | struct xfs_attr3_icleaf_hdr *from) |
| 134 | { | 210 | { |
| 135 | int i; | 211 | int i; |
| 136 | 212 | ||
| 137 | ASSERT(from->magic == XFS_ATTR_LEAF_MAGIC || | 213 | ASSERT(from->magic == XFS_ATTR_LEAF_MAGIC || |
| 138 | from->magic == XFS_ATTR3_LEAF_MAGIC); | 214 | from->magic == XFS_ATTR3_LEAF_MAGIC); |
| @@ -145,7 +221,7 @@ xfs_attr3_leaf_hdr_to_disk( | |||
| 145 | hdr3->info.hdr.magic = cpu_to_be16(from->magic); | 221 | hdr3->info.hdr.magic = cpu_to_be16(from->magic); |
| 146 | hdr3->count = cpu_to_be16(from->count); | 222 | hdr3->count = cpu_to_be16(from->count); |
| 147 | hdr3->usedbytes = cpu_to_be16(from->usedbytes); | 223 | hdr3->usedbytes = cpu_to_be16(from->usedbytes); |
| 148 | hdr3->firstused = cpu_to_be16(from->firstused); | 224 | xfs_attr3_leaf_firstused_to_disk(geo, to, from); |
| 149 | hdr3->holes = from->holes; | 225 | hdr3->holes = from->holes; |
| 150 | hdr3->pad1 = 0; | 226 | hdr3->pad1 = 0; |
| 151 | 227 | ||
| @@ -160,7 +236,7 @@ xfs_attr3_leaf_hdr_to_disk( | |||
| 160 | to->hdr.info.magic = cpu_to_be16(from->magic); | 236 | to->hdr.info.magic = cpu_to_be16(from->magic); |
| 161 | to->hdr.count = cpu_to_be16(from->count); | 237 | to->hdr.count = cpu_to_be16(from->count); |
| 162 | to->hdr.usedbytes = cpu_to_be16(from->usedbytes); | 238 | to->hdr.usedbytes = cpu_to_be16(from->usedbytes); |
| 163 | to->hdr.firstused = cpu_to_be16(from->firstused); | 239 | xfs_attr3_leaf_firstused_to_disk(geo, to, from); |
| 164 | to->hdr.holes = from->holes; | 240 | to->hdr.holes = from->holes; |
| 165 | to->hdr.pad1 = 0; | 241 | to->hdr.pad1 = 0; |
| 166 | 242 | ||
| @@ -178,7 +254,7 @@ xfs_attr3_leaf_verify( | |||
| 178 | struct xfs_attr_leafblock *leaf = bp->b_addr; | 254 | struct xfs_attr_leafblock *leaf = bp->b_addr; |
| 179 | struct xfs_attr3_icleaf_hdr ichdr; | 255 | struct xfs_attr3_icleaf_hdr ichdr; |
| 180 | 256 | ||
| 181 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 257 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf); |
| 182 | 258 | ||
| 183 | if (xfs_sb_version_hascrc(&mp->m_sb)) { | 259 | if (xfs_sb_version_hascrc(&mp->m_sb)) { |
| 184 | struct xfs_da3_node_hdr *hdr3 = bp->b_addr; | 260 | struct xfs_da3_node_hdr *hdr3 = bp->b_addr; |
| @@ -757,9 +833,10 @@ xfs_attr_shortform_allfit( | |||
| 757 | struct xfs_attr3_icleaf_hdr leafhdr; | 833 | struct xfs_attr3_icleaf_hdr leafhdr; |
| 758 | int bytes; | 834 | int bytes; |
| 759 | int i; | 835 | int i; |
| 836 | struct xfs_mount *mp = bp->b_target->bt_mount; | ||
| 760 | 837 | ||
| 761 | leaf = bp->b_addr; | 838 | leaf = bp->b_addr; |
| 762 | xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf); | 839 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf); |
| 763 | entry = xfs_attr3_leaf_entryp(leaf); | 840 | entry = xfs_attr3_leaf_entryp(leaf); |
| 764 | 841 | ||
| 765 | bytes = sizeof(struct xfs_attr_sf_hdr); | 842 | bytes = sizeof(struct xfs_attr_sf_hdr); |
| @@ -812,7 +889,7 @@ xfs_attr3_leaf_to_shortform( | |||
| 812 | memcpy(tmpbuffer, bp->b_addr, args->geo->blksize); | 889 | memcpy(tmpbuffer, bp->b_addr, args->geo->blksize); |
| 813 | 890 | ||
| 814 | leaf = (xfs_attr_leafblock_t *)tmpbuffer; | 891 | leaf = (xfs_attr_leafblock_t *)tmpbuffer; |
| 815 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 892 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); |
| 816 | entry = xfs_attr3_leaf_entryp(leaf); | 893 | entry = xfs_attr3_leaf_entryp(leaf); |
| 817 | 894 | ||
| 818 | /* XXX (dgc): buffer is about to be marked stale - why zero it? */ | 895 | /* XXX (dgc): buffer is about to be marked stale - why zero it? */ |
| @@ -923,7 +1000,7 @@ xfs_attr3_leaf_to_node( | |||
| 923 | btree = dp->d_ops->node_tree_p(node); | 1000 | btree = dp->d_ops->node_tree_p(node); |
| 924 | 1001 | ||
| 925 | leaf = bp2->b_addr; | 1002 | leaf = bp2->b_addr; |
| 926 | xfs_attr3_leaf_hdr_from_disk(&icleafhdr, leaf); | 1003 | xfs_attr3_leaf_hdr_from_disk(args->geo, &icleafhdr, leaf); |
| 927 | entries = xfs_attr3_leaf_entryp(leaf); | 1004 | entries = xfs_attr3_leaf_entryp(leaf); |
| 928 | 1005 | ||
| 929 | /* both on-disk, don't endian-flip twice */ | 1006 | /* both on-disk, don't endian-flip twice */ |
| @@ -988,7 +1065,7 @@ xfs_attr3_leaf_create( | |||
| 988 | } | 1065 | } |
| 989 | ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base; | 1066 | ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base; |
| 990 | 1067 | ||
| 991 | xfs_attr3_leaf_hdr_to_disk(leaf, &ichdr); | 1068 | xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr); |
| 992 | xfs_trans_log_buf(args->trans, bp, 0, args->geo->blksize - 1); | 1069 | xfs_trans_log_buf(args->trans, bp, 0, args->geo->blksize - 1); |
| 993 | 1070 | ||
| 994 | *bpp = bp; | 1071 | *bpp = bp; |
| @@ -1073,7 +1150,7 @@ xfs_attr3_leaf_add( | |||
| 1073 | trace_xfs_attr_leaf_add(args); | 1150 | trace_xfs_attr_leaf_add(args); |
| 1074 | 1151 | ||
| 1075 | leaf = bp->b_addr; | 1152 | leaf = bp->b_addr; |
| 1076 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 1153 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); |
| 1077 | ASSERT(args->index >= 0 && args->index <= ichdr.count); | 1154 | ASSERT(args->index >= 0 && args->index <= ichdr.count); |
| 1078 | entsize = xfs_attr_leaf_newentsize(args, NULL); | 1155 | entsize = xfs_attr_leaf_newentsize(args, NULL); |
| 1079 | 1156 | ||
| @@ -1126,7 +1203,7 @@ xfs_attr3_leaf_add( | |||
| 1126 | tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, 0); | 1203 | tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, 0); |
| 1127 | 1204 | ||
| 1128 | out_log_hdr: | 1205 | out_log_hdr: |
| 1129 | xfs_attr3_leaf_hdr_to_disk(leaf, &ichdr); | 1206 | xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr); |
| 1130 | xfs_trans_log_buf(args->trans, bp, | 1207 | xfs_trans_log_buf(args->trans, bp, |
| 1131 | XFS_DA_LOGRANGE(leaf, &leaf->hdr, | 1208 | XFS_DA_LOGRANGE(leaf, &leaf->hdr, |
| 1132 | xfs_attr3_leaf_hdr_size(leaf))); | 1209 | xfs_attr3_leaf_hdr_size(leaf))); |
| @@ -1294,7 +1371,7 @@ xfs_attr3_leaf_compact( | |||
| 1294 | ichdr_dst->freemap[0].base; | 1371 | ichdr_dst->freemap[0].base; |
| 1295 | 1372 | ||
| 1296 | /* write the header back to initialise the underlying buffer */ | 1373 | /* write the header back to initialise the underlying buffer */ |
| 1297 | xfs_attr3_leaf_hdr_to_disk(leaf_dst, ichdr_dst); | 1374 | xfs_attr3_leaf_hdr_to_disk(args->geo, leaf_dst, ichdr_dst); |
| 1298 | 1375 | ||
| 1299 | /* | 1376 | /* |
| 1300 | * Copy all entry's in the same (sorted) order, | 1377 | * Copy all entry's in the same (sorted) order, |
| @@ -1344,9 +1421,10 @@ xfs_attr_leaf_order( | |||
| 1344 | { | 1421 | { |
| 1345 | struct xfs_attr3_icleaf_hdr ichdr1; | 1422 | struct xfs_attr3_icleaf_hdr ichdr1; |
| 1346 | struct xfs_attr3_icleaf_hdr ichdr2; | 1423 | struct xfs_attr3_icleaf_hdr ichdr2; |
| 1424 | struct xfs_mount *mp = leaf1_bp->b_target->bt_mount; | ||
| 1347 | 1425 | ||
| 1348 | xfs_attr3_leaf_hdr_from_disk(&ichdr1, leaf1_bp->b_addr); | 1426 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr1, leaf1_bp->b_addr); |
| 1349 | xfs_attr3_leaf_hdr_from_disk(&ichdr2, leaf2_bp->b_addr); | 1427 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr2, leaf2_bp->b_addr); |
| 1350 | return xfs_attr3_leaf_order(leaf1_bp, &ichdr1, leaf2_bp, &ichdr2); | 1428 | return xfs_attr3_leaf_order(leaf1_bp, &ichdr1, leaf2_bp, &ichdr2); |
| 1351 | } | 1429 | } |
| 1352 | 1430 | ||
| @@ -1388,8 +1466,8 @@ xfs_attr3_leaf_rebalance( | |||
| 1388 | ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC); | 1466 | ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC); |
| 1389 | leaf1 = blk1->bp->b_addr; | 1467 | leaf1 = blk1->bp->b_addr; |
| 1390 | leaf2 = blk2->bp->b_addr; | 1468 | leaf2 = blk2->bp->b_addr; |
| 1391 | xfs_attr3_leaf_hdr_from_disk(&ichdr1, leaf1); | 1469 | xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr1, leaf1); |
| 1392 | xfs_attr3_leaf_hdr_from_disk(&ichdr2, leaf2); | 1470 | xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr2, leaf2); |
| 1393 | ASSERT(ichdr2.count == 0); | 1471 | ASSERT(ichdr2.count == 0); |
| 1394 | args = state->args; | 1472 | args = state->args; |
| 1395 | 1473 | ||
| @@ -1490,8 +1568,8 @@ xfs_attr3_leaf_rebalance( | |||
| 1490 | ichdr1.count, count); | 1568 | ichdr1.count, count); |
| 1491 | } | 1569 | } |
| 1492 | 1570 | ||
| 1493 | xfs_attr3_leaf_hdr_to_disk(leaf1, &ichdr1); | 1571 | xfs_attr3_leaf_hdr_to_disk(state->args->geo, leaf1, &ichdr1); |
| 1494 | xfs_attr3_leaf_hdr_to_disk(leaf2, &ichdr2); | 1572 | xfs_attr3_leaf_hdr_to_disk(state->args->geo, leaf2, &ichdr2); |
| 1495 | xfs_trans_log_buf(args->trans, blk1->bp, 0, args->geo->blksize - 1); | 1573 | xfs_trans_log_buf(args->trans, blk1->bp, 0, args->geo->blksize - 1); |
| 1496 | xfs_trans_log_buf(args->trans, blk2->bp, 0, args->geo->blksize - 1); | 1574 | xfs_trans_log_buf(args->trans, blk2->bp, 0, args->geo->blksize - 1); |
| 1497 | 1575 | ||
| @@ -1684,7 +1762,7 @@ xfs_attr3_leaf_toosmall( | |||
| 1684 | */ | 1762 | */ |
| 1685 | blk = &state->path.blk[ state->path.active-1 ]; | 1763 | blk = &state->path.blk[ state->path.active-1 ]; |
| 1686 | leaf = blk->bp->b_addr; | 1764 | leaf = blk->bp->b_addr; |
| 1687 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 1765 | xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr, leaf); |
| 1688 | bytes = xfs_attr3_leaf_hdr_size(leaf) + | 1766 | bytes = xfs_attr3_leaf_hdr_size(leaf) + |
| 1689 | ichdr.count * sizeof(xfs_attr_leaf_entry_t) + | 1767 | ichdr.count * sizeof(xfs_attr_leaf_entry_t) + |
| 1690 | ichdr.usedbytes; | 1768 | ichdr.usedbytes; |
| @@ -1740,7 +1818,7 @@ xfs_attr3_leaf_toosmall( | |||
| 1740 | if (error) | 1818 | if (error) |
| 1741 | return error; | 1819 | return error; |
| 1742 | 1820 | ||
| 1743 | xfs_attr3_leaf_hdr_from_disk(&ichdr2, bp->b_addr); | 1821 | xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr2, bp->b_addr); |
| 1744 | 1822 | ||
| 1745 | bytes = state->args->geo->blksize - | 1823 | bytes = state->args->geo->blksize - |
| 1746 | (state->args->geo->blksize >> 2) - | 1824 | (state->args->geo->blksize >> 2) - |
| @@ -1805,7 +1883,7 @@ xfs_attr3_leaf_remove( | |||
| 1805 | trace_xfs_attr_leaf_remove(args); | 1883 | trace_xfs_attr_leaf_remove(args); |
| 1806 | 1884 | ||
| 1807 | leaf = bp->b_addr; | 1885 | leaf = bp->b_addr; |
| 1808 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 1886 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); |
| 1809 | 1887 | ||
| 1810 | ASSERT(ichdr.count > 0 && ichdr.count < args->geo->blksize / 8); | 1888 | ASSERT(ichdr.count > 0 && ichdr.count < args->geo->blksize / 8); |
| 1811 | ASSERT(args->index >= 0 && args->index < ichdr.count); | 1889 | ASSERT(args->index >= 0 && args->index < ichdr.count); |
| @@ -1918,12 +1996,11 @@ xfs_attr3_leaf_remove( | |||
| 1918 | tmp = be16_to_cpu(entry->nameidx); | 1996 | tmp = be16_to_cpu(entry->nameidx); |
| 1919 | } | 1997 | } |
| 1920 | ichdr.firstused = tmp; | 1998 | ichdr.firstused = tmp; |
| 1921 | if (!ichdr.firstused) | 1999 | ASSERT(ichdr.firstused != 0); |
| 1922 | ichdr.firstused = tmp - XFS_ATTR_LEAF_NAME_ALIGN; | ||
| 1923 | } else { | 2000 | } else { |
| 1924 | ichdr.holes = 1; /* mark as needing compaction */ | 2001 | ichdr.holes = 1; /* mark as needing compaction */ |
| 1925 | } | 2002 | } |
| 1926 | xfs_attr3_leaf_hdr_to_disk(leaf, &ichdr); | 2003 | xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr); |
| 1927 | xfs_trans_log_buf(args->trans, bp, | 2004 | xfs_trans_log_buf(args->trans, bp, |
| 1928 | XFS_DA_LOGRANGE(leaf, &leaf->hdr, | 2005 | XFS_DA_LOGRANGE(leaf, &leaf->hdr, |
| 1929 | xfs_attr3_leaf_hdr_size(leaf))); | 2006 | xfs_attr3_leaf_hdr_size(leaf))); |
| @@ -1957,8 +2034,8 @@ xfs_attr3_leaf_unbalance( | |||
| 1957 | 2034 | ||
| 1958 | drop_leaf = drop_blk->bp->b_addr; | 2035 | drop_leaf = drop_blk->bp->b_addr; |
| 1959 | save_leaf = save_blk->bp->b_addr; | 2036 | save_leaf = save_blk->bp->b_addr; |
| 1960 | xfs_attr3_leaf_hdr_from_disk(&drophdr, drop_leaf); | 2037 | xfs_attr3_leaf_hdr_from_disk(state->args->geo, &drophdr, drop_leaf); |
| 1961 | xfs_attr3_leaf_hdr_from_disk(&savehdr, save_leaf); | 2038 | xfs_attr3_leaf_hdr_from_disk(state->args->geo, &savehdr, save_leaf); |
| 1962 | entry = xfs_attr3_leaf_entryp(drop_leaf); | 2039 | entry = xfs_attr3_leaf_entryp(drop_leaf); |
| 1963 | 2040 | ||
| 1964 | /* | 2041 | /* |
| @@ -2012,7 +2089,7 @@ xfs_attr3_leaf_unbalance( | |||
| 2012 | tmphdr.firstused = state->args->geo->blksize; | 2089 | tmphdr.firstused = state->args->geo->blksize; |
| 2013 | 2090 | ||
| 2014 | /* write the header to the temp buffer to initialise it */ | 2091 | /* write the header to the temp buffer to initialise it */ |
| 2015 | xfs_attr3_leaf_hdr_to_disk(tmp_leaf, &tmphdr); | 2092 | xfs_attr3_leaf_hdr_to_disk(state->args->geo, tmp_leaf, &tmphdr); |
| 2016 | 2093 | ||
| 2017 | if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, | 2094 | if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, |
| 2018 | drop_blk->bp, &drophdr)) { | 2095 | drop_blk->bp, &drophdr)) { |
| @@ -2039,7 +2116,7 @@ xfs_attr3_leaf_unbalance( | |||
| 2039 | kmem_free(tmp_leaf); | 2116 | kmem_free(tmp_leaf); |
| 2040 | } | 2117 | } |
| 2041 | 2118 | ||
| 2042 | xfs_attr3_leaf_hdr_to_disk(save_leaf, &savehdr); | 2119 | xfs_attr3_leaf_hdr_to_disk(state->args->geo, save_leaf, &savehdr); |
| 2043 | xfs_trans_log_buf(state->args->trans, save_blk->bp, 0, | 2120 | xfs_trans_log_buf(state->args->trans, save_blk->bp, 0, |
| 2044 | state->args->geo->blksize - 1); | 2121 | state->args->geo->blksize - 1); |
| 2045 | 2122 | ||
| @@ -2085,7 +2162,7 @@ xfs_attr3_leaf_lookup_int( | |||
| 2085 | trace_xfs_attr_leaf_lookup(args); | 2162 | trace_xfs_attr_leaf_lookup(args); |
| 2086 | 2163 | ||
| 2087 | leaf = bp->b_addr; | 2164 | leaf = bp->b_addr; |
| 2088 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 2165 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); |
| 2089 | entries = xfs_attr3_leaf_entryp(leaf); | 2166 | entries = xfs_attr3_leaf_entryp(leaf); |
| 2090 | ASSERT(ichdr.count < args->geo->blksize / 8); | 2167 | ASSERT(ichdr.count < args->geo->blksize / 8); |
| 2091 | 2168 | ||
| @@ -2190,7 +2267,7 @@ xfs_attr3_leaf_getvalue( | |||
| 2190 | int valuelen; | 2267 | int valuelen; |
| 2191 | 2268 | ||
| 2192 | leaf = bp->b_addr; | 2269 | leaf = bp->b_addr; |
| 2193 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 2270 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); |
| 2194 | ASSERT(ichdr.count < args->geo->blksize / 8); | 2271 | ASSERT(ichdr.count < args->geo->blksize / 8); |
| 2195 | ASSERT(args->index < ichdr.count); | 2272 | ASSERT(args->index < ichdr.count); |
| 2196 | 2273 | ||
| @@ -2391,8 +2468,9 @@ xfs_attr_leaf_lasthash( | |||
| 2391 | { | 2468 | { |
| 2392 | struct xfs_attr3_icleaf_hdr ichdr; | 2469 | struct xfs_attr3_icleaf_hdr ichdr; |
| 2393 | struct xfs_attr_leaf_entry *entries; | 2470 | struct xfs_attr_leaf_entry *entries; |
| 2471 | struct xfs_mount *mp = bp->b_target->bt_mount; | ||
| 2394 | 2472 | ||
| 2395 | xfs_attr3_leaf_hdr_from_disk(&ichdr, bp->b_addr); | 2473 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, bp->b_addr); |
| 2396 | entries = xfs_attr3_leaf_entryp(bp->b_addr); | 2474 | entries = xfs_attr3_leaf_entryp(bp->b_addr); |
| 2397 | if (count) | 2475 | if (count) |
| 2398 | *count = ichdr.count; | 2476 | *count = ichdr.count; |
| @@ -2486,7 +2564,7 @@ xfs_attr3_leaf_clearflag( | |||
| 2486 | ASSERT(entry->flags & XFS_ATTR_INCOMPLETE); | 2564 | ASSERT(entry->flags & XFS_ATTR_INCOMPLETE); |
| 2487 | 2565 | ||
| 2488 | #ifdef DEBUG | 2566 | #ifdef DEBUG |
| 2489 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 2567 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); |
| 2490 | ASSERT(args->index < ichdr.count); | 2568 | ASSERT(args->index < ichdr.count); |
| 2491 | ASSERT(args->index >= 0); | 2569 | ASSERT(args->index >= 0); |
| 2492 | 2570 | ||
| @@ -2550,7 +2628,7 @@ xfs_attr3_leaf_setflag( | |||
| 2550 | 2628 | ||
| 2551 | leaf = bp->b_addr; | 2629 | leaf = bp->b_addr; |
| 2552 | #ifdef DEBUG | 2630 | #ifdef DEBUG |
| 2553 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 2631 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); |
| 2554 | ASSERT(args->index < ichdr.count); | 2632 | ASSERT(args->index < ichdr.count); |
| 2555 | ASSERT(args->index >= 0); | 2633 | ASSERT(args->index >= 0); |
| 2556 | #endif | 2634 | #endif |
| @@ -2629,11 +2707,11 @@ xfs_attr3_leaf_flipflags( | |||
| 2629 | entry2 = &xfs_attr3_leaf_entryp(leaf2)[args->index2]; | 2707 | entry2 = &xfs_attr3_leaf_entryp(leaf2)[args->index2]; |
| 2630 | 2708 | ||
| 2631 | #ifdef DEBUG | 2709 | #ifdef DEBUG |
| 2632 | xfs_attr3_leaf_hdr_from_disk(&ichdr1, leaf1); | 2710 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr1, leaf1); |
| 2633 | ASSERT(args->index < ichdr1.count); | 2711 | ASSERT(args->index < ichdr1.count); |
| 2634 | ASSERT(args->index >= 0); | 2712 | ASSERT(args->index >= 0); |
| 2635 | 2713 | ||
| 2636 | xfs_attr3_leaf_hdr_from_disk(&ichdr2, leaf2); | 2714 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr2, leaf2); |
| 2637 | ASSERT(args->index2 < ichdr2.count); | 2715 | ASSERT(args->index2 < ichdr2.count); |
| 2638 | ASSERT(args->index2 >= 0); | 2716 | ASSERT(args->index2 >= 0); |
| 2639 | 2717 | ||
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h index e2929da7c3ba..025c4b820c03 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.h +++ b/fs/xfs/libxfs/xfs_attr_leaf.h | |||
| @@ -100,9 +100,11 @@ int xfs_attr_leaf_newentsize(struct xfs_da_args *args, int *local); | |||
| 100 | int xfs_attr3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, | 100 | int xfs_attr3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, |
| 101 | xfs_dablk_t bno, xfs_daddr_t mappedbno, | 101 | xfs_dablk_t bno, xfs_daddr_t mappedbno, |
| 102 | struct xfs_buf **bpp); | 102 | struct xfs_buf **bpp); |
| 103 | void xfs_attr3_leaf_hdr_from_disk(struct xfs_attr3_icleaf_hdr *to, | 103 | void xfs_attr3_leaf_hdr_from_disk(struct xfs_da_geometry *geo, |
| 104 | struct xfs_attr3_icleaf_hdr *to, | ||
| 104 | struct xfs_attr_leafblock *from); | 105 | struct xfs_attr_leafblock *from); |
| 105 | void xfs_attr3_leaf_hdr_to_disk(struct xfs_attr_leafblock *to, | 106 | void xfs_attr3_leaf_hdr_to_disk(struct xfs_da_geometry *geo, |
| 107 | struct xfs_attr_leafblock *to, | ||
| 106 | struct xfs_attr3_icleaf_hdr *from); | 108 | struct xfs_attr3_icleaf_hdr *from); |
| 107 | 109 | ||
| 108 | #endif /* __XFS_ATTR_LEAF_H__ */ | 110 | #endif /* __XFS_ATTR_LEAF_H__ */ |
diff --git a/fs/xfs/libxfs/xfs_da_format.h b/fs/xfs/libxfs/xfs_da_format.h index 0a49b0286372..74bcbabfa523 100644 --- a/fs/xfs/libxfs/xfs_da_format.h +++ b/fs/xfs/libxfs/xfs_da_format.h | |||
| @@ -725,7 +725,13 @@ struct xfs_attr3_icleaf_hdr { | |||
| 725 | __uint16_t magic; | 725 | __uint16_t magic; |
| 726 | __uint16_t count; | 726 | __uint16_t count; |
| 727 | __uint16_t usedbytes; | 727 | __uint16_t usedbytes; |
| 728 | __uint16_t firstused; | 728 | /* |
| 729 | * firstused is 32-bit here instead of 16-bit like the on-disk variant | ||
| 730 | * to support maximum fsb size of 64k without overflow issues throughout | ||
| 731 | * the attr code. Instead, the overflow condition is handled on | ||
| 732 | * conversion to/from disk. | ||
| 733 | */ | ||
| 734 | __uint32_t firstused; | ||
| 729 | __u8 holes; | 735 | __u8 holes; |
| 730 | struct { | 736 | struct { |
| 731 | __uint16_t base; | 737 | __uint16_t base; |
| @@ -734,6 +740,12 @@ struct xfs_attr3_icleaf_hdr { | |||
| 734 | }; | 740 | }; |
| 735 | 741 | ||
| 736 | /* | 742 | /* |
| 743 | * Special value to represent fs block size in the leaf header firstused field. | ||
| 744 | * Only used when block size overflows the 2-bytes available on disk. | ||
| 745 | */ | ||
| 746 | #define XFS_ATTR3_LEAF_NULLOFF 0 | ||
| 747 | |||
| 748 | /* | ||
| 737 | * Flags used in the leaf_entry[i].flags field. | 749 | * Flags used in the leaf_entry[i].flags field. |
| 738 | * NOTE: the INCOMPLETE bit must not collide with the flags bits specified | 750 | * NOTE: the INCOMPLETE bit must not collide with the flags bits specified |
| 739 | * on the system call, they are "or"ed together for various operations. | 751 | * on the system call, they are "or"ed together for various operations. |
diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c index 83af4c149635..f9c1c64782d3 100644 --- a/fs/xfs/xfs_attr_inactive.c +++ b/fs/xfs/xfs_attr_inactive.c | |||
| @@ -132,9 +132,10 @@ xfs_attr3_leaf_inactive( | |||
| 132 | int size; | 132 | int size; |
| 133 | int tmp; | 133 | int tmp; |
| 134 | int i; | 134 | int i; |
| 135 | struct xfs_mount *mp = bp->b_target->bt_mount; | ||
| 135 | 136 | ||
| 136 | leaf = bp->b_addr; | 137 | leaf = bp->b_addr; |
| 137 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 138 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf); |
| 138 | 139 | ||
| 139 | /* | 140 | /* |
| 140 | * Count the number of "remote" value extents. | 141 | * Count the number of "remote" value extents. |
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c index a43d370d2c58..65fb37a18e92 100644 --- a/fs/xfs/xfs_attr_list.c +++ b/fs/xfs/xfs_attr_list.c | |||
| @@ -225,6 +225,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) | |||
| 225 | int error, i; | 225 | int error, i; |
| 226 | struct xfs_buf *bp; | 226 | struct xfs_buf *bp; |
| 227 | struct xfs_inode *dp = context->dp; | 227 | struct xfs_inode *dp = context->dp; |
| 228 | struct xfs_mount *mp = dp->i_mount; | ||
| 228 | 229 | ||
| 229 | trace_xfs_attr_node_list(context); | 230 | trace_xfs_attr_node_list(context); |
| 230 | 231 | ||
| @@ -256,7 +257,8 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) | |||
| 256 | case XFS_ATTR_LEAF_MAGIC: | 257 | case XFS_ATTR_LEAF_MAGIC: |
| 257 | case XFS_ATTR3_LEAF_MAGIC: | 258 | case XFS_ATTR3_LEAF_MAGIC: |
| 258 | leaf = bp->b_addr; | 259 | leaf = bp->b_addr; |
| 259 | xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf); | 260 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, |
| 261 | &leafhdr, leaf); | ||
| 260 | entries = xfs_attr3_leaf_entryp(leaf); | 262 | entries = xfs_attr3_leaf_entryp(leaf); |
| 261 | if (cursor->hashval > be32_to_cpu( | 263 | if (cursor->hashval > be32_to_cpu( |
| 262 | entries[leafhdr.count - 1].hashval)) { | 264 | entries[leafhdr.count - 1].hashval)) { |
| @@ -340,7 +342,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) | |||
| 340 | xfs_trans_brelse(NULL, bp); | 342 | xfs_trans_brelse(NULL, bp); |
| 341 | return error; | 343 | return error; |
| 342 | } | 344 | } |
| 343 | xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf); | 345 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf); |
| 344 | if (context->seen_enough || leafhdr.forw == 0) | 346 | if (context->seen_enough || leafhdr.forw == 0) |
| 345 | break; | 347 | break; |
| 346 | cursor->blkno = leafhdr.forw; | 348 | cursor->blkno = leafhdr.forw; |
| @@ -368,11 +370,12 @@ xfs_attr3_leaf_list_int( | |||
| 368 | struct xfs_attr_leaf_entry *entry; | 370 | struct xfs_attr_leaf_entry *entry; |
| 369 | int retval; | 371 | int retval; |
| 370 | int i; | 372 | int i; |
| 373 | struct xfs_mount *mp = context->dp->i_mount; | ||
| 371 | 374 | ||
| 372 | trace_xfs_attr_list_leaf(context); | 375 | trace_xfs_attr_list_leaf(context); |
| 373 | 376 | ||
| 374 | leaf = bp->b_addr; | 377 | leaf = bp->b_addr; |
| 375 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 378 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf); |
| 376 | entries = xfs_attr3_leaf_entryp(leaf); | 379 | entries = xfs_attr3_leaf_entryp(leaf); |
| 377 | 380 | ||
| 378 | cursor = context->cursor; | 381 | cursor = context->cursor; |
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 1bd539321799..a52bbd3abc7d 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c | |||
| @@ -1383,7 +1383,7 @@ out: | |||
| 1383 | * If we are shifting right, we will start with last extent inside file space | 1383 | * If we are shifting right, we will start with last extent inside file space |
| 1384 | * and continue until we reach the block corresponding to offset. | 1384 | * and continue until we reach the block corresponding to offset. |
| 1385 | */ | 1385 | */ |
| 1386 | int | 1386 | static int |
| 1387 | xfs_shift_file_space( | 1387 | xfs_shift_file_space( |
| 1388 | struct xfs_inode *ip, | 1388 | struct xfs_inode *ip, |
| 1389 | xfs_off_t offset, | 1389 | xfs_off_t offset, |
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index dc5f609bea88..c203839cd5be 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
| @@ -559,7 +559,7 @@ restart: | |||
| 559 | if (error) | 559 | if (error) |
| 560 | return error; | 560 | return error; |
| 561 | 561 | ||
| 562 | error = xfs_break_layouts(inode, iolock); | 562 | error = xfs_break_layouts(inode, iolock, true); |
| 563 | if (error) | 563 | if (error) |
| 564 | return error; | 564 | return error; |
| 565 | 565 | ||
| @@ -848,7 +848,7 @@ xfs_file_fallocate( | |||
| 848 | return -EOPNOTSUPP; | 848 | return -EOPNOTSUPP; |
| 849 | 849 | ||
| 850 | xfs_ilock(ip, iolock); | 850 | xfs_ilock(ip, iolock); |
| 851 | error = xfs_break_layouts(inode, &iolock); | 851 | error = xfs_break_layouts(inode, &iolock, false); |
| 852 | if (error) | 852 | if (error) |
| 853 | goto out_unlock; | 853 | goto out_unlock; |
| 854 | 854 | ||
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 4ee44ddfdfb7..5f4a396f5186 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c | |||
| @@ -639,7 +639,7 @@ xfs_ioc_space( | |||
| 639 | return error; | 639 | return error; |
| 640 | 640 | ||
| 641 | xfs_ilock(ip, iolock); | 641 | xfs_ilock(ip, iolock); |
| 642 | error = xfs_break_layouts(inode, &iolock); | 642 | error = xfs_break_layouts(inode, &iolock, false); |
| 643 | if (error) | 643 | if (error) |
| 644 | goto out_unlock; | 644 | goto out_unlock; |
| 645 | 645 | ||
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 015d6a366b16..2f1839e4dd1b 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
| @@ -953,7 +953,7 @@ xfs_vn_setattr( | |||
| 953 | uint iolock = XFS_IOLOCK_EXCL; | 953 | uint iolock = XFS_IOLOCK_EXCL; |
| 954 | 954 | ||
| 955 | xfs_ilock(ip, iolock); | 955 | xfs_ilock(ip, iolock); |
| 956 | error = xfs_break_layouts(dentry->d_inode, &iolock); | 956 | error = xfs_break_layouts(dentry->d_inode, &iolock, true); |
| 957 | if (!error) { | 957 | if (!error) { |
| 958 | xfs_ilock(ip, XFS_MMAPLOCK_EXCL); | 958 | xfs_ilock(ip, XFS_MMAPLOCK_EXCL); |
| 959 | iolock |= XFS_MMAPLOCK_EXCL; | 959 | iolock |= XFS_MMAPLOCK_EXCL; |
diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c index 365dd57ea760..981a657eca39 100644 --- a/fs/xfs/xfs_pnfs.c +++ b/fs/xfs/xfs_pnfs.c | |||
| @@ -31,7 +31,8 @@ | |||
| 31 | int | 31 | int |
| 32 | xfs_break_layouts( | 32 | xfs_break_layouts( |
| 33 | struct inode *inode, | 33 | struct inode *inode, |
| 34 | uint *iolock) | 34 | uint *iolock, |
| 35 | bool with_imutex) | ||
| 35 | { | 36 | { |
| 36 | struct xfs_inode *ip = XFS_I(inode); | 37 | struct xfs_inode *ip = XFS_I(inode); |
| 37 | int error; | 38 | int error; |
| @@ -40,8 +41,12 @@ xfs_break_layouts( | |||
| 40 | 41 | ||
| 41 | while ((error = break_layout(inode, false) == -EWOULDBLOCK)) { | 42 | while ((error = break_layout(inode, false) == -EWOULDBLOCK)) { |
| 42 | xfs_iunlock(ip, *iolock); | 43 | xfs_iunlock(ip, *iolock); |
| 44 | if (with_imutex && (*iolock & XFS_IOLOCK_EXCL)) | ||
| 45 | mutex_unlock(&inode->i_mutex); | ||
| 43 | error = break_layout(inode, true); | 46 | error = break_layout(inode, true); |
| 44 | *iolock = XFS_IOLOCK_EXCL; | 47 | *iolock = XFS_IOLOCK_EXCL; |
| 48 | if (with_imutex) | ||
| 49 | mutex_lock(&inode->i_mutex); | ||
| 45 | xfs_ilock(ip, *iolock); | 50 | xfs_ilock(ip, *iolock); |
| 46 | } | 51 | } |
| 47 | 52 | ||
diff --git a/fs/xfs/xfs_pnfs.h b/fs/xfs/xfs_pnfs.h index b7fbfce660f6..8147ac108820 100644 --- a/fs/xfs/xfs_pnfs.h +++ b/fs/xfs/xfs_pnfs.h | |||
| @@ -8,9 +8,10 @@ int xfs_fs_map_blocks(struct inode *inode, loff_t offset, u64 length, | |||
| 8 | int xfs_fs_commit_blocks(struct inode *inode, struct iomap *maps, int nr_maps, | 8 | int xfs_fs_commit_blocks(struct inode *inode, struct iomap *maps, int nr_maps, |
| 9 | struct iattr *iattr); | 9 | struct iattr *iattr); |
| 10 | 10 | ||
| 11 | int xfs_break_layouts(struct inode *inode, uint *iolock); | 11 | int xfs_break_layouts(struct inode *inode, uint *iolock, bool with_imutex); |
| 12 | #else | 12 | #else |
| 13 | static inline int xfs_break_layouts(struct inode *inode, uint *iolock) | 13 | static inline int |
| 14 | xfs_break_layouts(struct inode *inode, uint *iolock, bool with_imutex) | ||
| 14 | { | 15 | { |
| 15 | return 0; | 16 | return 0; |
| 16 | } | 17 | } |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 8782b36517b5..5f357ca97e76 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
| @@ -1227,6 +1227,12 @@ xfs_fs_remount( | |||
| 1227 | 1227 | ||
| 1228 | /* ro -> rw */ | 1228 | /* ro -> rw */ |
| 1229 | if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) { | 1229 | if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) { |
| 1230 | if (mp->m_flags & XFS_MOUNT_NORECOVERY) { | ||
| 1231 | xfs_warn(mp, | ||
| 1232 | "ro->rw transition prohibited on norecovery mount"); | ||
| 1233 | return -EINVAL; | ||
| 1234 | } | ||
| 1235 | |||
| 1230 | mp->m_flags &= ~XFS_MOUNT_RDONLY; | 1236 | mp->m_flags &= ~XFS_MOUNT_RDONLY; |
| 1231 | 1237 | ||
| 1232 | /* | 1238 | /* |
