aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-04-24 04:58:55 -0400
committerBen Myers <bpm@sgi.com>2013-04-27 13:45:01 -0400
commit517c22207b045993a6529e1f8684095adaae9cf3 (patch)
tree3ce1f91a7334f878a28ef032f97706a5b15619c0 /fs/xfs
parentf5ea110044fa858925a880b4fa9f551bfa2dfc38 (diff)
xfs: add CRCs to attr leaf blocks
Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Ben Myers <bpm@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_attr.c125
-rw-r--r--fs/xfs/xfs_attr_leaf.c1740
-rw-r--r--fs/xfs/xfs_attr_leaf.h122
-rw-r--r--fs/xfs/xfs_da_btree.c34
-rw-r--r--fs/xfs/xfs_da_btree.h5
5 files changed, 1177 insertions, 849 deletions
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index 7afef2810e41..e70687541592 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -819,7 +819,7 @@ xfs_attr_inactive(xfs_inode_t *dp)
819 error = 0; 819 error = 0;
820 goto out; 820 goto out;
821 } 821 }
822 error = xfs_attr_root_inactive(&trans, dp); 822 error = xfs_attr3_root_inactive(&trans, dp);
823 if (error) 823 if (error)
824 goto out; 824 goto out;
825 825
@@ -905,7 +905,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
905 */ 905 */
906 dp = args->dp; 906 dp = args->dp;
907 args->blkno = 0; 907 args->blkno = 0;
908 error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno, -1, &bp); 908 error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
909 if (error) 909 if (error)
910 return error; 910 return error;
911 911
@@ -913,14 +913,14 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
913 * Look up the given attribute in the leaf block. Figure out if 913 * Look up the given attribute in the leaf block. Figure out if
914 * the given flags produce an error or call for an atomic rename. 914 * the given flags produce an error or call for an atomic rename.
915 */ 915 */
916 retval = xfs_attr_leaf_lookup_int(bp, args); 916 retval = xfs_attr3_leaf_lookup_int(bp, args);
917 if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) { 917 if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) {
918 xfs_trans_brelse(args->trans, bp); 918 xfs_trans_brelse(args->trans, bp);
919 return(retval); 919 return retval;
920 } else if (retval == EEXIST) { 920 } else if (retval == EEXIST) {
921 if (args->flags & ATTR_CREATE) { /* pure create op */ 921 if (args->flags & ATTR_CREATE) { /* pure create op */
922 xfs_trans_brelse(args->trans, bp); 922 xfs_trans_brelse(args->trans, bp);
923 return(retval); 923 return retval;
924 } 924 }
925 925
926 trace_xfs_attr_leaf_replace(args); 926 trace_xfs_attr_leaf_replace(args);
@@ -936,7 +936,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
936 * Add the attribute to the leaf block, transitioning to a Btree 936 * Add the attribute to the leaf block, transitioning to a Btree
937 * if required. 937 * if required.
938 */ 938 */
939 retval = xfs_attr_leaf_add(bp, args); 939 retval = xfs_attr3_leaf_add(bp, args);
940 if (retval == ENOSPC) { 940 if (retval == ENOSPC) {
941 /* 941 /*
942 * Promote the attribute list to the Btree format, then 942 * Promote the attribute list to the Btree format, then
@@ -944,7 +944,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
944 * can manage its own transactions. 944 * can manage its own transactions.
945 */ 945 */
946 xfs_bmap_init(args->flist, args->firstblock); 946 xfs_bmap_init(args->flist, args->firstblock);
947 error = xfs_attr_leaf_to_node(args); 947 error = xfs_attr3_leaf_to_node(args);
948 if (!error) { 948 if (!error) {
949 error = xfs_bmap_finish(&args->trans, args->flist, 949 error = xfs_bmap_finish(&args->trans, args->flist,
950 &committed); 950 &committed);
@@ -1009,7 +1009,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
1009 * In a separate transaction, set the incomplete flag on the 1009 * In a separate transaction, set the incomplete flag on the
1010 * "old" attr and clear the incomplete flag on the "new" attr. 1010 * "old" attr and clear the incomplete flag on the "new" attr.
1011 */ 1011 */
1012 error = xfs_attr_leaf_flipflags(args); 1012 error = xfs_attr3_leaf_flipflags(args);
1013 if (error) 1013 if (error)
1014 return(error); 1014 return(error);
1015 1015
@@ -1031,19 +1031,19 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
1031 * Read in the block containing the "old" attr, then 1031 * Read in the block containing the "old" attr, then
1032 * remove the "old" attr from that block (neat, huh!) 1032 * remove the "old" attr from that block (neat, huh!)
1033 */ 1033 */
1034 error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno, 1034 error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno,
1035 -1, &bp); 1035 -1, &bp);
1036 if (error) 1036 if (error)
1037 return error; 1037 return error;
1038 1038
1039 xfs_attr_leaf_remove(bp, args); 1039 xfs_attr3_leaf_remove(bp, args);
1040 1040
1041 /* 1041 /*
1042 * If the result is small enough, shrink it all into the inode. 1042 * If the result is small enough, shrink it all into the inode.
1043 */ 1043 */
1044 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { 1044 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
1045 xfs_bmap_init(args->flist, args->firstblock); 1045 xfs_bmap_init(args->flist, args->firstblock);
1046 error = xfs_attr_leaf_to_shortform(bp, args, forkoff); 1046 error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
1047 /* bp is gone due to xfs_da_shrink_inode */ 1047 /* bp is gone due to xfs_da_shrink_inode */
1048 if (!error) { 1048 if (!error) {
1049 error = xfs_bmap_finish(&args->trans, 1049 error = xfs_bmap_finish(&args->trans,
@@ -1075,9 +1075,9 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
1075 /* 1075 /*
1076 * Added a "remote" value, just clear the incomplete flag. 1076 * Added a "remote" value, just clear the incomplete flag.
1077 */ 1077 */
1078 error = xfs_attr_leaf_clearflag(args); 1078 error = xfs_attr3_leaf_clearflag(args);
1079 } 1079 }
1080 return(error); 1080 return error;
1081} 1081}
1082 1082
1083/* 1083/*
@@ -1100,24 +1100,24 @@ xfs_attr_leaf_removename(xfs_da_args_t *args)
1100 */ 1100 */
1101 dp = args->dp; 1101 dp = args->dp;
1102 args->blkno = 0; 1102 args->blkno = 0;
1103 error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno, -1, &bp); 1103 error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
1104 if (error) 1104 if (error)
1105 return error; 1105 return error;
1106 1106
1107 error = xfs_attr_leaf_lookup_int(bp, args); 1107 error = xfs_attr3_leaf_lookup_int(bp, args);
1108 if (error == ENOATTR) { 1108 if (error == ENOATTR) {
1109 xfs_trans_brelse(args->trans, bp); 1109 xfs_trans_brelse(args->trans, bp);
1110 return(error); 1110 return error;
1111 } 1111 }
1112 1112
1113 xfs_attr_leaf_remove(bp, args); 1113 xfs_attr3_leaf_remove(bp, args);
1114 1114
1115 /* 1115 /*
1116 * If the result is small enough, shrink it all into the inode. 1116 * If the result is small enough, shrink it all into the inode.
1117 */ 1117 */
1118 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { 1118 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
1119 xfs_bmap_init(args->flist, args->firstblock); 1119 xfs_bmap_init(args->flist, args->firstblock);
1120 error = xfs_attr_leaf_to_shortform(bp, args, forkoff); 1120 error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
1121 /* bp is gone due to xfs_da_shrink_inode */ 1121 /* bp is gone due to xfs_da_shrink_inode */
1122 if (!error) { 1122 if (!error) {
1123 error = xfs_bmap_finish(&args->trans, args->flist, 1123 error = xfs_bmap_finish(&args->trans, args->flist,
@@ -1127,7 +1127,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args)
1127 ASSERT(committed); 1127 ASSERT(committed);
1128 args->trans = NULL; 1128 args->trans = NULL;
1129 xfs_bmap_cancel(args->flist); 1129 xfs_bmap_cancel(args->flist);
1130 return(error); 1130 return error;
1131 } 1131 }
1132 1132
1133 /* 1133 /*
@@ -1137,7 +1137,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args)
1137 if (committed) 1137 if (committed)
1138 xfs_trans_ijoin(args->trans, dp, 0); 1138 xfs_trans_ijoin(args->trans, dp, 0);
1139 } 1139 }
1140 return(0); 1140 return 0;
1141} 1141}
1142 1142
1143/* 1143/*
@@ -1155,21 +1155,21 @@ xfs_attr_leaf_get(xfs_da_args_t *args)
1155 trace_xfs_attr_leaf_get(args); 1155 trace_xfs_attr_leaf_get(args);
1156 1156
1157 args->blkno = 0; 1157 args->blkno = 0;
1158 error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno, -1, &bp); 1158 error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
1159 if (error) 1159 if (error)
1160 return error; 1160 return error;
1161 1161
1162 error = xfs_attr_leaf_lookup_int(bp, args); 1162 error = xfs_attr3_leaf_lookup_int(bp, args);
1163 if (error != EEXIST) { 1163 if (error != EEXIST) {
1164 xfs_trans_brelse(args->trans, bp); 1164 xfs_trans_brelse(args->trans, bp);
1165 return(error); 1165 return error;
1166 } 1166 }
1167 error = xfs_attr_leaf_getvalue(bp, args); 1167 error = xfs_attr3_leaf_getvalue(bp, args);
1168 xfs_trans_brelse(args->trans, bp); 1168 xfs_trans_brelse(args->trans, bp);
1169 if (!error && (args->rmtblkno > 0) && !(args->flags & ATTR_KERNOVAL)) { 1169 if (!error && (args->rmtblkno > 0) && !(args->flags & ATTR_KERNOVAL)) {
1170 error = xfs_attr_rmtval_get(args); 1170 error = xfs_attr_rmtval_get(args);
1171 } 1171 }
1172 return(error); 1172 return error;
1173} 1173}
1174 1174
1175/* 1175/*
@@ -1184,11 +1184,11 @@ xfs_attr_leaf_list(xfs_attr_list_context_t *context)
1184 trace_xfs_attr_leaf_list(context); 1184 trace_xfs_attr_leaf_list(context);
1185 1185
1186 context->cursor->blkno = 0; 1186 context->cursor->blkno = 0;
1187 error = xfs_attr_leaf_read(NULL, context->dp, 0, -1, &bp); 1187 error = xfs_attr3_leaf_read(NULL, context->dp, 0, -1, &bp);
1188 if (error) 1188 if (error)
1189 return XFS_ERROR(error); 1189 return XFS_ERROR(error);
1190 1190
1191 error = xfs_attr_leaf_list_int(bp, context); 1191 error = xfs_attr3_leaf_list_int(bp, context);
1192 xfs_trans_brelse(NULL, bp); 1192 xfs_trans_brelse(NULL, bp);
1193 return XFS_ERROR(error); 1193 return XFS_ERROR(error);
1194} 1194}
@@ -1257,7 +1257,7 @@ restart:
1257 args->rmtblkcnt = 0; 1257 args->rmtblkcnt = 0;
1258 } 1258 }
1259 1259
1260 retval = xfs_attr_leaf_add(blk->bp, state->args); 1260 retval = xfs_attr3_leaf_add(blk->bp, state->args);
1261 if (retval == ENOSPC) { 1261 if (retval == ENOSPC) {
1262 if (state->path.active == 1) { 1262 if (state->path.active == 1) {
1263 /* 1263 /*
@@ -1267,7 +1267,7 @@ restart:
1267 */ 1267 */
1268 xfs_da_state_free(state); 1268 xfs_da_state_free(state);
1269 xfs_bmap_init(args->flist, args->firstblock); 1269 xfs_bmap_init(args->flist, args->firstblock);
1270 error = xfs_attr_leaf_to_node(args); 1270 error = xfs_attr3_leaf_to_node(args);
1271 if (!error) { 1271 if (!error) {
1272 error = xfs_bmap_finish(&args->trans, 1272 error = xfs_bmap_finish(&args->trans,
1273 args->flist, 1273 args->flist,
@@ -1369,7 +1369,7 @@ restart:
1369 * In a separate transaction, set the incomplete flag on the 1369 * In a separate transaction, set the incomplete flag on the
1370 * "old" attr and clear the incomplete flag on the "new" attr. 1370 * "old" attr and clear the incomplete flag on the "new" attr.
1371 */ 1371 */
1372 error = xfs_attr_leaf_flipflags(args); 1372 error = xfs_attr3_leaf_flipflags(args);
1373 if (error) 1373 if (error)
1374 goto out; 1374 goto out;
1375 1375
@@ -1408,7 +1408,7 @@ restart:
1408 */ 1408 */
1409 blk = &state->path.blk[ state->path.active-1 ]; 1409 blk = &state->path.blk[ state->path.active-1 ];
1410 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC); 1410 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1411 error = xfs_attr_leaf_remove(blk->bp, args); 1411 error = xfs_attr3_leaf_remove(blk->bp, args);
1412 xfs_da3_fixhashpath(state, &state->path); 1412 xfs_da3_fixhashpath(state, &state->path);
1413 1413
1414 /* 1414 /*
@@ -1449,7 +1449,7 @@ restart:
1449 /* 1449 /*
1450 * Added a "remote" value, just clear the incomplete flag. 1450 * Added a "remote" value, just clear the incomplete flag.
1451 */ 1451 */
1452 error = xfs_attr_leaf_clearflag(args); 1452 error = xfs_attr3_leaf_clearflag(args);
1453 if (error) 1453 if (error)
1454 goto out; 1454 goto out;
1455 } 1455 }
@@ -1523,7 +1523,7 @@ xfs_attr_node_removename(xfs_da_args_t *args)
1523 * Mark the attribute as INCOMPLETE, then bunmapi() the 1523 * Mark the attribute as INCOMPLETE, then bunmapi() the
1524 * remote value. 1524 * remote value.
1525 */ 1525 */
1526 error = xfs_attr_leaf_setflag(args); 1526 error = xfs_attr3_leaf_setflag(args);
1527 if (error) 1527 if (error)
1528 goto out; 1528 goto out;
1529 error = xfs_attr_rmtval_remove(args); 1529 error = xfs_attr_rmtval_remove(args);
@@ -1544,7 +1544,7 @@ xfs_attr_node_removename(xfs_da_args_t *args)
1544 */ 1544 */
1545 blk = &state->path.blk[ state->path.active-1 ]; 1545 blk = &state->path.blk[ state->path.active-1 ];
1546 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC); 1546 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1547 retval = xfs_attr_leaf_remove(blk->bp, args); 1547 retval = xfs_attr3_leaf_remove(blk->bp, args);
1548 xfs_da3_fixhashpath(state, &state->path); 1548 xfs_da3_fixhashpath(state, &state->path);
1549 1549
1550 /* 1550 /*
@@ -1590,13 +1590,13 @@ xfs_attr_node_removename(xfs_da_args_t *args)
1590 ASSERT(state->path.blk[0].bp); 1590 ASSERT(state->path.blk[0].bp);
1591 state->path.blk[0].bp = NULL; 1591 state->path.blk[0].bp = NULL;
1592 1592
1593 error = xfs_attr_leaf_read(args->trans, args->dp, 0, -1, &bp); 1593 error = xfs_attr3_leaf_read(args->trans, args->dp, 0, -1, &bp);
1594 if (error) 1594 if (error)
1595 goto out; 1595 goto out;
1596 1596
1597 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { 1597 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
1598 xfs_bmap_init(args->flist, args->firstblock); 1598 xfs_bmap_init(args->flist, args->firstblock);
1599 error = xfs_attr_leaf_to_shortform(bp, args, forkoff); 1599 error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
1600 /* bp is gone due to xfs_da_shrink_inode */ 1600 /* bp is gone due to xfs_da_shrink_inode */
1601 if (!error) { 1601 if (!error) {
1602 error = xfs_bmap_finish(&args->trans, 1602 error = xfs_bmap_finish(&args->trans,
@@ -1768,7 +1768,7 @@ xfs_attr_node_get(xfs_da_args_t *args)
1768 /* 1768 /*
1769 * Get the value, local or "remote" 1769 * Get the value, local or "remote"
1770 */ 1770 */
1771 retval = xfs_attr_leaf_getvalue(blk->bp, args); 1771 retval = xfs_attr3_leaf_getvalue(blk->bp, args);
1772 if (!retval && (args->rmtblkno > 0) 1772 if (!retval && (args->rmtblkno > 0)
1773 && !(args->flags & ATTR_KERNOVAL)) { 1773 && !(args->flags & ATTR_KERNOVAL)) {
1774 retval = xfs_attr_rmtval_get(args); 1774 retval = xfs_attr_rmtval_get(args);
@@ -1793,7 +1793,9 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
1793 attrlist_cursor_kern_t *cursor; 1793 attrlist_cursor_kern_t *cursor;
1794 xfs_attr_leafblock_t *leaf; 1794 xfs_attr_leafblock_t *leaf;
1795 xfs_da_intnode_t *node; 1795 xfs_da_intnode_t *node;
1796 xfs_da_node_entry_t *btree; 1796 struct xfs_attr3_icleaf_hdr leafhdr;
1797 struct xfs_da3_icnode_hdr nodehdr;
1798 struct xfs_da_node_entry *btree;
1797 int error, i; 1799 int error, i;
1798 struct xfs_buf *bp; 1800 struct xfs_buf *bp;
1799 1801
@@ -1814,22 +1816,28 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
1814 if ((error != 0) && (error != EFSCORRUPTED)) 1816 if ((error != 0) && (error != EFSCORRUPTED))
1815 return(error); 1817 return(error);
1816 if (bp) { 1818 if (bp) {
1819 struct xfs_attr_leaf_entry *entries;
1820
1817 node = bp->b_addr; 1821 node = bp->b_addr;
1818 switch (be16_to_cpu(node->hdr.info.magic)) { 1822 switch (be16_to_cpu(node->hdr.info.magic)) {
1819 case XFS_DA_NODE_MAGIC: 1823 case XFS_DA_NODE_MAGIC:
1824 case XFS_DA3_NODE_MAGIC:
1820 trace_xfs_attr_list_wrong_blk(context); 1825 trace_xfs_attr_list_wrong_blk(context);
1821 xfs_trans_brelse(NULL, bp); 1826 xfs_trans_brelse(NULL, bp);
1822 bp = NULL; 1827 bp = NULL;
1823 break; 1828 break;
1824 case XFS_ATTR_LEAF_MAGIC: 1829 case XFS_ATTR_LEAF_MAGIC:
1830 case XFS_ATTR3_LEAF_MAGIC:
1825 leaf = bp->b_addr; 1831 leaf = bp->b_addr;
1826 if (cursor->hashval > be32_to_cpu(leaf->entries[ 1832 xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf);
1827 be16_to_cpu(leaf->hdr.count)-1].hashval)) { 1833 entries = xfs_attr3_leaf_entryp(leaf);
1834 if (cursor->hashval > be32_to_cpu(
1835 entries[leafhdr.count - 1].hashval)) {
1828 trace_xfs_attr_list_wrong_blk(context); 1836 trace_xfs_attr_list_wrong_blk(context);
1829 xfs_trans_brelse(NULL, bp); 1837 xfs_trans_brelse(NULL, bp);
1830 bp = NULL; 1838 bp = NULL;
1831 } else if (cursor->hashval <= 1839 } else if (cursor->hashval <= be32_to_cpu(
1832 be32_to_cpu(leaf->entries[0].hashval)) { 1840 entries[0].hashval)) {
1833 trace_xfs_attr_list_wrong_blk(context); 1841 trace_xfs_attr_list_wrong_blk(context);
1834 xfs_trans_brelse(NULL, bp); 1842 xfs_trans_brelse(NULL, bp);
1835 bp = NULL; 1843 bp = NULL;
@@ -1851,27 +1859,31 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
1851 if (bp == NULL) { 1859 if (bp == NULL) {
1852 cursor->blkno = 0; 1860 cursor->blkno = 0;
1853 for (;;) { 1861 for (;;) {
1862 __uint16_t magic;
1863
1854 error = xfs_da3_node_read(NULL, context->dp, 1864 error = xfs_da3_node_read(NULL, context->dp,
1855 cursor->blkno, -1, &bp, 1865 cursor->blkno, -1, &bp,
1856 XFS_ATTR_FORK); 1866 XFS_ATTR_FORK);
1857 if (error) 1867 if (error)
1858 return(error); 1868 return(error);
1859 node = bp->b_addr; 1869 node = bp->b_addr;
1860 if (node->hdr.info.magic == 1870 magic = be16_to_cpu(node->hdr.info.magic);
1861 cpu_to_be16(XFS_ATTR_LEAF_MAGIC)) 1871 if (magic == XFS_ATTR_LEAF_MAGIC ||
1872 magic == XFS_ATTR3_LEAF_MAGIC)
1862 break; 1873 break;
1863 if (unlikely(node->hdr.info.magic != 1874 if (magic != XFS_DA_NODE_MAGIC &&
1864 cpu_to_be16(XFS_DA_NODE_MAGIC))) { 1875 magic != XFS_DA3_NODE_MAGIC) {
1865 XFS_CORRUPTION_ERROR("xfs_attr_node_list(3)", 1876 XFS_CORRUPTION_ERROR("xfs_attr_node_list(3)",
1866 XFS_ERRLEVEL_LOW, 1877 XFS_ERRLEVEL_LOW,
1867 context->dp->i_mount, 1878 context->dp->i_mount,
1868 node); 1879 node);
1869 xfs_trans_brelse(NULL, bp); 1880 xfs_trans_brelse(NULL, bp);
1870 return(XFS_ERROR(EFSCORRUPTED)); 1881 return XFS_ERROR(EFSCORRUPTED);
1871 } 1882 }
1883
1884 xfs_da3_node_hdr_from_disk(&nodehdr, node);
1872 btree = xfs_da3_node_tree_p(node); 1885 btree = xfs_da3_node_tree_p(node);
1873 for (i = 0; i < be16_to_cpu(node->hdr.count); 1886 for (i = 0; i < nodehdr.count; btree++, i++) {
1874 btree++, i++) {
1875 if (cursor->hashval 1887 if (cursor->hashval
1876 <= be32_to_cpu(btree->hashval)) { 1888 <= be32_to_cpu(btree->hashval)) {
1877 cursor->blkno = be32_to_cpu(btree->before); 1889 cursor->blkno = be32_to_cpu(btree->before);
@@ -1880,9 +1892,9 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
1880 break; 1892 break;
1881 } 1893 }
1882 } 1894 }
1883 if (i == be16_to_cpu(node->hdr.count)) { 1895 if (i == nodehdr.count) {
1884 xfs_trans_brelse(NULL, bp); 1896 xfs_trans_brelse(NULL, bp);
1885 return(0); 1897 return 0;
1886 } 1898 }
1887 xfs_trans_brelse(NULL, bp); 1899 xfs_trans_brelse(NULL, bp);
1888 } 1900 }
@@ -1896,22 +1908,23 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
1896 */ 1908 */
1897 for (;;) { 1909 for (;;) {
1898 leaf = bp->b_addr; 1910 leaf = bp->b_addr;
1899 error = xfs_attr_leaf_list_int(bp, context); 1911 error = xfs_attr3_leaf_list_int(bp, context);
1900 if (error) { 1912 if (error) {
1901 xfs_trans_brelse(NULL, bp); 1913 xfs_trans_brelse(NULL, bp);
1902 return error; 1914 return error;
1903 } 1915 }
1904 if (context->seen_enough || leaf->hdr.info.forw == 0) 1916 xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf);
1917 if (context->seen_enough || leafhdr.forw == 0)
1905 break; 1918 break;
1906 cursor->blkno = be32_to_cpu(leaf->hdr.info.forw); 1919 cursor->blkno = leafhdr.forw;
1907 xfs_trans_brelse(NULL, bp); 1920 xfs_trans_brelse(NULL, bp);
1908 error = xfs_attr_leaf_read(NULL, context->dp, cursor->blkno, -1, 1921 error = xfs_attr3_leaf_read(NULL, context->dp, cursor->blkno, -1,
1909 &bp); 1922 &bp);
1910 if (error) 1923 if (error)
1911 return error; 1924 return error;
1912 } 1925 }
1913 xfs_trans_brelse(NULL, bp); 1926 xfs_trans_brelse(NULL, bp);
1914 return(0); 1927 return 0;
1915} 1928}
1916 1929
1917 1930
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 54b0dc8cc82c..7f8b6c8a483f 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3 * Copyright (c) 2013 Red Hat, Inc.
3 * All Rights Reserved. 4 * All Rights Reserved.
4 * 5 *
5 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -39,6 +40,9 @@
39#include "xfs_attr_leaf.h" 40#include "xfs_attr_leaf.h"
40#include "xfs_error.h" 41#include "xfs_error.h"
41#include "xfs_trace.h" 42#include "xfs_trace.h"
43#include "xfs_buf_item.h"
44#include "xfs_cksum.h"
45
42 46
43/* 47/*
44 * xfs_attr_leaf.c 48 * xfs_attr_leaf.c
@@ -53,77 +57,213 @@
53/* 57/*
54 * Routines used for growing the Btree. 58 * Routines used for growing the Btree.
55 */ 59 */
56STATIC int xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t which_block, 60STATIC int xfs_attr3_leaf_create(struct xfs_da_args *args,
57 struct xfs_buf **bpp); 61 xfs_dablk_t which_block, struct xfs_buf **bpp);
58STATIC int xfs_attr_leaf_add_work(struct xfs_buf *leaf_buffer, 62STATIC int xfs_attr3_leaf_add_work(struct xfs_buf *leaf_buffer,
59 xfs_da_args_t *args, int freemap_index); 63 struct xfs_attr3_icleaf_hdr *ichdr,
60STATIC void xfs_attr_leaf_compact(struct xfs_da_args *args, 64 struct xfs_da_args *args, int freemap_index);
61 struct xfs_buf *leaf_buffer); 65STATIC void xfs_attr3_leaf_compact(struct xfs_da_args *args,
62STATIC void xfs_attr_leaf_rebalance(xfs_da_state_t *state, 66 struct xfs_attr3_icleaf_hdr *ichdr,
67 struct xfs_buf *leaf_buffer);
68STATIC void xfs_attr3_leaf_rebalance(xfs_da_state_t *state,
63 xfs_da_state_blk_t *blk1, 69 xfs_da_state_blk_t *blk1,
64 xfs_da_state_blk_t *blk2); 70 xfs_da_state_blk_t *blk2);
65STATIC int xfs_attr_leaf_figure_balance(xfs_da_state_t *state, 71STATIC int xfs_attr3_leaf_figure_balance(xfs_da_state_t *state,
66 xfs_da_state_blk_t *leaf_blk_1, 72 xfs_da_state_blk_t *leaf_blk_1,
67 xfs_da_state_blk_t *leaf_blk_2, 73 struct xfs_attr3_icleaf_hdr *ichdr1,
68 int *number_entries_in_blk1, 74 xfs_da_state_blk_t *leaf_blk_2,
69 int *number_usedbytes_in_blk1); 75 struct xfs_attr3_icleaf_hdr *ichdr2,
76 int *number_entries_in_blk1,
77 int *number_usedbytes_in_blk1);
70 78
71/* 79/*
72 * Routines used for shrinking the Btree. 80 * Routines used for shrinking the Btree.
73 */ 81 */
74STATIC int xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, 82STATIC int xfs_attr3_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp,
75 struct xfs_buf *bp, int level); 83 struct xfs_buf *bp, int level);
76STATIC int xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, 84STATIC int xfs_attr3_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp,
77 struct xfs_buf *bp); 85 struct xfs_buf *bp);
78STATIC int xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp, 86STATIC int xfs_attr3_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
79 xfs_dablk_t blkno, int blkcnt); 87 xfs_dablk_t blkno, int blkcnt);
80 88
81/* 89/*
82 * Utility routines. 90 * Utility routines.
83 */ 91 */
84STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf, 92STATIC void xfs_attr3_leaf_moveents(struct xfs_attr_leafblock *src_leaf,
85 int src_start, 93 struct xfs_attr3_icleaf_hdr *src_ichdr, int src_start,
86 xfs_attr_leafblock_t *dst_leaf, 94 struct xfs_attr_leafblock *dst_leaf,
87 int dst_start, int move_count, 95 struct xfs_attr3_icleaf_hdr *dst_ichdr, int dst_start,
88 xfs_mount_t *mp); 96 int move_count, struct xfs_mount *mp);
89STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); 97STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
90 98
91static void 99void
92xfs_attr_leaf_verify( 100xfs_attr3_leaf_hdr_from_disk(
101 struct xfs_attr3_icleaf_hdr *to,
102 struct xfs_attr_leafblock *from)
103{
104 int i;
105
106 ASSERT(from->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC) ||
107 from->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC));
108
109 if (from->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC)) {
110 struct xfs_attr3_leaf_hdr *hdr3 = (struct xfs_attr3_leaf_hdr *)from;
111
112 to->forw = be32_to_cpu(hdr3->info.hdr.forw);
113 to->back = be32_to_cpu(hdr3->info.hdr.back);
114 to->magic = be16_to_cpu(hdr3->info.hdr.magic);
115 to->count = be16_to_cpu(hdr3->count);
116 to->usedbytes = be16_to_cpu(hdr3->usedbytes);
117 to->firstused = be16_to_cpu(hdr3->firstused);
118 to->holes = hdr3->holes;
119
120 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
121 to->freemap[i].base = be16_to_cpu(hdr3->freemap[i].base);
122 to->freemap[i].size = be16_to_cpu(hdr3->freemap[i].size);
123 }
124 return;
125 }
126 to->forw = be32_to_cpu(from->hdr.info.forw);
127 to->back = be32_to_cpu(from->hdr.info.back);
128 to->magic = be16_to_cpu(from->hdr.info.magic);
129 to->count = be16_to_cpu(from->hdr.count);
130 to->usedbytes = be16_to_cpu(from->hdr.usedbytes);
131 to->firstused = be16_to_cpu(from->hdr.firstused);
132 to->holes = from->hdr.holes;
133
134 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
135 to->freemap[i].base = be16_to_cpu(from->hdr.freemap[i].base);
136 to->freemap[i].size = be16_to_cpu(from->hdr.freemap[i].size);
137 }
138}
139
140void
141xfs_attr3_leaf_hdr_to_disk(
142 struct xfs_attr_leafblock *to,
143 struct xfs_attr3_icleaf_hdr *from)
144{
145 int i;
146
147 ASSERT(from->magic == XFS_ATTR_LEAF_MAGIC ||
148 from->magic == XFS_ATTR3_LEAF_MAGIC);
149
150 if (from->magic == XFS_ATTR3_LEAF_MAGIC) {
151 struct xfs_attr3_leaf_hdr *hdr3 = (struct xfs_attr3_leaf_hdr *)to;
152
153 hdr3->info.hdr.forw = cpu_to_be32(from->forw);
154 hdr3->info.hdr.back = cpu_to_be32(from->back);
155 hdr3->info.hdr.magic = cpu_to_be16(from->magic);
156 hdr3->count = cpu_to_be16(from->count);
157 hdr3->usedbytes = cpu_to_be16(from->usedbytes);
158 hdr3->firstused = cpu_to_be16(from->firstused);
159 hdr3->holes = from->holes;
160 hdr3->pad1 = 0;
161
162 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
163 hdr3->freemap[i].base = cpu_to_be16(from->freemap[i].base);
164 hdr3->freemap[i].size = cpu_to_be16(from->freemap[i].size);
165 }
166 return;
167 }
168 to->hdr.info.forw = cpu_to_be32(from->forw);
169 to->hdr.info.back = cpu_to_be32(from->back);
170 to->hdr.info.magic = cpu_to_be16(from->magic);
171 to->hdr.count = cpu_to_be16(from->count);
172 to->hdr.usedbytes = cpu_to_be16(from->usedbytes);
173 to->hdr.firstused = cpu_to_be16(from->firstused);
174 to->hdr.holes = from->holes;
175 to->hdr.pad1 = 0;
176
177 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
178 to->hdr.freemap[i].base = cpu_to_be16(from->freemap[i].base);
179 to->hdr.freemap[i].size = cpu_to_be16(from->freemap[i].size);
180 }
181}
182
183static bool
184xfs_attr3_leaf_verify(
93 struct xfs_buf *bp) 185 struct xfs_buf *bp)
94{ 186{
95 struct xfs_mount *mp = bp->b_target->bt_mount; 187 struct xfs_mount *mp = bp->b_target->bt_mount;
96 struct xfs_attr_leaf_hdr *hdr = bp->b_addr; 188 struct xfs_attr_leafblock *leaf = bp->b_addr;
97 int block_ok = 0; 189 struct xfs_attr3_icleaf_hdr ichdr;
98 190
99 block_ok = hdr->info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC); 191 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
100 if (!block_ok) { 192
101 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr); 193 if (xfs_sb_version_hascrc(&mp->m_sb)) {
102 xfs_buf_ioerror(bp, EFSCORRUPTED); 194 struct xfs_da3_node_hdr *hdr3 = bp->b_addr;
195
196 if (ichdr.magic != XFS_ATTR3_LEAF_MAGIC)
197 return false;
198
199 if (!uuid_equal(&hdr3->info.uuid, &mp->m_sb.sb_uuid))
200 return false;
201 if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn)
202 return false;
203 } else {
204 if (ichdr.magic != XFS_ATTR_LEAF_MAGIC)
205 return false;
103 } 206 }
207 if (ichdr.count == 0)
208 return false;
209
210 /* XXX: need to range check rest of attr header values */
211 /* XXX: hash order check? */
212
213 return true;
104} 214}
105 215
106static void 216static void
107xfs_attr_leaf_read_verify( 217xfs_attr3_leaf_write_verify(
108 struct xfs_buf *bp) 218 struct xfs_buf *bp)
109{ 219{
110 xfs_attr_leaf_verify(bp); 220 struct xfs_mount *mp = bp->b_target->bt_mount;
221 struct xfs_buf_log_item *bip = bp->b_fspriv;
222 struct xfs_attr3_leaf_hdr *hdr3 = bp->b_addr;
223
224 if (!xfs_attr3_leaf_verify(bp)) {
225 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
226 xfs_buf_ioerror(bp, EFSCORRUPTED);
227 return;
228 }
229
230 if (!xfs_sb_version_hascrc(&mp->m_sb))
231 return;
232
233 if (bip)
234 hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn);
235
236 xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_ATTR3_LEAF_CRC_OFF);
111} 237}
112 238
239/*
240 * leaf/node format detection on trees is sketchy, so a node read can be done on
241 * leaf level blocks when detection identifies the tree as a node format tree
242 * incorrectly. In this case, we need to swap the verifier to match the correct
243 * format of the block being read.
244 */
113static void 245static void
114xfs_attr_leaf_write_verify( 246xfs_attr3_leaf_read_verify(
115 struct xfs_buf *bp) 247 struct xfs_buf *bp)
116{ 248{
117 xfs_attr_leaf_verify(bp); 249 struct xfs_mount *mp = bp->b_target->bt_mount;
250
251 if ((xfs_sb_version_hascrc(&mp->m_sb) &&
252 !xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
253 XFS_ATTR3_LEAF_CRC_OFF)) ||
254 !xfs_attr3_leaf_verify(bp)) {
255 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
256 xfs_buf_ioerror(bp, EFSCORRUPTED);
257 }
118} 258}
119 259
120const struct xfs_buf_ops xfs_attr_leaf_buf_ops = { 260const struct xfs_buf_ops xfs_attr3_leaf_buf_ops = {
121 .verify_read = xfs_attr_leaf_read_verify, 261 .verify_read = xfs_attr3_leaf_read_verify,
122 .verify_write = xfs_attr_leaf_write_verify, 262 .verify_write = xfs_attr3_leaf_write_verify,
123}; 263};
124 264
125int 265int
126xfs_attr_leaf_read( 266xfs_attr3_leaf_read(
127 struct xfs_trans *tp, 267 struct xfs_trans *tp,
128 struct xfs_inode *dp, 268 struct xfs_inode *dp,
129 xfs_dablk_t bno, 269 xfs_dablk_t bno,
@@ -131,7 +271,7 @@ xfs_attr_leaf_read(
131 struct xfs_buf **bpp) 271 struct xfs_buf **bpp)
132{ 272{
133 return xfs_da_read_buf(tp, dp, bno, mappedbno, bpp, 273 return xfs_da_read_buf(tp, dp, bno, mappedbno, bpp,
134 XFS_ATTR_FORK, &xfs_attr_leaf_buf_ops); 274 XFS_ATTR_FORK, &xfs_attr3_leaf_buf_ops);
135} 275}
136 276
137/*======================================================================== 277/*========================================================================
@@ -559,7 +699,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args)
559 } 699 }
560 700
561 ASSERT(blkno == 0); 701 ASSERT(blkno == 0);
562 error = xfs_attr_leaf_create(args, blkno, &bp); 702 error = xfs_attr3_leaf_create(args, blkno, &bp);
563 if (error) { 703 if (error) {
564 error = xfs_da_shrink_inode(args, 0, bp); 704 error = xfs_da_shrink_inode(args, 0, bp);
565 bp = NULL; 705 bp = NULL;
@@ -588,9 +728,9 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args)
588 nargs.hashval = xfs_da_hashname(sfe->nameval, 728 nargs.hashval = xfs_da_hashname(sfe->nameval,
589 sfe->namelen); 729 sfe->namelen);
590 nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags); 730 nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags);
591 error = xfs_attr_leaf_lookup_int(bp, &nargs); /* set a->index */ 731 error = xfs_attr3_leaf_lookup_int(bp, &nargs); /* set a->index */
592 ASSERT(error == ENOATTR); 732 ASSERT(error == ENOATTR);
593 error = xfs_attr_leaf_add(bp, &nargs); 733 error = xfs_attr3_leaf_add(bp, &nargs);
594 ASSERT(error != ENOSPC); 734 ASSERT(error != ENOSPC);
595 if (error) 735 if (error)
596 goto out; 736 goto out;
@@ -803,7 +943,7 @@ xfs_attr_shortform_allfit(
803 continue; /* don't copy partial entries */ 943 continue; /* don't copy partial entries */
804 if (!(entry->flags & XFS_ATTR_LOCAL)) 944 if (!(entry->flags & XFS_ATTR_LOCAL))
805 return(0); 945 return(0);
806 name_loc = xfs_attr_leaf_name_local(leaf, i); 946 name_loc = xfs_attr3_leaf_name_local(leaf, i);
807 if (name_loc->namelen >= XFS_ATTR_SF_ENTSIZE_MAX) 947 if (name_loc->namelen >= XFS_ATTR_SF_ENTSIZE_MAX)
808 return(0); 948 return(0);
809 if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX) 949 if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX)
@@ -823,29 +963,34 @@ xfs_attr_shortform_allfit(
823 * Convert a leaf attribute list to shortform attribute list 963 * Convert a leaf attribute list to shortform attribute list
824 */ 964 */
825int 965int
826xfs_attr_leaf_to_shortform( 966xfs_attr3_leaf_to_shortform(
827 struct xfs_buf *bp, 967 struct xfs_buf *bp,
828 xfs_da_args_t *args, 968 struct xfs_da_args *args,
829 int forkoff) 969 int forkoff)
830{ 970{
831 xfs_attr_leafblock_t *leaf; 971 struct xfs_attr_leafblock *leaf;
832 xfs_attr_leaf_entry_t *entry; 972 struct xfs_attr3_icleaf_hdr ichdr;
833 xfs_attr_leaf_name_local_t *name_loc; 973 struct xfs_attr_leaf_entry *entry;
834 xfs_da_args_t nargs; 974 struct xfs_attr_leaf_name_local *name_loc;
835 xfs_inode_t *dp; 975 struct xfs_da_args nargs;
836 char *tmpbuffer; 976 struct xfs_inode *dp = args->dp;
837 int error, i; 977 char *tmpbuffer;
978 int error;
979 int i;
838 980
839 trace_xfs_attr_leaf_to_sf(args); 981 trace_xfs_attr_leaf_to_sf(args);
840 982
841 dp = args->dp;
842 tmpbuffer = kmem_alloc(XFS_LBSIZE(dp->i_mount), KM_SLEEP); 983 tmpbuffer = kmem_alloc(XFS_LBSIZE(dp->i_mount), KM_SLEEP);
843 ASSERT(tmpbuffer != NULL); 984 if (!tmpbuffer)
985 return ENOMEM;
844 986
845 ASSERT(bp != NULL);
846 memcpy(tmpbuffer, bp->b_addr, XFS_LBSIZE(dp->i_mount)); 987 memcpy(tmpbuffer, bp->b_addr, XFS_LBSIZE(dp->i_mount));
988
847 leaf = (xfs_attr_leafblock_t *)tmpbuffer; 989 leaf = (xfs_attr_leafblock_t *)tmpbuffer;
848 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 990 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
991 entry = xfs_attr3_leaf_entryp(leaf);
992
993 /* XXX (dgc): buffer is about to be marked stale - why zero it? */
849 memset(bp->b_addr, 0, XFS_LBSIZE(dp->i_mount)); 994 memset(bp->b_addr, 0, XFS_LBSIZE(dp->i_mount));
850 995
851 /* 996 /*
@@ -875,14 +1020,14 @@ xfs_attr_leaf_to_shortform(
875 nargs.whichfork = XFS_ATTR_FORK; 1020 nargs.whichfork = XFS_ATTR_FORK;
876 nargs.trans = args->trans; 1021 nargs.trans = args->trans;
877 nargs.op_flags = XFS_DA_OP_OKNOENT; 1022 nargs.op_flags = XFS_DA_OP_OKNOENT;
878 entry = &leaf->entries[0]; 1023
879 for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { 1024 for (i = 0; i < ichdr.count; entry++, i++) {
880 if (entry->flags & XFS_ATTR_INCOMPLETE) 1025 if (entry->flags & XFS_ATTR_INCOMPLETE)
881 continue; /* don't copy partial entries */ 1026 continue; /* don't copy partial entries */
882 if (!entry->nameidx) 1027 if (!entry->nameidx)
883 continue; 1028 continue;
884 ASSERT(entry->flags & XFS_ATTR_LOCAL); 1029 ASSERT(entry->flags & XFS_ATTR_LOCAL);
885 name_loc = xfs_attr_leaf_name_local(leaf, i); 1030 name_loc = xfs_attr3_leaf_name_local(leaf, i);
886 nargs.name = name_loc->nameval; 1031 nargs.name = name_loc->nameval;
887 nargs.namelen = name_loc->namelen; 1032 nargs.namelen = name_loc->namelen;
888 nargs.value = &name_loc->nameval[nargs.namelen]; 1033 nargs.value = &name_loc->nameval[nargs.namelen];
@@ -895,43 +1040,50 @@ xfs_attr_leaf_to_shortform(
895 1040
896out: 1041out:
897 kmem_free(tmpbuffer); 1042 kmem_free(tmpbuffer);
898 return(error); 1043 return error;
899} 1044}
900 1045
901/* 1046/*
902 * Convert from using a single leaf to a root node and a leaf. 1047 * Convert from using a single leaf to a root node and a leaf.
903 */ 1048 */
904int 1049int
905xfs_attr_leaf_to_node(xfs_da_args_t *args) 1050xfs_attr3_leaf_to_node(
1051 struct xfs_da_args *args)
906{ 1052{
907 xfs_attr_leafblock_t *leaf; 1053 struct xfs_attr_leafblock *leaf;
908 xfs_da_intnode_t *node; 1054 struct xfs_attr3_icleaf_hdr icleafhdr;
909 xfs_inode_t *dp; 1055 struct xfs_attr_leaf_entry *entries;
910 struct xfs_buf *bp1, *bp2;
911 xfs_dablk_t blkno;
912 int error;
913 struct xfs_da_node_entry *btree; 1056 struct xfs_da_node_entry *btree;
1057 struct xfs_da3_icnode_hdr icnodehdr;
1058 struct xfs_da_intnode *node;
1059 struct xfs_inode *dp = args->dp;
1060 struct xfs_mount *mp = dp->i_mount;
1061 struct xfs_buf *bp1 = NULL;
1062 struct xfs_buf *bp2 = NULL;
1063 xfs_dablk_t blkno;
1064 int error;
914 1065
915 trace_xfs_attr_leaf_to_node(args); 1066 trace_xfs_attr_leaf_to_node(args);
916 1067
917 dp = args->dp;
918 bp1 = bp2 = NULL;
919 error = xfs_da_grow_inode(args, &blkno); 1068 error = xfs_da_grow_inode(args, &blkno);
920 if (error) 1069 if (error)
921 goto out; 1070 goto out;
922 error = xfs_attr_leaf_read(args->trans, args->dp, 0, -1, &bp1); 1071 error = xfs_attr3_leaf_read(args->trans, dp, 0, -1, &bp1);
923 if (error) 1072 if (error)
924 goto out; 1073 goto out;
925 1074
926 bp2 = NULL; 1075 error = xfs_da_get_buf(args->trans, dp, blkno, -1, &bp2, XFS_ATTR_FORK);
927 error = xfs_da_get_buf(args->trans, args->dp, blkno, -1, &bp2,
928 XFS_ATTR_FORK);
929 if (error) 1076 if (error)
930 goto out; 1077 goto out;
1078
1079 /* copy leaf to new buffer, update identifiers */
931 bp2->b_ops = bp1->b_ops; 1080 bp2->b_ops = bp1->b_ops;
932 memcpy(bp2->b_addr, bp1->b_addr, XFS_LBSIZE(dp->i_mount)); 1081 memcpy(bp2->b_addr, bp1->b_addr, XFS_LBSIZE(mp));
933 bp1 = NULL; 1082 if (xfs_sb_version_hascrc(&mp->m_sb)) {
934 xfs_trans_log_buf(args->trans, bp2, 0, XFS_LBSIZE(dp->i_mount) - 1); 1083 struct xfs_da3_blkinfo *hdr3 = bp2->b_addr;
1084 hdr3->blkno = cpu_to_be64(bp2->b_bn);
1085 }
1086 xfs_trans_log_buf(args->trans, bp2, 0, XFS_LBSIZE(mp) - 1);
935 1087
936 /* 1088 /*
937 * Set up the new root node. 1089 * Set up the new root node.
@@ -940,17 +1092,22 @@ xfs_attr_leaf_to_node(xfs_da_args_t *args)
940 if (error) 1092 if (error)
941 goto out; 1093 goto out;
942 node = bp1->b_addr; 1094 node = bp1->b_addr;
1095 xfs_da3_node_hdr_from_disk(&icnodehdr, node);
1096 btree = xfs_da3_node_tree_p(node);
1097
943 leaf = bp2->b_addr; 1098 leaf = bp2->b_addr;
944 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1099 xfs_attr3_leaf_hdr_from_disk(&icleafhdr, leaf);
1100 entries = xfs_attr3_leaf_entryp(leaf);
1101
945 /* both on-disk, don't endian-flip twice */ 1102 /* both on-disk, don't endian-flip twice */
946 btree = xfs_da3_node_tree_p(node); 1103 btree[0].hashval = entries[icleafhdr.count - 1].hashval;
947 btree[0].hashval = leaf->entries[be16_to_cpu(leaf->hdr.count)-1 ].hashval;
948 btree[0].before = cpu_to_be32(blkno); 1104 btree[0].before = cpu_to_be32(blkno);
949 node->hdr.count = cpu_to_be16(1); 1105 icnodehdr.count = 1;
950 xfs_trans_log_buf(args->trans, bp1, 0, XFS_LBSIZE(dp->i_mount) - 1); 1106 xfs_da3_node_hdr_to_disk(node, &icnodehdr);
1107 xfs_trans_log_buf(args->trans, bp1, 0, XFS_LBSIZE(mp) - 1);
951 error = 0; 1108 error = 0;
952out: 1109out:
953 return(error); 1110 return error;
954} 1111}
955 1112
956 1113
@@ -963,52 +1120,62 @@ out:
963 * or a leaf in a node attribute list. 1120 * or a leaf in a node attribute list.
964 */ 1121 */
965STATIC int 1122STATIC int
966xfs_attr_leaf_create( 1123xfs_attr3_leaf_create(
967 xfs_da_args_t *args, 1124 struct xfs_da_args *args,
968 xfs_dablk_t blkno, 1125 xfs_dablk_t blkno,
969 struct xfs_buf **bpp) 1126 struct xfs_buf **bpp)
970{ 1127{
971 xfs_attr_leafblock_t *leaf; 1128 struct xfs_attr_leafblock *leaf;
972 xfs_attr_leaf_hdr_t *hdr; 1129 struct xfs_attr3_icleaf_hdr ichdr;
973 xfs_inode_t *dp; 1130 struct xfs_inode *dp = args->dp;
974 struct xfs_buf *bp; 1131 struct xfs_mount *mp = dp->i_mount;
975 int error; 1132 struct xfs_buf *bp;
1133 int error;
976 1134
977 trace_xfs_attr_leaf_create(args); 1135 trace_xfs_attr_leaf_create(args);
978 1136
979 dp = args->dp;
980 ASSERT(dp != NULL);
981 error = xfs_da_get_buf(args->trans, args->dp, blkno, -1, &bp, 1137 error = xfs_da_get_buf(args->trans, args->dp, blkno, -1, &bp,
982 XFS_ATTR_FORK); 1138 XFS_ATTR_FORK);
983 if (error) 1139 if (error)
984 return(error); 1140 return error;
985 bp->b_ops = &xfs_attr_leaf_buf_ops; 1141 bp->b_ops = &xfs_attr3_leaf_buf_ops;
986 leaf = bp->b_addr; 1142 leaf = bp->b_addr;
987 memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount)); 1143 memset(leaf, 0, XFS_LBSIZE(mp));
988 hdr = &leaf->hdr; 1144
989 hdr->info.magic = cpu_to_be16(XFS_ATTR_LEAF_MAGIC); 1145 memset(&ichdr, 0, sizeof(ichdr));
990 hdr->firstused = cpu_to_be16(XFS_LBSIZE(dp->i_mount)); 1146 ichdr.firstused = XFS_LBSIZE(mp);
991 if (!hdr->firstused) { 1147
992 hdr->firstused = cpu_to_be16( 1148 if (xfs_sb_version_hascrc(&mp->m_sb)) {
993 XFS_LBSIZE(dp->i_mount) - XFS_ATTR_LEAF_NAME_ALIGN); 1149 struct xfs_da3_blkinfo *hdr3 = bp->b_addr;
994 } 1150
1151 ichdr.magic = XFS_ATTR3_LEAF_MAGIC;
1152
1153 hdr3->blkno = cpu_to_be64(bp->b_bn);
1154 hdr3->owner = cpu_to_be64(dp->i_ino);
1155 uuid_copy(&hdr3->uuid, &mp->m_sb.sb_uuid);
995 1156
996 hdr->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t)); 1157 ichdr.freemap[0].base = sizeof(struct xfs_attr3_leaf_hdr);
997 hdr->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr->firstused) - 1158 } else {
998 sizeof(xfs_attr_leaf_hdr_t)); 1159 ichdr.magic = XFS_ATTR_LEAF_MAGIC;
1160 ichdr.freemap[0].base = sizeof(struct xfs_attr_leaf_hdr);
1161 }
1162 ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base;
999 1163
1000 xfs_trans_log_buf(args->trans, bp, 0, XFS_LBSIZE(dp->i_mount) - 1); 1164 xfs_attr3_leaf_hdr_to_disk(leaf, &ichdr);
1165 xfs_trans_log_buf(args->trans, bp, 0, XFS_LBSIZE(mp) - 1);
1001 1166
1002 *bpp = bp; 1167 *bpp = bp;
1003 return(0); 1168 return 0;
1004} 1169}
1005 1170
1006/* 1171/*
1007 * Split the leaf node, rebalance, then add the new entry. 1172 * Split the leaf node, rebalance, then add the new entry.
1008 */ 1173 */
1009int 1174int
1010xfs_attr_leaf_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, 1175xfs_attr3_leaf_split(
1011 xfs_da_state_blk_t *newblk) 1176 struct xfs_da_state *state,
1177 struct xfs_da_state_blk *oldblk,
1178 struct xfs_da_state_blk *newblk)
1012{ 1179{
1013 xfs_dablk_t blkno; 1180 xfs_dablk_t blkno;
1014 int error; 1181 int error;
@@ -1022,7 +1189,7 @@ xfs_attr_leaf_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
1022 error = xfs_da_grow_inode(state->args, &blkno); 1189 error = xfs_da_grow_inode(state->args, &blkno);
1023 if (error) 1190 if (error)
1024 return(error); 1191 return(error);
1025 error = xfs_attr_leaf_create(state->args, blkno, &newblk->bp); 1192 error = xfs_attr3_leaf_create(state->args, blkno, &newblk->bp);
1026 if (error) 1193 if (error)
1027 return(error); 1194 return(error);
1028 newblk->blkno = blkno; 1195 newblk->blkno = blkno;
@@ -1032,7 +1199,7 @@ xfs_attr_leaf_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
1032 * Rebalance the entries across the two leaves. 1199 * Rebalance the entries across the two leaves.
1033 * NOTE: rebalance() currently depends on the 2nd block being empty. 1200 * NOTE: rebalance() currently depends on the 2nd block being empty.
1034 */ 1201 */
1035 xfs_attr_leaf_rebalance(state, oldblk, newblk); 1202 xfs_attr3_leaf_rebalance(state, oldblk, newblk);
1036 error = xfs_da3_blk_link(state, oldblk, newblk); 1203 error = xfs_da3_blk_link(state, oldblk, newblk);
1037 if (error) 1204 if (error)
1038 return(error); 1205 return(error);
@@ -1046,10 +1213,10 @@ xfs_attr_leaf_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
1046 */ 1213 */
1047 if (state->inleaf) { 1214 if (state->inleaf) {
1048 trace_xfs_attr_leaf_add_old(state->args); 1215 trace_xfs_attr_leaf_add_old(state->args);
1049 error = xfs_attr_leaf_add(oldblk->bp, state->args); 1216 error = xfs_attr3_leaf_add(oldblk->bp, state->args);
1050 } else { 1217 } else {
1051 trace_xfs_attr_leaf_add_new(state->args); 1218 trace_xfs_attr_leaf_add_new(state->args);
1052 error = xfs_attr_leaf_add(newblk->bp, state->args); 1219 error = xfs_attr3_leaf_add(newblk->bp, state->args);
1053 } 1220 }
1054 1221
1055 /* 1222 /*
@@ -1064,22 +1231,23 @@ xfs_attr_leaf_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
1064 * Add a name to the leaf attribute list structure. 1231 * Add a name to the leaf attribute list structure.
1065 */ 1232 */
1066int 1233int
1067xfs_attr_leaf_add( 1234xfs_attr3_leaf_add(
1068 struct xfs_buf *bp, 1235 struct xfs_buf *bp,
1069 struct xfs_da_args *args) 1236 struct xfs_da_args *args)
1070{ 1237{
1071 xfs_attr_leafblock_t *leaf; 1238 struct xfs_attr_leafblock *leaf;
1072 xfs_attr_leaf_hdr_t *hdr; 1239 struct xfs_attr3_icleaf_hdr ichdr;
1073 xfs_attr_leaf_map_t *map; 1240 int tablesize;
1074 int tablesize, entsize, sum, tmp, i; 1241 int entsize;
1242 int sum;
1243 int tmp;
1244 int i;
1075 1245
1076 trace_xfs_attr_leaf_add(args); 1246 trace_xfs_attr_leaf_add(args);
1077 1247
1078 leaf = bp->b_addr; 1248 leaf = bp->b_addr;
1079 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1249 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
1080 ASSERT((args->index >= 0) 1250 ASSERT(args->index >= 0 && args->index <= ichdr.count);
1081 && (args->index <= be16_to_cpu(leaf->hdr.count)));
1082 hdr = &leaf->hdr;
1083 entsize = xfs_attr_leaf_newentsize(args->namelen, args->valuelen, 1251 entsize = xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
1084 args->trans->t_mountp->m_sb.sb_blocksize, NULL); 1252 args->trans->t_mountp->m_sb.sb_blocksize, NULL);
1085 1253
@@ -1087,25 +1255,23 @@ xfs_attr_leaf_add(
1087 * Search through freemap for first-fit on new name length. 1255 * Search through freemap for first-fit on new name length.
1088 * (may need to figure in size of entry struct too) 1256 * (may need to figure in size of entry struct too)
1089 */ 1257 */
1090 tablesize = (be16_to_cpu(hdr->count) + 1) 1258 tablesize = (ichdr.count + 1) * sizeof(xfs_attr_leaf_entry_t)
1091 * sizeof(xfs_attr_leaf_entry_t) 1259 + xfs_attr3_leaf_hdr_size(leaf);
1092 + sizeof(xfs_attr_leaf_hdr_t); 1260 for (sum = 0, i = XFS_ATTR_LEAF_MAPSIZE - 1; i >= 0; i--) {
1093 map = &hdr->freemap[XFS_ATTR_LEAF_MAPSIZE-1]; 1261 if (tablesize > ichdr.firstused) {
1094 for (sum = 0, i = XFS_ATTR_LEAF_MAPSIZE-1; i >= 0; map--, i--) { 1262 sum += ichdr.freemap[i].size;
1095 if (tablesize > be16_to_cpu(hdr->firstused)) {
1096 sum += be16_to_cpu(map->size);
1097 continue; 1263 continue;
1098 } 1264 }
1099 if (!map->size) 1265 if (!ichdr.freemap[i].size)
1100 continue; /* no space in this map */ 1266 continue; /* no space in this map */
1101 tmp = entsize; 1267 tmp = entsize;
1102 if (be16_to_cpu(map->base) < be16_to_cpu(hdr->firstused)) 1268 if (ichdr.freemap[i].base < ichdr.firstused)
1103 tmp += sizeof(xfs_attr_leaf_entry_t); 1269 tmp += sizeof(xfs_attr_leaf_entry_t);
1104 if (be16_to_cpu(map->size) >= tmp) { 1270 if (ichdr.freemap[i].size >= tmp) {
1105 tmp = xfs_attr_leaf_add_work(bp, args, i); 1271 tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, i);
1106 return(tmp); 1272 goto out_log_hdr;
1107 } 1273 }
1108 sum += be16_to_cpu(map->size); 1274 sum += ichdr.freemap[i].size;
1109 } 1275 }
1110 1276
1111 /* 1277 /*
@@ -1113,82 +1279,89 @@ xfs_attr_leaf_add(
1113 * and we don't have enough freespace, then compaction will do us 1279 * and we don't have enough freespace, then compaction will do us
1114 * no good and we should just give up. 1280 * no good and we should just give up.
1115 */ 1281 */
1116 if (!hdr->holes && (sum < entsize)) 1282 if (!ichdr.holes && sum < entsize)
1117 return(XFS_ERROR(ENOSPC)); 1283 return XFS_ERROR(ENOSPC);
1118 1284
1119 /* 1285 /*
1120 * Compact the entries to coalesce free space. 1286 * Compact the entries to coalesce free space.
1121 * This may change the hdr->count via dropping INCOMPLETE entries. 1287 * This may change the hdr->count via dropping INCOMPLETE entries.
1122 */ 1288 */
1123 xfs_attr_leaf_compact(args, bp); 1289 xfs_attr3_leaf_compact(args, &ichdr, bp);
1124 1290
1125 /* 1291 /*
1126 * After compaction, the block is guaranteed to have only one 1292 * After compaction, the block is guaranteed to have only one
1127 * free region, in freemap[0]. If it is not big enough, give up. 1293 * free region, in freemap[0]. If it is not big enough, give up.
1128 */ 1294 */
1129 if (be16_to_cpu(hdr->freemap[0].size) 1295 if (ichdr.freemap[0].size < (entsize + sizeof(xfs_attr_leaf_entry_t))) {
1130 < (entsize + sizeof(xfs_attr_leaf_entry_t))) 1296 tmp = ENOSPC;
1131 return(XFS_ERROR(ENOSPC)); 1297 goto out_log_hdr;
1298 }
1299
1300 tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, 0);
1132 1301
1133 return(xfs_attr_leaf_add_work(bp, args, 0)); 1302out_log_hdr:
1303 xfs_attr3_leaf_hdr_to_disk(leaf, &ichdr);
1304 xfs_trans_log_buf(args->trans, bp,
1305 XFS_DA_LOGRANGE(leaf, &leaf->hdr,
1306 xfs_attr3_leaf_hdr_size(leaf)));
1307 return tmp;
1134} 1308}
1135 1309
1136/* 1310/*
1137 * Add a name to a leaf attribute list structure. 1311 * Add a name to a leaf attribute list structure.
1138 */ 1312 */
1139STATIC int 1313STATIC int
1140xfs_attr_leaf_add_work( 1314xfs_attr3_leaf_add_work(
1141 struct xfs_buf *bp, 1315 struct xfs_buf *bp,
1142 xfs_da_args_t *args, 1316 struct xfs_attr3_icleaf_hdr *ichdr,
1143 int mapindex) 1317 struct xfs_da_args *args,
1318 int mapindex)
1144{ 1319{
1145 xfs_attr_leafblock_t *leaf; 1320 struct xfs_attr_leafblock *leaf;
1146 xfs_attr_leaf_hdr_t *hdr; 1321 struct xfs_attr_leaf_entry *entry;
1147 xfs_attr_leaf_entry_t *entry; 1322 struct xfs_attr_leaf_name_local *name_loc;
1148 xfs_attr_leaf_name_local_t *name_loc; 1323 struct xfs_attr_leaf_name_remote *name_rmt;
1149 xfs_attr_leaf_name_remote_t *name_rmt; 1324 struct xfs_mount *mp;
1150 xfs_attr_leaf_map_t *map; 1325 int tmp;
1151 xfs_mount_t *mp; 1326 int i;
1152 int tmp, i;
1153 1327
1154 trace_xfs_attr_leaf_add_work(args); 1328 trace_xfs_attr_leaf_add_work(args);
1155 1329
1156 leaf = bp->b_addr; 1330 leaf = bp->b_addr;
1157 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1331 ASSERT(mapindex >= 0 && mapindex < XFS_ATTR_LEAF_MAPSIZE);
1158 hdr = &leaf->hdr; 1332 ASSERT(args->index >= 0 && args->index <= ichdr->count);
1159 ASSERT((mapindex >= 0) && (mapindex < XFS_ATTR_LEAF_MAPSIZE));
1160 ASSERT((args->index >= 0) && (args->index <= be16_to_cpu(hdr->count)));
1161 1333
1162 /* 1334 /*
1163 * Force open some space in the entry array and fill it in. 1335 * Force open some space in the entry array and fill it in.
1164 */ 1336 */
1165 entry = &leaf->entries[args->index]; 1337 entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
1166 if (args->index < be16_to_cpu(hdr->count)) { 1338 if (args->index < ichdr->count) {
1167 tmp = be16_to_cpu(hdr->count) - args->index; 1339 tmp = ichdr->count - args->index;
1168 tmp *= sizeof(xfs_attr_leaf_entry_t); 1340 tmp *= sizeof(xfs_attr_leaf_entry_t);
1169 memmove((char *)(entry+1), (char *)entry, tmp); 1341 memmove(entry + 1, entry, tmp);
1170 xfs_trans_log_buf(args->trans, bp, 1342 xfs_trans_log_buf(args->trans, bp,
1171 XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry))); 1343 XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry)));
1172 } 1344 }
1173 be16_add_cpu(&hdr->count, 1); 1345 ichdr->count++;
1174 1346
1175 /* 1347 /*
1176 * Allocate space for the new string (at the end of the run). 1348 * Allocate space for the new string (at the end of the run).
1177 */ 1349 */
1178 map = &hdr->freemap[mapindex];
1179 mp = args->trans->t_mountp; 1350 mp = args->trans->t_mountp;
1180 ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp)); 1351 ASSERT(ichdr->freemap[mapindex].base < XFS_LBSIZE(mp));
1181 ASSERT((be16_to_cpu(map->base) & 0x3) == 0); 1352 ASSERT((ichdr->freemap[mapindex].base & 0x3) == 0);
1182 ASSERT(be16_to_cpu(map->size) >= 1353 ASSERT(ichdr->freemap[mapindex].size >=
1183 xfs_attr_leaf_newentsize(args->namelen, args->valuelen, 1354 xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
1184 mp->m_sb.sb_blocksize, NULL)); 1355 mp->m_sb.sb_blocksize, NULL));
1185 ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp)); 1356 ASSERT(ichdr->freemap[mapindex].size < XFS_LBSIZE(mp));
1186 ASSERT((be16_to_cpu(map->size) & 0x3) == 0); 1357 ASSERT((ichdr->freemap[mapindex].size & 0x3) == 0);
1187 be16_add_cpu(&map->size, 1358
1188 -xfs_attr_leaf_newentsize(args->namelen, args->valuelen, 1359 ichdr->freemap[mapindex].size -=
1189 mp->m_sb.sb_blocksize, &tmp)); 1360 xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
1190 entry->nameidx = cpu_to_be16(be16_to_cpu(map->base) + 1361 mp->m_sb.sb_blocksize, &tmp);
1191 be16_to_cpu(map->size)); 1362
1363 entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base +
1364 ichdr->freemap[mapindex].size);
1192 entry->hashval = cpu_to_be32(args->hashval); 1365 entry->hashval = cpu_to_be32(args->hashval);
1193 entry->flags = tmp ? XFS_ATTR_LOCAL : 0; 1366 entry->flags = tmp ? XFS_ATTR_LOCAL : 0;
1194 entry->flags |= XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags); 1367 entry->flags |= XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags);
@@ -1203,7 +1376,7 @@ xfs_attr_leaf_add_work(
1203 XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); 1376 XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
1204 ASSERT((args->index == 0) || 1377 ASSERT((args->index == 0) ||
1205 (be32_to_cpu(entry->hashval) >= be32_to_cpu((entry-1)->hashval))); 1378 (be32_to_cpu(entry->hashval) >= be32_to_cpu((entry-1)->hashval)));
1206 ASSERT((args->index == be16_to_cpu(hdr->count)-1) || 1379 ASSERT((args->index == ichdr->count - 1) ||
1207 (be32_to_cpu(entry->hashval) <= be32_to_cpu((entry+1)->hashval))); 1380 (be32_to_cpu(entry->hashval) <= be32_to_cpu((entry+1)->hashval)));
1208 1381
1209 /* 1382 /*
@@ -1214,14 +1387,14 @@ xfs_attr_leaf_add_work(
1214 * as part of this transaction (a split operation for example). 1387 * as part of this transaction (a split operation for example).
1215 */ 1388 */
1216 if (entry->flags & XFS_ATTR_LOCAL) { 1389 if (entry->flags & XFS_ATTR_LOCAL) {
1217 name_loc = xfs_attr_leaf_name_local(leaf, args->index); 1390 name_loc = xfs_attr3_leaf_name_local(leaf, args->index);
1218 name_loc->namelen = args->namelen; 1391 name_loc->namelen = args->namelen;
1219 name_loc->valuelen = cpu_to_be16(args->valuelen); 1392 name_loc->valuelen = cpu_to_be16(args->valuelen);
1220 memcpy((char *)name_loc->nameval, args->name, args->namelen); 1393 memcpy((char *)name_loc->nameval, args->name, args->namelen);
1221 memcpy((char *)&name_loc->nameval[args->namelen], args->value, 1394 memcpy((char *)&name_loc->nameval[args->namelen], args->value,
1222 be16_to_cpu(name_loc->valuelen)); 1395 be16_to_cpu(name_loc->valuelen));
1223 } else { 1396 } else {
1224 name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); 1397 name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
1225 name_rmt->namelen = args->namelen; 1398 name_rmt->namelen = args->namelen;
1226 memcpy((char *)name_rmt->name, args->name, args->namelen); 1399 memcpy((char *)name_rmt->name, args->name, args->namelen);
1227 entry->flags |= XFS_ATTR_INCOMPLETE; 1400 entry->flags |= XFS_ATTR_INCOMPLETE;
@@ -1232,44 +1405,41 @@ xfs_attr_leaf_add_work(
1232 args->rmtblkcnt = XFS_B_TO_FSB(mp, args->valuelen); 1405 args->rmtblkcnt = XFS_B_TO_FSB(mp, args->valuelen);
1233 } 1406 }
1234 xfs_trans_log_buf(args->trans, bp, 1407 xfs_trans_log_buf(args->trans, bp,
1235 XFS_DA_LOGRANGE(leaf, xfs_attr_leaf_name(leaf, args->index), 1408 XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index),
1236 xfs_attr_leaf_entsize(leaf, args->index))); 1409 xfs_attr_leaf_entsize(leaf, args->index)));
1237 1410
1238 /* 1411 /*
1239 * Update the control info for this leaf node 1412 * Update the control info for this leaf node
1240 */ 1413 */
1241 if (be16_to_cpu(entry->nameidx) < be16_to_cpu(hdr->firstused)) { 1414 if (be16_to_cpu(entry->nameidx) < ichdr->firstused)
1242 /* both on-disk, don't endian-flip twice */ 1415 ichdr->firstused = be16_to_cpu(entry->nameidx);
1243 hdr->firstused = entry->nameidx; 1416
1244 } 1417 ASSERT(ichdr->firstused >= ichdr->count * sizeof(xfs_attr_leaf_entry_t)
1245 ASSERT(be16_to_cpu(hdr->firstused) >= 1418 + xfs_attr3_leaf_hdr_size(leaf));
1246 ((be16_to_cpu(hdr->count) * sizeof(*entry)) + sizeof(*hdr))); 1419 tmp = (ichdr->count - 1) * sizeof(xfs_attr_leaf_entry_t)
1247 tmp = (be16_to_cpu(hdr->count)-1) * sizeof(xfs_attr_leaf_entry_t) 1420 + xfs_attr3_leaf_hdr_size(leaf);
1248 + sizeof(xfs_attr_leaf_hdr_t); 1421
1249 map = &hdr->freemap[0]; 1422 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
1250 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; map++, i++) { 1423 if (ichdr->freemap[i].base == tmp) {
1251 if (be16_to_cpu(map->base) == tmp) { 1424 ichdr->freemap[i].base += sizeof(xfs_attr_leaf_entry_t);
1252 be16_add_cpu(&map->base, sizeof(xfs_attr_leaf_entry_t)); 1425 ichdr->freemap[i].size -= sizeof(xfs_attr_leaf_entry_t);
1253 be16_add_cpu(&map->size,
1254 -((int)sizeof(xfs_attr_leaf_entry_t)));
1255 } 1426 }
1256 } 1427 }
1257 be16_add_cpu(&hdr->usedbytes, xfs_attr_leaf_entsize(leaf, args->index)); 1428 ichdr->usedbytes += xfs_attr_leaf_entsize(leaf, args->index);
1258 xfs_trans_log_buf(args->trans, bp, 1429 return 0;
1259 XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr)));
1260 return(0);
1261} 1430}
1262 1431
1263/* 1432/*
1264 * Garbage collect a leaf attribute list block by copying it to a new buffer. 1433 * Garbage collect a leaf attribute list block by copying it to a new buffer.
1265 */ 1434 */
1266STATIC void 1435STATIC void
1267xfs_attr_leaf_compact( 1436xfs_attr3_leaf_compact(
1268 struct xfs_da_args *args, 1437 struct xfs_da_args *args,
1438 struct xfs_attr3_icleaf_hdr *ichdr_d,
1269 struct xfs_buf *bp) 1439 struct xfs_buf *bp)
1270{ 1440{
1271 xfs_attr_leafblock_t *leaf_s, *leaf_d; 1441 xfs_attr_leafblock_t *leaf_s, *leaf_d;
1272 xfs_attr_leaf_hdr_t *hdr_s, *hdr_d; 1442 struct xfs_attr3_icleaf_hdr ichdr_s;
1273 struct xfs_trans *trans = args->trans; 1443 struct xfs_trans *trans = args->trans;
1274 struct xfs_mount *mp = trans->t_mountp; 1444 struct xfs_mount *mp = trans->t_mountp;
1275 char *tmpbuffer; 1445 char *tmpbuffer;
@@ -1286,34 +1456,69 @@ xfs_attr_leaf_compact(
1286 */ 1456 */
1287 leaf_s = (xfs_attr_leafblock_t *)tmpbuffer; 1457 leaf_s = (xfs_attr_leafblock_t *)tmpbuffer;
1288 leaf_d = bp->b_addr; 1458 leaf_d = bp->b_addr;
1289 hdr_s = &leaf_s->hdr; 1459 ichdr_s = *ichdr_d; /* struct copy */
1290 hdr_d = &leaf_d->hdr; 1460 ichdr_d->firstused = XFS_LBSIZE(mp);
1291 hdr_d->info = hdr_s->info; /* struct copy */ 1461 ichdr_d->usedbytes = 0;
1292 hdr_d->firstused = cpu_to_be16(XFS_LBSIZE(mp)); 1462 ichdr_d->count = 0;
1293 /* handle truncation gracefully */ 1463 ichdr_d->holes = 0;
1294 if (!hdr_d->firstused) { 1464 ichdr_d->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_s);
1295 hdr_d->firstused = cpu_to_be16( 1465 ichdr_d->freemap[0].size = ichdr_d->firstused - ichdr_d->freemap[0].base;
1296 XFS_LBSIZE(mp) - XFS_ATTR_LEAF_NAME_ALIGN);
1297 }
1298 hdr_d->usedbytes = 0;
1299 hdr_d->count = 0;
1300 hdr_d->holes = 0;
1301 hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t));
1302 hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused) -
1303 sizeof(xfs_attr_leaf_hdr_t));
1304 1466
1305 /* 1467 /*
1306 * Copy all entry's in the same (sorted) order, 1468 * Copy all entry's in the same (sorted) order,
1307 * but allocate name/value pairs packed and in sequence. 1469 * but allocate name/value pairs packed and in sequence.
1308 */ 1470 */
1309 xfs_attr_leaf_moveents(leaf_s, 0, leaf_d, 0, 1471 xfs_attr3_leaf_moveents(leaf_s, &ichdr_s, 0, leaf_d, ichdr_d, 0,
1310 be16_to_cpu(hdr_s->count), mp); 1472 ichdr_s.count, mp);
1473 /*
1474 * this logs the entire buffer, but the caller must write the header
1475 * back to the buffer when it is finished modifying it.
1476 */
1311 xfs_trans_log_buf(trans, bp, 0, XFS_LBSIZE(mp) - 1); 1477 xfs_trans_log_buf(trans, bp, 0, XFS_LBSIZE(mp) - 1);
1312 1478
1313 kmem_free(tmpbuffer); 1479 kmem_free(tmpbuffer);
1314} 1480}
1315 1481
1316/* 1482/*
1483 * Compare two leaf blocks "order".
1484 * Return 0 unless leaf2 should go before leaf1.
1485 */
1486static int
1487xfs_attr3_leaf_order(
1488 struct xfs_buf *leaf1_bp,
1489 struct xfs_attr3_icleaf_hdr *leaf1hdr,
1490 struct xfs_buf *leaf2_bp,
1491 struct xfs_attr3_icleaf_hdr *leaf2hdr)
1492{
1493 struct xfs_attr_leaf_entry *entries1;
1494 struct xfs_attr_leaf_entry *entries2;
1495
1496 entries1 = xfs_attr3_leaf_entryp(leaf1_bp->b_addr);
1497 entries2 = xfs_attr3_leaf_entryp(leaf2_bp->b_addr);
1498 if (leaf1hdr->count > 0 && leaf2hdr->count > 0 &&
1499 ((be32_to_cpu(entries2[0].hashval) <
1500 be32_to_cpu(entries1[0].hashval)) ||
1501 (be32_to_cpu(entries2[leaf2hdr->count - 1].hashval) <
1502 be32_to_cpu(entries1[leaf1hdr->count - 1].hashval)))) {
1503 return 1;
1504 }
1505 return 0;
1506}
1507
1508int
1509xfs_attr_leaf_order(
1510 struct xfs_buf *leaf1_bp,
1511 struct xfs_buf *leaf2_bp)
1512{
1513 struct xfs_attr3_icleaf_hdr ichdr1;
1514 struct xfs_attr3_icleaf_hdr ichdr2;
1515
1516 xfs_attr3_leaf_hdr_from_disk(&ichdr1, leaf1_bp->b_addr);
1517 xfs_attr3_leaf_hdr_from_disk(&ichdr2, leaf2_bp->b_addr);
1518 return xfs_attr3_leaf_order(leaf1_bp, &ichdr1, leaf2_bp, &ichdr2);
1519}
1520
1521/*
1317 * Redistribute the attribute list entries between two leaf nodes, 1522 * Redistribute the attribute list entries between two leaf nodes,
1318 * taking into account the size of the new entry. 1523 * taking into account the size of the new entry.
1319 * 1524 *
@@ -1326,14 +1531,23 @@ xfs_attr_leaf_compact(
1326 * the "new" and "old" values can end up in different blocks. 1531 * the "new" and "old" values can end up in different blocks.
1327 */ 1532 */
1328STATIC void 1533STATIC void
1329xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, 1534xfs_attr3_leaf_rebalance(
1330 xfs_da_state_blk_t *blk2) 1535 struct xfs_da_state *state,
1536 struct xfs_da_state_blk *blk1,
1537 struct xfs_da_state_blk *blk2)
1331{ 1538{
1332 xfs_da_args_t *args; 1539 struct xfs_da_args *args;
1333 xfs_da_state_blk_t *tmp_blk; 1540 struct xfs_attr_leafblock *leaf1;
1334 xfs_attr_leafblock_t *leaf1, *leaf2; 1541 struct xfs_attr_leafblock *leaf2;
1335 xfs_attr_leaf_hdr_t *hdr1, *hdr2; 1542 struct xfs_attr3_icleaf_hdr ichdr1;
1336 int count, totallen, max, space, swap; 1543 struct xfs_attr3_icleaf_hdr ichdr2;
1544 struct xfs_attr_leaf_entry *entries1;
1545 struct xfs_attr_leaf_entry *entries2;
1546 int count;
1547 int totallen;
1548 int max;
1549 int space;
1550 int swap;
1337 1551
1338 /* 1552 /*
1339 * Set up environment. 1553 * Set up environment.
@@ -1342,9 +1556,9 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
1342 ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC); 1556 ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC);
1343 leaf1 = blk1->bp->b_addr; 1557 leaf1 = blk1->bp->b_addr;
1344 leaf2 = blk2->bp->b_addr; 1558 leaf2 = blk2->bp->b_addr;
1345 ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1559 xfs_attr3_leaf_hdr_from_disk(&ichdr1, leaf1);
1346 ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1560 xfs_attr3_leaf_hdr_from_disk(&ichdr2, leaf2);
1347 ASSERT(leaf2->hdr.count == 0); 1561 ASSERT(ichdr2.count == 0);
1348 args = state->args; 1562 args = state->args;
1349 1563
1350 trace_xfs_attr_leaf_rebalance(args); 1564 trace_xfs_attr_leaf_rebalance(args);
@@ -1356,16 +1570,23 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
1356 * second block, this code should never set "swap". 1570 * second block, this code should never set "swap".
1357 */ 1571 */
1358 swap = 0; 1572 swap = 0;
1359 if (xfs_attr_leaf_order(blk1->bp, blk2->bp)) { 1573 if (xfs_attr3_leaf_order(blk1->bp, &ichdr1, blk2->bp, &ichdr2)) {
1574 struct xfs_da_state_blk *tmp_blk;
1575 struct xfs_attr3_icleaf_hdr tmp_ichdr;
1576
1360 tmp_blk = blk1; 1577 tmp_blk = blk1;
1361 blk1 = blk2; 1578 blk1 = blk2;
1362 blk2 = tmp_blk; 1579 blk2 = tmp_blk;
1580
1581 /* struct copies to swap them rather than reconverting */
1582 tmp_ichdr = ichdr1;
1583 ichdr1 = ichdr2;
1584 ichdr2 = tmp_ichdr;
1585
1363 leaf1 = blk1->bp->b_addr; 1586 leaf1 = blk1->bp->b_addr;
1364 leaf2 = blk2->bp->b_addr; 1587 leaf2 = blk2->bp->b_addr;
1365 swap = 1; 1588 swap = 1;
1366 } 1589 }
1367 hdr1 = &leaf1->hdr;
1368 hdr2 = &leaf2->hdr;
1369 1590
1370 /* 1591 /*
1371 * Examine entries until we reduce the absolute difference in 1592 * Examine entries until we reduce the absolute difference in
@@ -1375,41 +1596,39 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
1375 * "inleaf" is true if the new entry should be inserted into blk1. 1596 * "inleaf" is true if the new entry should be inserted into blk1.
1376 * If "swap" is also true, then reverse the sense of "inleaf". 1597 * If "swap" is also true, then reverse the sense of "inleaf".
1377 */ 1598 */
1378 state->inleaf = xfs_attr_leaf_figure_balance(state, blk1, blk2, 1599 state->inleaf = xfs_attr3_leaf_figure_balance(state, blk1, &ichdr1,
1379 &count, &totallen); 1600 blk2, &ichdr2,
1601 &count, &totallen);
1380 if (swap) 1602 if (swap)
1381 state->inleaf = !state->inleaf; 1603 state->inleaf = !state->inleaf;
1382 1604
1383 /* 1605 /*
1384 * Move any entries required from leaf to leaf: 1606 * Move any entries required from leaf to leaf:
1385 */ 1607 */
1386 if (count < be16_to_cpu(hdr1->count)) { 1608 if (count < ichdr1.count) {
1387 /* 1609 /*
1388 * Figure the total bytes to be added to the destination leaf. 1610 * Figure the total bytes to be added to the destination leaf.
1389 */ 1611 */
1390 /* number entries being moved */ 1612 /* number entries being moved */
1391 count = be16_to_cpu(hdr1->count) - count; 1613 count = ichdr1.count - count;
1392 space = be16_to_cpu(hdr1->usedbytes) - totallen; 1614 space = ichdr1.usedbytes - totallen;
1393 space += count * sizeof(xfs_attr_leaf_entry_t); 1615 space += count * sizeof(xfs_attr_leaf_entry_t);
1394 1616
1395 /* 1617 /*
1396 * leaf2 is the destination, compact it if it looks tight. 1618 * leaf2 is the destination, compact it if it looks tight.
1397 */ 1619 */
1398 max = be16_to_cpu(hdr2->firstused) 1620 max = ichdr2.firstused - xfs_attr3_leaf_hdr_size(leaf1);
1399 - sizeof(xfs_attr_leaf_hdr_t); 1621 max -= ichdr2.count * sizeof(xfs_attr_leaf_entry_t);
1400 max -= be16_to_cpu(hdr2->count) * sizeof(xfs_attr_leaf_entry_t);
1401 if (space > max) 1622 if (space > max)
1402 xfs_attr_leaf_compact(args, blk2->bp); 1623 xfs_attr3_leaf_compact(args, &ichdr2, blk2->bp);
1403 1624
1404 /* 1625 /*
1405 * Move high entries from leaf1 to low end of leaf2. 1626 * Move high entries from leaf1 to low end of leaf2.
1406 */ 1627 */
1407 xfs_attr_leaf_moveents(leaf1, be16_to_cpu(hdr1->count) - count, 1628 xfs_attr3_leaf_moveents(leaf1, &ichdr1, ichdr1.count - count,
1408 leaf2, 0, count, state->mp); 1629 leaf2, &ichdr2, 0, count, state->mp);
1409 1630
1410 xfs_trans_log_buf(args->trans, blk1->bp, 0, state->blocksize-1); 1631 } else if (count > ichdr1.count) {
1411 xfs_trans_log_buf(args->trans, blk2->bp, 0, state->blocksize-1);
1412 } else if (count > be16_to_cpu(hdr1->count)) {
1413 /* 1632 /*
1414 * I assert that since all callers pass in an empty 1633 * I assert that since all callers pass in an empty
1415 * second buffer, this code should never execute. 1634 * second buffer, this code should never execute.
@@ -1420,36 +1639,37 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
1420 * Figure the total bytes to be added to the destination leaf. 1639 * Figure the total bytes to be added to the destination leaf.
1421 */ 1640 */
1422 /* number entries being moved */ 1641 /* number entries being moved */
1423 count -= be16_to_cpu(hdr1->count); 1642 count -= ichdr1.count;
1424 space = totallen - be16_to_cpu(hdr1->usedbytes); 1643 space = totallen - ichdr1.usedbytes;
1425 space += count * sizeof(xfs_attr_leaf_entry_t); 1644 space += count * sizeof(xfs_attr_leaf_entry_t);
1426 1645
1427 /* 1646 /*
1428 * leaf1 is the destination, compact it if it looks tight. 1647 * leaf1 is the destination, compact it if it looks tight.
1429 */ 1648 */
1430 max = be16_to_cpu(hdr1->firstused) 1649 max = ichdr1.firstused - xfs_attr3_leaf_hdr_size(leaf1);
1431 - sizeof(xfs_attr_leaf_hdr_t); 1650 max -= ichdr1.count * sizeof(xfs_attr_leaf_entry_t);
1432 max -= be16_to_cpu(hdr1->count) * sizeof(xfs_attr_leaf_entry_t);
1433 if (space > max) 1651 if (space > max)
1434 xfs_attr_leaf_compact(args, blk1->bp); 1652 xfs_attr3_leaf_compact(args, &ichdr1, blk1->bp);
1435 1653
1436 /* 1654 /*
1437 * Move low entries from leaf2 to high end of leaf1. 1655 * Move low entries from leaf2 to high end of leaf1.
1438 */ 1656 */
1439 xfs_attr_leaf_moveents(leaf2, 0, leaf1, 1657 xfs_attr3_leaf_moveents(leaf2, &ichdr2, 0, leaf1, &ichdr1,
1440 be16_to_cpu(hdr1->count), count, state->mp); 1658 ichdr1.count, count, state->mp);
1441
1442 xfs_trans_log_buf(args->trans, blk1->bp, 0, state->blocksize-1);
1443 xfs_trans_log_buf(args->trans, blk2->bp, 0, state->blocksize-1);
1444 } 1659 }
1445 1660
1661 xfs_attr3_leaf_hdr_to_disk(leaf1, &ichdr1);
1662 xfs_attr3_leaf_hdr_to_disk(leaf2, &ichdr2);
1663 xfs_trans_log_buf(args->trans, blk1->bp, 0, state->blocksize-1);
1664 xfs_trans_log_buf(args->trans, blk2->bp, 0, state->blocksize-1);
1665
1446 /* 1666 /*
1447 * Copy out last hashval in each block for B-tree code. 1667 * Copy out last hashval in each block for B-tree code.
1448 */ 1668 */
1449 blk1->hashval = be32_to_cpu( 1669 entries1 = xfs_attr3_leaf_entryp(leaf1);
1450 leaf1->entries[be16_to_cpu(leaf1->hdr.count)-1].hashval); 1670 entries2 = xfs_attr3_leaf_entryp(leaf2);
1451 blk2->hashval = be32_to_cpu( 1671 blk1->hashval = be32_to_cpu(entries1[ichdr1.count - 1].hashval);
1452 leaf2->entries[be16_to_cpu(leaf2->hdr.count)-1].hashval); 1672 blk2->hashval = be32_to_cpu(entries2[ichdr2.count - 1].hashval);
1453 1673
1454 /* 1674 /*
1455 * Adjust the expected index for insertion. 1675 * Adjust the expected index for insertion.
@@ -1463,12 +1683,12 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
1463 * inserting. The index/blkno fields refer to the "old" entry, 1683 * inserting. The index/blkno fields refer to the "old" entry,
1464 * while the index2/blkno2 fields refer to the "new" entry. 1684 * while the index2/blkno2 fields refer to the "new" entry.
1465 */ 1685 */
1466 if (blk1->index > be16_to_cpu(leaf1->hdr.count)) { 1686 if (blk1->index > ichdr1.count) {
1467 ASSERT(state->inleaf == 0); 1687 ASSERT(state->inleaf == 0);
1468 blk2->index = blk1->index - be16_to_cpu(leaf1->hdr.count); 1688 blk2->index = blk1->index - ichdr1.count;
1469 args->index = args->index2 = blk2->index; 1689 args->index = args->index2 = blk2->index;
1470 args->blkno = args->blkno2 = blk2->blkno; 1690 args->blkno = args->blkno2 = blk2->blkno;
1471 } else if (blk1->index == be16_to_cpu(leaf1->hdr.count)) { 1691 } else if (blk1->index == ichdr1.count) {
1472 if (state->inleaf) { 1692 if (state->inleaf) {
1473 args->index = blk1->index; 1693 args->index = blk1->index;
1474 args->blkno = blk1->blkno; 1694 args->blkno = blk1->blkno;
@@ -1480,8 +1700,7 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
1480 * is already stored in blkno2/index2, so don't 1700 * is already stored in blkno2/index2, so don't
1481 * overwrite it overwise we corrupt the tree. 1701 * overwrite it overwise we corrupt the tree.
1482 */ 1702 */
1483 blk2->index = blk1->index 1703 blk2->index = blk1->index - ichdr1.count;
1484 - be16_to_cpu(leaf1->hdr.count);
1485 args->index = blk2->index; 1704 args->index = blk2->index;
1486 args->blkno = blk2->blkno; 1705 args->blkno = blk2->blkno;
1487 if (!state->extravalid) { 1706 if (!state->extravalid) {
@@ -1509,42 +1728,40 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
1509 * GROT: Do a double-split for this case? 1728 * GROT: Do a double-split for this case?
1510 */ 1729 */
1511STATIC int 1730STATIC int
1512xfs_attr_leaf_figure_balance(xfs_da_state_t *state, 1731xfs_attr3_leaf_figure_balance(
1513 xfs_da_state_blk_t *blk1, 1732 struct xfs_da_state *state,
1514 xfs_da_state_blk_t *blk2, 1733 struct xfs_da_state_blk *blk1,
1515 int *countarg, int *usedbytesarg) 1734 struct xfs_attr3_icleaf_hdr *ichdr1,
1735 struct xfs_da_state_blk *blk2,
1736 struct xfs_attr3_icleaf_hdr *ichdr2,
1737 int *countarg,
1738 int *usedbytesarg)
1516{ 1739{
1517 xfs_attr_leafblock_t *leaf1, *leaf2; 1740 struct xfs_attr_leafblock *leaf1 = blk1->bp->b_addr;
1518 xfs_attr_leaf_hdr_t *hdr1, *hdr2; 1741 struct xfs_attr_leafblock *leaf2 = blk2->bp->b_addr;
1519 xfs_attr_leaf_entry_t *entry; 1742 struct xfs_attr_leaf_entry *entry;
1520 int count, max, index, totallen, half; 1743 int count;
1521 int lastdelta, foundit, tmp; 1744 int max;
1522 1745 int index;
1523 /* 1746 int totallen = 0;
1524 * Set up environment. 1747 int half;
1525 */ 1748 int lastdelta;
1526 leaf1 = blk1->bp->b_addr; 1749 int foundit = 0;
1527 leaf2 = blk2->bp->b_addr; 1750 int tmp;
1528 hdr1 = &leaf1->hdr;
1529 hdr2 = &leaf2->hdr;
1530 foundit = 0;
1531 totallen = 0;
1532 1751
1533 /* 1752 /*
1534 * Examine entries until we reduce the absolute difference in 1753 * Examine entries until we reduce the absolute difference in
1535 * byte usage between the two blocks to a minimum. 1754 * byte usage between the two blocks to a minimum.
1536 */ 1755 */
1537 max = be16_to_cpu(hdr1->count) + be16_to_cpu(hdr2->count); 1756 max = ichdr1->count + ichdr2->count;
1538 half = (max+1) * sizeof(*entry); 1757 half = (max + 1) * sizeof(*entry);
1539 half += be16_to_cpu(hdr1->usedbytes) + 1758 half += ichdr1->usedbytes + ichdr2->usedbytes +
1540 be16_to_cpu(hdr2->usedbytes) + 1759 xfs_attr_leaf_newentsize(state->args->namelen,
1541 xfs_attr_leaf_newentsize( 1760 state->args->valuelen,
1542 state->args->namelen, 1761 state->blocksize, NULL);
1543 state->args->valuelen,
1544 state->blocksize, NULL);
1545 half /= 2; 1762 half /= 2;
1546 lastdelta = state->blocksize; 1763 lastdelta = state->blocksize;
1547 entry = &leaf1->entries[0]; 1764 entry = xfs_attr3_leaf_entryp(leaf1);
1548 for (count = index = 0; count < max; entry++, index++, count++) { 1765 for (count = index = 0; count < max; entry++, index++, count++) {
1549 1766
1550#define XFS_ATTR_ABS(A) (((A) < 0) ? -(A) : (A)) 1767#define XFS_ATTR_ABS(A) (((A) < 0) ? -(A) : (A))
@@ -1567,9 +1784,9 @@ xfs_attr_leaf_figure_balance(xfs_da_state_t *state,
1567 /* 1784 /*
1568 * Wrap around into the second block if necessary. 1785 * Wrap around into the second block if necessary.
1569 */ 1786 */
1570 if (count == be16_to_cpu(hdr1->count)) { 1787 if (count == ichdr1->count) {
1571 leaf1 = leaf2; 1788 leaf1 = leaf2;
1572 entry = &leaf1->entries[0]; 1789 entry = xfs_attr3_leaf_entryp(leaf1);
1573 index = 0; 1790 index = 0;
1574 } 1791 }
1575 1792
@@ -1600,7 +1817,7 @@ xfs_attr_leaf_figure_balance(xfs_da_state_t *state,
1600 1817
1601 *countarg = count; 1818 *countarg = count;
1602 *usedbytesarg = totallen; 1819 *usedbytesarg = totallen;
1603 return(foundit); 1820 return foundit;
1604} 1821}
1605 1822
1606/*======================================================================== 1823/*========================================================================
@@ -1619,14 +1836,20 @@ xfs_attr_leaf_figure_balance(xfs_da_state_t *state,
1619 * GROT: allow for INCOMPLETE entries in calculation. 1836 * GROT: allow for INCOMPLETE entries in calculation.
1620 */ 1837 */
1621int 1838int
1622xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action) 1839xfs_attr3_leaf_toosmall(
1840 struct xfs_da_state *state,
1841 int *action)
1623{ 1842{
1624 xfs_attr_leafblock_t *leaf; 1843 struct xfs_attr_leafblock *leaf;
1625 xfs_da_state_blk_t *blk; 1844 struct xfs_da_state_blk *blk;
1626 xfs_da_blkinfo_t *info; 1845 struct xfs_attr3_icleaf_hdr ichdr;
1627 int count, bytes, forward, error, retval, i; 1846 struct xfs_buf *bp;
1628 xfs_dablk_t blkno; 1847 xfs_dablk_t blkno;
1629 struct xfs_buf *bp; 1848 int bytes;
1849 int forward;
1850 int error;
1851 int retval;
1852 int i;
1630 1853
1631 trace_xfs_attr_leaf_toosmall(state->args); 1854 trace_xfs_attr_leaf_toosmall(state->args);
1632 1855
@@ -1636,13 +1859,11 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action)
1636 * to coalesce with a sibling. 1859 * to coalesce with a sibling.
1637 */ 1860 */
1638 blk = &state->path.blk[ state->path.active-1 ]; 1861 blk = &state->path.blk[ state->path.active-1 ];
1639 info = blk->bp->b_addr; 1862 leaf = blk->bp->b_addr;
1640 ASSERT(info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1863 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
1641 leaf = (xfs_attr_leafblock_t *)info; 1864 bytes = xfs_attr3_leaf_hdr_size(leaf) +
1642 count = be16_to_cpu(leaf->hdr.count); 1865 ichdr.count * sizeof(xfs_attr_leaf_entry_t) +
1643 bytes = sizeof(xfs_attr_leaf_hdr_t) + 1866 ichdr.usedbytes;
1644 count * sizeof(xfs_attr_leaf_entry_t) +
1645 be16_to_cpu(leaf->hdr.usedbytes);
1646 if (bytes > (state->blocksize >> 1)) { 1867 if (bytes > (state->blocksize >> 1)) {
1647 *action = 0; /* blk over 50%, don't try to join */ 1868 *action = 0; /* blk over 50%, don't try to join */
1648 return(0); 1869 return(0);
@@ -1654,12 +1875,12 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action)
1654 * coalesce it with a sibling block. We choose (arbitrarily) 1875 * coalesce it with a sibling block. We choose (arbitrarily)
1655 * to merge with the forward block unless it is NULL. 1876 * to merge with the forward block unless it is NULL.
1656 */ 1877 */
1657 if (count == 0) { 1878 if (ichdr.count == 0) {
1658 /* 1879 /*
1659 * Make altpath point to the block we want to keep and 1880 * Make altpath point to the block we want to keep and
1660 * path point to the block we want to drop (this one). 1881 * path point to the block we want to drop (this one).
1661 */ 1882 */
1662 forward = (info->forw != 0); 1883 forward = (ichdr.forw != 0);
1663 memcpy(&state->altpath, &state->path, sizeof(state->path)); 1884 memcpy(&state->altpath, &state->path, sizeof(state->path));
1664 error = xfs_da3_path_shift(state, &state->altpath, forward, 1885 error = xfs_da3_path_shift(state, &state->altpath, forward,
1665 0, &retval); 1886 0, &retval);
@@ -1670,7 +1891,7 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action)
1670 } else { 1891 } else {
1671 *action = 2; 1892 *action = 2;
1672 } 1893 }
1673 return(0); 1894 return 0;
1674 } 1895 }
1675 1896
1676 /* 1897 /*
@@ -1681,28 +1902,28 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action)
1681 * to shrink an attribute list over time. 1902 * to shrink an attribute list over time.
1682 */ 1903 */
1683 /* start with smaller blk num */ 1904 /* start with smaller blk num */
1684 forward = (be32_to_cpu(info->forw) < be32_to_cpu(info->back)); 1905 forward = ichdr.forw < ichdr.back;
1685 for (i = 0; i < 2; forward = !forward, i++) { 1906 for (i = 0; i < 2; forward = !forward, i++) {
1907 struct xfs_attr3_icleaf_hdr ichdr2;
1686 if (forward) 1908 if (forward)
1687 blkno = be32_to_cpu(info->forw); 1909 blkno = ichdr.forw;
1688 else 1910 else
1689 blkno = be32_to_cpu(info->back); 1911 blkno = ichdr.back;
1690 if (blkno == 0) 1912 if (blkno == 0)
1691 continue; 1913 continue;
1692 error = xfs_attr_leaf_read(state->args->trans, state->args->dp, 1914 error = xfs_attr3_leaf_read(state->args->trans, state->args->dp,
1693 blkno, -1, &bp); 1915 blkno, -1, &bp);
1694 if (error) 1916 if (error)
1695 return(error); 1917 return(error);
1696 1918
1697 leaf = (xfs_attr_leafblock_t *)info; 1919 xfs_attr3_leaf_hdr_from_disk(&ichdr2, bp->b_addr);
1698 count = be16_to_cpu(leaf->hdr.count); 1920
1699 bytes = state->blocksize - (state->blocksize>>2); 1921 bytes = state->blocksize - (state->blocksize >> 2) -
1700 bytes -= be16_to_cpu(leaf->hdr.usedbytes); 1922 ichdr.usedbytes - ichdr2.usedbytes -
1701 leaf = bp->b_addr; 1923 ((ichdr.count + ichdr2.count) *
1702 count += be16_to_cpu(leaf->hdr.count); 1924 sizeof(xfs_attr_leaf_entry_t)) -
1703 bytes -= be16_to_cpu(leaf->hdr.usedbytes); 1925 xfs_attr3_leaf_hdr_size(leaf);
1704 bytes -= count * sizeof(xfs_attr_leaf_entry_t); 1926
1705 bytes -= sizeof(xfs_attr_leaf_hdr_t);
1706 xfs_trans_brelse(state->args->trans, bp); 1927 xfs_trans_brelse(state->args->trans, bp);
1707 if (bytes >= 0) 1928 if (bytes >= 0)
1708 break; /* fits with at least 25% to spare */ 1929 break; /* fits with at least 25% to spare */
@@ -1741,32 +1962,35 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action)
1741 * If two leaves are 37% full, when combined they will leave 25% free. 1962 * If two leaves are 37% full, when combined they will leave 25% free.
1742 */ 1963 */
1743int 1964int
1744xfs_attr_leaf_remove( 1965xfs_attr3_leaf_remove(
1745 struct xfs_buf *bp, 1966 struct xfs_buf *bp,
1746 xfs_da_args_t *args) 1967 struct xfs_da_args *args)
1747{ 1968{
1748 xfs_attr_leafblock_t *leaf; 1969 struct xfs_attr_leafblock *leaf;
1749 xfs_attr_leaf_hdr_t *hdr; 1970 struct xfs_attr3_icleaf_hdr ichdr;
1750 xfs_attr_leaf_map_t *map; 1971 struct xfs_attr_leaf_entry *entry;
1751 xfs_attr_leaf_entry_t *entry; 1972 struct xfs_mount *mp = args->trans->t_mountp;
1752 int before, after, smallest, entsize; 1973 int before;
1753 int tablesize, tmp, i; 1974 int after;
1754 xfs_mount_t *mp; 1975 int smallest;
1976 int entsize;
1977 int tablesize;
1978 int tmp;
1979 int i;
1755 1980
1756 trace_xfs_attr_leaf_remove(args); 1981 trace_xfs_attr_leaf_remove(args);
1757 1982
1758 leaf = bp->b_addr; 1983 leaf = bp->b_addr;
1759 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1984 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
1760 hdr = &leaf->hdr; 1985
1761 mp = args->trans->t_mountp; 1986 ASSERT(ichdr.count > 0 && ichdr.count < XFS_LBSIZE(mp) / 8);
1762 ASSERT((be16_to_cpu(hdr->count) > 0) 1987 ASSERT(args->index >= 0 && args->index < ichdr.count);
1763 && (be16_to_cpu(hdr->count) < (XFS_LBSIZE(mp)/8))); 1988 ASSERT(ichdr.firstused >= ichdr.count * sizeof(*entry) +
1764 ASSERT((args->index >= 0) 1989 xfs_attr3_leaf_hdr_size(leaf));
1765 && (args->index < be16_to_cpu(hdr->count))); 1990
1766 ASSERT(be16_to_cpu(hdr->firstused) >= 1991 entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
1767 ((be16_to_cpu(hdr->count) * sizeof(*entry)) + sizeof(*hdr))); 1992
1768 entry = &leaf->entries[args->index]; 1993 ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused);
1769 ASSERT(be16_to_cpu(entry->nameidx) >= be16_to_cpu(hdr->firstused));
1770 ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp)); 1994 ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp));
1771 1995
1772 /* 1996 /*
@@ -1775,30 +1999,28 @@ xfs_attr_leaf_remove(
1775 * find smallest free region in case we need to replace it, 1999 * find smallest free region in case we need to replace it,
1776 * adjust any map that borders the entry table, 2000 * adjust any map that borders the entry table,
1777 */ 2001 */
1778 tablesize = be16_to_cpu(hdr->count) * sizeof(xfs_attr_leaf_entry_t) 2002 tablesize = ichdr.count * sizeof(xfs_attr_leaf_entry_t)
1779 + sizeof(xfs_attr_leaf_hdr_t); 2003 + xfs_attr3_leaf_hdr_size(leaf);
1780 map = &hdr->freemap[0]; 2004 tmp = ichdr.freemap[0].size;
1781 tmp = be16_to_cpu(map->size);
1782 before = after = -1; 2005 before = after = -1;
1783 smallest = XFS_ATTR_LEAF_MAPSIZE - 1; 2006 smallest = XFS_ATTR_LEAF_MAPSIZE - 1;
1784 entsize = xfs_attr_leaf_entsize(leaf, args->index); 2007 entsize = xfs_attr_leaf_entsize(leaf, args->index);
1785 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; map++, i++) { 2008 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
1786 ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp)); 2009 ASSERT(ichdr.freemap[i].base < XFS_LBSIZE(mp));
1787 ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp)); 2010 ASSERT(ichdr.freemap[i].size < XFS_LBSIZE(mp));
1788 if (be16_to_cpu(map->base) == tablesize) { 2011 if (ichdr.freemap[i].base == tablesize) {
1789 be16_add_cpu(&map->base, 2012 ichdr.freemap[i].base -= sizeof(xfs_attr_leaf_entry_t);
1790 -((int)sizeof(xfs_attr_leaf_entry_t))); 2013 ichdr.freemap[i].size += sizeof(xfs_attr_leaf_entry_t);
1791 be16_add_cpu(&map->size, sizeof(xfs_attr_leaf_entry_t));
1792 } 2014 }
1793 2015
1794 if ((be16_to_cpu(map->base) + be16_to_cpu(map->size)) 2016 if (ichdr.freemap[i].base + ichdr.freemap[i].size ==
1795 == be16_to_cpu(entry->nameidx)) { 2017 be16_to_cpu(entry->nameidx)) {
1796 before = i; 2018 before = i;
1797 } else if (be16_to_cpu(map->base) 2019 } else if (ichdr.freemap[i].base ==
1798 == (be16_to_cpu(entry->nameidx) + entsize)) { 2020 (be16_to_cpu(entry->nameidx) + entsize)) {
1799 after = i; 2021 after = i;
1800 } else if (be16_to_cpu(map->size) < tmp) { 2022 } else if (ichdr.freemap[i].size < tmp) {
1801 tmp = be16_to_cpu(map->size); 2023 tmp = ichdr.freemap[i].size;
1802 smallest = i; 2024 smallest = i;
1803 } 2025 }
1804 } 2026 }
@@ -1809,36 +2031,30 @@ xfs_attr_leaf_remove(
1809 */ 2031 */
1810 if ((before >= 0) || (after >= 0)) { 2032 if ((before >= 0) || (after >= 0)) {
1811 if ((before >= 0) && (after >= 0)) { 2033 if ((before >= 0) && (after >= 0)) {
1812 map = &hdr->freemap[before]; 2034 ichdr.freemap[before].size += entsize;
1813 be16_add_cpu(&map->size, entsize); 2035 ichdr.freemap[before].size += ichdr.freemap[after].size;
1814 be16_add_cpu(&map->size, 2036 ichdr.freemap[after].base = 0;
1815 be16_to_cpu(hdr->freemap[after].size)); 2037 ichdr.freemap[after].size = 0;
1816 hdr->freemap[after].base = 0;
1817 hdr->freemap[after].size = 0;
1818 } else if (before >= 0) { 2038 } else if (before >= 0) {
1819 map = &hdr->freemap[before]; 2039 ichdr.freemap[before].size += entsize;
1820 be16_add_cpu(&map->size, entsize);
1821 } else { 2040 } else {
1822 map = &hdr->freemap[after]; 2041 ichdr.freemap[after].base = be16_to_cpu(entry->nameidx);
1823 /* both on-disk, don't endian flip twice */ 2042 ichdr.freemap[after].size += entsize;
1824 map->base = entry->nameidx;
1825 be16_add_cpu(&map->size, entsize);
1826 } 2043 }
1827 } else { 2044 } else {
1828 /* 2045 /*
1829 * Replace smallest region (if it is smaller than free'd entry) 2046 * Replace smallest region (if it is smaller than free'd entry)
1830 */ 2047 */
1831 map = &hdr->freemap[smallest]; 2048 if (ichdr.freemap[smallest].size < entsize) {
1832 if (be16_to_cpu(map->size) < entsize) { 2049 ichdr.freemap[smallest].base = be16_to_cpu(entry->nameidx);
1833 map->base = cpu_to_be16(be16_to_cpu(entry->nameidx)); 2050 ichdr.freemap[smallest].size = entsize;
1834 map->size = cpu_to_be16(entsize);
1835 } 2051 }
1836 } 2052 }
1837 2053
1838 /* 2054 /*
1839 * Did we remove the first entry? 2055 * Did we remove the first entry?
1840 */ 2056 */
1841 if (be16_to_cpu(entry->nameidx) == be16_to_cpu(hdr->firstused)) 2057 if (be16_to_cpu(entry->nameidx) == ichdr.firstused)
1842 smallest = 1; 2058 smallest = 1;
1843 else 2059 else
1844 smallest = 0; 2060 smallest = 0;
@@ -1846,20 +2062,20 @@ xfs_attr_leaf_remove(
1846 /* 2062 /*
1847 * Compress the remaining entries and zero out the removed stuff. 2063 * Compress the remaining entries and zero out the removed stuff.
1848 */ 2064 */
1849 memset(xfs_attr_leaf_name(leaf, args->index), 0, entsize); 2065 memset(xfs_attr3_leaf_name(leaf, args->index), 0, entsize);
1850 be16_add_cpu(&hdr->usedbytes, -entsize); 2066 ichdr.usedbytes -= entsize;
1851 xfs_trans_log_buf(args->trans, bp, 2067 xfs_trans_log_buf(args->trans, bp,
1852 XFS_DA_LOGRANGE(leaf, xfs_attr_leaf_name(leaf, args->index), 2068 XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index),
1853 entsize)); 2069 entsize));
1854 2070
1855 tmp = (be16_to_cpu(hdr->count) - args->index) 2071 tmp = (ichdr.count - args->index) * sizeof(xfs_attr_leaf_entry_t);
1856 * sizeof(xfs_attr_leaf_entry_t); 2072 memmove(entry, entry + 1, tmp);
1857 memmove((char *)entry, (char *)(entry+1), tmp); 2073 ichdr.count--;
1858 be16_add_cpu(&hdr->count, -1);
1859 xfs_trans_log_buf(args->trans, bp, 2074 xfs_trans_log_buf(args->trans, bp,
1860 XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry))); 2075 XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(xfs_attr_leaf_entry_t)));
1861 entry = &leaf->entries[be16_to_cpu(hdr->count)]; 2076
1862 memset((char *)entry, 0, sizeof(xfs_attr_leaf_entry_t)); 2077 entry = &xfs_attr3_leaf_entryp(leaf)[ichdr.count];
2078 memset(entry, 0, sizeof(xfs_attr_leaf_entry_t));
1863 2079
1864 /* 2080 /*
1865 * If we removed the first entry, re-find the first used byte 2081 * If we removed the first entry, re-find the first used byte
@@ -1869,130 +2085,130 @@ xfs_attr_leaf_remove(
1869 */ 2085 */
1870 if (smallest) { 2086 if (smallest) {
1871 tmp = XFS_LBSIZE(mp); 2087 tmp = XFS_LBSIZE(mp);
1872 entry = &leaf->entries[0]; 2088 entry = xfs_attr3_leaf_entryp(leaf);
1873 for (i = be16_to_cpu(hdr->count)-1; i >= 0; entry++, i--) { 2089 for (i = ichdr.count - 1; i >= 0; entry++, i--) {
1874 ASSERT(be16_to_cpu(entry->nameidx) >= 2090 ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused);
1875 be16_to_cpu(hdr->firstused));
1876 ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp)); 2091 ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp));
1877 2092
1878 if (be16_to_cpu(entry->nameidx) < tmp) 2093 if (be16_to_cpu(entry->nameidx) < tmp)
1879 tmp = be16_to_cpu(entry->nameidx); 2094 tmp = be16_to_cpu(entry->nameidx);
1880 } 2095 }
1881 hdr->firstused = cpu_to_be16(tmp); 2096 ichdr.firstused = tmp;
1882 if (!hdr->firstused) { 2097 if (!ichdr.firstused)
1883 hdr->firstused = cpu_to_be16( 2098 ichdr.firstused = tmp - XFS_ATTR_LEAF_NAME_ALIGN;
1884 tmp - XFS_ATTR_LEAF_NAME_ALIGN);
1885 }
1886 } else { 2099 } else {
1887 hdr->holes = 1; /* mark as needing compaction */ 2100 ichdr.holes = 1; /* mark as needing compaction */
1888 } 2101 }
2102 xfs_attr3_leaf_hdr_to_disk(leaf, &ichdr);
1889 xfs_trans_log_buf(args->trans, bp, 2103 xfs_trans_log_buf(args->trans, bp,
1890 XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); 2104 XFS_DA_LOGRANGE(leaf, &leaf->hdr,
2105 xfs_attr3_leaf_hdr_size(leaf)));
1891 2106
1892 /* 2107 /*
1893 * Check if leaf is less than 50% full, caller may want to 2108 * Check if leaf is less than 50% full, caller may want to
1894 * "join" the leaf with a sibling if so. 2109 * "join" the leaf with a sibling if so.
1895 */ 2110 */
1896 tmp = sizeof(xfs_attr_leaf_hdr_t); 2111 tmp = ichdr.usedbytes + xfs_attr3_leaf_hdr_size(leaf) +
1897 tmp += be16_to_cpu(leaf->hdr.count) * sizeof(xfs_attr_leaf_entry_t); 2112 ichdr.count * sizeof(xfs_attr_leaf_entry_t);
1898 tmp += be16_to_cpu(leaf->hdr.usedbytes); 2113
1899 return(tmp < mp->m_attr_magicpct); /* leaf is < 37% full */ 2114 return tmp < mp->m_attr_magicpct; /* leaf is < 37% full */
1900} 2115}
1901 2116
1902/* 2117/*
1903 * Move all the attribute list entries from drop_leaf into save_leaf. 2118 * Move all the attribute list entries from drop_leaf into save_leaf.
1904 */ 2119 */
1905void 2120void
1906xfs_attr_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, 2121xfs_attr3_leaf_unbalance(
1907 xfs_da_state_blk_t *save_blk) 2122 struct xfs_da_state *state,
2123 struct xfs_da_state_blk *drop_blk,
2124 struct xfs_da_state_blk *save_blk)
1908{ 2125{
1909 xfs_attr_leafblock_t *drop_leaf, *save_leaf, *tmp_leaf; 2126 struct xfs_attr_leafblock *drop_leaf = drop_blk->bp->b_addr;
1910 xfs_attr_leaf_hdr_t *drop_hdr, *save_hdr, *tmp_hdr; 2127 struct xfs_attr_leafblock *save_leaf = save_blk->bp->b_addr;
1911 xfs_mount_t *mp; 2128 struct xfs_attr3_icleaf_hdr drophdr;
1912 char *tmpbuffer; 2129 struct xfs_attr3_icleaf_hdr savehdr;
2130 struct xfs_attr_leaf_entry *entry;
2131 struct xfs_mount *mp = state->mp;
1913 2132
1914 trace_xfs_attr_leaf_unbalance(state->args); 2133 trace_xfs_attr_leaf_unbalance(state->args);
1915 2134
1916 /*
1917 * Set up environment.
1918 */
1919 mp = state->mp;
1920 ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC);
1921 ASSERT(save_blk->magic == XFS_ATTR_LEAF_MAGIC);
1922 drop_leaf = drop_blk->bp->b_addr; 2135 drop_leaf = drop_blk->bp->b_addr;
1923 save_leaf = save_blk->bp->b_addr; 2136 save_leaf = save_blk->bp->b_addr;
1924 ASSERT(drop_leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 2137 xfs_attr3_leaf_hdr_from_disk(&drophdr, drop_leaf);
1925 ASSERT(save_leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 2138 xfs_attr3_leaf_hdr_from_disk(&savehdr, save_leaf);
1926 drop_hdr = &drop_leaf->hdr; 2139 entry = xfs_attr3_leaf_entryp(drop_leaf);
1927 save_hdr = &save_leaf->hdr;
1928 2140
1929 /* 2141 /*
1930 * Save last hashval from dying block for later Btree fixup. 2142 * Save last hashval from dying block for later Btree fixup.
1931 */ 2143 */
1932 drop_blk->hashval = be32_to_cpu( 2144 drop_blk->hashval = be32_to_cpu(entry[drophdr.count - 1].hashval);
1933 drop_leaf->entries[be16_to_cpu(drop_leaf->hdr.count)-1].hashval);
1934 2145
1935 /* 2146 /*
1936 * Check if we need a temp buffer, or can we do it in place. 2147 * Check if we need a temp buffer, or can we do it in place.
1937 * Note that we don't check "leaf" for holes because we will 2148 * Note that we don't check "leaf" for holes because we will
1938 * always be dropping it, toosmall() decided that for us already. 2149 * always be dropping it, toosmall() decided that for us already.
1939 */ 2150 */
1940 if (save_hdr->holes == 0) { 2151 if (savehdr.holes == 0) {
1941 /* 2152 /*
1942 * dest leaf has no holes, so we add there. May need 2153 * dest leaf has no holes, so we add there. May need
1943 * to make some room in the entry array. 2154 * to make some room in the entry array.
1944 */ 2155 */
1945 if (xfs_attr_leaf_order(save_blk->bp, drop_blk->bp)) { 2156 if (xfs_attr3_leaf_order(save_blk->bp, &savehdr,
1946 xfs_attr_leaf_moveents(drop_leaf, 0, save_leaf, 0, 2157 drop_blk->bp, &drophdr)) {
1947 be16_to_cpu(drop_hdr->count), mp); 2158 xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0,
2159 save_leaf, &savehdr, 0,
2160 drophdr.count, mp);
1948 } else { 2161 } else {
1949 xfs_attr_leaf_moveents(drop_leaf, 0, save_leaf, 2162 xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0,
1950 be16_to_cpu(save_hdr->count), 2163 save_leaf, &savehdr,
1951 be16_to_cpu(drop_hdr->count), mp); 2164 savehdr.count, drophdr.count, mp);
1952 } 2165 }
1953 } else { 2166 } else {
1954 /* 2167 /*
1955 * Destination has holes, so we make a temporary copy 2168 * Destination has holes, so we make a temporary copy
1956 * of the leaf and add them both to that. 2169 * of the leaf and add them both to that.
1957 */ 2170 */
1958 tmpbuffer = kmem_alloc(state->blocksize, KM_SLEEP); 2171 struct xfs_attr_leafblock *tmp_leaf;
1959 ASSERT(tmpbuffer != NULL); 2172 struct xfs_attr3_icleaf_hdr tmphdr;
1960 memset(tmpbuffer, 0, state->blocksize); 2173
1961 tmp_leaf = (xfs_attr_leafblock_t *)tmpbuffer; 2174 tmp_leaf = kmem_alloc(state->blocksize, KM_SLEEP);
1962 tmp_hdr = &tmp_leaf->hdr; 2175 memset(tmp_leaf, 0, state->blocksize);
1963 tmp_hdr->info = save_hdr->info; /* struct copy */ 2176 memset(&tmphdr, 0, sizeof(tmphdr));
1964 tmp_hdr->count = 0; 2177
1965 tmp_hdr->firstused = cpu_to_be16(state->blocksize); 2178 tmphdr.magic = savehdr.magic;
1966 if (!tmp_hdr->firstused) { 2179 tmphdr.forw = savehdr.forw;
1967 tmp_hdr->firstused = cpu_to_be16( 2180 tmphdr.back = savehdr.back;
1968 state->blocksize - XFS_ATTR_LEAF_NAME_ALIGN); 2181 tmphdr.firstused = state->blocksize;
1969 } 2182 if (xfs_attr3_leaf_order(save_blk->bp, &savehdr,
1970 tmp_hdr->usedbytes = 0; 2183 drop_blk->bp, &drophdr)) {
1971 if (xfs_attr_leaf_order(save_blk->bp, drop_blk->bp)) { 2184 xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0,
1972 xfs_attr_leaf_moveents(drop_leaf, 0, tmp_leaf, 0, 2185 tmp_leaf, &tmphdr, 0,
1973 be16_to_cpu(drop_hdr->count), mp); 2186 drophdr.count, mp);
1974 xfs_attr_leaf_moveents(save_leaf, 0, tmp_leaf, 2187 xfs_attr3_leaf_moveents(save_leaf, &savehdr, 0,
1975 be16_to_cpu(tmp_leaf->hdr.count), 2188 tmp_leaf, &tmphdr, tmphdr.count,
1976 be16_to_cpu(save_hdr->count), mp); 2189 savehdr.count, mp);
1977 } else { 2190 } else {
1978 xfs_attr_leaf_moveents(save_leaf, 0, tmp_leaf, 0, 2191 xfs_attr3_leaf_moveents(save_leaf, &savehdr, 0,
1979 be16_to_cpu(save_hdr->count), mp); 2192 tmp_leaf, &tmphdr, 0,
1980 xfs_attr_leaf_moveents(drop_leaf, 0, tmp_leaf, 2193 savehdr.count, mp);
1981 be16_to_cpu(tmp_leaf->hdr.count), 2194 xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0,
1982 be16_to_cpu(drop_hdr->count), mp); 2195 tmp_leaf, &tmphdr, tmphdr.count,
2196 drophdr.count, mp);
1983 } 2197 }
1984 memcpy((char *)save_leaf, (char *)tmp_leaf, state->blocksize); 2198 memcpy(save_leaf, tmp_leaf, state->blocksize);
1985 kmem_free(tmpbuffer); 2199 savehdr = tmphdr; /* struct copy */
2200 kmem_free(tmp_leaf);
1986 } 2201 }
1987 2202
2203 xfs_attr3_leaf_hdr_to_disk(save_leaf, &savehdr);
1988 xfs_trans_log_buf(state->args->trans, save_blk->bp, 0, 2204 xfs_trans_log_buf(state->args->trans, save_blk->bp, 0,
1989 state->blocksize - 1); 2205 state->blocksize - 1);
1990 2206
1991 /* 2207 /*
1992 * Copy out last hashval in each block for B-tree code. 2208 * Copy out last hashval in each block for B-tree code.
1993 */ 2209 */
1994 save_blk->hashval = be32_to_cpu( 2210 entry = xfs_attr3_leaf_entryp(save_leaf);
1995 save_leaf->entries[be16_to_cpu(save_leaf->hdr.count)-1].hashval); 2211 save_blk->hashval = be32_to_cpu(entry[savehdr.count - 1].hashval);
1996} 2212}
1997 2213
1998/*======================================================================== 2214/*========================================================================
@@ -2013,31 +2229,33 @@ xfs_attr_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
2013 * Don't change the args->value unless we find the attribute. 2229 * Don't change the args->value unless we find the attribute.
2014 */ 2230 */
2015int 2231int
2016xfs_attr_leaf_lookup_int( 2232xfs_attr3_leaf_lookup_int(
2017 struct xfs_buf *bp, 2233 struct xfs_buf *bp,
2018 xfs_da_args_t *args) 2234 struct xfs_da_args *args)
2019{ 2235{
2020 xfs_attr_leafblock_t *leaf; 2236 struct xfs_attr_leafblock *leaf;
2021 xfs_attr_leaf_entry_t *entry; 2237 struct xfs_attr3_icleaf_hdr ichdr;
2022 xfs_attr_leaf_name_local_t *name_loc; 2238 struct xfs_attr_leaf_entry *entry;
2023 xfs_attr_leaf_name_remote_t *name_rmt; 2239 struct xfs_attr_leaf_entry *entries;
2024 int probe, span; 2240 struct xfs_attr_leaf_name_local *name_loc;
2025 xfs_dahash_t hashval; 2241 struct xfs_attr_leaf_name_remote *name_rmt;
2242 xfs_dahash_t hashval;
2243 int probe;
2244 int span;
2026 2245
2027 trace_xfs_attr_leaf_lookup(args); 2246 trace_xfs_attr_leaf_lookup(args);
2028 2247
2029 leaf = bp->b_addr; 2248 leaf = bp->b_addr;
2030 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 2249 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
2031 ASSERT(be16_to_cpu(leaf->hdr.count) 2250 entries = xfs_attr3_leaf_entryp(leaf);
2032 < (XFS_LBSIZE(args->dp->i_mount)/8)); 2251 ASSERT(ichdr.count < XFS_LBSIZE(args->dp->i_mount) / 8);
2033 2252
2034 /* 2253 /*
2035 * Binary search. (note: small blocks will skip this loop) 2254 * Binary search. (note: small blocks will skip this loop)
2036 */ 2255 */
2037 hashval = args->hashval; 2256 hashval = args->hashval;
2038 probe = span = be16_to_cpu(leaf->hdr.count) / 2; 2257 probe = span = ichdr.count / 2;
2039 for (entry = &leaf->entries[probe]; span > 4; 2258 for (entry = &entries[probe]; span > 4; entry = &entries[probe]) {
2040 entry = &leaf->entries[probe]) {
2041 span /= 2; 2259 span /= 2;
2042 if (be32_to_cpu(entry->hashval) < hashval) 2260 if (be32_to_cpu(entry->hashval) < hashval)
2043 probe += span; 2261 probe += span;
@@ -2046,35 +2264,31 @@ xfs_attr_leaf_lookup_int(
2046 else 2264 else
2047 break; 2265 break;
2048 } 2266 }
2049 ASSERT((probe >= 0) && 2267 ASSERT(probe >= 0 && (!ichdr.count || probe < ichdr.count));
2050 (!leaf->hdr.count 2268 ASSERT(span <= 4 || be32_to_cpu(entry->hashval) == hashval);
2051 || (probe < be16_to_cpu(leaf->hdr.count))));
2052 ASSERT((span <= 4) || (be32_to_cpu(entry->hashval) == hashval));
2053 2269
2054 /* 2270 /*
2055 * Since we may have duplicate hashval's, find the first matching 2271 * Since we may have duplicate hashval's, find the first matching
2056 * hashval in the leaf. 2272 * hashval in the leaf.
2057 */ 2273 */
2058 while ((probe > 0) && (be32_to_cpu(entry->hashval) >= hashval)) { 2274 while (probe > 0 && be32_to_cpu(entry->hashval) >= hashval) {
2059 entry--; 2275 entry--;
2060 probe--; 2276 probe--;
2061 } 2277 }
2062 while ((probe < be16_to_cpu(leaf->hdr.count)) && 2278 while (probe < ichdr.count &&
2063 (be32_to_cpu(entry->hashval) < hashval)) { 2279 be32_to_cpu(entry->hashval) < hashval) {
2064 entry++; 2280 entry++;
2065 probe++; 2281 probe++;
2066 } 2282 }
2067 if ((probe == be16_to_cpu(leaf->hdr.count)) || 2283 if (probe == ichdr.count || be32_to_cpu(entry->hashval) != hashval) {
2068 (be32_to_cpu(entry->hashval) != hashval)) {
2069 args->index = probe; 2284 args->index = probe;
2070 return(XFS_ERROR(ENOATTR)); 2285 return XFS_ERROR(ENOATTR);
2071 } 2286 }
2072 2287
2073 /* 2288 /*
2074 * Duplicate keys may be present, so search all of them for a match. 2289 * Duplicate keys may be present, so search all of them for a match.
2075 */ 2290 */
2076 for ( ; (probe < be16_to_cpu(leaf->hdr.count)) && 2291 for (; probe < ichdr.count && (be32_to_cpu(entry->hashval) == hashval);
2077 (be32_to_cpu(entry->hashval) == hashval);
2078 entry++, probe++) { 2292 entry++, probe++) {
2079/* 2293/*
2080 * GROT: Add code to remove incomplete entries. 2294 * GROT: Add code to remove incomplete entries.
@@ -2088,21 +2302,22 @@ xfs_attr_leaf_lookup_int(
2088 continue; 2302 continue;
2089 } 2303 }
2090 if (entry->flags & XFS_ATTR_LOCAL) { 2304 if (entry->flags & XFS_ATTR_LOCAL) {
2091 name_loc = xfs_attr_leaf_name_local(leaf, probe); 2305 name_loc = xfs_attr3_leaf_name_local(leaf, probe);
2092 if (name_loc->namelen != args->namelen) 2306 if (name_loc->namelen != args->namelen)
2093 continue; 2307 continue;
2094 if (memcmp(args->name, (char *)name_loc->nameval, args->namelen) != 0) 2308 if (memcmp(args->name, name_loc->nameval,
2309 args->namelen) != 0)
2095 continue; 2310 continue;
2096 if (!xfs_attr_namesp_match(args->flags, entry->flags)) 2311 if (!xfs_attr_namesp_match(args->flags, entry->flags))
2097 continue; 2312 continue;
2098 args->index = probe; 2313 args->index = probe;
2099 return(XFS_ERROR(EEXIST)); 2314 return XFS_ERROR(EEXIST);
2100 } else { 2315 } else {
2101 name_rmt = xfs_attr_leaf_name_remote(leaf, probe); 2316 name_rmt = xfs_attr3_leaf_name_remote(leaf, probe);
2102 if (name_rmt->namelen != args->namelen) 2317 if (name_rmt->namelen != args->namelen)
2103 continue; 2318 continue;
2104 if (memcmp(args->name, (char *)name_rmt->name, 2319 if (memcmp(args->name, name_rmt->name,
2105 args->namelen) != 0) 2320 args->namelen) != 0)
2106 continue; 2321 continue;
2107 if (!xfs_attr_namesp_match(args->flags, entry->flags)) 2322 if (!xfs_attr_namesp_match(args->flags, entry->flags))
2108 continue; 2323 continue;
@@ -2110,11 +2325,11 @@ xfs_attr_leaf_lookup_int(
2110 args->rmtblkno = be32_to_cpu(name_rmt->valueblk); 2325 args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
2111 args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, 2326 args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount,
2112 be32_to_cpu(name_rmt->valuelen)); 2327 be32_to_cpu(name_rmt->valuelen));
2113 return(XFS_ERROR(EEXIST)); 2328 return XFS_ERROR(EEXIST);
2114 } 2329 }
2115 } 2330 }
2116 args->index = probe; 2331 args->index = probe;
2117 return(XFS_ERROR(ENOATTR)); 2332 return XFS_ERROR(ENOATTR);
2118} 2333}
2119 2334
2120/* 2335/*
@@ -2122,40 +2337,40 @@ xfs_attr_leaf_lookup_int(
2122 * list structure. 2337 * list structure.
2123 */ 2338 */
2124int 2339int
2125xfs_attr_leaf_getvalue( 2340xfs_attr3_leaf_getvalue(
2126 struct xfs_buf *bp, 2341 struct xfs_buf *bp,
2127 xfs_da_args_t *args) 2342 struct xfs_da_args *args)
2128{ 2343{
2129 int valuelen; 2344 struct xfs_attr_leafblock *leaf;
2130 xfs_attr_leafblock_t *leaf; 2345 struct xfs_attr3_icleaf_hdr ichdr;
2131 xfs_attr_leaf_entry_t *entry; 2346 struct xfs_attr_leaf_entry *entry;
2132 xfs_attr_leaf_name_local_t *name_loc; 2347 struct xfs_attr_leaf_name_local *name_loc;
2133 xfs_attr_leaf_name_remote_t *name_rmt; 2348 struct xfs_attr_leaf_name_remote *name_rmt;
2349 int valuelen;
2134 2350
2135 leaf = bp->b_addr; 2351 leaf = bp->b_addr;
2136 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 2352 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
2137 ASSERT(be16_to_cpu(leaf->hdr.count) 2353 ASSERT(ichdr.count < XFS_LBSIZE(args->dp->i_mount) / 8);
2138 < (XFS_LBSIZE(args->dp->i_mount)/8)); 2354 ASSERT(args->index < ichdr.count);
2139 ASSERT(args->index < be16_to_cpu(leaf->hdr.count));
2140 2355
2141 entry = &leaf->entries[args->index]; 2356 entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
2142 if (entry->flags & XFS_ATTR_LOCAL) { 2357 if (entry->flags & XFS_ATTR_LOCAL) {
2143 name_loc = xfs_attr_leaf_name_local(leaf, args->index); 2358 name_loc = xfs_attr3_leaf_name_local(leaf, args->index);
2144 ASSERT(name_loc->namelen == args->namelen); 2359 ASSERT(name_loc->namelen == args->namelen);
2145 ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0); 2360 ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0);
2146 valuelen = be16_to_cpu(name_loc->valuelen); 2361 valuelen = be16_to_cpu(name_loc->valuelen);
2147 if (args->flags & ATTR_KERNOVAL) { 2362 if (args->flags & ATTR_KERNOVAL) {
2148 args->valuelen = valuelen; 2363 args->valuelen = valuelen;
2149 return(0); 2364 return 0;
2150 } 2365 }
2151 if (args->valuelen < valuelen) { 2366 if (args->valuelen < valuelen) {
2152 args->valuelen = valuelen; 2367 args->valuelen = valuelen;
2153 return(XFS_ERROR(ERANGE)); 2368 return XFS_ERROR(ERANGE);
2154 } 2369 }
2155 args->valuelen = valuelen; 2370 args->valuelen = valuelen;
2156 memcpy(args->value, &name_loc->nameval[args->namelen], valuelen); 2371 memcpy(args->value, &name_loc->nameval[args->namelen], valuelen);
2157 } else { 2372 } else {
2158 name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); 2373 name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
2159 ASSERT(name_rmt->namelen == args->namelen); 2374 ASSERT(name_rmt->namelen == args->namelen);
2160 ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0); 2375 ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0);
2161 valuelen = be32_to_cpu(name_rmt->valuelen); 2376 valuelen = be32_to_cpu(name_rmt->valuelen);
@@ -2163,15 +2378,15 @@ xfs_attr_leaf_getvalue(
2163 args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, valuelen); 2378 args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, valuelen);
2164 if (args->flags & ATTR_KERNOVAL) { 2379 if (args->flags & ATTR_KERNOVAL) {
2165 args->valuelen = valuelen; 2380 args->valuelen = valuelen;
2166 return(0); 2381 return 0;
2167 } 2382 }
2168 if (args->valuelen < valuelen) { 2383 if (args->valuelen < valuelen) {
2169 args->valuelen = valuelen; 2384 args->valuelen = valuelen;
2170 return(XFS_ERROR(ERANGE)); 2385 return XFS_ERROR(ERANGE);
2171 } 2386 }
2172 args->valuelen = valuelen; 2387 args->valuelen = valuelen;
2173 } 2388 }
2174 return(0); 2389 return 0;
2175} 2390}
2176 2391
2177/*======================================================================== 2392/*========================================================================
@@ -2184,13 +2399,21 @@ xfs_attr_leaf_getvalue(
2184 */ 2399 */
2185/*ARGSUSED*/ 2400/*ARGSUSED*/
2186STATIC void 2401STATIC void
2187xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s, 2402xfs_attr3_leaf_moveents(
2188 xfs_attr_leafblock_t *leaf_d, int start_d, 2403 struct xfs_attr_leafblock *leaf_s,
2189 int count, xfs_mount_t *mp) 2404 struct xfs_attr3_icleaf_hdr *ichdr_s,
2405 int start_s,
2406 struct xfs_attr_leafblock *leaf_d,
2407 struct xfs_attr3_icleaf_hdr *ichdr_d,
2408 int start_d,
2409 int count,
2410 struct xfs_mount *mp)
2190{ 2411{
2191 xfs_attr_leaf_hdr_t *hdr_s, *hdr_d; 2412 struct xfs_attr_leaf_entry *entry_s;
2192 xfs_attr_leaf_entry_t *entry_s, *entry_d; 2413 struct xfs_attr_leaf_entry *entry_d;
2193 int desti, tmp, i; 2414 int desti;
2415 int tmp;
2416 int i;
2194 2417
2195 /* 2418 /*
2196 * Check for nothing to do. 2419 * Check for nothing to do.
@@ -2201,45 +2424,41 @@ xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s,
2201 /* 2424 /*
2202 * Set up environment. 2425 * Set up environment.
2203 */ 2426 */
2204 ASSERT(leaf_s->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 2427 ASSERT(ichdr_s->magic == XFS_ATTR_LEAF_MAGIC ||
2205 ASSERT(leaf_d->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 2428 ichdr_s->magic == XFS_ATTR3_LEAF_MAGIC);
2206 hdr_s = &leaf_s->hdr; 2429 ASSERT(ichdr_s->magic == ichdr_d->magic);
2207 hdr_d = &leaf_d->hdr; 2430 ASSERT(ichdr_s->count > 0 && ichdr_s->count < XFS_LBSIZE(mp) / 8);
2208 ASSERT((be16_to_cpu(hdr_s->count) > 0) && 2431 ASSERT(ichdr_s->firstused >= (ichdr_s->count * sizeof(*entry_s))
2209 (be16_to_cpu(hdr_s->count) < (XFS_LBSIZE(mp)/8))); 2432 + xfs_attr3_leaf_hdr_size(leaf_s));
2210 ASSERT(be16_to_cpu(hdr_s->firstused) >= 2433 ASSERT(ichdr_d->count < XFS_LBSIZE(mp) / 8);
2211 ((be16_to_cpu(hdr_s->count) 2434 ASSERT(ichdr_d->firstused >= (ichdr_d->count * sizeof(*entry_d))
2212 * sizeof(*entry_s))+sizeof(*hdr_s))); 2435 + xfs_attr3_leaf_hdr_size(leaf_d));
2213 ASSERT(be16_to_cpu(hdr_d->count) < (XFS_LBSIZE(mp)/8)); 2436
2214 ASSERT(be16_to_cpu(hdr_d->firstused) >= 2437 ASSERT(start_s < ichdr_s->count);
2215 ((be16_to_cpu(hdr_d->count) 2438 ASSERT(start_d <= ichdr_d->count);
2216 * sizeof(*entry_d))+sizeof(*hdr_d))); 2439 ASSERT(count <= ichdr_s->count);
2217 2440
2218 ASSERT(start_s < be16_to_cpu(hdr_s->count));
2219 ASSERT(start_d <= be16_to_cpu(hdr_d->count));
2220 ASSERT(count <= be16_to_cpu(hdr_s->count));
2221 2441
2222 /* 2442 /*
2223 * Move the entries in the destination leaf up to make a hole? 2443 * Move the entries in the destination leaf up to make a hole?
2224 */ 2444 */
2225 if (start_d < be16_to_cpu(hdr_d->count)) { 2445 if (start_d < ichdr_d->count) {
2226 tmp = be16_to_cpu(hdr_d->count) - start_d; 2446 tmp = ichdr_d->count - start_d;
2227 tmp *= sizeof(xfs_attr_leaf_entry_t); 2447 tmp *= sizeof(xfs_attr_leaf_entry_t);
2228 entry_s = &leaf_d->entries[start_d]; 2448 entry_s = &xfs_attr3_leaf_entryp(leaf_d)[start_d];
2229 entry_d = &leaf_d->entries[start_d + count]; 2449 entry_d = &xfs_attr3_leaf_entryp(leaf_d)[start_d + count];
2230 memmove((char *)entry_d, (char *)entry_s, tmp); 2450 memmove(entry_d, entry_s, tmp);
2231 } 2451 }
2232 2452
2233 /* 2453 /*
2234 * Copy all entry's in the same (sorted) order, 2454 * Copy all entry's in the same (sorted) order,
2235 * but allocate attribute info packed and in sequence. 2455 * but allocate attribute info packed and in sequence.
2236 */ 2456 */
2237 entry_s = &leaf_s->entries[start_s]; 2457 entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s];
2238 entry_d = &leaf_d->entries[start_d]; 2458 entry_d = &xfs_attr3_leaf_entryp(leaf_d)[start_d];
2239 desti = start_d; 2459 desti = start_d;
2240 for (i = 0; i < count; entry_s++, entry_d++, desti++, i++) { 2460 for (i = 0; i < count; entry_s++, entry_d++, desti++, i++) {
2241 ASSERT(be16_to_cpu(entry_s->nameidx) 2461 ASSERT(be16_to_cpu(entry_s->nameidx) >= ichdr_s->firstused);
2242 >= be16_to_cpu(hdr_s->firstused));
2243 tmp = xfs_attr_leaf_entsize(leaf_s, start_s + i); 2462 tmp = xfs_attr_leaf_entsize(leaf_s, start_s + i);
2244#ifdef GROT 2463#ifdef GROT
2245 /* 2464 /*
@@ -2248,36 +2467,34 @@ xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s,
2248 * off for 6.2, should be revisited later. 2467 * off for 6.2, should be revisited later.
2249 */ 2468 */
2250 if (entry_s->flags & XFS_ATTR_INCOMPLETE) { /* skip partials? */ 2469 if (entry_s->flags & XFS_ATTR_INCOMPLETE) { /* skip partials? */
2251 memset(xfs_attr_leaf_name(leaf_s, start_s + i), 0, tmp); 2470 memset(xfs_attr3_leaf_name(leaf_s, start_s + i), 0, tmp);
2252 be16_add_cpu(&hdr_s->usedbytes, -tmp); 2471 ichdr_s->usedbytes -= tmp;
2253 be16_add_cpu(&hdr_s->count, -1); 2472 ichdr_s->count -= 1;
2254 entry_d--; /* to compensate for ++ in loop hdr */ 2473 entry_d--; /* to compensate for ++ in loop hdr */
2255 desti--; 2474 desti--;
2256 if ((start_s + i) < offset) 2475 if ((start_s + i) < offset)
2257 result++; /* insertion index adjustment */ 2476 result++; /* insertion index adjustment */
2258 } else { 2477 } else {
2259#endif /* GROT */ 2478#endif /* GROT */
2260 be16_add_cpu(&hdr_d->firstused, -tmp); 2479 ichdr_d->firstused -= tmp;
2261 /* both on-disk, don't endian flip twice */ 2480 /* both on-disk, don't endian flip twice */
2262 entry_d->hashval = entry_s->hashval; 2481 entry_d->hashval = entry_s->hashval;
2263 /* both on-disk, don't endian flip twice */ 2482 entry_d->nameidx = cpu_to_be16(ichdr_d->firstused);
2264 entry_d->nameidx = hdr_d->firstused;
2265 entry_d->flags = entry_s->flags; 2483 entry_d->flags = entry_s->flags;
2266 ASSERT(be16_to_cpu(entry_d->nameidx) + tmp 2484 ASSERT(be16_to_cpu(entry_d->nameidx) + tmp
2267 <= XFS_LBSIZE(mp)); 2485 <= XFS_LBSIZE(mp));
2268 memmove(xfs_attr_leaf_name(leaf_d, desti), 2486 memmove(xfs_attr3_leaf_name(leaf_d, desti),
2269 xfs_attr_leaf_name(leaf_s, start_s + i), tmp); 2487 xfs_attr3_leaf_name(leaf_s, start_s + i), tmp);
2270 ASSERT(be16_to_cpu(entry_s->nameidx) + tmp 2488 ASSERT(be16_to_cpu(entry_s->nameidx) + tmp
2271 <= XFS_LBSIZE(mp)); 2489 <= XFS_LBSIZE(mp));
2272 memset(xfs_attr_leaf_name(leaf_s, start_s + i), 0, tmp); 2490 memset(xfs_attr3_leaf_name(leaf_s, start_s + i), 0, tmp);
2273 be16_add_cpu(&hdr_s->usedbytes, -tmp); 2491 ichdr_s->usedbytes -= tmp;
2274 be16_add_cpu(&hdr_d->usedbytes, tmp); 2492 ichdr_d->usedbytes += tmp;
2275 be16_add_cpu(&hdr_s->count, -1); 2493 ichdr_s->count -= 1;
2276 be16_add_cpu(&hdr_d->count, 1); 2494 ichdr_d->count += 1;
2277 tmp = be16_to_cpu(hdr_d->count) 2495 tmp = ichdr_d->count * sizeof(xfs_attr_leaf_entry_t)
2278 * sizeof(xfs_attr_leaf_entry_t) 2496 + xfs_attr3_leaf_hdr_size(leaf_d);
2279 + sizeof(xfs_attr_leaf_hdr_t); 2497 ASSERT(ichdr_d->firstused >= tmp);
2280 ASSERT(be16_to_cpu(hdr_d->firstused) >= tmp);
2281#ifdef GROT 2498#ifdef GROT
2282 } 2499 }
2283#endif /* GROT */ 2500#endif /* GROT */
@@ -2286,71 +2503,40 @@ xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s,
2286 /* 2503 /*
2287 * Zero out the entries we just copied. 2504 * Zero out the entries we just copied.
2288 */ 2505 */
2289 if (start_s == be16_to_cpu(hdr_s->count)) { 2506 if (start_s == ichdr_s->count) {
2290 tmp = count * sizeof(xfs_attr_leaf_entry_t); 2507 tmp = count * sizeof(xfs_attr_leaf_entry_t);
2291 entry_s = &leaf_s->entries[start_s]; 2508 entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s];
2292 ASSERT(((char *)entry_s + tmp) <= 2509 ASSERT(((char *)entry_s + tmp) <=
2293 ((char *)leaf_s + XFS_LBSIZE(mp))); 2510 ((char *)leaf_s + XFS_LBSIZE(mp)));
2294 memset((char *)entry_s, 0, tmp); 2511 memset(entry_s, 0, tmp);
2295 } else { 2512 } else {
2296 /* 2513 /*
2297 * Move the remaining entries down to fill the hole, 2514 * Move the remaining entries down to fill the hole,
2298 * then zero the entries at the top. 2515 * then zero the entries at the top.
2299 */ 2516 */
2300 tmp = be16_to_cpu(hdr_s->count) - count; 2517 tmp = (ichdr_s->count - count) * sizeof(xfs_attr_leaf_entry_t);
2301 tmp *= sizeof(xfs_attr_leaf_entry_t); 2518 entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s + count];
2302 entry_s = &leaf_s->entries[start_s + count]; 2519 entry_d = &xfs_attr3_leaf_entryp(leaf_s)[start_s];
2303 entry_d = &leaf_s->entries[start_s]; 2520 memmove(entry_d, entry_s, tmp);
2304 memmove((char *)entry_d, (char *)entry_s, tmp);
2305 2521
2306 tmp = count * sizeof(xfs_attr_leaf_entry_t); 2522 tmp = count * sizeof(xfs_attr_leaf_entry_t);
2307 entry_s = &leaf_s->entries[be16_to_cpu(hdr_s->count)]; 2523 entry_s = &xfs_attr3_leaf_entryp(leaf_s)[ichdr_s->count];
2308 ASSERT(((char *)entry_s + tmp) <= 2524 ASSERT(((char *)entry_s + tmp) <=
2309 ((char *)leaf_s + XFS_LBSIZE(mp))); 2525 ((char *)leaf_s + XFS_LBSIZE(mp)));
2310 memset((char *)entry_s, 0, tmp); 2526 memset(entry_s, 0, tmp);
2311 } 2527 }
2312 2528
2313 /* 2529 /*
2314 * Fill in the freemap information 2530 * Fill in the freemap information
2315 */ 2531 */
2316 hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t)); 2532 ichdr_d->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_d);
2317 be16_add_cpu(&hdr_d->freemap[0].base, be16_to_cpu(hdr_d->count) * 2533 ichdr_d->freemap[0].base += ichdr_d->count * sizeof(xfs_attr_leaf_entry_t);
2318 sizeof(xfs_attr_leaf_entry_t)); 2534 ichdr_d->freemap[0].size = ichdr_d->firstused - ichdr_d->freemap[0].base;
2319 hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused) 2535 ichdr_d->freemap[1].base = 0;
2320 - be16_to_cpu(hdr_d->freemap[0].base)); 2536 ichdr_d->freemap[2].base = 0;
2321 hdr_d->freemap[1].base = 0; 2537 ichdr_d->freemap[1].size = 0;
2322 hdr_d->freemap[2].base = 0; 2538 ichdr_d->freemap[2].size = 0;
2323 hdr_d->freemap[1].size = 0; 2539 ichdr_s->holes = 1; /* leaf may not be compact */
2324 hdr_d->freemap[2].size = 0;
2325 hdr_s->holes = 1; /* leaf may not be compact */
2326}
2327
2328/*
2329 * Compare two leaf blocks "order".
2330 * Return 0 unless leaf2 should go before leaf1.
2331 */
2332int
2333xfs_attr_leaf_order(
2334 struct xfs_buf *leaf1_bp,
2335 struct xfs_buf *leaf2_bp)
2336{
2337 xfs_attr_leafblock_t *leaf1, *leaf2;
2338
2339 leaf1 = leaf1_bp->b_addr;
2340 leaf2 = leaf2_bp->b_addr;
2341 ASSERT((leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)) &&
2342 (leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)));
2343 if ((be16_to_cpu(leaf1->hdr.count) > 0) &&
2344 (be16_to_cpu(leaf2->hdr.count) > 0) &&
2345 ((be32_to_cpu(leaf2->entries[0].hashval) <
2346 be32_to_cpu(leaf1->entries[0].hashval)) ||
2347 (be32_to_cpu(leaf2->entries[
2348 be16_to_cpu(leaf2->hdr.count)-1].hashval) <
2349 be32_to_cpu(leaf1->entries[
2350 be16_to_cpu(leaf1->hdr.count)-1].hashval)))) {
2351 return(1);
2352 }
2353 return(0);
2354} 2540}
2355 2541
2356/* 2542/*
@@ -2361,15 +2547,16 @@ xfs_attr_leaf_lasthash(
2361 struct xfs_buf *bp, 2547 struct xfs_buf *bp,
2362 int *count) 2548 int *count)
2363{ 2549{
2364 xfs_attr_leafblock_t *leaf; 2550 struct xfs_attr3_icleaf_hdr ichdr;
2551 struct xfs_attr_leaf_entry *entries;
2365 2552
2366 leaf = bp->b_addr; 2553 xfs_attr3_leaf_hdr_from_disk(&ichdr, bp->b_addr);
2367 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 2554 entries = xfs_attr3_leaf_entryp(bp->b_addr);
2368 if (count) 2555 if (count)
2369 *count = be16_to_cpu(leaf->hdr.count); 2556 *count = ichdr.count;
2370 if (!leaf->hdr.count) 2557 if (!ichdr.count)
2371 return(0); 2558 return 0;
2372 return be32_to_cpu(leaf->entries[be16_to_cpu(leaf->hdr.count)-1].hashval); 2559 return be32_to_cpu(entries[ichdr.count - 1].hashval);
2373} 2560}
2374 2561
2375/* 2562/*
@@ -2379,20 +2566,21 @@ xfs_attr_leaf_lasthash(
2379STATIC int 2566STATIC int
2380xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index) 2567xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index)
2381{ 2568{
2569 struct xfs_attr_leaf_entry *entries;
2382 xfs_attr_leaf_name_local_t *name_loc; 2570 xfs_attr_leaf_name_local_t *name_loc;
2383 xfs_attr_leaf_name_remote_t *name_rmt; 2571 xfs_attr_leaf_name_remote_t *name_rmt;
2384 int size; 2572 int size;
2385 2573
2386 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 2574 entries = xfs_attr3_leaf_entryp(leaf);
2387 if (leaf->entries[index].flags & XFS_ATTR_LOCAL) { 2575 if (entries[index].flags & XFS_ATTR_LOCAL) {
2388 name_loc = xfs_attr_leaf_name_local(leaf, index); 2576 name_loc = xfs_attr3_leaf_name_local(leaf, index);
2389 size = xfs_attr_leaf_entsize_local(name_loc->namelen, 2577 size = xfs_attr_leaf_entsize_local(name_loc->namelen,
2390 be16_to_cpu(name_loc->valuelen)); 2578 be16_to_cpu(name_loc->valuelen));
2391 } else { 2579 } else {
2392 name_rmt = xfs_attr_leaf_name_remote(leaf, index); 2580 name_rmt = xfs_attr3_leaf_name_remote(leaf, index);
2393 size = xfs_attr_leaf_entsize_remote(name_rmt->namelen); 2581 size = xfs_attr_leaf_entsize_remote(name_rmt->namelen);
2394 } 2582 }
2395 return(size); 2583 return size;
2396} 2584}
2397 2585
2398/* 2586/*
@@ -2417,35 +2605,40 @@ xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int *local)
2417 *local = 0; 2605 *local = 0;
2418 } 2606 }
2419 } 2607 }
2420 return(size); 2608 return size;
2421} 2609}
2422 2610
2423/* 2611/*
2424 * Copy out attribute list entries for attr_list(), for leaf attribute lists. 2612 * Copy out attribute list entries for attr_list(), for leaf attribute lists.
2425 */ 2613 */
2426int 2614int
2427xfs_attr_leaf_list_int( 2615xfs_attr3_leaf_list_int(
2428 struct xfs_buf *bp, 2616 struct xfs_buf *bp,
2429 xfs_attr_list_context_t *context) 2617 struct xfs_attr_list_context *context)
2430{ 2618{
2431 attrlist_cursor_kern_t *cursor; 2619 struct attrlist_cursor_kern *cursor;
2432 xfs_attr_leafblock_t *leaf; 2620 struct xfs_attr_leafblock *leaf;
2433 xfs_attr_leaf_entry_t *entry; 2621 struct xfs_attr3_icleaf_hdr ichdr;
2434 int retval, i; 2622 struct xfs_attr_leaf_entry *entries;
2623 struct xfs_attr_leaf_entry *entry;
2624 int retval;
2625 int i;
2626
2627 trace_xfs_attr_list_leaf(context);
2435 2628
2436 ASSERT(bp != NULL);
2437 leaf = bp->b_addr; 2629 leaf = bp->b_addr;
2630 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
2631 entries = xfs_attr3_leaf_entryp(leaf);
2632
2438 cursor = context->cursor; 2633 cursor = context->cursor;
2439 cursor->initted = 1; 2634 cursor->initted = 1;
2440 2635
2441 trace_xfs_attr_list_leaf(context);
2442
2443 /* 2636 /*
2444 * Re-find our place in the leaf block if this is a new syscall. 2637 * Re-find our place in the leaf block if this is a new syscall.
2445 */ 2638 */
2446 if (context->resynch) { 2639 if (context->resynch) {
2447 entry = &leaf->entries[0]; 2640 entry = &entries[0];
2448 for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { 2641 for (i = 0; i < ichdr.count; entry++, i++) {
2449 if (be32_to_cpu(entry->hashval) == cursor->hashval) { 2642 if (be32_to_cpu(entry->hashval) == cursor->hashval) {
2450 if (cursor->offset == context->dupcnt) { 2643 if (cursor->offset == context->dupcnt) {
2451 context->dupcnt = 0; 2644 context->dupcnt = 0;
@@ -2458,12 +2651,12 @@ xfs_attr_leaf_list_int(
2458 break; 2651 break;
2459 } 2652 }
2460 } 2653 }
2461 if (i == be16_to_cpu(leaf->hdr.count)) { 2654 if (i == ichdr.count) {
2462 trace_xfs_attr_list_notfound(context); 2655 trace_xfs_attr_list_notfound(context);
2463 return(0); 2656 return 0;
2464 } 2657 }
2465 } else { 2658 } else {
2466 entry = &leaf->entries[0]; 2659 entry = &entries[0];
2467 i = 0; 2660 i = 0;
2468 } 2661 }
2469 context->resynch = 0; 2662 context->resynch = 0;
@@ -2472,7 +2665,7 @@ xfs_attr_leaf_list_int(
2472 * We have found our place, start copying out the new attributes. 2665 * We have found our place, start copying out the new attributes.
2473 */ 2666 */
2474 retval = 0; 2667 retval = 0;
2475 for ( ; (i < be16_to_cpu(leaf->hdr.count)); entry++, i++) { 2668 for (; i < ichdr.count; entry++, i++) {
2476 if (be32_to_cpu(entry->hashval) != cursor->hashval) { 2669 if (be32_to_cpu(entry->hashval) != cursor->hashval) {
2477 cursor->hashval = be32_to_cpu(entry->hashval); 2670 cursor->hashval = be32_to_cpu(entry->hashval);
2478 cursor->offset = 0; 2671 cursor->offset = 0;
@@ -2483,7 +2676,7 @@ xfs_attr_leaf_list_int(
2483 2676
2484 if (entry->flags & XFS_ATTR_LOCAL) { 2677 if (entry->flags & XFS_ATTR_LOCAL) {
2485 xfs_attr_leaf_name_local_t *name_loc = 2678 xfs_attr_leaf_name_local_t *name_loc =
2486 xfs_attr_leaf_name_local(leaf, i); 2679 xfs_attr3_leaf_name_local(leaf, i);
2487 2680
2488 retval = context->put_listent(context, 2681 retval = context->put_listent(context,
2489 entry->flags, 2682 entry->flags,
@@ -2495,7 +2688,7 @@ xfs_attr_leaf_list_int(
2495 return retval; 2688 return retval;
2496 } else { 2689 } else {
2497 xfs_attr_leaf_name_remote_t *name_rmt = 2690 xfs_attr_leaf_name_remote_t *name_rmt =
2498 xfs_attr_leaf_name_remote(leaf, i); 2691 xfs_attr3_leaf_name_remote(leaf, i);
2499 2692
2500 int valuelen = be32_to_cpu(name_rmt->valuelen); 2693 int valuelen = be32_to_cpu(name_rmt->valuelen);
2501 2694
@@ -2535,7 +2728,7 @@ xfs_attr_leaf_list_int(
2535 cursor->offset++; 2728 cursor->offset++;
2536 } 2729 }
2537 trace_xfs_attr_list_leaf_end(context); 2730 trace_xfs_attr_list_leaf_end(context);
2538 return(retval); 2731 return retval;
2539} 2732}
2540 2733
2541 2734
@@ -2547,14 +2740,16 @@ xfs_attr_leaf_list_int(
2547 * Clear the INCOMPLETE flag on an entry in a leaf block. 2740 * Clear the INCOMPLETE flag on an entry in a leaf block.
2548 */ 2741 */
2549int 2742int
2550xfs_attr_leaf_clearflag(xfs_da_args_t *args) 2743xfs_attr3_leaf_clearflag(
2744 struct xfs_da_args *args)
2551{ 2745{
2552 xfs_attr_leafblock_t *leaf; 2746 struct xfs_attr_leafblock *leaf;
2553 xfs_attr_leaf_entry_t *entry; 2747 struct xfs_attr_leaf_entry *entry;
2554 xfs_attr_leaf_name_remote_t *name_rmt; 2748 struct xfs_attr_leaf_name_remote *name_rmt;
2555 struct xfs_buf *bp; 2749 struct xfs_buf *bp;
2556 int error; 2750 int error;
2557#ifdef DEBUG 2751#ifdef DEBUG
2752 struct xfs_attr3_icleaf_hdr ichdr;
2558 xfs_attr_leaf_name_local_t *name_loc; 2753 xfs_attr_leaf_name_local_t *name_loc;
2559 int namelen; 2754 int namelen;
2560 char *name; 2755 char *name;
@@ -2564,23 +2759,25 @@ xfs_attr_leaf_clearflag(xfs_da_args_t *args)
2564 /* 2759 /*
2565 * Set up the operation. 2760 * Set up the operation.
2566 */ 2761 */
2567 error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno, -1, &bp); 2762 error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
2568 if (error) 2763 if (error)
2569 return(error); 2764 return(error);
2570 2765
2571 leaf = bp->b_addr; 2766 leaf = bp->b_addr;
2572 ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); 2767 entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
2573 ASSERT(args->index >= 0);
2574 entry = &leaf->entries[ args->index ];
2575 ASSERT(entry->flags & XFS_ATTR_INCOMPLETE); 2768 ASSERT(entry->flags & XFS_ATTR_INCOMPLETE);
2576 2769
2577#ifdef DEBUG 2770#ifdef DEBUG
2771 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
2772 ASSERT(args->index < ichdr.count);
2773 ASSERT(args->index >= 0);
2774
2578 if (entry->flags & XFS_ATTR_LOCAL) { 2775 if (entry->flags & XFS_ATTR_LOCAL) {
2579 name_loc = xfs_attr_leaf_name_local(leaf, args->index); 2776 name_loc = xfs_attr3_leaf_name_local(leaf, args->index);
2580 namelen = name_loc->namelen; 2777 namelen = name_loc->namelen;
2581 name = (char *)name_loc->nameval; 2778 name = (char *)name_loc->nameval;
2582 } else { 2779 } else {
2583 name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); 2780 name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
2584 namelen = name_rmt->namelen; 2781 namelen = name_rmt->namelen;
2585 name = (char *)name_rmt->name; 2782 name = (char *)name_rmt->name;
2586 } 2783 }
@@ -2595,7 +2792,7 @@ xfs_attr_leaf_clearflag(xfs_da_args_t *args)
2595 2792
2596 if (args->rmtblkno) { 2793 if (args->rmtblkno) {
2597 ASSERT((entry->flags & XFS_ATTR_LOCAL) == 0); 2794 ASSERT((entry->flags & XFS_ATTR_LOCAL) == 0);
2598 name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); 2795 name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
2599 name_rmt->valueblk = cpu_to_be32(args->rmtblkno); 2796 name_rmt->valueblk = cpu_to_be32(args->rmtblkno);
2600 name_rmt->valuelen = cpu_to_be32(args->valuelen); 2797 name_rmt->valuelen = cpu_to_be32(args->valuelen);
2601 xfs_trans_log_buf(args->trans, bp, 2798 xfs_trans_log_buf(args->trans, bp,
@@ -2612,34 +2809,41 @@ xfs_attr_leaf_clearflag(xfs_da_args_t *args)
2612 * Set the INCOMPLETE flag on an entry in a leaf block. 2809 * Set the INCOMPLETE flag on an entry in a leaf block.
2613 */ 2810 */
2614int 2811int
2615xfs_attr_leaf_setflag(xfs_da_args_t *args) 2812xfs_attr3_leaf_setflag(
2813 struct xfs_da_args *args)
2616{ 2814{
2617 xfs_attr_leafblock_t *leaf; 2815 struct xfs_attr_leafblock *leaf;
2618 xfs_attr_leaf_entry_t *entry; 2816 struct xfs_attr_leaf_entry *entry;
2619 xfs_attr_leaf_name_remote_t *name_rmt; 2817 struct xfs_attr_leaf_name_remote *name_rmt;
2620 struct xfs_buf *bp; 2818 struct xfs_buf *bp;
2621 int error; 2819 int error;
2820#ifdef DEBUG
2821 struct xfs_attr3_icleaf_hdr ichdr;
2822#endif
2622 2823
2623 trace_xfs_attr_leaf_setflag(args); 2824 trace_xfs_attr_leaf_setflag(args);
2624 2825
2625 /* 2826 /*
2626 * Set up the operation. 2827 * Set up the operation.
2627 */ 2828 */
2628 error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno, -1, &bp); 2829 error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
2629 if (error) 2830 if (error)
2630 return(error); 2831 return(error);
2631 2832
2632 leaf = bp->b_addr; 2833 leaf = bp->b_addr;
2633 ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); 2834#ifdef DEBUG
2835 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
2836 ASSERT(args->index < ichdr.count);
2634 ASSERT(args->index >= 0); 2837 ASSERT(args->index >= 0);
2635 entry = &leaf->entries[ args->index ]; 2838#endif
2839 entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
2636 2840
2637 ASSERT((entry->flags & XFS_ATTR_INCOMPLETE) == 0); 2841 ASSERT((entry->flags & XFS_ATTR_INCOMPLETE) == 0);
2638 entry->flags |= XFS_ATTR_INCOMPLETE; 2842 entry->flags |= XFS_ATTR_INCOMPLETE;
2639 xfs_trans_log_buf(args->trans, bp, 2843 xfs_trans_log_buf(args->trans, bp,
2640 XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); 2844 XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
2641 if ((entry->flags & XFS_ATTR_LOCAL) == 0) { 2845 if ((entry->flags & XFS_ATTR_LOCAL) == 0) {
2642 name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); 2846 name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
2643 name_rmt->valueblk = 0; 2847 name_rmt->valueblk = 0;
2644 name_rmt->valuelen = 0; 2848 name_rmt->valuelen = 0;
2645 xfs_trans_log_buf(args->trans, bp, 2849 xfs_trans_log_buf(args->trans, bp,
@@ -2660,14 +2864,20 @@ xfs_attr_leaf_setflag(xfs_da_args_t *args)
2660 * Note that they could be in different blocks, or in the same block. 2864 * Note that they could be in different blocks, or in the same block.
2661 */ 2865 */
2662int 2866int
2663xfs_attr_leaf_flipflags(xfs_da_args_t *args) 2867xfs_attr3_leaf_flipflags(
2868 struct xfs_da_args *args)
2664{ 2869{
2665 xfs_attr_leafblock_t *leaf1, *leaf2; 2870 struct xfs_attr_leafblock *leaf1;
2666 xfs_attr_leaf_entry_t *entry1, *entry2; 2871 struct xfs_attr_leafblock *leaf2;
2667 xfs_attr_leaf_name_remote_t *name_rmt; 2872 struct xfs_attr_leaf_entry *entry1;
2668 struct xfs_buf *bp1, *bp2; 2873 struct xfs_attr_leaf_entry *entry2;
2874 struct xfs_attr_leaf_name_remote *name_rmt;
2875 struct xfs_buf *bp1;
2876 struct xfs_buf *bp2;
2669 int error; 2877 int error;
2670#ifdef DEBUG 2878#ifdef DEBUG
2879 struct xfs_attr3_icleaf_hdr ichdr1;
2880 struct xfs_attr3_icleaf_hdr ichdr2;
2671 xfs_attr_leaf_name_local_t *name_loc; 2881 xfs_attr_leaf_name_local_t *name_loc;
2672 int namelen1, namelen2; 2882 int namelen1, namelen2;
2673 char *name1, *name2; 2883 char *name1, *name2;
@@ -2678,7 +2888,7 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args)
2678 /* 2888 /*
2679 * Read the block containing the "old" attr 2889 * Read the block containing the "old" attr
2680 */ 2890 */
2681 error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno, -1, &bp1); 2891 error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp1);
2682 if (error) 2892 if (error)
2683 return error; 2893 return error;
2684 2894
@@ -2686,7 +2896,7 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args)
2686 * Read the block containing the "new" attr, if it is different 2896 * Read the block containing the "new" attr, if it is different
2687 */ 2897 */
2688 if (args->blkno2 != args->blkno) { 2898 if (args->blkno2 != args->blkno) {
2689 error = xfs_attr_leaf_read(args->trans, args->dp, args->blkno2, 2899 error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno2,
2690 -1, &bp2); 2900 -1, &bp2);
2691 if (error) 2901 if (error)
2692 return error; 2902 return error;
@@ -2695,31 +2905,35 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args)
2695 } 2905 }
2696 2906
2697 leaf1 = bp1->b_addr; 2907 leaf1 = bp1->b_addr;
2698 ASSERT(args->index < be16_to_cpu(leaf1->hdr.count)); 2908 entry1 = &xfs_attr3_leaf_entryp(leaf1)[args->index];
2699 ASSERT(args->index >= 0);
2700 entry1 = &leaf1->entries[ args->index ];
2701 2909
2702 leaf2 = bp2->b_addr; 2910 leaf2 = bp2->b_addr;
2703 ASSERT(args->index2 < be16_to_cpu(leaf2->hdr.count)); 2911 entry2 = &xfs_attr3_leaf_entryp(leaf2)[args->index2];
2704 ASSERT(args->index2 >= 0);
2705 entry2 = &leaf2->entries[ args->index2 ];
2706 2912
2707#ifdef DEBUG 2913#ifdef DEBUG
2914 xfs_attr3_leaf_hdr_from_disk(&ichdr1, leaf1);
2915 ASSERT(args->index < ichdr1.count);
2916 ASSERT(args->index >= 0);
2917
2918 xfs_attr3_leaf_hdr_from_disk(&ichdr2, leaf2);
2919 ASSERT(args->index2 < ichdr2.count);
2920 ASSERT(args->index2 >= 0);
2921
2708 if (entry1->flags & XFS_ATTR_LOCAL) { 2922 if (entry1->flags & XFS_ATTR_LOCAL) {
2709 name_loc = xfs_attr_leaf_name_local(leaf1, args->index); 2923 name_loc = xfs_attr3_leaf_name_local(leaf1, args->index);
2710 namelen1 = name_loc->namelen; 2924 namelen1 = name_loc->namelen;
2711 name1 = (char *)name_loc->nameval; 2925 name1 = (char *)name_loc->nameval;
2712 } else { 2926 } else {
2713 name_rmt = xfs_attr_leaf_name_remote(leaf1, args->index); 2927 name_rmt = xfs_attr3_leaf_name_remote(leaf1, args->index);
2714 namelen1 = name_rmt->namelen; 2928 namelen1 = name_rmt->namelen;
2715 name1 = (char *)name_rmt->name; 2929 name1 = (char *)name_rmt->name;
2716 } 2930 }
2717 if (entry2->flags & XFS_ATTR_LOCAL) { 2931 if (entry2->flags & XFS_ATTR_LOCAL) {
2718 name_loc = xfs_attr_leaf_name_local(leaf2, args->index2); 2932 name_loc = xfs_attr3_leaf_name_local(leaf2, args->index2);
2719 namelen2 = name_loc->namelen; 2933 namelen2 = name_loc->namelen;
2720 name2 = (char *)name_loc->nameval; 2934 name2 = (char *)name_loc->nameval;
2721 } else { 2935 } else {
2722 name_rmt = xfs_attr_leaf_name_remote(leaf2, args->index2); 2936 name_rmt = xfs_attr3_leaf_name_remote(leaf2, args->index2);
2723 namelen2 = name_rmt->namelen; 2937 namelen2 = name_rmt->namelen;
2724 name2 = (char *)name_rmt->name; 2938 name2 = (char *)name_rmt->name;
2725 } 2939 }
@@ -2736,7 +2950,7 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args)
2736 XFS_DA_LOGRANGE(leaf1, entry1, sizeof(*entry1))); 2950 XFS_DA_LOGRANGE(leaf1, entry1, sizeof(*entry1)));
2737 if (args->rmtblkno) { 2951 if (args->rmtblkno) {
2738 ASSERT((entry1->flags & XFS_ATTR_LOCAL) == 0); 2952 ASSERT((entry1->flags & XFS_ATTR_LOCAL) == 0);
2739 name_rmt = xfs_attr_leaf_name_remote(leaf1, args->index); 2953 name_rmt = xfs_attr3_leaf_name_remote(leaf1, args->index);
2740 name_rmt->valueblk = cpu_to_be32(args->rmtblkno); 2954 name_rmt->valueblk = cpu_to_be32(args->rmtblkno);
2741 name_rmt->valuelen = cpu_to_be32(args->valuelen); 2955 name_rmt->valuelen = cpu_to_be32(args->valuelen);
2742 xfs_trans_log_buf(args->trans, bp1, 2956 xfs_trans_log_buf(args->trans, bp1,
@@ -2747,7 +2961,7 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args)
2747 xfs_trans_log_buf(args->trans, bp2, 2961 xfs_trans_log_buf(args->trans, bp2,
2748 XFS_DA_LOGRANGE(leaf2, entry2, sizeof(*entry2))); 2962 XFS_DA_LOGRANGE(leaf2, entry2, sizeof(*entry2)));
2749 if ((entry2->flags & XFS_ATTR_LOCAL) == 0) { 2963 if ((entry2->flags & XFS_ATTR_LOCAL) == 0) {
2750 name_rmt = xfs_attr_leaf_name_remote(leaf2, args->index2); 2964 name_rmt = xfs_attr3_leaf_name_remote(leaf2, args->index2);
2751 name_rmt->valueblk = 0; 2965 name_rmt->valueblk = 0;
2752 name_rmt->valuelen = 0; 2966 name_rmt->valuelen = 0;
2753 xfs_trans_log_buf(args->trans, bp2, 2967 xfs_trans_log_buf(args->trans, bp2,
@@ -2759,7 +2973,7 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args)
2759 */ 2973 */
2760 error = xfs_trans_roll(&args->trans, args->dp); 2974 error = xfs_trans_roll(&args->trans, args->dp);
2761 2975
2762 return(error); 2976 return error;
2763} 2977}
2764 2978
2765/*======================================================================== 2979/*========================================================================
@@ -2771,12 +2985,14 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args)
2771 * We're doing a depth-first traversal in order to invalidate everything. 2985 * We're doing a depth-first traversal in order to invalidate everything.
2772 */ 2986 */
2773int 2987int
2774xfs_attr_root_inactive(xfs_trans_t **trans, xfs_inode_t *dp) 2988xfs_attr3_root_inactive(
2989 struct xfs_trans **trans,
2990 struct xfs_inode *dp)
2775{ 2991{
2776 xfs_da_blkinfo_t *info; 2992 struct xfs_da_blkinfo *info;
2777 xfs_daddr_t blkno; 2993 struct xfs_buf *bp;
2778 struct xfs_buf *bp; 2994 xfs_daddr_t blkno;
2779 int error; 2995 int error;
2780 2996
2781 /* 2997 /*
2782 * Read block 0 to see what we have to work with. 2998 * Read block 0 to see what we have to work with.
@@ -2786,38 +3002,44 @@ xfs_attr_root_inactive(xfs_trans_t **trans, xfs_inode_t *dp)
2786 */ 3002 */
2787 error = xfs_da3_node_read(*trans, dp, 0, -1, &bp, XFS_ATTR_FORK); 3003 error = xfs_da3_node_read(*trans, dp, 0, -1, &bp, XFS_ATTR_FORK);
2788 if (error) 3004 if (error)
2789 return(error); 3005 return error;
2790 blkno = XFS_BUF_ADDR(bp); 3006 blkno = bp->b_bn;
2791 3007
2792 /* 3008 /*
2793 * Invalidate the tree, even if the "tree" is only a single leaf block. 3009 * Invalidate the tree, even if the "tree" is only a single leaf block.
2794 * This is a depth-first traversal! 3010 * This is a depth-first traversal!
2795 */ 3011 */
2796 info = bp->b_addr; 3012 info = bp->b_addr;
2797 if (info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC)) { 3013 switch (info->magic) {
2798 error = xfs_attr_node_inactive(trans, dp, bp, 1); 3014 case cpu_to_be16(XFS_DA_NODE_MAGIC):
2799 } else if (info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)) { 3015 case cpu_to_be16(XFS_DA3_NODE_MAGIC):
2800 error = xfs_attr_leaf_inactive(trans, dp, bp); 3016 error = xfs_attr3_node_inactive(trans, dp, bp, 1);
2801 } else { 3017 break;
3018 case cpu_to_be16(XFS_ATTR_LEAF_MAGIC):
3019 case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC):
3020 error = xfs_attr3_leaf_inactive(trans, dp, bp);
3021 break;
3022 default:
2802 error = XFS_ERROR(EIO); 3023 error = XFS_ERROR(EIO);
2803 xfs_trans_brelse(*trans, bp); 3024 xfs_trans_brelse(*trans, bp);
3025 break;
2804 } 3026 }
2805 if (error) 3027 if (error)
2806 return(error); 3028 return error;
2807 3029
2808 /* 3030 /*
2809 * Invalidate the incore copy of the root block. 3031 * Invalidate the incore copy of the root block.
2810 */ 3032 */
2811 error = xfs_da_get_buf(*trans, dp, 0, blkno, &bp, XFS_ATTR_FORK); 3033 error = xfs_da_get_buf(*trans, dp, 0, blkno, &bp, XFS_ATTR_FORK);
2812 if (error) 3034 if (error)
2813 return(error); 3035 return error;
2814 xfs_trans_binval(*trans, bp); /* remove from cache */ 3036 xfs_trans_binval(*trans, bp); /* remove from cache */
2815 /* 3037 /*
2816 * Commit the invalidate and start the next transaction. 3038 * Commit the invalidate and start the next transaction.
2817 */ 3039 */
2818 error = xfs_trans_roll(trans, dp); 3040 error = xfs_trans_roll(trans, dp);
2819 3041
2820 return (error); 3042 return error;
2821} 3043}
2822 3044
2823/* 3045/*
@@ -2825,7 +3047,7 @@ xfs_attr_root_inactive(xfs_trans_t **trans, xfs_inode_t *dp)
2825 * We're doing a depth-first traversal in order to invalidate everything. 3047 * We're doing a depth-first traversal in order to invalidate everything.
2826 */ 3048 */
2827STATIC int 3049STATIC int
2828xfs_attr_node_inactive( 3050xfs_attr3_node_inactive(
2829 struct xfs_trans **trans, 3051 struct xfs_trans **trans,
2830 struct xfs_inode *dp, 3052 struct xfs_inode *dp,
2831 struct xfs_buf *bp, 3053 struct xfs_buf *bp,
@@ -2835,25 +3057,25 @@ xfs_attr_node_inactive(
2835 xfs_da_intnode_t *node; 3057 xfs_da_intnode_t *node;
2836 xfs_dablk_t child_fsb; 3058 xfs_dablk_t child_fsb;
2837 xfs_daddr_t parent_blkno, child_blkno; 3059 xfs_daddr_t parent_blkno, child_blkno;
2838 int error, count, i; 3060 int error, i;
2839 struct xfs_buf *child_bp; 3061 struct xfs_buf *child_bp;
2840 struct xfs_da_node_entry *btree; 3062 struct xfs_da_node_entry *btree;
3063 struct xfs_da3_icnode_hdr ichdr;
2841 3064
2842 /* 3065 /*
2843 * Since this code is recursive (gasp!) we must protect ourselves. 3066 * Since this code is recursive (gasp!) we must protect ourselves.
2844 */ 3067 */
2845 if (level > XFS_DA_NODE_MAXDEPTH) { 3068 if (level > XFS_DA_NODE_MAXDEPTH) {
2846 xfs_trans_brelse(*trans, bp); /* no locks for later trans */ 3069 xfs_trans_brelse(*trans, bp); /* no locks for later trans */
2847 return(XFS_ERROR(EIO)); 3070 return XFS_ERROR(EIO);
2848 } 3071 }
2849 3072
2850 node = bp->b_addr; 3073 node = bp->b_addr;
2851 ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); 3074 xfs_da3_node_hdr_from_disk(&ichdr, node);
2852 parent_blkno = XFS_BUF_ADDR(bp); /* save for re-read later */ 3075 parent_blkno = bp->b_bn;
2853 count = be16_to_cpu(node->hdr.count); 3076 if (!ichdr.count) {
2854 if (!count) {
2855 xfs_trans_brelse(*trans, bp); 3077 xfs_trans_brelse(*trans, bp);
2856 return(0); 3078 return 0;
2857 } 3079 }
2858 btree = xfs_da3_node_tree_p(node); 3080 btree = xfs_da3_node_tree_p(node);
2859 child_fsb = be32_to_cpu(btree[0].before); 3081 child_fsb = be32_to_cpu(btree[0].before);
@@ -2864,7 +3086,7 @@ xfs_attr_node_inactive(
2864 * over the leaves removing all of them. If this is higher up 3086 * over the leaves removing all of them. If this is higher up
2865 * in the tree, recurse downward. 3087 * in the tree, recurse downward.
2866 */ 3088 */
2867 for (i = 0; i < count; i++) { 3089 for (i = 0; i < ichdr.count; i++) {
2868 /* 3090 /*
2869 * Read the subsidiary block to see what we have to work with. 3091 * Read the subsidiary block to see what we have to work with.
2870 * Don't do this in a transaction. This is a depth-first 3092 * Don't do this in a transaction. This is a depth-first
@@ -2883,18 +3105,24 @@ xfs_attr_node_inactive(
2883 * Invalidate the subtree, however we have to. 3105 * Invalidate the subtree, however we have to.
2884 */ 3106 */
2885 info = child_bp->b_addr; 3107 info = child_bp->b_addr;
2886 if (info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC)) { 3108 switch (info->magic) {
2887 error = xfs_attr_node_inactive(trans, dp, 3109 case cpu_to_be16(XFS_DA_NODE_MAGIC):
2888 child_bp, level+1); 3110 case cpu_to_be16(XFS_DA3_NODE_MAGIC):
2889 } else if (info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)) { 3111 error = xfs_attr3_node_inactive(trans, dp,
2890 error = xfs_attr_leaf_inactive(trans, dp, 3112 child_bp, level + 1);
2891 child_bp); 3113 break;
2892 } else { 3114 case cpu_to_be16(XFS_ATTR_LEAF_MAGIC):
3115 case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC):
3116 error = xfs_attr3_leaf_inactive(trans, dp,
3117 child_bp);
3118 break;
3119 default:
2893 error = XFS_ERROR(EIO); 3120 error = XFS_ERROR(EIO);
2894 xfs_trans_brelse(*trans, child_bp); 3121 xfs_trans_brelse(*trans, child_bp);
3122 break;
2895 } 3123 }
2896 if (error) 3124 if (error)
2897 return(error); 3125 return error;
2898 3126
2899 /* 3127 /*
2900 * Remove the subsidiary block from the cache 3128 * Remove the subsidiary block from the cache
@@ -2903,7 +3131,7 @@ xfs_attr_node_inactive(
2903 error = xfs_da_get_buf(*trans, dp, 0, child_blkno, 3131 error = xfs_da_get_buf(*trans, dp, 0, child_blkno,
2904 &child_bp, XFS_ATTR_FORK); 3132 &child_bp, XFS_ATTR_FORK);
2905 if (error) 3133 if (error)
2906 return(error); 3134 return error;
2907 xfs_trans_binval(*trans, child_bp); 3135 xfs_trans_binval(*trans, child_bp);
2908 } 3136 }
2909 3137
@@ -2911,12 +3139,12 @@ xfs_attr_node_inactive(
2911 * If we're not done, re-read the parent to get the next 3139 * If we're not done, re-read the parent to get the next
2912 * child block number. 3140 * child block number.
2913 */ 3141 */
2914 if ((i+1) < count) { 3142 if (i + 1 < ichdr.count) {
2915 error = xfs_da3_node_read(*trans, dp, 0, parent_blkno, 3143 error = xfs_da3_node_read(*trans, dp, 0, parent_blkno,
2916 &bp, XFS_ATTR_FORK); 3144 &bp, XFS_ATTR_FORK);
2917 if (error) 3145 if (error)
2918 return(error); 3146 return error;
2919 child_fsb = be32_to_cpu(btree[i+1].before); 3147 child_fsb = be32_to_cpu(btree[i + 1].before);
2920 xfs_trans_brelse(*trans, bp); 3148 xfs_trans_brelse(*trans, bp);
2921 } 3149 }
2922 /* 3150 /*
@@ -2924,10 +3152,10 @@ xfs_attr_node_inactive(
2924 */ 3152 */
2925 error = xfs_trans_roll(trans, dp); 3153 error = xfs_trans_roll(trans, dp);
2926 if (error) 3154 if (error)
2927 return (error); 3155 return error;
2928 } 3156 }
2929 3157
2930 return(0); 3158 return 0;
2931} 3159}
2932 3160
2933/* 3161/*
@@ -2937,29 +3165,35 @@ xfs_attr_node_inactive(
2937 * caught holding something that the logging code wants to flush to disk. 3165 * caught holding something that the logging code wants to flush to disk.
2938 */ 3166 */
2939STATIC int 3167STATIC int
2940xfs_attr_leaf_inactive( 3168xfs_attr3_leaf_inactive(
2941 struct xfs_trans **trans, 3169 struct xfs_trans **trans,
2942 struct xfs_inode *dp, 3170 struct xfs_inode *dp,
2943 struct xfs_buf *bp) 3171 struct xfs_buf *bp)
2944{ 3172{
2945 xfs_attr_leafblock_t *leaf; 3173 struct xfs_attr_leafblock *leaf;
2946 xfs_attr_leaf_entry_t *entry; 3174 struct xfs_attr3_icleaf_hdr ichdr;
2947 xfs_attr_leaf_name_remote_t *name_rmt; 3175 struct xfs_attr_leaf_entry *entry;
2948 xfs_attr_inactive_list_t *list, *lp; 3176 struct xfs_attr_leaf_name_remote *name_rmt;
2949 int error, count, size, tmp, i; 3177 struct xfs_attr_inactive_list *list;
3178 struct xfs_attr_inactive_list *lp;
3179 int error;
3180 int count;
3181 int size;
3182 int tmp;
3183 int i;
2950 3184
2951 leaf = bp->b_addr; 3185 leaf = bp->b_addr;
2952 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 3186 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
2953 3187
2954 /* 3188 /*
2955 * Count the number of "remote" value extents. 3189 * Count the number of "remote" value extents.
2956 */ 3190 */
2957 count = 0; 3191 count = 0;
2958 entry = &leaf->entries[0]; 3192 entry = xfs_attr3_leaf_entryp(leaf);
2959 for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { 3193 for (i = 0; i < ichdr.count; entry++, i++) {
2960 if (be16_to_cpu(entry->nameidx) && 3194 if (be16_to_cpu(entry->nameidx) &&
2961 ((entry->flags & XFS_ATTR_LOCAL) == 0)) { 3195 ((entry->flags & XFS_ATTR_LOCAL) == 0)) {
2962 name_rmt = xfs_attr_leaf_name_remote(leaf, i); 3196 name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
2963 if (name_rmt->valueblk) 3197 if (name_rmt->valueblk)
2964 count++; 3198 count++;
2965 } 3199 }
@@ -2970,24 +3204,24 @@ xfs_attr_leaf_inactive(
2970 */ 3204 */
2971 if (count == 0) { 3205 if (count == 0) {
2972 xfs_trans_brelse(*trans, bp); 3206 xfs_trans_brelse(*trans, bp);
2973 return(0); 3207 return 0;
2974 } 3208 }
2975 3209
2976 /* 3210 /*
2977 * Allocate storage for a list of all the "remote" value extents. 3211 * Allocate storage for a list of all the "remote" value extents.
2978 */ 3212 */
2979 size = count * sizeof(xfs_attr_inactive_list_t); 3213 size = count * sizeof(xfs_attr_inactive_list_t);
2980 list = (xfs_attr_inactive_list_t *)kmem_alloc(size, KM_SLEEP); 3214 list = kmem_alloc(size, KM_SLEEP);
2981 3215
2982 /* 3216 /*
2983 * Identify each of the "remote" value extents. 3217 * Identify each of the "remote" value extents.
2984 */ 3218 */
2985 lp = list; 3219 lp = list;
2986 entry = &leaf->entries[0]; 3220 entry = xfs_attr3_leaf_entryp(leaf);
2987 for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { 3221 for (i = 0; i < ichdr.count; entry++, i++) {
2988 if (be16_to_cpu(entry->nameidx) && 3222 if (be16_to_cpu(entry->nameidx) &&
2989 ((entry->flags & XFS_ATTR_LOCAL) == 0)) { 3223 ((entry->flags & XFS_ATTR_LOCAL) == 0)) {
2990 name_rmt = xfs_attr_leaf_name_remote(leaf, i); 3224 name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
2991 if (name_rmt->valueblk) { 3225 if (name_rmt->valueblk) {
2992 lp->valueblk = be32_to_cpu(name_rmt->valueblk); 3226 lp->valueblk = be32_to_cpu(name_rmt->valueblk);
2993 lp->valuelen = XFS_B_TO_FSB(dp->i_mount, 3227 lp->valuelen = XFS_B_TO_FSB(dp->i_mount,
@@ -3003,15 +3237,15 @@ xfs_attr_leaf_inactive(
3003 */ 3237 */
3004 error = 0; 3238 error = 0;
3005 for (lp = list, i = 0; i < count; i++, lp++) { 3239 for (lp = list, i = 0; i < count; i++, lp++) {
3006 tmp = xfs_attr_leaf_freextent(trans, dp, 3240 tmp = xfs_attr3_leaf_freextent(trans, dp,
3007 lp->valueblk, lp->valuelen); 3241 lp->valueblk, lp->valuelen);
3008 3242
3009 if (error == 0) 3243 if (error == 0)
3010 error = tmp; /* save only the 1st errno */ 3244 error = tmp; /* save only the 1st errno */
3011 } 3245 }
3012 3246
3013 kmem_free((xfs_caddr_t)list); 3247 kmem_free(list);
3014 return(error); 3248 return error;
3015} 3249}
3016 3250
3017/* 3251/*
@@ -3019,14 +3253,20 @@ xfs_attr_leaf_inactive(
3019 * invalidate any buffers that are incore/in transactions. 3253 * invalidate any buffers that are incore/in transactions.
3020 */ 3254 */
3021STATIC int 3255STATIC int
3022xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp, 3256xfs_attr3_leaf_freextent(
3023 xfs_dablk_t blkno, int blkcnt) 3257 struct xfs_trans **trans,
3258 struct xfs_inode *dp,
3259 xfs_dablk_t blkno,
3260 int blkcnt)
3024{ 3261{
3025 xfs_bmbt_irec_t map; 3262 struct xfs_bmbt_irec map;
3026 xfs_dablk_t tblkno; 3263 struct xfs_buf *bp;
3027 int tblkcnt, dblkcnt, nmap, error; 3264 xfs_dablk_t tblkno;
3028 xfs_daddr_t dblkno; 3265 xfs_daddr_t dblkno;
3029 xfs_buf_t *bp; 3266 int tblkcnt;
3267 int dblkcnt;
3268 int nmap;
3269 int error;
3030 3270
3031 /* 3271 /*
3032 * Roll through the "value", invalidating the attribute value's 3272 * Roll through the "value", invalidating the attribute value's
diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h
index 77de139a58f0..f9d7846097e2 100644
--- a/fs/xfs/xfs_attr_leaf.h
+++ b/fs/xfs/xfs_attr_leaf.h
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2000,2002-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000,2002-2003,2005 Silicon Graphics, Inc.
3 * Copyright (c) 2013 Red Hat, Inc.
3 * All Rights Reserved. 4 * All Rights Reserved.
4 * 5 *
5 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -89,7 +90,7 @@ typedef struct xfs_attr_leaf_hdr { /* constant-structure header block */
89 90
90typedef struct xfs_attr_leaf_entry { /* sorted on key, not name */ 91typedef struct xfs_attr_leaf_entry { /* sorted on key, not name */
91 __be32 hashval; /* hash value of name */ 92 __be32 hashval; /* hash value of name */
92 __be16 nameidx; /* index into buffer of name/value */ 93 __be16 nameidx; /* index into buffer of name/value */
93 __u8 flags; /* LOCAL/ROOT/SECURE/INCOMPLETE flag */ 94 __u8 flags; /* LOCAL/ROOT/SECURE/INCOMPLETE flag */
94 __u8 pad2; /* unused pad byte */ 95 __u8 pad2; /* unused pad byte */
95} xfs_attr_leaf_entry_t; 96} xfs_attr_leaf_entry_t;
@@ -115,6 +116,54 @@ typedef struct xfs_attr_leafblock {
115} xfs_attr_leafblock_t; 116} xfs_attr_leafblock_t;
116 117
117/* 118/*
119 * CRC enabled leaf structures. Called "version 3" structures to match the
120 * version number of the directory and dablk structures for this feature, and
121 * attr2 is already taken by the variable inode attribute fork size feature.
122 */
123struct xfs_attr3_leaf_hdr {
124 struct xfs_da3_blkinfo info;
125 __be16 count;
126 __be16 usedbytes;
127 __be16 firstused;
128 __u8 holes;
129 __u8 pad1;
130 struct xfs_attr_leaf_map freemap[XFS_ATTR_LEAF_MAPSIZE];
131};
132
133#define XFS_ATTR3_LEAF_CRC_OFF (offsetof(struct xfs_attr3_leaf_hdr, info.crc))
134
135struct xfs_attr3_leafblock {
136 struct xfs_attr3_leaf_hdr hdr;
137 struct xfs_attr_leaf_entry entries[1];
138
139 /*
140 * The rest of the block contains the following structures after the
141 * leaf entries, growing from the bottom up. The variables are never
142 * referenced, the locations accessed purely from helper functions.
143 *
144 * struct xfs_attr_leaf_name_local
145 * struct xfs_attr_leaf_name_remote
146 */
147};
148
149/*
150 * incore, neutral version of the attribute leaf header
151 */
152struct xfs_attr3_icleaf_hdr {
153 __uint32_t forw;
154 __uint32_t back;
155 __uint16_t magic;
156 __uint16_t count;
157 __uint16_t usedbytes;
158 __uint16_t firstused;
159 __u8 holes;
160 struct {
161 __uint16_t base;
162 __uint16_t size;
163 } freemap[XFS_ATTR_LEAF_MAPSIZE];
164};
165
166/*
118 * Flags used in the leaf_entry[i].flags field. 167 * Flags used in the leaf_entry[i].flags field.
119 * NOTE: the INCOMPLETE bit must not collide with the flags bits specified 168 * NOTE: the INCOMPLETE bit must not collide with the flags bits specified
120 * on the system call, they are "or"ed together for various operations. 169 * on the system call, they are "or"ed together for various operations.
@@ -147,26 +196,43 @@ typedef struct xfs_attr_leafblock {
147 */ 196 */
148#define XFS_ATTR_LEAF_NAME_ALIGN ((uint)sizeof(xfs_dablk_t)) 197#define XFS_ATTR_LEAF_NAME_ALIGN ((uint)sizeof(xfs_dablk_t))
149 198
199static inline int
200xfs_attr3_leaf_hdr_size(struct xfs_attr_leafblock *leafp)
201{
202 if (leafp->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC))
203 return sizeof(struct xfs_attr3_leaf_hdr);
204 return sizeof(struct xfs_attr_leaf_hdr);
205}
206
207static inline struct xfs_attr_leaf_entry *
208xfs_attr3_leaf_entryp(xfs_attr_leafblock_t *leafp)
209{
210 if (leafp->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC))
211 return &((struct xfs_attr3_leafblock *)leafp)->entries[0];
212 return &leafp->entries[0];
213}
214
150/* 215/*
151 * Cast typed pointers for "local" and "remote" name/value structs. 216 * Cast typed pointers for "local" and "remote" name/value structs.
152 */ 217 */
153static inline xfs_attr_leaf_name_remote_t * 218static inline char *
154xfs_attr_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx) 219xfs_attr3_leaf_name(xfs_attr_leafblock_t *leafp, int idx)
155{ 220{
156 return (xfs_attr_leaf_name_remote_t *) 221 struct xfs_attr_leaf_entry *entries = xfs_attr3_leaf_entryp(leafp);
157 &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)]; 222
223 return &((char *)leafp)[be16_to_cpu(entries[idx].nameidx)];
158} 224}
159 225
160static inline xfs_attr_leaf_name_local_t * 226static inline xfs_attr_leaf_name_remote_t *
161xfs_attr_leaf_name_local(xfs_attr_leafblock_t *leafp, int idx) 227xfs_attr3_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx)
162{ 228{
163 return (xfs_attr_leaf_name_local_t *) 229 return (xfs_attr_leaf_name_remote_t *)xfs_attr3_leaf_name(leafp, idx);
164 &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)];
165} 230}
166 231
167static inline char *xfs_attr_leaf_name(xfs_attr_leafblock_t *leafp, int idx) 232static inline xfs_attr_leaf_name_local_t *
233xfs_attr3_leaf_name_local(xfs_attr_leafblock_t *leafp, int idx)
168{ 234{
169 return &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)]; 235 return (xfs_attr_leaf_name_local_t *)xfs_attr3_leaf_name(leafp, idx);
170} 236}
171 237
172/* 238/*
@@ -221,37 +287,37 @@ int xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes);
221/* 287/*
222 * Internal routines when attribute fork size == XFS_LBSIZE(mp). 288 * Internal routines when attribute fork size == XFS_LBSIZE(mp).
223 */ 289 */
224int xfs_attr_leaf_to_node(struct xfs_da_args *args); 290int xfs_attr3_leaf_to_node(struct xfs_da_args *args);
225int xfs_attr_leaf_to_shortform(struct xfs_buf *bp, 291int xfs_attr3_leaf_to_shortform(struct xfs_buf *bp,
226 struct xfs_da_args *args, int forkoff); 292 struct xfs_da_args *args, int forkoff);
227int xfs_attr_leaf_clearflag(struct xfs_da_args *args); 293int xfs_attr3_leaf_clearflag(struct xfs_da_args *args);
228int xfs_attr_leaf_setflag(struct xfs_da_args *args); 294int xfs_attr3_leaf_setflag(struct xfs_da_args *args);
229int xfs_attr_leaf_flipflags(xfs_da_args_t *args); 295int xfs_attr3_leaf_flipflags(struct xfs_da_args *args);
230 296
231/* 297/*
232 * Routines used for growing the Btree. 298 * Routines used for growing the Btree.
233 */ 299 */
234int xfs_attr_leaf_split(struct xfs_da_state *state, 300int xfs_attr3_leaf_split(struct xfs_da_state *state,
235 struct xfs_da_state_blk *oldblk, 301 struct xfs_da_state_blk *oldblk,
236 struct xfs_da_state_blk *newblk); 302 struct xfs_da_state_blk *newblk);
237int xfs_attr_leaf_lookup_int(struct xfs_buf *leaf, 303int xfs_attr3_leaf_lookup_int(struct xfs_buf *leaf,
238 struct xfs_da_args *args); 304 struct xfs_da_args *args);
239int xfs_attr_leaf_getvalue(struct xfs_buf *bp, struct xfs_da_args *args); 305int xfs_attr3_leaf_getvalue(struct xfs_buf *bp, struct xfs_da_args *args);
240int xfs_attr_leaf_add(struct xfs_buf *leaf_buffer, 306int xfs_attr3_leaf_add(struct xfs_buf *leaf_buffer,
241 struct xfs_da_args *args); 307 struct xfs_da_args *args);
242int xfs_attr_leaf_remove(struct xfs_buf *leaf_buffer, 308int xfs_attr3_leaf_remove(struct xfs_buf *leaf_buffer,
243 struct xfs_da_args *args); 309 struct xfs_da_args *args);
244int xfs_attr_leaf_list_int(struct xfs_buf *bp, 310int xfs_attr3_leaf_list_int(struct xfs_buf *bp,
245 struct xfs_attr_list_context *context); 311 struct xfs_attr_list_context *context);
246 312
247/* 313/*
248 * Routines used for shrinking the Btree. 314 * Routines used for shrinking the Btree.
249 */ 315 */
250int xfs_attr_leaf_toosmall(struct xfs_da_state *state, int *retval); 316int xfs_attr3_leaf_toosmall(struct xfs_da_state *state, int *retval);
251void xfs_attr_leaf_unbalance(struct xfs_da_state *state, 317void xfs_attr3_leaf_unbalance(struct xfs_da_state *state,
252 struct xfs_da_state_blk *drop_blk, 318 struct xfs_da_state_blk *drop_blk,
253 struct xfs_da_state_blk *save_blk); 319 struct xfs_da_state_blk *save_blk);
254int xfs_attr_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp); 320int xfs_attr3_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp);
255 321
256/* 322/*
257 * Utility routines. 323 * Utility routines.
@@ -261,10 +327,12 @@ int xfs_attr_leaf_order(struct xfs_buf *leaf1_bp,
261 struct xfs_buf *leaf2_bp); 327 struct xfs_buf *leaf2_bp);
262int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, 328int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize,
263 int *local); 329 int *local);
264int xfs_attr_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, 330int xfs_attr3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp,
265 xfs_dablk_t bno, xfs_daddr_t mappedbno, 331 xfs_dablk_t bno, xfs_daddr_t mappedbno,
266 struct xfs_buf **bpp); 332 struct xfs_buf **bpp);
333void xfs_attr3_leaf_hdr_from_disk(struct xfs_attr3_icleaf_hdr *to,
334 struct xfs_attr_leafblock *from);
267 335
268extern const struct xfs_buf_ops xfs_attr_leaf_buf_ops; 336extern const struct xfs_buf_ops xfs_attr3_leaf_buf_ops;
269 337
270#endif /* __XFS_ATTR_LEAF_H__ */ 338#endif /* __XFS_ATTR_LEAF_H__ */
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index 6a1eb752af03..779ecdcdbe02 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -143,14 +143,14 @@ xfs_da3_node_hdr_from_disk(
143 to->forw = be32_to_cpu(hdr3->info.hdr.forw); 143 to->forw = be32_to_cpu(hdr3->info.hdr.forw);
144 to->back = be32_to_cpu(hdr3->info.hdr.back); 144 to->back = be32_to_cpu(hdr3->info.hdr.back);
145 to->magic = be16_to_cpu(hdr3->info.hdr.magic); 145 to->magic = be16_to_cpu(hdr3->info.hdr.magic);
146 to->count = be16_to_cpu(hdr3->count); 146 to->count = be16_to_cpu(hdr3->__count);
147 to->level = be16_to_cpu(hdr3->__level); 147 to->level = be16_to_cpu(hdr3->__level);
148 return; 148 return;
149 } 149 }
150 to->forw = be32_to_cpu(from->hdr.info.forw); 150 to->forw = be32_to_cpu(from->hdr.info.forw);
151 to->back = be32_to_cpu(from->hdr.info.back); 151 to->back = be32_to_cpu(from->hdr.info.back);
152 to->magic = be16_to_cpu(from->hdr.info.magic); 152 to->magic = be16_to_cpu(from->hdr.info.magic);
153 to->count = be16_to_cpu(from->hdr.count); 153 to->count = be16_to_cpu(from->hdr.__count);
154 to->level = be16_to_cpu(from->hdr.__level); 154 to->level = be16_to_cpu(from->hdr.__level);
155} 155}
156 156
@@ -168,14 +168,14 @@ xfs_da3_node_hdr_to_disk(
168 hdr3->info.hdr.forw = cpu_to_be32(from->forw); 168 hdr3->info.hdr.forw = cpu_to_be32(from->forw);
169 hdr3->info.hdr.back = cpu_to_be32(from->back); 169 hdr3->info.hdr.back = cpu_to_be32(from->back);
170 hdr3->info.hdr.magic = cpu_to_be16(from->magic); 170 hdr3->info.hdr.magic = cpu_to_be16(from->magic);
171 hdr3->count = cpu_to_be16(from->count); 171 hdr3->__count = cpu_to_be16(from->count);
172 hdr3->__level = cpu_to_be16(from->level); 172 hdr3->__level = cpu_to_be16(from->level);
173 return; 173 return;
174 } 174 }
175 to->hdr.info.forw = cpu_to_be32(from->forw); 175 to->hdr.info.forw = cpu_to_be32(from->forw);
176 to->hdr.info.back = cpu_to_be32(from->back); 176 to->hdr.info.back = cpu_to_be32(from->back);
177 to->hdr.info.magic = cpu_to_be16(from->magic); 177 to->hdr.info.magic = cpu_to_be16(from->magic);
178 to->hdr.count = cpu_to_be16(from->count); 178 to->hdr.__count = cpu_to_be16(from->count);
179 to->hdr.__level = cpu_to_be16(from->level); 179 to->hdr.__level = cpu_to_be16(from->level);
180} 180}
181 181
@@ -270,7 +270,7 @@ xfs_da3_node_read_verify(
270 break; 270 break;
271 return; 271 return;
272 case XFS_ATTR_LEAF_MAGIC: 272 case XFS_ATTR_LEAF_MAGIC:
273 bp->b_ops = &xfs_attr_leaf_buf_ops; 273 bp->b_ops = &xfs_attr3_leaf_buf_ops;
274 bp->b_ops->verify_read(bp); 274 bp->b_ops->verify_read(bp);
275 return; 275 return;
276 case XFS_DIR2_LEAFN_MAGIC: 276 case XFS_DIR2_LEAFN_MAGIC:
@@ -401,7 +401,7 @@ xfs_da3_split(
401 */ 401 */
402 switch (oldblk->magic) { 402 switch (oldblk->magic) {
403 case XFS_ATTR_LEAF_MAGIC: 403 case XFS_ATTR_LEAF_MAGIC:
404 error = xfs_attr_leaf_split(state, oldblk, newblk); 404 error = xfs_attr3_leaf_split(state, oldblk, newblk);
405 if ((error != 0) && (error != ENOSPC)) { 405 if ((error != 0) && (error != ENOSPC)) {
406 return(error); /* GROT: attr is inconsistent */ 406 return(error); /* GROT: attr is inconsistent */
407 } 407 }
@@ -416,12 +416,12 @@ xfs_da3_split(
416 if (state->inleaf) { 416 if (state->inleaf) {
417 state->extraafter = 0; /* before newblk */ 417 state->extraafter = 0; /* before newblk */
418 trace_xfs_attr_leaf_split_before(state->args); 418 trace_xfs_attr_leaf_split_before(state->args);
419 error = xfs_attr_leaf_split(state, oldblk, 419 error = xfs_attr3_leaf_split(state, oldblk,
420 &state->extrablk); 420 &state->extrablk);
421 } else { 421 } else {
422 state->extraafter = 1; /* after newblk */ 422 state->extraafter = 1; /* after newblk */
423 trace_xfs_attr_leaf_split_after(state->args); 423 trace_xfs_attr_leaf_split_after(state->args);
424 error = xfs_attr_leaf_split(state, newblk, 424 error = xfs_attr3_leaf_split(state, newblk,
425 &state->extrablk); 425 &state->extrablk);
426 } 426 }
427 if (error) 427 if (error)
@@ -963,12 +963,12 @@ xfs_da3_join(
963 */ 963 */
964 switch (drop_blk->magic) { 964 switch (drop_blk->magic) {
965 case XFS_ATTR_LEAF_MAGIC: 965 case XFS_ATTR_LEAF_MAGIC:
966 error = xfs_attr_leaf_toosmall(state, &action); 966 error = xfs_attr3_leaf_toosmall(state, &action);
967 if (error) 967 if (error)
968 return(error); 968 return(error);
969 if (action == 0) 969 if (action == 0)
970 return(0); 970 return(0);
971 xfs_attr_leaf_unbalance(state, drop_blk, save_blk); 971 xfs_attr3_leaf_unbalance(state, drop_blk, save_blk);
972 break; 972 break;
973 case XFS_DIR2_LEAFN_MAGIC: 973 case XFS_DIR2_LEAFN_MAGIC:
974 error = xfs_dir2_leafn_toosmall(state, &action); 974 error = xfs_dir2_leafn_toosmall(state, &action);
@@ -1024,7 +1024,8 @@ xfs_da_blkinfo_onlychild_validate(struct xfs_da_blkinfo *blkinfo, __u16 level)
1024 if (level == 1) { 1024 if (level == 1) {
1025 ASSERT(magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || 1025 ASSERT(magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
1026 magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC) || 1026 magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC) ||
1027 magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1027 magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC) ||
1028 magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC));
1028 } else { 1029 } else {
1029 ASSERT(magic == cpu_to_be16(XFS_DA_NODE_MAGIC) || 1030 ASSERT(magic == cpu_to_be16(XFS_DA_NODE_MAGIC) ||
1030 magic == cpu_to_be16(XFS_DA3_NODE_MAGIC)); 1031 magic == cpu_to_be16(XFS_DA3_NODE_MAGIC));
@@ -1482,7 +1483,9 @@ xfs_da3_node_lookup_int(
1482 curr = blk->bp->b_addr; 1483 curr = blk->bp->b_addr;
1483 blk->magic = be16_to_cpu(curr->magic); 1484 blk->magic = be16_to_cpu(curr->magic);
1484 1485
1485 if (blk->magic == XFS_ATTR_LEAF_MAGIC) { 1486 if (blk->magic == XFS_ATTR_LEAF_MAGIC ||
1487 blk->magic == XFS_ATTR3_LEAF_MAGIC) {
1488 blk->magic = XFS_ATTR_LEAF_MAGIC;
1486 blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); 1489 blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL);
1487 break; 1490 break;
1488 } 1491 }
@@ -1562,7 +1565,7 @@ xfs_da3_node_lookup_int(
1562 retval = xfs_dir2_leafn_lookup_int(blk->bp, args, 1565 retval = xfs_dir2_leafn_lookup_int(blk->bp, args,
1563 &blk->index, state); 1566 &blk->index, state);
1564 } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { 1567 } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
1565 retval = xfs_attr_leaf_lookup_int(blk->bp, args); 1568 retval = xfs_attr3_leaf_lookup_int(blk->bp, args);
1566 blk->index = args->index; 1569 blk->index = args->index;
1567 args->blkno = blk->blkno; 1570 args->blkno = blk->blkno;
1568 } else { 1571 } else {
@@ -1874,7 +1877,8 @@ xfs_da3_path_shift(
1874 info->magic == cpu_to_be16(XFS_DA3_NODE_MAGIC) || 1877 info->magic == cpu_to_be16(XFS_DA3_NODE_MAGIC) ||
1875 info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || 1878 info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
1876 info->magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC) || 1879 info->magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC) ||
1877 info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1880 info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC) ||
1881 info->magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC));
1878 1882
1879 1883
1880 /* 1884 /*
@@ -1896,6 +1900,7 @@ xfs_da3_path_shift(
1896 blkno = be32_to_cpu(btree[blk->index].before); 1900 blkno = be32_to_cpu(btree[blk->index].before);
1897 break; 1901 break;
1898 case XFS_ATTR_LEAF_MAGIC: 1902 case XFS_ATTR_LEAF_MAGIC:
1903 case XFS_ATTR3_LEAF_MAGIC:
1899 blk->magic = XFS_ATTR_LEAF_MAGIC; 1904 blk->magic = XFS_ATTR_LEAF_MAGIC;
1900 ASSERT(level == path->active-1); 1905 ASSERT(level == path->active-1);
1901 blk->index = 0; 1906 blk->index = 0;
@@ -2626,6 +2631,7 @@ xfs_da_read_buf(
2626 XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && 2631 XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
2627 (magic != XFS_DA3_NODE_MAGIC) && 2632 (magic != XFS_DA3_NODE_MAGIC) &&
2628 (magic != XFS_ATTR_LEAF_MAGIC) && 2633 (magic != XFS_ATTR_LEAF_MAGIC) &&
2634 (magic != XFS_ATTR3_LEAF_MAGIC) &&
2629 (magic != XFS_DIR2_LEAF1_MAGIC) && 2635 (magic != XFS_DIR2_LEAF1_MAGIC) &&
2630 (magic != XFS_DIR3_LEAF1_MAGIC) && 2636 (magic != XFS_DIR3_LEAF1_MAGIC) &&
2631 (magic != XFS_DIR2_LEAFN_MAGIC) && 2637 (magic != XFS_DIR2_LEAFN_MAGIC) &&
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h
index 6bedb3c1f5d3..0e8182c5210b 100644
--- a/fs/xfs/xfs_da_btree.h
+++ b/fs/xfs/xfs_da_btree.h
@@ -55,6 +55,7 @@ typedef struct xfs_da_blkinfo {
55 * magic numbers without modification for both v2 and v3 nodes. 55 * magic numbers without modification for both v2 and v3 nodes.
56 */ 56 */
57#define XFS_DA3_NODE_MAGIC 0x3ebe /* magic number: non-leaf blocks */ 57#define XFS_DA3_NODE_MAGIC 0x3ebe /* magic number: non-leaf blocks */
58#define XFS_ATTR3_LEAF_MAGIC 0x3bee /* magic number: attribute leaf blks */
58#define XFS_DIR3_LEAF1_MAGIC 0x3df1 /* magic number: v2 dirlf single blks */ 59#define XFS_DIR3_LEAF1_MAGIC 0x3df1 /* magic number: v2 dirlf single blks */
59#define XFS_DIR3_LEAFN_MAGIC 0x3dff /* magic number: v2 dirlf multi blks */ 60#define XFS_DIR3_LEAFN_MAGIC 0x3dff /* magic number: v2 dirlf multi blks */
60 61
@@ -85,13 +86,13 @@ struct xfs_da3_blkinfo {
85 86
86typedef struct xfs_da_node_hdr { 87typedef struct xfs_da_node_hdr {
87 struct xfs_da_blkinfo info; /* block type, links, etc. */ 88 struct xfs_da_blkinfo info; /* block type, links, etc. */
88 __be16 count; /* count of active entries */ 89 __be16 __count; /* count of active entries */
89 __be16 __level; /* level above leaves (leaf == 0) */ 90 __be16 __level; /* level above leaves (leaf == 0) */
90} xfs_da_node_hdr_t; 91} xfs_da_node_hdr_t;
91 92
92struct xfs_da3_node_hdr { 93struct xfs_da3_node_hdr {
93 struct xfs_da3_blkinfo info; /* block type, links, etc. */ 94 struct xfs_da3_blkinfo info; /* block type, links, etc. */
94 __be16 count; /* count of active entries */ 95 __be16 __count; /* count of active entries */
95 __be16 __level; /* level above leaves (leaf == 0) */ 96 __be16 __level; /* level above leaves (leaf == 0) */
96 __be32 __pad32; 97 __be32 __pad32;
97}; 98};