aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDave Chinner <david@fromorbit.com>2013-10-29 07:11:51 -0400
committerBen Myers <bpm@sgi.com>2013-10-30 14:43:28 -0400
commit4bceb18f1551c8c047eeb54d48cda9f5453dc12f (patch)
tree913bd230913f0a09e7131af633985b7b55c6d891 /fs
parent4141956ae05e0685b14b30f92fdc8fb11b4a0cb2 (diff)
xfs: vectorise DA btree operations
The remaining non-vectorised code for the directory structure is the node format blocks. This is shared with the attribute tree, and so is slightly more complex to vectorise. Introduce a "non-directory" directory ops structure that is attached to all non-directory inodes so that attribute operations can be vectorised for all inodes. Once we do this, we can vectorise all the da btree operations. Because this patch adds more infrastructure than it removes the binary size does not decrease: text data bss dec hex filename 794490 96802 1096 892388 d9de4 fs/xfs/xfs.o.orig 792986 96802 1096 890884 d9804 fs/xfs/xfs.o.p1 792350 96802 1096 890248 d9588 fs/xfs/xfs.o.p2 789293 96802 1096 887191 d8997 fs/xfs/xfs.o.p3 789005 96802 1096 886903 d8997 fs/xfs/xfs.o.p4 789061 96802 1096 886959 d88af fs/xfs/xfs.o.p5 789733 96802 1096 887631 d8b4f fs/xfs/xfs.o.p6 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')
-rw-r--r--fs/xfs/xfs_attr_inactive.c3
-rw-r--r--fs/xfs/xfs_attr_leaf.c3
-rw-r--r--fs/xfs/xfs_attr_list.c11
-rw-r--r--fs/xfs/xfs_da_btree.c104
-rw-r--r--fs/xfs/xfs_da_format.c59
-rw-r--r--fs/xfs/xfs_da_format.h25
-rw-r--r--fs/xfs/xfs_dir2.c7
-rw-r--r--fs/xfs/xfs_dir2.h6
-rw-r--r--fs/xfs/xfs_iops.c1
-rw-r--r--fs/xfs/xfs_mount.h1
10 files changed, 139 insertions, 81 deletions
diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c
index f33fb62b7f17..4855085f8c6b 100644
--- a/fs/xfs/xfs_attr_inactive.c
+++ b/fs/xfs/xfs_attr_inactive.c
@@ -40,6 +40,7 @@
40#include "xfs_quota.h" 40#include "xfs_quota.h"
41#include "xfs_trace.h" 41#include "xfs_trace.h"
42#include "xfs_dinode.h" 42#include "xfs_dinode.h"
43#include "xfs_dir2.h"
43 44
44/* 45/*
45 * Look at all the extents for this logical region, 46 * Look at all the extents for this logical region,
@@ -236,7 +237,7 @@ xfs_attr3_node_inactive(
236 xfs_trans_brelse(*trans, bp); 237 xfs_trans_brelse(*trans, bp);
237 return 0; 238 return 0;
238 } 239 }
239 btree = xfs_da3_node_tree_p(node); 240 btree = dp->d_ops->node_tree_p(node);
240 child_fsb = be32_to_cpu(btree[0].before); 241 child_fsb = be32_to_cpu(btree[0].before);
241 xfs_trans_brelse(*trans, bp); /* no locks for later trans */ 242 xfs_trans_brelse(*trans, bp); /* no locks for later trans */
242 243
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index a0f90193a247..82f1354c77b6 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -41,6 +41,7 @@
41#include "xfs_buf_item.h" 41#include "xfs_buf_item.h"
42#include "xfs_cksum.h" 42#include "xfs_cksum.h"
43#include "xfs_dinode.h" 43#include "xfs_dinode.h"
44#include "xfs_dir2.h"
44 45
45 46
46/* 47/*
@@ -916,7 +917,7 @@ xfs_attr3_leaf_to_node(
916 goto out; 917 goto out;
917 node = bp1->b_addr; 918 node = bp1->b_addr;
918 xfs_da3_node_hdr_from_disk(&icnodehdr, node); 919 xfs_da3_node_hdr_from_disk(&icnodehdr, node);
919 btree = xfs_da3_node_tree_p(node); 920 btree = dp->d_ops->node_tree_p(node);
920 921
921 leaf = bp2->b_addr; 922 leaf = bp2->b_addr;
922 xfs_attr3_leaf_hdr_from_disk(&icleafhdr, leaf); 923 xfs_attr3_leaf_hdr_from_disk(&icleafhdr, leaf);
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
index 46c4ce148a43..ea1c4c46c24f 100644
--- a/fs/xfs/xfs_attr_list.c
+++ b/fs/xfs/xfs_attr_list.c
@@ -40,6 +40,7 @@
40#include "xfs_buf_item.h" 40#include "xfs_buf_item.h"
41#include "xfs_cksum.h" 41#include "xfs_cksum.h"
42#include "xfs_dinode.h" 42#include "xfs_dinode.h"
43#include "xfs_dir2.h"
43 44
44STATIC int 45STATIC int
45xfs_attr_shortform_compare(const void *a, const void *b) 46xfs_attr_shortform_compare(const void *a, const void *b)
@@ -226,6 +227,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
226 struct xfs_da_node_entry *btree; 227 struct xfs_da_node_entry *btree;
227 int error, i; 228 int error, i;
228 struct xfs_buf *bp; 229 struct xfs_buf *bp;
230 struct xfs_inode *dp = context->dp;
229 231
230 trace_xfs_attr_node_list(context); 232 trace_xfs_attr_node_list(context);
231 233
@@ -239,7 +241,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
239 */ 241 */
240 bp = NULL; 242 bp = NULL;
241 if (cursor->blkno > 0) { 243 if (cursor->blkno > 0) {
242 error = xfs_da3_node_read(NULL, context->dp, cursor->blkno, -1, 244 error = xfs_da3_node_read(NULL, dp, cursor->blkno, -1,
243 &bp, XFS_ATTR_FORK); 245 &bp, XFS_ATTR_FORK);
244 if ((error != 0) && (error != EFSCORRUPTED)) 246 if ((error != 0) && (error != EFSCORRUPTED))
245 return(error); 247 return(error);
@@ -289,7 +291,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
289 for (;;) { 291 for (;;) {
290 __uint16_t magic; 292 __uint16_t magic;
291 293
292 error = xfs_da3_node_read(NULL, context->dp, 294 error = xfs_da3_node_read(NULL, dp,
293 cursor->blkno, -1, &bp, 295 cursor->blkno, -1, &bp,
294 XFS_ATTR_FORK); 296 XFS_ATTR_FORK);
295 if (error) 297 if (error)
@@ -310,7 +312,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
310 } 312 }
311 313
312 xfs_da3_node_hdr_from_disk(&nodehdr, node); 314 xfs_da3_node_hdr_from_disk(&nodehdr, node);
313 btree = xfs_da3_node_tree_p(node); 315 btree = dp->d_ops->node_tree_p(node);
314 for (i = 0; i < nodehdr.count; btree++, i++) { 316 for (i = 0; i < nodehdr.count; btree++, i++) {
315 if (cursor->hashval 317 if (cursor->hashval
316 <= be32_to_cpu(btree->hashval)) { 318 <= be32_to_cpu(btree->hashval)) {
@@ -346,8 +348,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
346 break; 348 break;
347 cursor->blkno = leafhdr.forw; 349 cursor->blkno = leafhdr.forw;
348 xfs_trans_brelse(NULL, bp); 350 xfs_trans_brelse(NULL, bp);
349 error = xfs_attr3_leaf_read(NULL, context->dp, cursor->blkno, -1, 351 error = xfs_attr3_leaf_read(NULL, dp, cursor->blkno, -1, &bp);
350 &bp);
351 if (error) 352 if (error)
352 return error; 353 return error;
353 } 354 }
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index df3759c51470..26dfc42a28f9 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -379,7 +379,8 @@ xfs_da3_node_create(
379 379
380 xfs_da3_node_hdr_to_disk(node, &ichdr); 380 xfs_da3_node_hdr_to_disk(node, &ichdr);
381 xfs_trans_log_buf(tp, bp, 381 xfs_trans_log_buf(tp, bp,
382 XFS_DA_LOGRANGE(node, &node->hdr, xfs_da3_node_hdr_size(node))); 382 XFS_DA_LOGRANGE(node, &node->hdr,
383 args->dp->d_ops->node_hdr_size()));
383 384
384 *bpp = bp; 385 *bpp = bp;
385 return(0); 386 return(0);
@@ -590,7 +591,7 @@ xfs_da3_root_split(
590 struct xfs_da3_icnode_hdr nodehdr; 591 struct xfs_da3_icnode_hdr nodehdr;
591 592
592 xfs_da3_node_hdr_from_disk(&nodehdr, oldroot); 593 xfs_da3_node_hdr_from_disk(&nodehdr, oldroot);
593 btree = xfs_da3_node_tree_p(oldroot); 594 btree = dp->d_ops->node_tree_p(oldroot);
594 size = (int)((char *)&btree[nodehdr.count] - (char *)oldroot); 595 size = (int)((char *)&btree[nodehdr.count] - (char *)oldroot);
595 level = nodehdr.level; 596 level = nodehdr.level;
596 597
@@ -650,7 +651,7 @@ xfs_da3_root_split(
650 651
651 node = bp->b_addr; 652 node = bp->b_addr;
652 xfs_da3_node_hdr_from_disk(&nodehdr, node); 653 xfs_da3_node_hdr_from_disk(&nodehdr, node);
653 btree = xfs_da3_node_tree_p(node); 654 btree = dp->d_ops->node_tree_p(node);
654 btree[0].hashval = cpu_to_be32(blk1->hashval); 655 btree[0].hashval = cpu_to_be32(blk1->hashval);
655 btree[0].before = cpu_to_be32(blk1->blkno); 656 btree[0].before = cpu_to_be32(blk1->blkno);
656 btree[1].hashval = cpu_to_be32(blk2->hashval); 657 btree[1].hashval = cpu_to_be32(blk2->hashval);
@@ -793,6 +794,7 @@ xfs_da3_node_rebalance(
793 int count; 794 int count;
794 int tmp; 795 int tmp;
795 int swap = 0; 796 int swap = 0;
797 struct xfs_inode *dp = state->args->dp;
796 798
797 trace_xfs_da_node_rebalance(state->args); 799 trace_xfs_da_node_rebalance(state->args);
798 800
@@ -800,8 +802,8 @@ xfs_da3_node_rebalance(
800 node2 = blk2->bp->b_addr; 802 node2 = blk2->bp->b_addr;
801 xfs_da3_node_hdr_from_disk(&nodehdr1, node1); 803 xfs_da3_node_hdr_from_disk(&nodehdr1, node1);
802 xfs_da3_node_hdr_from_disk(&nodehdr2, node2); 804 xfs_da3_node_hdr_from_disk(&nodehdr2, node2);
803 btree1 = xfs_da3_node_tree_p(node1); 805 btree1 = dp->d_ops->node_tree_p(node1);
804 btree2 = xfs_da3_node_tree_p(node2); 806 btree2 = dp->d_ops->node_tree_p(node2);
805 807
806 /* 808 /*
807 * Figure out how many entries need to move, and in which direction. 809 * Figure out how many entries need to move, and in which direction.
@@ -816,8 +818,8 @@ xfs_da3_node_rebalance(
816 node2 = tmpnode; 818 node2 = tmpnode;
817 xfs_da3_node_hdr_from_disk(&nodehdr1, node1); 819 xfs_da3_node_hdr_from_disk(&nodehdr1, node1);
818 xfs_da3_node_hdr_from_disk(&nodehdr2, node2); 820 xfs_da3_node_hdr_from_disk(&nodehdr2, node2);
819 btree1 = xfs_da3_node_tree_p(node1); 821 btree1 = dp->d_ops->node_tree_p(node1);
820 btree2 = xfs_da3_node_tree_p(node2); 822 btree2 = dp->d_ops->node_tree_p(node2);
821 swap = 1; 823 swap = 1;
822 } 824 }
823 825
@@ -882,12 +884,12 @@ xfs_da3_node_rebalance(
882 xfs_da3_node_hdr_to_disk(node1, &nodehdr1); 884 xfs_da3_node_hdr_to_disk(node1, &nodehdr1);
883 xfs_trans_log_buf(tp, blk1->bp, 885 xfs_trans_log_buf(tp, blk1->bp,
884 XFS_DA_LOGRANGE(node1, &node1->hdr, 886 XFS_DA_LOGRANGE(node1, &node1->hdr,
885 xfs_da3_node_hdr_size(node1))); 887 dp->d_ops->node_hdr_size()));
886 888
887 xfs_da3_node_hdr_to_disk(node2, &nodehdr2); 889 xfs_da3_node_hdr_to_disk(node2, &nodehdr2);
888 xfs_trans_log_buf(tp, blk2->bp, 890 xfs_trans_log_buf(tp, blk2->bp,
889 XFS_DA_LOGRANGE(node2, &node2->hdr, 891 XFS_DA_LOGRANGE(node2, &node2->hdr,
890 xfs_da3_node_hdr_size(node2) + 892 dp->d_ops->node_hdr_size() +
891 (sizeof(btree2[0]) * nodehdr2.count))); 893 (sizeof(btree2[0]) * nodehdr2.count)));
892 894
893 /* 895 /*
@@ -899,8 +901,8 @@ xfs_da3_node_rebalance(
899 node2 = blk2->bp->b_addr; 901 node2 = blk2->bp->b_addr;
900 xfs_da3_node_hdr_from_disk(&nodehdr1, node1); 902 xfs_da3_node_hdr_from_disk(&nodehdr1, node1);
901 xfs_da3_node_hdr_from_disk(&nodehdr2, node2); 903 xfs_da3_node_hdr_from_disk(&nodehdr2, node2);
902 btree1 = xfs_da3_node_tree_p(node1); 904 btree1 = dp->d_ops->node_tree_p(node1);
903 btree2 = xfs_da3_node_tree_p(node2); 905 btree2 = dp->d_ops->node_tree_p(node2);
904 } 906 }
905 blk1->hashval = be32_to_cpu(btree1[nodehdr1.count - 1].hashval); 907 blk1->hashval = be32_to_cpu(btree1[nodehdr1.count - 1].hashval);
906 blk2->hashval = be32_to_cpu(btree2[nodehdr2.count - 1].hashval); 908 blk2->hashval = be32_to_cpu(btree2[nodehdr2.count - 1].hashval);
@@ -927,12 +929,13 @@ xfs_da3_node_add(
927 struct xfs_da3_icnode_hdr nodehdr; 929 struct xfs_da3_icnode_hdr nodehdr;
928 struct xfs_da_node_entry *btree; 930 struct xfs_da_node_entry *btree;
929 int tmp; 931 int tmp;
932 struct xfs_inode *dp = state->args->dp;
930 933
931 trace_xfs_da_node_add(state->args); 934 trace_xfs_da_node_add(state->args);
932 935
933 node = oldblk->bp->b_addr; 936 node = oldblk->bp->b_addr;
934 xfs_da3_node_hdr_from_disk(&nodehdr, node); 937 xfs_da3_node_hdr_from_disk(&nodehdr, node);
935 btree = xfs_da3_node_tree_p(node); 938 btree = dp->d_ops->node_tree_p(node);
936 939
937 ASSERT(oldblk->index >= 0 && oldblk->index <= nodehdr.count); 940 ASSERT(oldblk->index >= 0 && oldblk->index <= nodehdr.count);
938 ASSERT(newblk->blkno != 0); 941 ASSERT(newblk->blkno != 0);
@@ -957,7 +960,7 @@ xfs_da3_node_add(
957 nodehdr.count += 1; 960 nodehdr.count += 1;
958 xfs_da3_node_hdr_to_disk(node, &nodehdr); 961 xfs_da3_node_hdr_to_disk(node, &nodehdr);
959 xfs_trans_log_buf(state->args->trans, oldblk->bp, 962 xfs_trans_log_buf(state->args->trans, oldblk->bp,
960 XFS_DA_LOGRANGE(node, &node->hdr, xfs_da3_node_hdr_size(node))); 963 XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size()));
961 964
962 /* 965 /*
963 * Copy the last hash value from the oldblk to propagate upwards. 966 * Copy the last hash value from the oldblk to propagate upwards.
@@ -1115,7 +1118,7 @@ xfs_da3_root_join(
1115 * Read in the (only) child block, then copy those bytes into 1118 * Read in the (only) child block, then copy those bytes into
1116 * the root block's buffer and free the original child block. 1119 * the root block's buffer and free the original child block.
1117 */ 1120 */
1118 btree = xfs_da3_node_tree_p(oldroot); 1121 btree = args->dp->d_ops->node_tree_p(oldroot);
1119 child = be32_to_cpu(btree[0].before); 1122 child = be32_to_cpu(btree[0].before);
1120 ASSERT(child != 0); 1123 ASSERT(child != 0);
1121 error = xfs_da3_node_read(args->trans, args->dp, child, -1, &bp, 1124 error = xfs_da3_node_read(args->trans, args->dp, child, -1, &bp,
@@ -1275,6 +1278,7 @@ xfs_da3_node_toosmall(
1275 */ 1278 */
1276STATIC uint 1279STATIC uint
1277xfs_da3_node_lasthash( 1280xfs_da3_node_lasthash(
1281 struct xfs_inode *dp,
1278 struct xfs_buf *bp, 1282 struct xfs_buf *bp,
1279 int *count) 1283 int *count)
1280{ 1284{
@@ -1288,7 +1292,7 @@ xfs_da3_node_lasthash(
1288 *count = nodehdr.count; 1292 *count = nodehdr.count;
1289 if (!nodehdr.count) 1293 if (!nodehdr.count)
1290 return 0; 1294 return 0;
1291 btree = xfs_da3_node_tree_p(node); 1295 btree = dp->d_ops->node_tree_p(node);
1292 return be32_to_cpu(btree[nodehdr.count - 1].hashval); 1296 return be32_to_cpu(btree[nodehdr.count - 1].hashval);
1293} 1297}
1294 1298
@@ -1307,6 +1311,7 @@ xfs_da3_fixhashpath(
1307 xfs_dahash_t lasthash=0; 1311 xfs_dahash_t lasthash=0;
1308 int level; 1312 int level;
1309 int count; 1313 int count;
1314 struct xfs_inode *dp = state->args->dp;
1310 1315
1311 trace_xfs_da_fixhashpath(state->args); 1316 trace_xfs_da_fixhashpath(state->args);
1312 1317
@@ -1319,13 +1324,12 @@ xfs_da3_fixhashpath(
1319 return; 1324 return;
1320 break; 1325 break;
1321 case XFS_DIR2_LEAFN_MAGIC: 1326 case XFS_DIR2_LEAFN_MAGIC:
1322 lasthash = xfs_dir2_leafn_lasthash(state->args->dp, 1327 lasthash = xfs_dir2_leafn_lasthash(dp, blk->bp, &count);
1323 blk->bp, &count);
1324 if (count == 0) 1328 if (count == 0)
1325 return; 1329 return;
1326 break; 1330 break;
1327 case XFS_DA_NODE_MAGIC: 1331 case XFS_DA_NODE_MAGIC:
1328 lasthash = xfs_da3_node_lasthash(blk->bp, &count); 1332 lasthash = xfs_da3_node_lasthash(dp, blk->bp, &count);
1329 if (count == 0) 1333 if (count == 0)
1330 return; 1334 return;
1331 break; 1335 break;
@@ -1335,7 +1339,7 @@ xfs_da3_fixhashpath(
1335 1339
1336 node = blk->bp->b_addr; 1340 node = blk->bp->b_addr;
1337 xfs_da3_node_hdr_from_disk(&nodehdr, node); 1341 xfs_da3_node_hdr_from_disk(&nodehdr, node);
1338 btree = xfs_da3_node_tree_p(node); 1342 btree = dp->d_ops->node_tree_p(node);
1339 if (be32_to_cpu(btree->hashval) == lasthash) 1343 if (be32_to_cpu(btree->hashval) == lasthash)
1340 break; 1344 break;
1341 blk->hashval = lasthash; 1345 blk->hashval = lasthash;
@@ -1361,6 +1365,7 @@ xfs_da3_node_remove(
1361 struct xfs_da_node_entry *btree; 1365 struct xfs_da_node_entry *btree;
1362 int index; 1366 int index;
1363 int tmp; 1367 int tmp;
1368 struct xfs_inode *dp = state->args->dp;
1364 1369
1365 trace_xfs_da_node_remove(state->args); 1370 trace_xfs_da_node_remove(state->args);
1366 1371
@@ -1373,7 +1378,7 @@ xfs_da3_node_remove(
1373 * Copy over the offending entry, or just zero it out. 1378 * Copy over the offending entry, or just zero it out.
1374 */ 1379 */
1375 index = drop_blk->index; 1380 index = drop_blk->index;
1376 btree = xfs_da3_node_tree_p(node); 1381 btree = dp->d_ops->node_tree_p(node);
1377 if (index < nodehdr.count - 1) { 1382 if (index < nodehdr.count - 1) {
1378 tmp = nodehdr.count - index - 1; 1383 tmp = nodehdr.count - index - 1;
1379 tmp *= (uint)sizeof(xfs_da_node_entry_t); 1384 tmp *= (uint)sizeof(xfs_da_node_entry_t);
@@ -1388,7 +1393,7 @@ xfs_da3_node_remove(
1388 nodehdr.count -= 1; 1393 nodehdr.count -= 1;
1389 xfs_da3_node_hdr_to_disk(node, &nodehdr); 1394 xfs_da3_node_hdr_to_disk(node, &nodehdr);
1390 xfs_trans_log_buf(state->args->trans, drop_blk->bp, 1395 xfs_trans_log_buf(state->args->trans, drop_blk->bp,
1391 XFS_DA_LOGRANGE(node, &node->hdr, xfs_da3_node_hdr_size(node))); 1396 XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size()));
1392 1397
1393 /* 1398 /*
1394 * Copy the last hash value from the block to propagate upwards. 1399 * Copy the last hash value from the block to propagate upwards.
@@ -1415,6 +1420,7 @@ xfs_da3_node_unbalance(
1415 struct xfs_trans *tp; 1420 struct xfs_trans *tp;
1416 int sindex; 1421 int sindex;
1417 int tmp; 1422 int tmp;
1423 struct xfs_inode *dp = state->args->dp;
1418 1424
1419 trace_xfs_da_node_unbalance(state->args); 1425 trace_xfs_da_node_unbalance(state->args);
1420 1426
@@ -1422,8 +1428,8 @@ xfs_da3_node_unbalance(
1422 save_node = save_blk->bp->b_addr; 1428 save_node = save_blk->bp->b_addr;
1423 xfs_da3_node_hdr_from_disk(&drop_hdr, drop_node); 1429 xfs_da3_node_hdr_from_disk(&drop_hdr, drop_node);
1424 xfs_da3_node_hdr_from_disk(&save_hdr, save_node); 1430 xfs_da3_node_hdr_from_disk(&save_hdr, save_node);
1425 drop_btree = xfs_da3_node_tree_p(drop_node); 1431 drop_btree = dp->d_ops->node_tree_p(drop_node);
1426 save_btree = xfs_da3_node_tree_p(save_node); 1432 save_btree = dp->d_ops->node_tree_p(save_node);
1427 tp = state->args->trans; 1433 tp = state->args->trans;
1428 1434
1429 /* 1435 /*
@@ -1460,7 +1466,7 @@ xfs_da3_node_unbalance(
1460 xfs_da3_node_hdr_to_disk(save_node, &save_hdr); 1466 xfs_da3_node_hdr_to_disk(save_node, &save_hdr);
1461 xfs_trans_log_buf(tp, save_blk->bp, 1467 xfs_trans_log_buf(tp, save_blk->bp,
1462 XFS_DA_LOGRANGE(save_node, &save_node->hdr, 1468 XFS_DA_LOGRANGE(save_node, &save_node->hdr,
1463 xfs_da3_node_hdr_size(save_node))); 1469 dp->d_ops->node_hdr_size()));
1464 1470
1465 /* 1471 /*
1466 * Save the last hashval in the remaining block for upward propagation. 1472 * Save the last hashval in the remaining block for upward propagation.
@@ -1502,6 +1508,7 @@ xfs_da3_node_lookup_int(
1502 int max; 1508 int max;
1503 int error; 1509 int error;
1504 int retval; 1510 int retval;
1511 struct xfs_inode *dp = state->args->dp;
1505 1512
1506 args = state->args; 1513 args = state->args;
1507 1514
@@ -1550,7 +1557,7 @@ xfs_da3_node_lookup_int(
1550 */ 1557 */
1551 node = blk->bp->b_addr; 1558 node = blk->bp->b_addr;
1552 xfs_da3_node_hdr_from_disk(&nodehdr, node); 1559 xfs_da3_node_hdr_from_disk(&nodehdr, node);
1553 btree = xfs_da3_node_tree_p(node); 1560 btree = dp->d_ops->node_tree_p(node);
1554 1561
1555 max = nodehdr.count; 1562 max = nodehdr.count;
1556 blk->hashval = be32_to_cpu(btree[max - 1].hashval); 1563 blk->hashval = be32_to_cpu(btree[max - 1].hashval);
@@ -1645,6 +1652,7 @@ xfs_da3_node_lookup_int(
1645 */ 1652 */
1646STATIC int 1653STATIC int
1647xfs_da3_node_order( 1654xfs_da3_node_order(
1655 struct xfs_inode *dp,
1648 struct xfs_buf *node1_bp, 1656 struct xfs_buf *node1_bp,
1649 struct xfs_buf *node2_bp) 1657 struct xfs_buf *node2_bp)
1650{ 1658{
@@ -1659,8 +1667,8 @@ xfs_da3_node_order(
1659 node2 = node2_bp->b_addr; 1667 node2 = node2_bp->b_addr;
1660 xfs_da3_node_hdr_from_disk(&node1hdr, node1); 1668 xfs_da3_node_hdr_from_disk(&node1hdr, node1);
1661 xfs_da3_node_hdr_from_disk(&node2hdr, node2); 1669 xfs_da3_node_hdr_from_disk(&node2hdr, node2);
1662 btree1 = xfs_da3_node_tree_p(node1); 1670 btree1 = dp->d_ops->node_tree_p(node1);
1663 btree2 = xfs_da3_node_tree_p(node2); 1671 btree2 = dp->d_ops->node_tree_p(node2);
1664 1672
1665 if (node1hdr.count > 0 && node2hdr.count > 0 && 1673 if (node1hdr.count > 0 && node2hdr.count > 0 &&
1666 ((be32_to_cpu(btree2[0].hashval) < be32_to_cpu(btree1[0].hashval)) || 1674 ((be32_to_cpu(btree2[0].hashval) < be32_to_cpu(btree1[0].hashval)) ||
@@ -1687,6 +1695,7 @@ xfs_da3_blk_link(
1687 struct xfs_buf *bp; 1695 struct xfs_buf *bp;
1688 int before = 0; 1696 int before = 0;
1689 int error; 1697 int error;
1698 struct xfs_inode *dp = state->args->dp;
1690 1699
1691 /* 1700 /*
1692 * Set up environment. 1701 * Set up environment.
@@ -1704,10 +1713,10 @@ xfs_da3_blk_link(
1704 before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp); 1713 before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp);
1705 break; 1714 break;
1706 case XFS_DIR2_LEAFN_MAGIC: 1715 case XFS_DIR2_LEAFN_MAGIC:
1707 before = xfs_dir2_leafn_order(args->dp, old_blk->bp, new_blk->bp); 1716 before = xfs_dir2_leafn_order(dp, old_blk->bp, new_blk->bp);
1708 break; 1717 break;
1709 case XFS_DA_NODE_MAGIC: 1718 case XFS_DA_NODE_MAGIC:
1710 before = xfs_da3_node_order(old_blk->bp, new_blk->bp); 1719 before = xfs_da3_node_order(dp, old_blk->bp, new_blk->bp);
1711 break; 1720 break;
1712 } 1721 }
1713 1722
@@ -1722,7 +1731,7 @@ xfs_da3_blk_link(
1722 new_info->forw = cpu_to_be32(old_blk->blkno); 1731 new_info->forw = cpu_to_be32(old_blk->blkno);
1723 new_info->back = old_info->back; 1732 new_info->back = old_info->back;
1724 if (old_info->back) { 1733 if (old_info->back) {
1725 error = xfs_da3_node_read(args->trans, args->dp, 1734 error = xfs_da3_node_read(args->trans, dp,
1726 be32_to_cpu(old_info->back), 1735 be32_to_cpu(old_info->back),
1727 -1, &bp, args->whichfork); 1736 -1, &bp, args->whichfork);
1728 if (error) 1737 if (error)
@@ -1743,7 +1752,7 @@ xfs_da3_blk_link(
1743 new_info->forw = old_info->forw; 1752 new_info->forw = old_info->forw;
1744 new_info->back = cpu_to_be32(old_blk->blkno); 1753 new_info->back = cpu_to_be32(old_blk->blkno);
1745 if (old_info->forw) { 1754 if (old_info->forw) {
1746 error = xfs_da3_node_read(args->trans, args->dp, 1755 error = xfs_da3_node_read(args->trans, dp,
1747 be32_to_cpu(old_info->forw), 1756 be32_to_cpu(old_info->forw),
1748 -1, &bp, args->whichfork); 1757 -1, &bp, args->whichfork);
1749 if (error) 1758 if (error)
@@ -1863,6 +1872,7 @@ xfs_da3_path_shift(
1863 xfs_dablk_t blkno = 0; 1872 xfs_dablk_t blkno = 0;
1864 int level; 1873 int level;
1865 int error; 1874 int error;
1875 struct xfs_inode *dp = state->args->dp;
1866 1876
1867 trace_xfs_da_path_shift(state->args); 1877 trace_xfs_da_path_shift(state->args);
1868 1878
@@ -1879,7 +1889,7 @@ xfs_da3_path_shift(
1879 for (blk = &path->blk[level]; level >= 0; blk--, level--) { 1889 for (blk = &path->blk[level]; level >= 0; blk--, level--) {
1880 node = blk->bp->b_addr; 1890 node = blk->bp->b_addr;
1881 xfs_da3_node_hdr_from_disk(&nodehdr, node); 1891 xfs_da3_node_hdr_from_disk(&nodehdr, node);
1882 btree = xfs_da3_node_tree_p(node); 1892 btree = dp->d_ops->node_tree_p(node);
1883 1893
1884 if (forward && (blk->index < nodehdr.count - 1)) { 1894 if (forward && (blk->index < nodehdr.count - 1)) {
1885 blk->index++; 1895 blk->index++;
@@ -1913,7 +1923,7 @@ xfs_da3_path_shift(
1913 * Read the next child block. 1923 * Read the next child block.
1914 */ 1924 */
1915 blk->blkno = blkno; 1925 blk->blkno = blkno;
1916 error = xfs_da3_node_read(args->trans, args->dp, blkno, -1, 1926 error = xfs_da3_node_read(args->trans, dp, blkno, -1,
1917 &blk->bp, args->whichfork); 1927 &blk->bp, args->whichfork);
1918 if (error) 1928 if (error)
1919 return(error); 1929 return(error);
@@ -1936,7 +1946,7 @@ xfs_da3_path_shift(
1936 blk->magic = XFS_DA_NODE_MAGIC; 1946 blk->magic = XFS_DA_NODE_MAGIC;
1937 node = (xfs_da_intnode_t *)info; 1947 node = (xfs_da_intnode_t *)info;
1938 xfs_da3_node_hdr_from_disk(&nodehdr, node); 1948 xfs_da3_node_hdr_from_disk(&nodehdr, node);
1939 btree = xfs_da3_node_tree_p(node); 1949 btree = dp->d_ops->node_tree_p(node);
1940 blk->hashval = be32_to_cpu(btree[nodehdr.count - 1].hashval); 1950 blk->hashval = be32_to_cpu(btree[nodehdr.count - 1].hashval);
1941 if (forward) 1951 if (forward)
1942 blk->index = 0; 1952 blk->index = 0;
@@ -2164,7 +2174,7 @@ xfs_da3_swap_lastblock(
2164 struct xfs_dir2_leaf *dead_leaf2; 2174 struct xfs_dir2_leaf *dead_leaf2;
2165 struct xfs_da_node_entry *btree; 2175 struct xfs_da_node_entry *btree;
2166 struct xfs_da3_icnode_hdr par_hdr; 2176 struct xfs_da3_icnode_hdr par_hdr;
2167 struct xfs_inode *ip; 2177 struct xfs_inode *dp;
2168 struct xfs_trans *tp; 2178 struct xfs_trans *tp;
2169 struct xfs_mount *mp; 2179 struct xfs_mount *mp;
2170 struct xfs_buf *dead_buf; 2180 struct xfs_buf *dead_buf;
@@ -2188,12 +2198,12 @@ xfs_da3_swap_lastblock(
2188 dead_buf = *dead_bufp; 2198 dead_buf = *dead_bufp;
2189 dead_blkno = *dead_blknop; 2199 dead_blkno = *dead_blknop;
2190 tp = args->trans; 2200 tp = args->trans;
2191 ip = args->dp; 2201 dp = args->dp;
2192 w = args->whichfork; 2202 w = args->whichfork;
2193 ASSERT(w == XFS_DATA_FORK); 2203 ASSERT(w == XFS_DATA_FORK);
2194 mp = ip->i_mount; 2204 mp = dp->i_mount;
2195 lastoff = mp->m_dirfreeblk; 2205 lastoff = mp->m_dirfreeblk;
2196 error = xfs_bmap_last_before(tp, ip, &lastoff, w); 2206 error = xfs_bmap_last_before(tp, dp, &lastoff, w);
2197 if (error) 2207 if (error)
2198 return error; 2208 return error;
2199 if (unlikely(lastoff == 0)) { 2209 if (unlikely(lastoff == 0)) {
@@ -2205,7 +2215,7 @@ xfs_da3_swap_lastblock(
2205 * Read the last block in the btree space. 2215 * Read the last block in the btree space.
2206 */ 2216 */
2207 last_blkno = (xfs_dablk_t)lastoff - mp->m_dirblkfsbs; 2217 last_blkno = (xfs_dablk_t)lastoff - mp->m_dirblkfsbs;
2208 error = xfs_da3_node_read(tp, ip, last_blkno, -1, &last_buf, w); 2218 error = xfs_da3_node_read(tp, dp, last_blkno, -1, &last_buf, w);
2209 if (error) 2219 if (error)
2210 return error; 2220 return error;
2211 /* 2221 /*
@@ -2224,7 +2234,7 @@ xfs_da3_swap_lastblock(
2224 2234
2225 dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; 2235 dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;
2226 xfs_dir3_leaf_hdr_from_disk(&leafhdr, dead_leaf2); 2236 xfs_dir3_leaf_hdr_from_disk(&leafhdr, dead_leaf2);
2227 ents = ip->d_ops->leaf_ents_p(dead_leaf2); 2237 ents = dp->d_ops->leaf_ents_p(dead_leaf2);
2228 dead_level = 0; 2238 dead_level = 0;
2229 dead_hash = be32_to_cpu(ents[leafhdr.count - 1].hashval); 2239 dead_hash = be32_to_cpu(ents[leafhdr.count - 1].hashval);
2230 } else { 2240 } else {
@@ -2232,7 +2242,7 @@ xfs_da3_swap_lastblock(
2232 2242
2233 dead_node = (xfs_da_intnode_t *)dead_info; 2243 dead_node = (xfs_da_intnode_t *)dead_info;
2234 xfs_da3_node_hdr_from_disk(&deadhdr, dead_node); 2244 xfs_da3_node_hdr_from_disk(&deadhdr, dead_node);
2235 btree = xfs_da3_node_tree_p(dead_node); 2245 btree = dp->d_ops->node_tree_p(dead_node);
2236 dead_level = deadhdr.level; 2246 dead_level = deadhdr.level;
2237 dead_hash = be32_to_cpu(btree[deadhdr.count - 1].hashval); 2247 dead_hash = be32_to_cpu(btree[deadhdr.count - 1].hashval);
2238 } 2248 }
@@ -2241,7 +2251,7 @@ xfs_da3_swap_lastblock(
2241 * If the moved block has a left sibling, fix up the pointers. 2251 * If the moved block has a left sibling, fix up the pointers.
2242 */ 2252 */
2243 if ((sib_blkno = be32_to_cpu(dead_info->back))) { 2253 if ((sib_blkno = be32_to_cpu(dead_info->back))) {
2244 error = xfs_da3_node_read(tp, ip, sib_blkno, -1, &sib_buf, w); 2254 error = xfs_da3_node_read(tp, dp, sib_blkno, -1, &sib_buf, w);
2245 if (error) 2255 if (error)
2246 goto done; 2256 goto done;
2247 sib_info = sib_buf->b_addr; 2257 sib_info = sib_buf->b_addr;
@@ -2263,7 +2273,7 @@ xfs_da3_swap_lastblock(
2263 * If the moved block has a right sibling, fix up the pointers. 2273 * If the moved block has a right sibling, fix up the pointers.
2264 */ 2274 */
2265 if ((sib_blkno = be32_to_cpu(dead_info->forw))) { 2275 if ((sib_blkno = be32_to_cpu(dead_info->forw))) {
2266 error = xfs_da3_node_read(tp, ip, sib_blkno, -1, &sib_buf, w); 2276 error = xfs_da3_node_read(tp, dp, sib_blkno, -1, &sib_buf, w);
2267 if (error) 2277 if (error)
2268 goto done; 2278 goto done;
2269 sib_info = sib_buf->b_addr; 2279 sib_info = sib_buf->b_addr;
@@ -2287,7 +2297,7 @@ xfs_da3_swap_lastblock(
2287 * Walk down the tree looking for the parent of the moved block. 2297 * Walk down the tree looking for the parent of the moved block.
2288 */ 2298 */
2289 for (;;) { 2299 for (;;) {
2290 error = xfs_da3_node_read(tp, ip, par_blkno, -1, &par_buf, w); 2300 error = xfs_da3_node_read(tp, dp, par_blkno, -1, &par_buf, w);
2291 if (error) 2301 if (error)
2292 goto done; 2302 goto done;
2293 par_node = par_buf->b_addr; 2303 par_node = par_buf->b_addr;
@@ -2299,7 +2309,7 @@ xfs_da3_swap_lastblock(
2299 goto done; 2309 goto done;
2300 } 2310 }
2301 level = par_hdr.level; 2311 level = par_hdr.level;
2302 btree = xfs_da3_node_tree_p(par_node); 2312 btree = dp->d_ops->node_tree_p(par_node);
2303 for (entno = 0; 2313 for (entno = 0;
2304 entno < par_hdr.count && 2314 entno < par_hdr.count &&
2305 be32_to_cpu(btree[entno].hashval) < dead_hash; 2315 be32_to_cpu(btree[entno].hashval) < dead_hash;
@@ -2338,7 +2348,7 @@ xfs_da3_swap_lastblock(
2338 error = XFS_ERROR(EFSCORRUPTED); 2348 error = XFS_ERROR(EFSCORRUPTED);
2339 goto done; 2349 goto done;
2340 } 2350 }
2341 error = xfs_da3_node_read(tp, ip, par_blkno, -1, &par_buf, w); 2351 error = xfs_da3_node_read(tp, dp, par_blkno, -1, &par_buf, w);
2342 if (error) 2352 if (error)
2343 goto done; 2353 goto done;
2344 par_node = par_buf->b_addr; 2354 par_node = par_buf->b_addr;
@@ -2349,7 +2359,7 @@ xfs_da3_swap_lastblock(
2349 error = XFS_ERROR(EFSCORRUPTED); 2359 error = XFS_ERROR(EFSCORRUPTED);
2350 goto done; 2360 goto done;
2351 } 2361 }
2352 btree = xfs_da3_node_tree_p(par_node); 2362 btree = dp->d_ops->node_tree_p(par_node);
2353 entno = 0; 2363 entno = 0;
2354 } 2364 }
2355 /* 2365 /*
diff --git a/fs/xfs/xfs_da_format.c b/fs/xfs/xfs_da_format.c
index ff8b50368c94..72b48b5ec69a 100644
--- a/fs/xfs/xfs_da_format.c
+++ b/fs/xfs/xfs_da_format.c
@@ -477,6 +477,33 @@ xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp)
477 return ((struct xfs_dir3_leaf *)lp)->__ents; 477 return ((struct xfs_dir3_leaf *)lp)->__ents;
478} 478}
479 479
480/*
481 * Directory/Attribute Node block operations
482 */
483static inline int
484xfs_da2_node_hdr_size(void)
485{
486 return sizeof(struct xfs_da_node_hdr);
487}
488
489static struct xfs_da_node_entry *
490xfs_da2_node_tree_p(struct xfs_da_intnode *dap)
491{
492 return dap->__btree;
493}
494
495static inline int
496xfs_da3_node_hdr_size(void)
497{
498 return sizeof(struct xfs_da3_node_hdr);
499}
500
501static inline struct xfs_da_node_entry *
502xfs_da3_node_tree_p(struct xfs_da_intnode *dap)
503{
504 return ((struct xfs_da3_intnode *)dap)->__btree;
505}
506
480const struct xfs_dir_ops xfs_dir2_ops = { 507const struct xfs_dir_ops xfs_dir2_ops = {
481 .sf_entsize = xfs_dir2_sf_entsize, 508 .sf_entsize = xfs_dir2_sf_entsize,
482 .sf_nextentry = xfs_dir2_sf_nextentry, 509 .sf_nextentry = xfs_dir2_sf_nextentry,
@@ -508,6 +535,8 @@ const struct xfs_dir_ops xfs_dir2_ops = {
508 .leaf_max_ents = xfs_dir2_max_leaf_ents, 535 .leaf_max_ents = xfs_dir2_max_leaf_ents,
509 .leaf_ents_p = xfs_dir2_leaf_ents_p, 536 .leaf_ents_p = xfs_dir2_leaf_ents_p,
510 537
538 .node_hdr_size = xfs_da2_node_hdr_size,
539 .node_tree_p = xfs_da2_node_tree_p,
511}; 540};
512 541
513const struct xfs_dir_ops xfs_dir2_ftype_ops = { 542const struct xfs_dir_ops xfs_dir2_ftype_ops = {
@@ -540,6 +569,9 @@ const struct xfs_dir_ops xfs_dir2_ftype_ops = {
540 .leaf_hdr_size = xfs_dir2_leaf_hdr_size, 569 .leaf_hdr_size = xfs_dir2_leaf_hdr_size,
541 .leaf_max_ents = xfs_dir2_max_leaf_ents, 570 .leaf_max_ents = xfs_dir2_max_leaf_ents,
542 .leaf_ents_p = xfs_dir2_leaf_ents_p, 571 .leaf_ents_p = xfs_dir2_leaf_ents_p,
572
573 .node_hdr_size = xfs_da2_node_hdr_size,
574 .node_tree_p = xfs_da2_node_tree_p,
543}; 575};
544 576
545const struct xfs_dir_ops xfs_dir3_ops = { 577const struct xfs_dir_ops xfs_dir3_ops = {
@@ -572,6 +604,19 @@ const struct xfs_dir_ops xfs_dir3_ops = {
572 .leaf_hdr_size = xfs_dir3_leaf_hdr_size, 604 .leaf_hdr_size = xfs_dir3_leaf_hdr_size,
573 .leaf_max_ents = xfs_dir3_max_leaf_ents, 605 .leaf_max_ents = xfs_dir3_max_leaf_ents,
574 .leaf_ents_p = xfs_dir3_leaf_ents_p, 606 .leaf_ents_p = xfs_dir3_leaf_ents_p,
607
608 .node_hdr_size = xfs_da3_node_hdr_size,
609 .node_tree_p = xfs_da3_node_tree_p,
610};
611
612const struct xfs_dir_ops xfs_dir2_nondir_ops = {
613 .node_hdr_size = xfs_da2_node_hdr_size,
614 .node_tree_p = xfs_da2_node_tree_p,
615};
616
617const struct xfs_dir_ops xfs_dir3_nondir_ops = {
618 .node_hdr_size = xfs_da3_node_hdr_size,
619 .node_tree_p = xfs_da3_node_tree_p,
575}; 620};
576 621
577/* 622/*
@@ -594,3 +639,17 @@ xfs_dir_get_ops(
594 return &xfs_dir2_ftype_ops; 639 return &xfs_dir2_ftype_ops;
595 return &xfs_dir2_ops; 640 return &xfs_dir2_ops;
596} 641}
642
643const struct xfs_dir_ops *
644xfs_nondir_get_ops(
645 struct xfs_mount *mp,
646 struct xfs_inode *dp)
647{
648 if (dp)
649 return dp->d_ops;
650 if (mp->m_nondir_inode_ops)
651 return mp->m_nondir_inode_ops;
652 if (xfs_sb_version_hascrc(&mp->m_sb))
653 return &xfs_dir3_nondir_ops;
654 return &xfs_dir2_nondir_ops;
655}
diff --git a/fs/xfs/xfs_da_format.h b/fs/xfs/xfs_da_format.h
index 0a567e25cf59..69b4c6e1c52e 100644
--- a/fs/xfs/xfs_da_format.h
+++ b/fs/xfs/xfs_da_format.h
@@ -127,31 +127,6 @@ extern void xfs_da3_node_hdr_from_disk(struct xfs_da3_icnode_hdr *to,
127extern void xfs_da3_node_hdr_to_disk(struct xfs_da_intnode *to, 127extern void xfs_da3_node_hdr_to_disk(struct xfs_da_intnode *to,
128 struct xfs_da3_icnode_hdr *from); 128 struct xfs_da3_icnode_hdr *from);
129 129
130static inline int
131__xfs_da3_node_hdr_size(bool v3)
132{
133 if (v3)
134 return sizeof(struct xfs_da3_node_hdr);
135 return sizeof(struct xfs_da_node_hdr);
136}
137static inline int
138xfs_da3_node_hdr_size(struct xfs_da_intnode *dap)
139{
140 bool v3 = dap->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC);
141
142 return __xfs_da3_node_hdr_size(v3);
143}
144
145static inline struct xfs_da_node_entry *
146xfs_da3_node_tree_p(struct xfs_da_intnode *dap)
147{
148 if (dap->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC)) {
149 struct xfs_da3_intnode *dap3 = (struct xfs_da3_intnode *)dap;
150 return dap3->__btree;
151 }
152 return dap->__btree;
153}
154
155extern void xfs_da3_intnode_from_disk(struct xfs_da3_icnode_hdr *to, 130extern void xfs_da3_intnode_from_disk(struct xfs_da3_icnode_hdr *to,
156 struct xfs_da_intnode *from); 131 struct xfs_da_intnode *from);
157extern void xfs_da3_intnode_to_disk(struct xfs_da_intnode *to, 132extern void xfs_da3_intnode_to_disk(struct xfs_da_intnode *to,
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index 2b98a33ca383..1b44e83924b7 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -95,13 +95,17 @@ xfs_dir_mount(
95 ASSERT(xfs_sb_version_hasdirv2(&mp->m_sb)); 95 ASSERT(xfs_sb_version_hasdirv2(&mp->m_sb));
96 ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <= 96 ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <=
97 XFS_MAX_BLOCKSIZE); 97 XFS_MAX_BLOCKSIZE);
98
99 mp->m_dir_inode_ops = xfs_dir_get_ops(mp, NULL);
100 mp->m_nondir_inode_ops = xfs_nondir_get_ops(mp, NULL);
101
98 mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog); 102 mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog);
99 mp->m_dirblkfsbs = 1 << mp->m_sb.sb_dirblklog; 103 mp->m_dirblkfsbs = 1 << mp->m_sb.sb_dirblklog;
100 mp->m_dirdatablk = xfs_dir2_db_to_da(mp, XFS_DIR2_DATA_FIRSTDB(mp)); 104 mp->m_dirdatablk = xfs_dir2_db_to_da(mp, XFS_DIR2_DATA_FIRSTDB(mp));
101 mp->m_dirleafblk = xfs_dir2_db_to_da(mp, XFS_DIR2_LEAF_FIRSTDB(mp)); 105 mp->m_dirleafblk = xfs_dir2_db_to_da(mp, XFS_DIR2_LEAF_FIRSTDB(mp));
102 mp->m_dirfreeblk = xfs_dir2_db_to_da(mp, XFS_DIR2_FREE_FIRSTDB(mp)); 106 mp->m_dirfreeblk = xfs_dir2_db_to_da(mp, XFS_DIR2_FREE_FIRSTDB(mp));
103 107
104 nodehdr_size = __xfs_da3_node_hdr_size(xfs_sb_version_hascrc(&mp->m_sb)); 108 nodehdr_size = mp->m_dir_inode_ops->node_hdr_size();
105 mp->m_attr_node_ents = (mp->m_sb.sb_blocksize - nodehdr_size) / 109 mp->m_attr_node_ents = (mp->m_sb.sb_blocksize - nodehdr_size) /
106 (uint)sizeof(xfs_da_node_entry_t); 110 (uint)sizeof(xfs_da_node_entry_t);
107 mp->m_dir_node_ents = (mp->m_dirblksize - nodehdr_size) / 111 mp->m_dir_node_ents = (mp->m_dirblksize - nodehdr_size) /
@@ -113,7 +117,6 @@ xfs_dir_mount(
113 else 117 else
114 mp->m_dirnameops = &xfs_default_nameops; 118 mp->m_dirnameops = &xfs_default_nameops;
115 119
116 mp->m_dir_inode_ops = xfs_dir_get_ops(mp, NULL);
117} 120}
118 121
119/* 122/*
diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h
index 9ba9db731990..c5cad9d9239d 100644
--- a/fs/xfs/xfs_dir2.h
+++ b/fs/xfs/xfs_dir2.h
@@ -79,10 +79,16 @@ struct xfs_dir_ops {
79 int (*leaf_max_ents)(struct xfs_mount *mp); 79 int (*leaf_max_ents)(struct xfs_mount *mp);
80 struct xfs_dir2_leaf_entry * 80 struct xfs_dir2_leaf_entry *
81 (*leaf_ents_p)(struct xfs_dir2_leaf *lp); 81 (*leaf_ents_p)(struct xfs_dir2_leaf *lp);
82
83 int (*node_hdr_size)(void);
84 struct xfs_da_node_entry *
85 (*node_tree_p)(struct xfs_da_intnode *dap);
82}; 86};
83 87
84extern const struct xfs_dir_ops * 88extern const struct xfs_dir_ops *
85 xfs_dir_get_ops(struct xfs_mount *mp, struct xfs_inode *dp); 89 xfs_dir_get_ops(struct xfs_mount *mp, struct xfs_inode *dp);
90extern const struct xfs_dir_ops *
91 xfs_nondir_get_ops(struct xfs_mount *mp, struct xfs_inode *dp);
86 92
87/* 93/*
88 * Generic directory interface routines 94 * Generic directory interface routines
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 0493587ea6bc..c4cd6d47f523 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -1203,6 +1203,7 @@ xfs_setup_inode(
1203 inode->i_ctime.tv_nsec = ip->i_d.di_ctime.t_nsec; 1203 inode->i_ctime.tv_nsec = ip->i_d.di_ctime.t_nsec;
1204 xfs_diflags_to_iflags(inode, ip); 1204 xfs_diflags_to_iflags(inode, ip);
1205 1205
1206 ip->d_ops = ip->i_mount->m_nondir_inode_ops;
1206 switch (inode->i_mode & S_IFMT) { 1207 switch (inode->i_mode & S_IFMT) {
1207 case S_IFREG: 1208 case S_IFREG:
1208 inode->i_op = &xfs_inode_operations; 1209 inode->i_op = &xfs_inode_operations;
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 973397f66c6b..1d8101a10d8e 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -150,6 +150,7 @@ typedef struct xfs_mount {
150 __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ 150 __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */
151 const struct xfs_nameops *m_dirnameops; /* vector of dir name ops */ 151 const struct xfs_nameops *m_dirnameops; /* vector of dir name ops */
152 const struct xfs_dir_ops *m_dir_inode_ops; /* vector of dir inode ops */ 152 const struct xfs_dir_ops *m_dir_inode_ops; /* vector of dir inode ops */
153 const struct xfs_dir_ops *m_nondir_inode_ops; /* !dir inode ops */
153 int m_dirblksize; /* directory block sz--bytes */ 154 int m_dirblksize; /* directory block sz--bytes */
154 int m_dirblkfsbs; /* directory block sz--fsbs */ 155 int m_dirblkfsbs; /* directory block sz--fsbs */
155 xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */ 156 xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */