aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <david@fromorbit.com>2015-04-12 21:40:16 -0400
committerDave Chinner <david@fromorbit.com>2015-04-12 21:40:16 -0400
commit6a63ef064b2444883ce8b68b0779d0c739d27204 (patch)
tree03414baf93943556fc492e041a389b1c9a671b6a /fs/xfs
parenta448f8f1b744611fb1867ea811170cca2a9a6588 (diff)
parent21c3ea18819b5f650c75f59a0457415bc05d2b17 (diff)
Merge branch 'xfs-misc-fixes-for-4.1-3' into for-next
Conflicts: fs/xfs/xfs_iops.c
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/libxfs/xfs_attr_leaf.c150
-rw-r--r--fs/xfs/libxfs/xfs_attr_leaf.h6
-rw-r--r--fs/xfs/libxfs/xfs_da_format.h14
-rw-r--r--fs/xfs/xfs_attr_inactive.c3
-rw-r--r--fs/xfs/xfs_attr_list.c9
-rw-r--r--fs/xfs/xfs_bmap_util.c2
-rw-r--r--fs/xfs/xfs_file.c4
-rw-r--r--fs/xfs/xfs_ioctl.c2
-rw-r--r--fs/xfs/xfs_iops.c2
-rw-r--r--fs/xfs/xfs_pnfs.c7
-rw-r--r--fs/xfs/xfs_pnfs.h5
-rw-r--r--fs/xfs/xfs_super.c6
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);
87STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); 87STATIC 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
105static void
106xfs_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
132static void
133xfs_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
89void 163void
90xfs_attr3_leaf_hdr_from_disk( 164xfs_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
130void 205void
131xfs_attr3_leaf_hdr_to_disk( 206xfs_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
1128out_log_hdr: 1205out_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);
100int xfs_attr3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, 100int 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);
103void xfs_attr3_leaf_hdr_from_disk(struct xfs_attr3_icleaf_hdr *to, 103void 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);
105void xfs_attr3_leaf_hdr_to_disk(struct xfs_attr_leafblock *to, 106void 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 */
1386int 1386static int
1387xfs_shift_file_space( 1387xfs_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 @@
31int 31int
32xfs_break_layouts( 32xfs_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,
8int xfs_fs_commit_blocks(struct inode *inode, struct iomap *maps, int nr_maps, 8int xfs_fs_commit_blocks(struct inode *inode, struct iomap *maps, int nr_maps,
9 struct iattr *iattr); 9 struct iattr *iattr);
10 10
11int xfs_break_layouts(struct inode *inode, uint *iolock); 11int xfs_break_layouts(struct inode *inode, uint *iolock, bool with_imutex);
12#else 12#else
13static inline int xfs_break_layouts(struct inode *inode, uint *iolock) 13static inline int
14xfs_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 /*