hc
2024-05-16 8d2a02b24d66aa359e83eebc1ed3c0f85367a1cb
kernel/fs/xfs/libxfs/xfs_da_btree.c
....@@ -12,20 +12,14 @@
1212 #include "xfs_trans_resv.h"
1313 #include "xfs_bit.h"
1414 #include "xfs_mount.h"
15
-#include "xfs_da_format.h"
16
-#include "xfs_da_btree.h"
15
+#include "xfs_inode.h"
1716 #include "xfs_dir2.h"
1817 #include "xfs_dir2_priv.h"
19
-#include "xfs_inode.h"
2018 #include "xfs_trans.h"
21
-#include "xfs_inode_item.h"
22
-#include "xfs_alloc.h"
2319 #include "xfs_bmap.h"
24
-#include "xfs_attr.h"
2520 #include "xfs_attr_leaf.h"
2621 #include "xfs_error.h"
2722 #include "xfs_trace.h"
28
-#include "xfs_cksum.h"
2923 #include "xfs_buf_item.h"
3024 #include "xfs_log.h"
3125
....@@ -84,10 +78,16 @@
8478 * Allocate a dir-state structure.
8579 * We don't put them on the stack since they're large.
8680 */
87
-xfs_da_state_t *
88
-xfs_da_state_alloc(void)
81
+struct xfs_da_state *
82
+xfs_da_state_alloc(
83
+ struct xfs_da_args *args)
8984 {
90
- return kmem_zone_zalloc(xfs_da_state_zone, KM_NOFS);
85
+ struct xfs_da_state *state;
86
+
87
+ state = kmem_cache_zalloc(xfs_da_state_zone, GFP_NOFS | __GFP_NOFAIL);
88
+ state->args = args;
89
+ state->mp = args->dp->i_mount;
90
+ return state;
9191 }
9292
9393 /*
....@@ -113,38 +113,111 @@
113113 #ifdef DEBUG
114114 memset((char *)state, 0, sizeof(*state));
115115 #endif /* DEBUG */
116
- kmem_zone_free(xfs_da_state_zone, state);
116
+ kmem_cache_free(xfs_da_state_zone, state);
117
+}
118
+
119
+static inline int xfs_dabuf_nfsb(struct xfs_mount *mp, int whichfork)
120
+{
121
+ if (whichfork == XFS_DATA_FORK)
122
+ return mp->m_dir_geo->fsbcount;
123
+ return mp->m_attr_geo->fsbcount;
124
+}
125
+
126
+void
127
+xfs_da3_node_hdr_from_disk(
128
+ struct xfs_mount *mp,
129
+ struct xfs_da3_icnode_hdr *to,
130
+ struct xfs_da_intnode *from)
131
+{
132
+ if (xfs_sb_version_hascrc(&mp->m_sb)) {
133
+ struct xfs_da3_intnode *from3 = (struct xfs_da3_intnode *)from;
134
+
135
+ to->forw = be32_to_cpu(from3->hdr.info.hdr.forw);
136
+ to->back = be32_to_cpu(from3->hdr.info.hdr.back);
137
+ to->magic = be16_to_cpu(from3->hdr.info.hdr.magic);
138
+ to->count = be16_to_cpu(from3->hdr.__count);
139
+ to->level = be16_to_cpu(from3->hdr.__level);
140
+ to->btree = from3->__btree;
141
+ ASSERT(to->magic == XFS_DA3_NODE_MAGIC);
142
+ } else {
143
+ to->forw = be32_to_cpu(from->hdr.info.forw);
144
+ to->back = be32_to_cpu(from->hdr.info.back);
145
+ to->magic = be16_to_cpu(from->hdr.info.magic);
146
+ to->count = be16_to_cpu(from->hdr.__count);
147
+ to->level = be16_to_cpu(from->hdr.__level);
148
+ to->btree = from->__btree;
149
+ ASSERT(to->magic == XFS_DA_NODE_MAGIC);
150
+ }
151
+}
152
+
153
+void
154
+xfs_da3_node_hdr_to_disk(
155
+ struct xfs_mount *mp,
156
+ struct xfs_da_intnode *to,
157
+ struct xfs_da3_icnode_hdr *from)
158
+{
159
+ if (xfs_sb_version_hascrc(&mp->m_sb)) {
160
+ struct xfs_da3_intnode *to3 = (struct xfs_da3_intnode *)to;
161
+
162
+ ASSERT(from->magic == XFS_DA3_NODE_MAGIC);
163
+ to3->hdr.info.hdr.forw = cpu_to_be32(from->forw);
164
+ to3->hdr.info.hdr.back = cpu_to_be32(from->back);
165
+ to3->hdr.info.hdr.magic = cpu_to_be16(from->magic);
166
+ to3->hdr.__count = cpu_to_be16(from->count);
167
+ to3->hdr.__level = cpu_to_be16(from->level);
168
+ } else {
169
+ ASSERT(from->magic == XFS_DA_NODE_MAGIC);
170
+ to->hdr.info.forw = cpu_to_be32(from->forw);
171
+ to->hdr.info.back = cpu_to_be32(from->back);
172
+ to->hdr.info.magic = cpu_to_be16(from->magic);
173
+ to->hdr.__count = cpu_to_be16(from->count);
174
+ to->hdr.__level = cpu_to_be16(from->level);
175
+ }
176
+}
177
+
178
+/*
179
+ * Verify an xfs_da3_blkinfo structure. Note that the da3 fields are only
180
+ * accessible on v5 filesystems. This header format is common across da node,
181
+ * attr leaf and dir leaf blocks.
182
+ */
183
+xfs_failaddr_t
184
+xfs_da3_blkinfo_verify(
185
+ struct xfs_buf *bp,
186
+ struct xfs_da3_blkinfo *hdr3)
187
+{
188
+ struct xfs_mount *mp = bp->b_mount;
189
+ struct xfs_da_blkinfo *hdr = &hdr3->hdr;
190
+
191
+ if (!xfs_verify_magic16(bp, hdr->magic))
192
+ return __this_address;
193
+
194
+ if (xfs_sb_version_hascrc(&mp->m_sb)) {
195
+ if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_meta_uuid))
196
+ return __this_address;
197
+ if (be64_to_cpu(hdr3->blkno) != bp->b_bn)
198
+ return __this_address;
199
+ if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->lsn)))
200
+ return __this_address;
201
+ }
202
+
203
+ return NULL;
117204 }
118205
119206 static xfs_failaddr_t
120207 xfs_da3_node_verify(
121208 struct xfs_buf *bp)
122209 {
123
- struct xfs_mount *mp = bp->b_target->bt_mount;
210
+ struct xfs_mount *mp = bp->b_mount;
124211 struct xfs_da_intnode *hdr = bp->b_addr;
125212 struct xfs_da3_icnode_hdr ichdr;
126
- const struct xfs_dir_ops *ops;
213
+ xfs_failaddr_t fa;
127214
128
- ops = xfs_dir_get_ops(mp, NULL);
215
+ xfs_da3_node_hdr_from_disk(mp, &ichdr, hdr);
129216
130
- ops->node_hdr_from_disk(&ichdr, hdr);
217
+ fa = xfs_da3_blkinfo_verify(bp, bp->b_addr);
218
+ if (fa)
219
+ return fa;
131220
132
- if (xfs_sb_version_hascrc(&mp->m_sb)) {
133
- struct xfs_da3_node_hdr *hdr3 = bp->b_addr;
134
-
135
- if (ichdr.magic != XFS_DA3_NODE_MAGIC)
136
- return __this_address;
137
-
138
- if (!uuid_equal(&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))
139
- return __this_address;
140
- if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn)
141
- return __this_address;
142
- if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->info.lsn)))
143
- return __this_address;
144
- } else {
145
- if (ichdr.magic != XFS_DA_NODE_MAGIC)
146
- return __this_address;
147
- }
148221 if (ichdr.level == 0)
149222 return __this_address;
150223 if (ichdr.level > XFS_DA_NODE_MAXDEPTH)
....@@ -169,7 +242,7 @@
169242 xfs_da3_node_write_verify(
170243 struct xfs_buf *bp)
171244 {
172
- struct xfs_mount *mp = bp->b_target->bt_mount;
245
+ struct xfs_mount *mp = bp->b_mount;
173246 struct xfs_buf_log_item *bip = bp->b_log_item;
174247 struct xfs_da3_node_hdr *hdr3 = bp->b_addr;
175248 xfs_failaddr_t fa;
....@@ -257,51 +330,83 @@
257330
258331 const struct xfs_buf_ops xfs_da3_node_buf_ops = {
259332 .name = "xfs_da3_node",
333
+ .magic16 = { cpu_to_be16(XFS_DA_NODE_MAGIC),
334
+ cpu_to_be16(XFS_DA3_NODE_MAGIC) },
260335 .verify_read = xfs_da3_node_read_verify,
261336 .verify_write = xfs_da3_node_write_verify,
262337 .verify_struct = xfs_da3_node_verify_struct,
263338 };
339
+
340
+static int
341
+xfs_da3_node_set_type(
342
+ struct xfs_trans *tp,
343
+ struct xfs_buf *bp)
344
+{
345
+ struct xfs_da_blkinfo *info = bp->b_addr;
346
+
347
+ switch (be16_to_cpu(info->magic)) {
348
+ case XFS_DA_NODE_MAGIC:
349
+ case XFS_DA3_NODE_MAGIC:
350
+ xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DA_NODE_BUF);
351
+ return 0;
352
+ case XFS_ATTR_LEAF_MAGIC:
353
+ case XFS_ATTR3_LEAF_MAGIC:
354
+ xfs_trans_buf_set_type(tp, bp, XFS_BLFT_ATTR_LEAF_BUF);
355
+ return 0;
356
+ case XFS_DIR2_LEAFN_MAGIC:
357
+ case XFS_DIR3_LEAFN_MAGIC:
358
+ xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_LEAFN_BUF);
359
+ return 0;
360
+ default:
361
+ XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, tp->t_mountp,
362
+ info, sizeof(*info));
363
+ xfs_trans_brelse(tp, bp);
364
+ return -EFSCORRUPTED;
365
+ }
366
+}
264367
265368 int
266369 xfs_da3_node_read(
267370 struct xfs_trans *tp,
268371 struct xfs_inode *dp,
269372 xfs_dablk_t bno,
373
+ struct xfs_buf **bpp,
374
+ int whichfork)
375
+{
376
+ int error;
377
+
378
+ error = xfs_da_read_buf(tp, dp, bno, 0, bpp, whichfork,
379
+ &xfs_da3_node_buf_ops);
380
+ if (error || !*bpp || !tp)
381
+ return error;
382
+ return xfs_da3_node_set_type(tp, *bpp);
383
+}
384
+
385
+int
386
+xfs_da3_node_read_mapped(
387
+ struct xfs_trans *tp,
388
+ struct xfs_inode *dp,
270389 xfs_daddr_t mappedbno,
271390 struct xfs_buf **bpp,
272
- int which_fork)
391
+ int whichfork)
273392 {
274
- int err;
393
+ struct xfs_mount *mp = dp->i_mount;
394
+ int error;
275395
276
- err = xfs_da_read_buf(tp, dp, bno, mappedbno, bpp,
277
- which_fork, &xfs_da3_node_buf_ops);
278
- if (!err && tp && *bpp) {
279
- struct xfs_da_blkinfo *info = (*bpp)->b_addr;
280
- int type;
396
+ error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, mappedbno,
397
+ XFS_FSB_TO_BB(mp, xfs_dabuf_nfsb(mp, whichfork)), 0,
398
+ bpp, &xfs_da3_node_buf_ops);
399
+ if (error || !*bpp)
400
+ return error;
281401
282
- switch (be16_to_cpu(info->magic)) {
283
- case XFS_DA_NODE_MAGIC:
284
- case XFS_DA3_NODE_MAGIC:
285
- type = XFS_BLFT_DA_NODE_BUF;
286
- break;
287
- case XFS_ATTR_LEAF_MAGIC:
288
- case XFS_ATTR3_LEAF_MAGIC:
289
- type = XFS_BLFT_ATTR_LEAF_BUF;
290
- break;
291
- case XFS_DIR2_LEAFN_MAGIC:
292
- case XFS_DIR3_LEAFN_MAGIC:
293
- type = XFS_BLFT_DIR_LEAFN_BUF;
294
- break;
295
- default:
296
- XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
297
- tp->t_mountp, info, sizeof(*info));
298
- xfs_trans_brelse(tp, *bpp);
299
- *bpp = NULL;
300
- return -EFSCORRUPTED;
301
- }
302
- xfs_trans_buf_set_type(tp, *bpp, type);
303
- }
304
- return err;
402
+ if (whichfork == XFS_ATTR_FORK)
403
+ xfs_buf_set_ref(*bpp, XFS_ATTR_BTREE_REF);
404
+ else
405
+ xfs_buf_set_ref(*bpp, XFS_DIR_BTREE_REF);
406
+
407
+ if (!tp)
408
+ return 0;
409
+ return xfs_da3_node_set_type(tp, *bpp);
305410 }
306411
307412 /*========================================================================
....@@ -330,7 +435,7 @@
330435 trace_xfs_da_node_create(args);
331436 ASSERT(level <= XFS_DA_NODE_MAXDEPTH);
332437
333
- error = xfs_da_get_buf(tp, dp, blkno, -1, &bp, whichfork);
438
+ error = xfs_da_get_buf(tp, dp, blkno, &bp, whichfork);
334439 if (error)
335440 return error;
336441 bp->b_ops = &xfs_da3_node_buf_ops;
....@@ -350,9 +455,9 @@
350455 }
351456 ichdr.level = level;
352457
353
- dp->d_ops->node_hdr_to_disk(node, &ichdr);
458
+ xfs_da3_node_hdr_to_disk(dp->i_mount, node, &ichdr);
354459 xfs_trans_log_buf(tp, bp,
355
- XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size));
460
+ XFS_DA_LOGRANGE(node, &node->hdr, args->geo->node_hdr_size));
356461
357462 *bpp = bp;
358463 return 0;
....@@ -474,10 +579,8 @@
474579 ASSERT(state->path.active == 0);
475580 oldblk = &state->path.blk[0];
476581 error = xfs_da3_root_split(state, oldblk, addblk);
477
- if (error) {
478
- addblk->bp = NULL;
479
- return error; /* GROT: dir is inconsistent */
480
- }
582
+ if (error)
583
+ goto out;
481584
482585 /*
483586 * Update pointers to the node which used to be block 0 and just got
....@@ -492,7 +595,11 @@
492595 */
493596 node = oldblk->bp->b_addr;
494597 if (node->hdr.info.forw) {
495
- ASSERT(be32_to_cpu(node->hdr.info.forw) == addblk->blkno);
598
+ if (be32_to_cpu(node->hdr.info.forw) != addblk->blkno) {
599
+ xfs_buf_mark_corrupt(oldblk->bp);
600
+ error = -EFSCORRUPTED;
601
+ goto out;
602
+ }
496603 node = addblk->bp->b_addr;
497604 node->hdr.info.back = cpu_to_be32(oldblk->blkno);
498605 xfs_trans_log_buf(state->args->trans, addblk->bp,
....@@ -501,15 +608,20 @@
501608 }
502609 node = oldblk->bp->b_addr;
503610 if (node->hdr.info.back) {
504
- ASSERT(be32_to_cpu(node->hdr.info.back) == addblk->blkno);
611
+ if (be32_to_cpu(node->hdr.info.back) != addblk->blkno) {
612
+ xfs_buf_mark_corrupt(oldblk->bp);
613
+ error = -EFSCORRUPTED;
614
+ goto out;
615
+ }
505616 node = addblk->bp->b_addr;
506617 node->hdr.info.forw = cpu_to_be32(oldblk->blkno);
507618 xfs_trans_log_buf(state->args->trans, addblk->bp,
508619 XFS_DA_LOGRANGE(node, &node->hdr.info,
509620 sizeof(node->hdr.info)));
510621 }
622
+out:
511623 addblk->bp = NULL;
512
- return 0;
624
+ return error;
513625 }
514626
515627 /*
....@@ -550,7 +662,7 @@
550662
551663 dp = args->dp;
552664 tp = args->trans;
553
- error = xfs_da_get_buf(tp, dp, blkno, -1, &bp, args->whichfork);
665
+ error = xfs_da_get_buf(tp, dp, blkno, &bp, args->whichfork);
554666 if (error)
555667 return error;
556668 node = bp->b_addr;
....@@ -559,8 +671,8 @@
559671 oldroot->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC)) {
560672 struct xfs_da3_icnode_hdr icnodehdr;
561673
562
- dp->d_ops->node_hdr_from_disk(&icnodehdr, oldroot);
563
- btree = dp->d_ops->node_tree_p(oldroot);
674
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &icnodehdr, oldroot);
675
+ btree = icnodehdr.btree;
564676 size = (int)((char *)&btree[icnodehdr.count] - (char *)oldroot);
565677 level = icnodehdr.level;
566678
....@@ -571,15 +683,14 @@
571683 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DA_NODE_BUF);
572684 } else {
573685 struct xfs_dir3_icleaf_hdr leafhdr;
574
- struct xfs_dir2_leaf_entry *ents;
575686
576687 leaf = (xfs_dir2_leaf_t *)oldroot;
577
- dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
578
- ents = dp->d_ops->leaf_ents_p(leaf);
688
+ xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
579689
580690 ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
581691 leafhdr.magic == XFS_DIR3_LEAFN_MAGIC);
582
- size = (int)((char *)&ents[leafhdr.count] - (char *)leaf);
692
+ size = (int)((char *)&leafhdr.ents[leafhdr.count] -
693
+ (char *)leaf);
583694 level = 0;
584695
585696 /*
....@@ -619,14 +730,14 @@
619730 return error;
620731
621732 node = bp->b_addr;
622
- dp->d_ops->node_hdr_from_disk(&nodehdr, node);
623
- btree = dp->d_ops->node_tree_p(node);
733
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
734
+ btree = nodehdr.btree;
624735 btree[0].hashval = cpu_to_be32(blk1->hashval);
625736 btree[0].before = cpu_to_be32(blk1->blkno);
626737 btree[1].hashval = cpu_to_be32(blk2->hashval);
627738 btree[1].before = cpu_to_be32(blk2->blkno);
628739 nodehdr.count = 2;
629
- dp->d_ops->node_hdr_to_disk(node, &nodehdr);
740
+ xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr);
630741
631742 #ifdef DEBUG
632743 if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
....@@ -668,7 +779,7 @@
668779 trace_xfs_da_node_split(state->args);
669780
670781 node = oldblk->bp->b_addr;
671
- dp->d_ops->node_hdr_from_disk(&nodehdr, node);
782
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
672783
673784 /*
674785 * With V2 dirs the extra block is data or freespace.
....@@ -715,7 +826,7 @@
715826 * If we had double-split op below us, then add the extra block too.
716827 */
717828 node = oldblk->bp->b_addr;
718
- dp->d_ops->node_hdr_from_disk(&nodehdr, node);
829
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
719830 if (oldblk->index <= nodehdr.count) {
720831 oldblk->index++;
721832 xfs_da3_node_add(state, oldblk, addblk);
....@@ -770,10 +881,10 @@
770881
771882 node1 = blk1->bp->b_addr;
772883 node2 = blk2->bp->b_addr;
773
- dp->d_ops->node_hdr_from_disk(&nodehdr1, node1);
774
- dp->d_ops->node_hdr_from_disk(&nodehdr2, node2);
775
- btree1 = dp->d_ops->node_tree_p(node1);
776
- btree2 = dp->d_ops->node_tree_p(node2);
884
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1);
885
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2);
886
+ btree1 = nodehdr1.btree;
887
+ btree2 = nodehdr2.btree;
777888
778889 /*
779890 * Figure out how many entries need to move, and in which direction.
....@@ -786,10 +897,10 @@
786897 tmpnode = node1;
787898 node1 = node2;
788899 node2 = tmpnode;
789
- dp->d_ops->node_hdr_from_disk(&nodehdr1, node1);
790
- dp->d_ops->node_hdr_from_disk(&nodehdr2, node2);
791
- btree1 = dp->d_ops->node_tree_p(node1);
792
- btree2 = dp->d_ops->node_tree_p(node2);
900
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1);
901
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2);
902
+ btree1 = nodehdr1.btree;
903
+ btree2 = nodehdr2.btree;
793904 swap = 1;
794905 }
795906
....@@ -851,14 +962,15 @@
851962 /*
852963 * Log header of node 1 and all current bits of node 2.
853964 */
854
- dp->d_ops->node_hdr_to_disk(node1, &nodehdr1);
965
+ xfs_da3_node_hdr_to_disk(dp->i_mount, node1, &nodehdr1);
855966 xfs_trans_log_buf(tp, blk1->bp,
856
- XFS_DA_LOGRANGE(node1, &node1->hdr, dp->d_ops->node_hdr_size));
967
+ XFS_DA_LOGRANGE(node1, &node1->hdr,
968
+ state->args->geo->node_hdr_size));
857969
858
- dp->d_ops->node_hdr_to_disk(node2, &nodehdr2);
970
+ xfs_da3_node_hdr_to_disk(dp->i_mount, node2, &nodehdr2);
859971 xfs_trans_log_buf(tp, blk2->bp,
860972 XFS_DA_LOGRANGE(node2, &node2->hdr,
861
- dp->d_ops->node_hdr_size +
973
+ state->args->geo->node_hdr_size +
862974 (sizeof(btree2[0]) * nodehdr2.count)));
863975
864976 /*
....@@ -868,10 +980,10 @@
868980 if (swap) {
869981 node1 = blk1->bp->b_addr;
870982 node2 = blk2->bp->b_addr;
871
- dp->d_ops->node_hdr_from_disk(&nodehdr1, node1);
872
- dp->d_ops->node_hdr_from_disk(&nodehdr2, node2);
873
- btree1 = dp->d_ops->node_tree_p(node1);
874
- btree2 = dp->d_ops->node_tree_p(node2);
983
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1);
984
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2);
985
+ btree1 = nodehdr1.btree;
986
+ btree2 = nodehdr2.btree;
875987 }
876988 blk1->hashval = be32_to_cpu(btree1[nodehdr1.count - 1].hashval);
877989 blk2->hashval = be32_to_cpu(btree2[nodehdr2.count - 1].hashval);
....@@ -903,8 +1015,8 @@
9031015 trace_xfs_da_node_add(state->args);
9041016
9051017 node = oldblk->bp->b_addr;
906
- dp->d_ops->node_hdr_from_disk(&nodehdr, node);
907
- btree = dp->d_ops->node_tree_p(node);
1018
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
1019
+ btree = nodehdr.btree;
9081020
9091021 ASSERT(oldblk->index >= 0 && oldblk->index <= nodehdr.count);
9101022 ASSERT(newblk->blkno != 0);
....@@ -927,9 +1039,10 @@
9271039 tmp + sizeof(*btree)));
9281040
9291041 nodehdr.count += 1;
930
- dp->d_ops->node_hdr_to_disk(node, &nodehdr);
1042
+ xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr);
9311043 xfs_trans_log_buf(state->args->trans, oldblk->bp,
932
- XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size));
1044
+ XFS_DA_LOGRANGE(node, &node->hdr,
1045
+ state->args->geo->node_hdr_size));
9331046
9341047 /*
9351048 * Copy the last hash value from the oldblk to propagate upwards.
....@@ -1064,7 +1177,6 @@
10641177 xfs_dablk_t child;
10651178 struct xfs_buf *bp;
10661179 struct xfs_da3_icnode_hdr oldroothdr;
1067
- struct xfs_da_node_entry *btree;
10681180 int error;
10691181 struct xfs_inode *dp = state->args->dp;
10701182
....@@ -1074,7 +1186,7 @@
10741186
10751187 args = state->args;
10761188 oldroot = root_blk->bp->b_addr;
1077
- dp->d_ops->node_hdr_from_disk(&oldroothdr, oldroot);
1189
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &oldroothdr, oldroot);
10781190 ASSERT(oldroothdr.forw == 0);
10791191 ASSERT(oldroothdr.back == 0);
10801192
....@@ -1088,11 +1200,9 @@
10881200 * Read in the (only) child block, then copy those bytes into
10891201 * the root block's buffer and free the original child block.
10901202 */
1091
- btree = dp->d_ops->node_tree_p(oldroot);
1092
- child = be32_to_cpu(btree[0].before);
1203
+ child = be32_to_cpu(oldroothdr.btree[0].before);
10931204 ASSERT(child != 0);
1094
- error = xfs_da3_node_read(args->trans, dp, child, -1, &bp,
1095
- args->whichfork);
1205
+ error = xfs_da3_node_read(args->trans, dp, child, &bp, args->whichfork);
10961206 if (error)
10971207 return error;
10981208 xfs_da_blkinfo_onlychild_validate(bp->b_addr, oldroothdr.level);
....@@ -1154,7 +1264,7 @@
11541264 blk = &state->path.blk[ state->path.active-1 ];
11551265 info = blk->bp->b_addr;
11561266 node = (xfs_da_intnode_t *)info;
1157
- dp->d_ops->node_hdr_from_disk(&nodehdr, node);
1267
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
11581268 if (nodehdr.count > (state->args->geo->node_ents >> 1)) {
11591269 *action = 0; /* blk over 50%, don't try to join */
11601270 return 0; /* blk over 50%, don't try to join */
....@@ -1206,13 +1316,13 @@
12061316 blkno = nodehdr.back;
12071317 if (blkno == 0)
12081318 continue;
1209
- error = xfs_da3_node_read(state->args->trans, dp,
1210
- blkno, -1, &bp, state->args->whichfork);
1319
+ error = xfs_da3_node_read(state->args->trans, dp, blkno, &bp,
1320
+ state->args->whichfork);
12111321 if (error)
12121322 return error;
12131323
12141324 node = bp->b_addr;
1215
- dp->d_ops->node_hdr_from_disk(&thdr, node);
1325
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &thdr, node);
12161326 xfs_trans_brelse(state->args->trans, bp);
12171327
12181328 if (count - thdr.count >= 0)
....@@ -1254,18 +1364,14 @@
12541364 struct xfs_buf *bp,
12551365 int *count)
12561366 {
1257
- struct xfs_da_intnode *node;
1258
- struct xfs_da_node_entry *btree;
12591367 struct xfs_da3_icnode_hdr nodehdr;
12601368
1261
- node = bp->b_addr;
1262
- dp->d_ops->node_hdr_from_disk(&nodehdr, node);
1369
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, bp->b_addr);
12631370 if (count)
12641371 *count = nodehdr.count;
12651372 if (!nodehdr.count)
12661373 return 0;
1267
- btree = dp->d_ops->node_tree_p(node);
1268
- return be32_to_cpu(btree[nodehdr.count - 1].hashval);
1374
+ return be32_to_cpu(nodehdr.btree[nodehdr.count - 1].hashval);
12691375 }
12701376
12711377 /*
....@@ -1310,8 +1416,8 @@
13101416 struct xfs_da3_icnode_hdr nodehdr;
13111417
13121418 node = blk->bp->b_addr;
1313
- dp->d_ops->node_hdr_from_disk(&nodehdr, node);
1314
- btree = dp->d_ops->node_tree_p(node);
1419
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
1420
+ btree = nodehdr.btree;
13151421 if (be32_to_cpu(btree[blk->index].hashval) == lasthash)
13161422 break;
13171423 blk->hashval = lasthash;
....@@ -1342,7 +1448,7 @@
13421448 trace_xfs_da_node_remove(state->args);
13431449
13441450 node = drop_blk->bp->b_addr;
1345
- dp->d_ops->node_hdr_from_disk(&nodehdr, node);
1451
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
13461452 ASSERT(drop_blk->index < nodehdr.count);
13471453 ASSERT(drop_blk->index >= 0);
13481454
....@@ -1350,7 +1456,7 @@
13501456 * Copy over the offending entry, or just zero it out.
13511457 */
13521458 index = drop_blk->index;
1353
- btree = dp->d_ops->node_tree_p(node);
1459
+ btree = nodehdr.btree;
13541460 if (index < nodehdr.count - 1) {
13551461 tmp = nodehdr.count - index - 1;
13561462 tmp *= (uint)sizeof(xfs_da_node_entry_t);
....@@ -1363,9 +1469,9 @@
13631469 xfs_trans_log_buf(state->args->trans, drop_blk->bp,
13641470 XFS_DA_LOGRANGE(node, &btree[index], sizeof(btree[index])));
13651471 nodehdr.count -= 1;
1366
- dp->d_ops->node_hdr_to_disk(node, &nodehdr);
1472
+ xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr);
13671473 xfs_trans_log_buf(state->args->trans, drop_blk->bp,
1368
- XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size));
1474
+ XFS_DA_LOGRANGE(node, &node->hdr, state->args->geo->node_hdr_size));
13691475
13701476 /*
13711477 * Copy the last hash value from the block to propagate upwards.
....@@ -1398,10 +1504,10 @@
13981504
13991505 drop_node = drop_blk->bp->b_addr;
14001506 save_node = save_blk->bp->b_addr;
1401
- dp->d_ops->node_hdr_from_disk(&drop_hdr, drop_node);
1402
- dp->d_ops->node_hdr_from_disk(&save_hdr, save_node);
1403
- drop_btree = dp->d_ops->node_tree_p(drop_node);
1404
- save_btree = dp->d_ops->node_tree_p(save_node);
1507
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &drop_hdr, drop_node);
1508
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &save_hdr, save_node);
1509
+ drop_btree = drop_hdr.btree;
1510
+ save_btree = save_hdr.btree;
14051511 tp = state->args->trans;
14061512
14071513 /*
....@@ -1435,10 +1541,10 @@
14351541 memcpy(&save_btree[sindex], &drop_btree[0], tmp);
14361542 save_hdr.count += drop_hdr.count;
14371543
1438
- dp->d_ops->node_hdr_to_disk(save_node, &save_hdr);
1544
+ xfs_da3_node_hdr_to_disk(dp->i_mount, save_node, &save_hdr);
14391545 xfs_trans_log_buf(tp, save_blk->bp,
14401546 XFS_DA_LOGRANGE(save_node, &save_node->hdr,
1441
- dp->d_ops->node_hdr_size));
1547
+ state->args->geo->node_hdr_size));
14421548
14431549 /*
14441550 * Save the last hashval in the remaining block for upward propagation.
....@@ -1499,7 +1605,7 @@
14991605 */
15001606 blk->blkno = blkno;
15011607 error = xfs_da3_node_read(args->trans, args->dp, blkno,
1502
- -1, &blk->bp, args->whichfork);
1608
+ &blk->bp, args->whichfork);
15031609 if (error) {
15041610 blk->blkno = 0;
15051611 state->path.active--;
....@@ -1523,8 +1629,10 @@
15231629 break;
15241630 }
15251631
1526
- if (magic != XFS_DA_NODE_MAGIC && magic != XFS_DA3_NODE_MAGIC)
1632
+ if (magic != XFS_DA_NODE_MAGIC && magic != XFS_DA3_NODE_MAGIC) {
1633
+ xfs_buf_mark_corrupt(blk->bp);
15271634 return -EFSCORRUPTED;
1635
+ }
15281636
15291637 blk->magic = XFS_DA_NODE_MAGIC;
15301638
....@@ -1532,19 +1640,22 @@
15321640 * Search an intermediate node for a match.
15331641 */
15341642 node = blk->bp->b_addr;
1535
- dp->d_ops->node_hdr_from_disk(&nodehdr, node);
1536
- btree = dp->d_ops->node_tree_p(node);
1643
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
1644
+ btree = nodehdr.btree;
15371645
15381646 /* Tree taller than we can handle; bail out! */
1539
- if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH)
1647
+ if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) {
1648
+ xfs_buf_mark_corrupt(blk->bp);
15401649 return -EFSCORRUPTED;
1650
+ }
15411651
15421652 /* Check the level from the root. */
15431653 if (blkno == args->geo->leafblk)
15441654 expected_level = nodehdr.level - 1;
1545
- else if (expected_level != nodehdr.level)
1655
+ else if (expected_level != nodehdr.level) {
1656
+ xfs_buf_mark_corrupt(blk->bp);
15461657 return -EFSCORRUPTED;
1547
- else
1658
+ } else
15481659 expected_level--;
15491660
15501661 max = nodehdr.count;
....@@ -1594,11 +1705,11 @@
15941705 }
15951706
15961707 /* We can't point back to the root. */
1597
- if (blkno == args->geo->leafblk)
1708
+ if (XFS_IS_CORRUPT(dp->i_mount, blkno == args->geo->leafblk))
15981709 return -EFSCORRUPTED;
15991710 }
16001711
1601
- if (expected_level != 0)
1712
+ if (XFS_IS_CORRUPT(dp->i_mount, expected_level != 0))
16021713 return -EFSCORRUPTED;
16031714
16041715 /*
....@@ -1660,10 +1771,10 @@
16601771
16611772 node1 = node1_bp->b_addr;
16621773 node2 = node2_bp->b_addr;
1663
- dp->d_ops->node_hdr_from_disk(&node1hdr, node1);
1664
- dp->d_ops->node_hdr_from_disk(&node2hdr, node2);
1665
- btree1 = dp->d_ops->node_tree_p(node1);
1666
- btree2 = dp->d_ops->node_tree_p(node2);
1774
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &node1hdr, node1);
1775
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &node2hdr, node2);
1776
+ btree1 = node1hdr.btree;
1777
+ btree2 = node2hdr.btree;
16671778
16681779 if (node1hdr.count > 0 && node2hdr.count > 0 &&
16691780 ((be32_to_cpu(btree2[0].hashval) < be32_to_cpu(btree1[0].hashval)) ||
....@@ -1728,7 +1839,7 @@
17281839 if (old_info->back) {
17291840 error = xfs_da3_node_read(args->trans, dp,
17301841 be32_to_cpu(old_info->back),
1731
- -1, &bp, args->whichfork);
1842
+ &bp, args->whichfork);
17321843 if (error)
17331844 return error;
17341845 ASSERT(bp != NULL);
....@@ -1749,7 +1860,7 @@
17491860 if (old_info->forw) {
17501861 error = xfs_da3_node_read(args->trans, dp,
17511862 be32_to_cpu(old_info->forw),
1752
- -1, &bp, args->whichfork);
1863
+ &bp, args->whichfork);
17531864 if (error)
17541865 return error;
17551866 ASSERT(bp != NULL);
....@@ -1808,7 +1919,7 @@
18081919 if (drop_info->back) {
18091920 error = xfs_da3_node_read(args->trans, args->dp,
18101921 be32_to_cpu(drop_info->back),
1811
- -1, &bp, args->whichfork);
1922
+ &bp, args->whichfork);
18121923 if (error)
18131924 return error;
18141925 ASSERT(bp != NULL);
....@@ -1825,7 +1936,7 @@
18251936 if (drop_info->forw) {
18261937 error = xfs_da3_node_read(args->trans, args->dp,
18271938 be32_to_cpu(drop_info->forw),
1828
- -1, &bp, args->whichfork);
1939
+ &bp, args->whichfork);
18291940 if (error)
18301941 return error;
18311942 ASSERT(bp != NULL);
....@@ -1860,7 +1971,6 @@
18601971 {
18611972 struct xfs_da_state_blk *blk;
18621973 struct xfs_da_blkinfo *info;
1863
- struct xfs_da_intnode *node;
18641974 struct xfs_da_args *args;
18651975 struct xfs_da_node_entry *btree;
18661976 struct xfs_da3_icnode_hdr nodehdr;
....@@ -1882,18 +1992,18 @@
18821992 ASSERT(path != NULL);
18831993 ASSERT((path->active > 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
18841994 level = (path->active-1) - 1; /* skip bottom layer in path */
1885
- for (blk = &path->blk[level]; level >= 0; blk--, level--) {
1886
- node = blk->bp->b_addr;
1887
- dp->d_ops->node_hdr_from_disk(&nodehdr, node);
1888
- btree = dp->d_ops->node_tree_p(node);
1995
+ for (; level >= 0; level--) {
1996
+ blk = &path->blk[level];
1997
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr,
1998
+ blk->bp->b_addr);
18891999
18902000 if (forward && (blk->index < nodehdr.count - 1)) {
18912001 blk->index++;
1892
- blkno = be32_to_cpu(btree[blk->index].before);
2002
+ blkno = be32_to_cpu(nodehdr.btree[blk->index].before);
18932003 break;
18942004 } else if (!forward && (blk->index > 0)) {
18952005 blk->index--;
1896
- blkno = be32_to_cpu(btree[blk->index].before);
2006
+ blkno = be32_to_cpu(nodehdr.btree[blk->index].before);
18972007 break;
18982008 }
18992009 }
....@@ -1911,7 +2021,7 @@
19112021 /*
19122022 * Read the next child block into a local buffer.
19132023 */
1914
- error = xfs_da3_node_read(args->trans, dp, blkno, -1, &bp,
2024
+ error = xfs_da3_node_read(args->trans, dp, blkno, &bp,
19152025 args->whichfork);
19162026 if (error)
19172027 return error;
....@@ -1944,9 +2054,9 @@
19442054 case XFS_DA_NODE_MAGIC:
19452055 case XFS_DA3_NODE_MAGIC:
19462056 blk->magic = XFS_DA_NODE_MAGIC;
1947
- node = (xfs_da_intnode_t *)info;
1948
- dp->d_ops->node_hdr_from_disk(&nodehdr, node);
1949
- btree = dp->d_ops->node_tree_p(node);
2057
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr,
2058
+ bp->b_addr);
2059
+ btree = nodehdr.btree;
19502060 blk->hashval = be32_to_cpu(btree[nodehdr.count - 1].hashval);
19512061 if (forward)
19522062 blk->index = 0;
....@@ -2026,18 +2136,6 @@
20262136 XFS_CMP_EXACT : XFS_CMP_DIFFERENT;
20272137 }
20282138
2029
-static xfs_dahash_t
2030
-xfs_default_hashname(
2031
- struct xfs_name *name)
2032
-{
2033
- return xfs_da_hashname(name->name, name->len);
2034
-}
2035
-
2036
-const struct xfs_nameops xfs_default_nameops = {
2037
- .hashname = xfs_default_hashname,
2038
- .compname = xfs_da_compname
2039
-};
2040
-
20412139 int
20422140 xfs_da_grow_inode_int(
20432141 struct xfs_da_args *args,
....@@ -2080,7 +2178,7 @@
20802178 * If we didn't get it and the block might work if fragmented,
20812179 * try without the CONTIG flag. Loop until we get it all.
20822180 */
2083
- mapp = kmem_alloc(sizeof(*mapp) * count, KM_SLEEP);
2181
+ mapp = kmem_alloc(sizeof(*mapp) * count, 0);
20842182 for (b = *bno, mapi = 0; b < *bno + count; ) {
20852183 nmap = min(XFS_BMAP_MAX_NMAP, count);
20862184 c = (int)(*bno + count - b);
....@@ -2195,16 +2293,13 @@
21952293 error = xfs_bmap_last_before(tp, dp, &lastoff, w);
21962294 if (error)
21972295 return error;
2198
- if (unlikely(lastoff == 0)) {
2199
- XFS_ERROR_REPORT("xfs_da_swap_lastblock(1)", XFS_ERRLEVEL_LOW,
2200
- mp);
2296
+ if (XFS_IS_CORRUPT(mp, lastoff == 0))
22012297 return -EFSCORRUPTED;
2202
- }
22032298 /*
22042299 * Read the last block in the btree space.
22052300 */
22062301 last_blkno = (xfs_dablk_t)lastoff - args->geo->fsbcount;
2207
- error = xfs_da3_node_read(tp, dp, last_blkno, -1, &last_buf, w);
2302
+ error = xfs_da3_node_read(tp, dp, last_blkno, &last_buf, w);
22082303 if (error)
22092304 return error;
22102305 /*
....@@ -2222,16 +2317,17 @@
22222317 struct xfs_dir2_leaf_entry *ents;
22232318
22242319 dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;
2225
- dp->d_ops->leaf_hdr_from_disk(&leafhdr, dead_leaf2);
2226
- ents = dp->d_ops->leaf_ents_p(dead_leaf2);
2320
+ xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr,
2321
+ dead_leaf2);
2322
+ ents = leafhdr.ents;
22272323 dead_level = 0;
22282324 dead_hash = be32_to_cpu(ents[leafhdr.count - 1].hashval);
22292325 } else {
22302326 struct xfs_da3_icnode_hdr deadhdr;
22312327
22322328 dead_node = (xfs_da_intnode_t *)dead_info;
2233
- dp->d_ops->node_hdr_from_disk(&deadhdr, dead_node);
2234
- btree = dp->d_ops->node_tree_p(dead_node);
2329
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &deadhdr, dead_node);
2330
+ btree = deadhdr.btree;
22352331 dead_level = deadhdr.level;
22362332 dead_hash = be32_to_cpu(btree[deadhdr.count - 1].hashval);
22372333 }
....@@ -2240,15 +2336,13 @@
22402336 * If the moved block has a left sibling, fix up the pointers.
22412337 */
22422338 if ((sib_blkno = be32_to_cpu(dead_info->back))) {
2243
- error = xfs_da3_node_read(tp, dp, sib_blkno, -1, &sib_buf, w);
2339
+ error = xfs_da3_node_read(tp, dp, sib_blkno, &sib_buf, w);
22442340 if (error)
22452341 goto done;
22462342 sib_info = sib_buf->b_addr;
2247
- if (unlikely(
2248
- be32_to_cpu(sib_info->forw) != last_blkno ||
2249
- sib_info->magic != dead_info->magic)) {
2250
- XFS_ERROR_REPORT("xfs_da_swap_lastblock(2)",
2251
- XFS_ERRLEVEL_LOW, mp);
2343
+ if (XFS_IS_CORRUPT(mp,
2344
+ be32_to_cpu(sib_info->forw) != last_blkno ||
2345
+ sib_info->magic != dead_info->magic)) {
22522346 error = -EFSCORRUPTED;
22532347 goto done;
22542348 }
....@@ -2262,15 +2356,13 @@
22622356 * If the moved block has a right sibling, fix up the pointers.
22632357 */
22642358 if ((sib_blkno = be32_to_cpu(dead_info->forw))) {
2265
- error = xfs_da3_node_read(tp, dp, sib_blkno, -1, &sib_buf, w);
2359
+ error = xfs_da3_node_read(tp, dp, sib_blkno, &sib_buf, w);
22662360 if (error)
22672361 goto done;
22682362 sib_info = sib_buf->b_addr;
2269
- if (unlikely(
2270
- be32_to_cpu(sib_info->back) != last_blkno ||
2271
- sib_info->magic != dead_info->magic)) {
2272
- XFS_ERROR_REPORT("xfs_da_swap_lastblock(3)",
2273
- XFS_ERRLEVEL_LOW, mp);
2363
+ if (XFS_IS_CORRUPT(mp,
2364
+ be32_to_cpu(sib_info->back) != last_blkno ||
2365
+ sib_info->magic != dead_info->magic)) {
22742366 error = -EFSCORRUPTED;
22752367 goto done;
22762368 }
....@@ -2286,27 +2378,24 @@
22862378 * Walk down the tree looking for the parent of the moved block.
22872379 */
22882380 for (;;) {
2289
- error = xfs_da3_node_read(tp, dp, par_blkno, -1, &par_buf, w);
2381
+ error = xfs_da3_node_read(tp, dp, par_blkno, &par_buf, w);
22902382 if (error)
22912383 goto done;
22922384 par_node = par_buf->b_addr;
2293
- dp->d_ops->node_hdr_from_disk(&par_hdr, par_node);
2294
- if (level >= 0 && level != par_hdr.level + 1) {
2295
- XFS_ERROR_REPORT("xfs_da_swap_lastblock(4)",
2296
- XFS_ERRLEVEL_LOW, mp);
2385
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &par_hdr, par_node);
2386
+ if (XFS_IS_CORRUPT(mp,
2387
+ level >= 0 && level != par_hdr.level + 1)) {
22972388 error = -EFSCORRUPTED;
22982389 goto done;
22992390 }
23002391 level = par_hdr.level;
2301
- btree = dp->d_ops->node_tree_p(par_node);
2392
+ btree = par_hdr.btree;
23022393 for (entno = 0;
23032394 entno < par_hdr.count &&
23042395 be32_to_cpu(btree[entno].hashval) < dead_hash;
23052396 entno++)
23062397 continue;
2307
- if (entno == par_hdr.count) {
2308
- XFS_ERROR_REPORT("xfs_da_swap_lastblock(5)",
2309
- XFS_ERRLEVEL_LOW, mp);
2398
+ if (XFS_IS_CORRUPT(mp, entno == par_hdr.count)) {
23102399 error = -EFSCORRUPTED;
23112400 goto done;
23122401 }
....@@ -2331,24 +2420,20 @@
23312420 par_blkno = par_hdr.forw;
23322421 xfs_trans_brelse(tp, par_buf);
23332422 par_buf = NULL;
2334
- if (unlikely(par_blkno == 0)) {
2335
- XFS_ERROR_REPORT("xfs_da_swap_lastblock(6)",
2336
- XFS_ERRLEVEL_LOW, mp);
2423
+ if (XFS_IS_CORRUPT(mp, par_blkno == 0)) {
23372424 error = -EFSCORRUPTED;
23382425 goto done;
23392426 }
2340
- error = xfs_da3_node_read(tp, dp, par_blkno, -1, &par_buf, w);
2427
+ error = xfs_da3_node_read(tp, dp, par_blkno, &par_buf, w);
23412428 if (error)
23422429 goto done;
23432430 par_node = par_buf->b_addr;
2344
- dp->d_ops->node_hdr_from_disk(&par_hdr, par_node);
2345
- if (par_hdr.level != level) {
2346
- XFS_ERROR_REPORT("xfs_da_swap_lastblock(7)",
2347
- XFS_ERRLEVEL_LOW, mp);
2431
+ xfs_da3_node_hdr_from_disk(dp->i_mount, &par_hdr, par_node);
2432
+ if (XFS_IS_CORRUPT(mp, par_hdr.level != level)) {
23482433 error = -EFSCORRUPTED;
23492434 goto done;
23502435 }
2351
- btree = dp->d_ops->node_tree_p(par_node);
2436
+ btree = par_hdr.btree;
23522437 entno = 0;
23532438 }
23542439 /*
....@@ -2411,159 +2496,86 @@
24112496 return error;
24122497 }
24132498
2414
-/*
2415
- * See if the mapping(s) for this btree block are valid, i.e.
2416
- * don't contain holes, are logically contiguous, and cover the whole range.
2417
- */
2418
-STATIC int
2419
-xfs_da_map_covers_blocks(
2420
- int nmap,
2421
- xfs_bmbt_irec_t *mapp,
2422
- xfs_dablk_t bno,
2423
- int count)
2424
-{
2425
- int i;
2426
- xfs_fileoff_t off;
2427
-
2428
- for (i = 0, off = bno; i < nmap; i++) {
2429
- if (mapp[i].br_startblock == HOLESTARTBLOCK ||
2430
- mapp[i].br_startblock == DELAYSTARTBLOCK) {
2431
- return 0;
2432
- }
2433
- if (off != mapp[i].br_startoff) {
2434
- return 0;
2435
- }
2436
- off += mapp[i].br_blockcount;
2437
- }
2438
- return off == bno + count;
2439
-}
2440
-
2441
-/*
2442
- * Convert a struct xfs_bmbt_irec to a struct xfs_buf_map.
2443
- *
2444
- * For the single map case, it is assumed that the caller has provided a pointer
2445
- * to a valid xfs_buf_map. For the multiple map case, this function will
2446
- * allocate the xfs_buf_map to hold all the maps and replace the caller's single
2447
- * map pointer with the allocated map.
2448
- */
2449
-static int
2450
-xfs_buf_map_from_irec(
2451
- struct xfs_mount *mp,
2452
- struct xfs_buf_map **mapp,
2453
- int *nmaps,
2454
- struct xfs_bmbt_irec *irecs,
2455
- int nirecs)
2456
-{
2457
- struct xfs_buf_map *map;
2458
- int i;
2459
-
2460
- ASSERT(*nmaps == 1);
2461
- ASSERT(nirecs >= 1);
2462
-
2463
- if (nirecs > 1) {
2464
- map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map),
2465
- KM_SLEEP | KM_NOFS);
2466
- if (!map)
2467
- return -ENOMEM;
2468
- *mapp = map;
2469
- }
2470
-
2471
- *nmaps = nirecs;
2472
- map = *mapp;
2473
- for (i = 0; i < *nmaps; i++) {
2474
- ASSERT(irecs[i].br_startblock != DELAYSTARTBLOCK &&
2475
- irecs[i].br_startblock != HOLESTARTBLOCK);
2476
- map[i].bm_bn = XFS_FSB_TO_DADDR(mp, irecs[i].br_startblock);
2477
- map[i].bm_len = XFS_FSB_TO_BB(mp, irecs[i].br_blockcount);
2478
- }
2479
- return 0;
2480
-}
2481
-
2482
-/*
2483
- * Map the block we are given ready for reading. There are three possible return
2484
- * values:
2485
- * -1 - will be returned if we land in a hole and mappedbno == -2 so the
2486
- * caller knows not to execute a subsequent read.
2487
- * 0 - if we mapped the block successfully
2488
- * >0 - positive error number if there was an error.
2489
- */
24902499 static int
24912500 xfs_dabuf_map(
24922501 struct xfs_inode *dp,
24932502 xfs_dablk_t bno,
2494
- xfs_daddr_t mappedbno,
2503
+ unsigned int flags,
24952504 int whichfork,
2496
- struct xfs_buf_map **map,
2505
+ struct xfs_buf_map **mapp,
24972506 int *nmaps)
24982507 {
24992508 struct xfs_mount *mp = dp->i_mount;
2500
- int nfsb;
2501
- int error = 0;
2502
- struct xfs_bmbt_irec irec;
2503
- struct xfs_bmbt_irec *irecs = &irec;
2504
- int nirecs;
2509
+ int nfsb = xfs_dabuf_nfsb(mp, whichfork);
2510
+ struct xfs_bmbt_irec irec, *irecs = &irec;
2511
+ struct xfs_buf_map *map = *mapp;
2512
+ xfs_fileoff_t off = bno;
2513
+ int error = 0, nirecs, i;
25052514
2506
- ASSERT(map && *map);
2507
- ASSERT(*nmaps == 1);
2515
+ if (nfsb > 1)
2516
+ irecs = kmem_zalloc(sizeof(irec) * nfsb, KM_NOFS);
25082517
2509
- if (whichfork == XFS_DATA_FORK)
2510
- nfsb = mp->m_dir_geo->fsbcount;
2511
- else
2512
- nfsb = mp->m_attr_geo->fsbcount;
2518
+ nirecs = nfsb;
2519
+ error = xfs_bmapi_read(dp, bno, nfsb, irecs, &nirecs,
2520
+ xfs_bmapi_aflag(whichfork));
2521
+ if (error)
2522
+ goto out_free_irecs;
25132523
25142524 /*
2515
- * Caller doesn't have a mapping. -2 means don't complain
2516
- * if we land in a hole.
2525
+ * Use the caller provided map for the single map case, else allocate a
2526
+ * larger one that needs to be free by the caller.
25172527 */
2518
- if (mappedbno == -1 || mappedbno == -2) {
2519
- /*
2520
- * Optimize the one-block case.
2521
- */
2522
- if (nfsb != 1)
2523
- irecs = kmem_zalloc(sizeof(irec) * nfsb,
2524
- KM_SLEEP | KM_NOFS);
2525
-
2526
- nirecs = nfsb;
2527
- error = xfs_bmapi_read(dp, (xfs_fileoff_t)bno, nfsb, irecs,
2528
- &nirecs, xfs_bmapi_aflag(whichfork));
2529
- if (error)
2530
- goto out;
2531
- } else {
2532
- irecs->br_startblock = XFS_DADDR_TO_FSB(mp, mappedbno);
2533
- irecs->br_startoff = (xfs_fileoff_t)bno;
2534
- irecs->br_blockcount = nfsb;
2535
- irecs->br_state = 0;
2536
- nirecs = 1;
2537
- }
2538
-
2539
- if (!xfs_da_map_covers_blocks(nirecs, irecs, bno, nfsb)) {
2540
- error = mappedbno == -2 ? -1 : -EFSCORRUPTED;
2541
- if (unlikely(error == -EFSCORRUPTED)) {
2542
- if (xfs_error_level >= XFS_ERRLEVEL_LOW) {
2543
- int i;
2544
- xfs_alert(mp, "%s: bno %lld dir: inode %lld",
2545
- __func__, (long long)bno,
2546
- (long long)dp->i_ino);
2547
- for (i = 0; i < *nmaps; i++) {
2548
- xfs_alert(mp,
2549
-"[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d",
2550
- i,
2551
- (long long)irecs[i].br_startoff,
2552
- (long long)irecs[i].br_startblock,
2553
- (long long)irecs[i].br_blockcount,
2554
- irecs[i].br_state);
2555
- }
2556
- }
2557
- XFS_ERROR_REPORT("xfs_da_do_buf(1)",
2558
- XFS_ERRLEVEL_LOW, mp);
2528
+ if (nirecs > 1) {
2529
+ map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), KM_NOFS);
2530
+ if (!map) {
2531
+ error = -ENOMEM;
2532
+ goto out_free_irecs;
25592533 }
2560
- goto out;
2534
+ *mapp = map;
25612535 }
2562
- error = xfs_buf_map_from_irec(mp, map, nmaps, irecs, nirecs);
2563
-out:
2536
+
2537
+ for (i = 0; i < nirecs; i++) {
2538
+ if (irecs[i].br_startblock == HOLESTARTBLOCK ||
2539
+ irecs[i].br_startblock == DELAYSTARTBLOCK)
2540
+ goto invalid_mapping;
2541
+ if (off != irecs[i].br_startoff)
2542
+ goto invalid_mapping;
2543
+
2544
+ map[i].bm_bn = XFS_FSB_TO_DADDR(mp, irecs[i].br_startblock);
2545
+ map[i].bm_len = XFS_FSB_TO_BB(mp, irecs[i].br_blockcount);
2546
+ off += irecs[i].br_blockcount;
2547
+ }
2548
+
2549
+ if (off != bno + nfsb)
2550
+ goto invalid_mapping;
2551
+
2552
+ *nmaps = nirecs;
2553
+out_free_irecs:
25642554 if (irecs != &irec)
25652555 kmem_free(irecs);
25662556 return error;
2557
+
2558
+invalid_mapping:
2559
+ /* Caller ok with no mapping. */
2560
+ if (XFS_IS_CORRUPT(mp, !(flags & XFS_DABUF_MAP_HOLE_OK))) {
2561
+ error = -EFSCORRUPTED;
2562
+ if (xfs_error_level >= XFS_ERRLEVEL_LOW) {
2563
+ xfs_alert(mp, "%s: bno %u inode %llu",
2564
+ __func__, bno, dp->i_ino);
2565
+
2566
+ for (i = 0; i < nirecs; i++) {
2567
+ xfs_alert(mp,
2568
+"[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d",
2569
+ i, irecs[i].br_startoff,
2570
+ irecs[i].br_startblock,
2571
+ irecs[i].br_blockcount,
2572
+ irecs[i].br_state);
2573
+ }
2574
+ }
2575
+ } else {
2576
+ *nmaps = 0;
2577
+ }
2578
+ goto out_free_irecs;
25672579 }
25682580
25692581 /*
....@@ -2571,39 +2583,26 @@
25712583 */
25722584 int
25732585 xfs_da_get_buf(
2574
- struct xfs_trans *trans,
2586
+ struct xfs_trans *tp,
25752587 struct xfs_inode *dp,
25762588 xfs_dablk_t bno,
2577
- xfs_daddr_t mappedbno,
25782589 struct xfs_buf **bpp,
25792590 int whichfork)
25802591 {
2592
+ struct xfs_mount *mp = dp->i_mount;
25812593 struct xfs_buf *bp;
2582
- struct xfs_buf_map map;
2583
- struct xfs_buf_map *mapp;
2584
- int nmap;
2594
+ struct xfs_buf_map map, *mapp = &map;
2595
+ int nmap = 1;
25852596 int error;
25862597
25872598 *bpp = NULL;
2588
- mapp = &map;
2589
- nmap = 1;
2590
- error = xfs_dabuf_map(dp, bno, mappedbno, whichfork,
2591
- &mapp, &nmap);
2592
- if (error) {
2593
- /* mapping a hole is not an error, but we don't continue */
2594
- if (error == -1)
2595
- error = 0;
2599
+ error = xfs_dabuf_map(dp, bno, 0, whichfork, &mapp, &nmap);
2600
+ if (error || nmap == 0)
25962601 goto out_free;
2597
- }
25982602
2599
- bp = xfs_trans_get_buf_map(trans, dp->i_mount->m_ddev_targp,
2600
- mapp, nmap, 0);
2601
- error = bp ? bp->b_error : -EIO;
2602
- if (error) {
2603
- if (bp)
2604
- xfs_trans_brelse(trans, bp);
2603
+ error = xfs_trans_get_buf_map(tp, mp->m_ddev_targp, mapp, nmap, 0, &bp);
2604
+ if (error)
26052605 goto out_free;
2606
- }
26072606
26082607 *bpp = bp;
26092608
....@@ -2619,35 +2618,27 @@
26192618 */
26202619 int
26212620 xfs_da_read_buf(
2622
- struct xfs_trans *trans,
2621
+ struct xfs_trans *tp,
26232622 struct xfs_inode *dp,
26242623 xfs_dablk_t bno,
2625
- xfs_daddr_t mappedbno,
2624
+ unsigned int flags,
26262625 struct xfs_buf **bpp,
26272626 int whichfork,
26282627 const struct xfs_buf_ops *ops)
26292628 {
2629
+ struct xfs_mount *mp = dp->i_mount;
26302630 struct xfs_buf *bp;
2631
- struct xfs_buf_map map;
2632
- struct xfs_buf_map *mapp;
2633
- int nmap;
2631
+ struct xfs_buf_map map, *mapp = &map;
2632
+ int nmap = 1;
26342633 int error;
26352634
26362635 *bpp = NULL;
2637
- mapp = &map;
2638
- nmap = 1;
2639
- error = xfs_dabuf_map(dp, bno, mappedbno, whichfork,
2640
- &mapp, &nmap);
2641
- if (error) {
2642
- /* mapping a hole is not an error, but we don't continue */
2643
- if (error == -1)
2644
- error = 0;
2636
+ error = xfs_dabuf_map(dp, bno, flags, whichfork, &mapp, &nmap);
2637
+ if (error || !nmap)
26452638 goto out_free;
2646
- }
26472639
2648
- error = xfs_trans_read_buf_map(dp->i_mount, trans,
2649
- dp->i_mount->m_ddev_targp,
2650
- mapp, nmap, 0, &bp, ops);
2640
+ error = xfs_trans_read_buf_map(mp, tp, mp->m_ddev_targp, mapp, nmap, 0,
2641
+ &bp, ops);
26512642 if (error)
26522643 goto out_free;
26532644
....@@ -2670,7 +2661,7 @@
26702661 xfs_da_reada_buf(
26712662 struct xfs_inode *dp,
26722663 xfs_dablk_t bno,
2673
- xfs_daddr_t mappedbno,
2664
+ unsigned int flags,
26742665 int whichfork,
26752666 const struct xfs_buf_ops *ops)
26762667 {
....@@ -2681,16 +2672,10 @@
26812672
26822673 mapp = &map;
26832674 nmap = 1;
2684
- error = xfs_dabuf_map(dp, bno, mappedbno, whichfork,
2685
- &mapp, &nmap);
2686
- if (error) {
2687
- /* mapping a hole is not an error, but we don't continue */
2688
- if (error == -1)
2689
- error = 0;
2675
+ error = xfs_dabuf_map(dp, bno, flags, whichfork, &mapp, &nmap);
2676
+ if (error || !nmap)
26902677 goto out_free;
2691
- }
26922678
2693
- mappedbno = mapp[0].bm_bn;
26942679 xfs_buf_readahead_map(dp->i_mount->m_ddev_targp, mapp, nmap, ops);
26952680
26962681 out_free: