hc
2024-09-20 a36159eec6ca17402b0e146b86efaf76568dc353
kernel/fs/xfs/libxfs/xfs_bmap.c
....@@ -13,14 +13,10 @@
1313 #include "xfs_sb.h"
1414 #include "xfs_mount.h"
1515 #include "xfs_defer.h"
16
-#include "xfs_da_format.h"
17
-#include "xfs_da_btree.h"
1816 #include "xfs_dir2.h"
1917 #include "xfs_inode.h"
2018 #include "xfs_btree.h"
2119 #include "xfs_trans.h"
22
-#include "xfs_inode_item.h"
23
-#include "xfs_extfree_item.h"
2420 #include "xfs_alloc.h"
2521 #include "xfs_bmap.h"
2622 #include "xfs_bmap_util.h"
....@@ -32,13 +28,13 @@
3228 #include "xfs_trans_space.h"
3329 #include "xfs_buf_item.h"
3430 #include "xfs_trace.h"
35
-#include "xfs_symlink.h"
3631 #include "xfs_attr_leaf.h"
3732 #include "xfs_filestream.h"
3833 #include "xfs_rmap.h"
3934 #include "xfs_ag_resv.h"
4035 #include "xfs_refcount.h"
4136 #include "xfs_icache.h"
37
+#include "xfs_iomap.h"
4238
4339
4440 kmem_zone_t *xfs_bmap_free_item_zone;
....@@ -65,10 +61,10 @@
6561 int sz; /* root block size */
6662
6763 /*
68
- * The maximum number of extents in a file, hence the maximum
69
- * number of leaf entries, is controlled by the type of di_nextents
70
- * (a signed 32-bit number, xfs_extnum_t), or by di_anextents
71
- * (a signed 16-bit number, xfs_aextnum_t).
64
+ * The maximum number of extents in a file, hence the maximum number of
65
+ * leaf entries, is controlled by the size of the on-disk extent count,
66
+ * either a signed 32-bit number for the data fork, or a signed 16-bit
67
+ * number for the attr fork.
7268 *
7369 * Note that we can no longer assume that if we are in ATTR1 that
7470 * the fork offset of all the inodes will be
....@@ -124,10 +120,11 @@
124120 */
125121 static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork)
126122 {
123
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
124
+
127125 return whichfork != XFS_COW_FORK &&
128
- XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
129
- XFS_IFORK_NEXTENTS(ip, whichfork) >
130
- XFS_IFORK_MAXEXT(ip, whichfork);
126
+ ifp->if_format == XFS_DINODE_FMT_EXTENTS &&
127
+ ifp->if_nextents > XFS_IFORK_MAXEXT(ip, whichfork);
131128 }
132129
133130 /*
....@@ -135,10 +132,11 @@
135132 */
136133 static inline bool xfs_bmap_wants_extents(struct xfs_inode *ip, int whichfork)
137134 {
135
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
136
+
138137 return whichfork != XFS_COW_FORK &&
139
- XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE &&
140
- XFS_IFORK_NEXTENTS(ip, whichfork) <=
141
- XFS_IFORK_MAXEXT(ip, whichfork);
138
+ ifp->if_format == XFS_DINODE_FMT_BTREE &&
139
+ ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork);
142140 }
143141
144142 /*
....@@ -197,14 +195,12 @@
197195 struct xfs_mount *mp = ip->i_mount;
198196 uint offset;
199197
200
- if (mp->m_sb.sb_inodesize == 256) {
201
- offset = XFS_LITINO(mp, ip->i_d.di_version) -
202
- XFS_BMDR_SPACE_CALC(MINABTPTRS);
203
- } else {
198
+ if (mp->m_sb.sb_inodesize == 256)
199
+ offset = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS);
200
+ else
204201 offset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);
205
- }
206202
207
- ASSERT(offset < XFS_LITINO(mp, ip->i_d.di_version));
203
+ ASSERT(offset < XFS_LITINO(mp));
208204 return offset;
209205 }
210206
....@@ -219,8 +215,8 @@
219215 int whichfork)
220216 {
221217 if (whichfork == XFS_ATTR_FORK &&
222
- ip->i_d.di_format != XFS_DINODE_FMT_DEV &&
223
- ip->i_d.di_format != XFS_DINODE_FMT_BTREE) {
218
+ ip->i_df.if_format != XFS_DINODE_FMT_DEV &&
219
+ ip->i_df.if_format != XFS_DINODE_FMT_BTREE) {
224220 uint dfl_forkoff = xfs_default_attroffset(ip) >> 3;
225221
226222 if (dfl_forkoff > ip->i_d.di_forkoff)
....@@ -321,31 +317,28 @@
321317 xfs_inode_t *ip, /* incore inode pointer */
322318 int whichfork) /* data or attr fork */
323319 {
320
+ struct xfs_mount *mp = ip->i_mount;
321
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
324322 struct xfs_btree_block *block; /* current btree block */
325323 xfs_fsblock_t bno; /* block # of "block" */
326324 xfs_buf_t *bp; /* buffer for "block" */
327325 int error; /* error return value */
328326 xfs_extnum_t i=0, j; /* index into the extents list */
329
- struct xfs_ifork *ifp; /* fork structure */
330327 int level; /* btree level, for checking */
331
- xfs_mount_t *mp; /* file system mount structure */
332328 __be64 *pp; /* pointer to block address */
333329 xfs_bmbt_rec_t *ep; /* pointer to current extent */
334330 xfs_bmbt_rec_t last = {0, 0}; /* last extent in prev block */
335331 xfs_bmbt_rec_t *nextp; /* pointer to next extent */
336332 int bp_release = 0;
337333
338
- if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) {
334
+ if (ifp->if_format != XFS_DINODE_FMT_BTREE)
339335 return;
340
- }
341336
342337 /* skip large extent count inodes */
343
- if (ip->i_d.di_nextents > 10000)
338
+ if (ip->i_df.if_nextents > 10000)
344339 return;
345340
346341 bno = NULLFSBLOCK;
347
- mp = ip->i_mount;
348
- ifp = XFS_IFORK_PTR(ip, whichfork);
349342 block = ifp->if_broot;
350343 /*
351344 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
....@@ -370,7 +363,7 @@
370363 bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno));
371364 if (!bp) {
372365 bp_release = 1;
373
- error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp,
366
+ error = xfs_btree_read_bufl(mp, NULL, bno, &bp,
374367 XFS_BMAP_BTREE_REF,
375368 &xfs_bmbt_buf_ops);
376369 if (error)
....@@ -388,8 +381,10 @@
388381 xfs_check_block(block, mp, 0, 0);
389382 pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
390383 bno = be64_to_cpu(*pp);
391
- XFS_WANT_CORRUPTED_GOTO(mp,
392
- xfs_verify_fsbno(mp, bno), error0);
384
+ if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbno(mp, bno))) {
385
+ error = -EFSCORRUPTED;
386
+ goto error0;
387
+ }
393388 if (bp_release) {
394389 bp_release = 0;
395390 xfs_trans_brelse(NULL, bp);
....@@ -454,7 +449,7 @@
454449 bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno));
455450 if (!bp) {
456451 bp_release = 1;
457
- error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp,
452
+ error = xfs_btree_read_bufl(mp, NULL, bno, &bp,
458453 XFS_BMAP_BTREE_REF,
459454 &xfs_bmbt_buf_ops);
460455 if (error)
....@@ -536,7 +531,7 @@
536531 struct xfs_trans *tp,
537532 xfs_fsblock_t bno,
538533 xfs_filblks_t len,
539
- struct xfs_owner_info *oinfo,
534
+ const struct xfs_owner_info *oinfo,
540535 bool skip_discard)
541536 {
542537 struct xfs_extent_free_item *new; /* new element */
....@@ -558,13 +553,14 @@
558553 #endif
559554 ASSERT(xfs_bmap_free_item_zone != NULL);
560555
561
- new = kmem_zone_alloc(xfs_bmap_free_item_zone, KM_SLEEP);
556
+ new = kmem_cache_alloc(xfs_bmap_free_item_zone,
557
+ GFP_KERNEL | __GFP_NOFAIL);
562558 new->xefi_startblock = bno;
563559 new->xefi_blockcount = (xfs_extlen_t)len;
564560 if (oinfo)
565561 new->xefi_oinfo = *oinfo;
566562 else
567
- xfs_rmap_skip_owner_update(&new->xefi_oinfo);
563
+ new->xefi_oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;
568564 new->xefi_skip_discard = skip_discard;
569565 trace_xfs_bmap_free_defer(tp->t_mountp,
570566 XFS_FSB_TO_AGNO(tp->t_mountp, bno), 0,
....@@ -577,47 +573,49 @@
577573 */
578574
579575 /*
580
- * Transform a btree format file with only one leaf node, where the
581
- * extents list will fit in the inode, into an extents format file.
582
- * Since the file extents are already in-core, all we have to do is
583
- * give up the space for the btree root and pitch the leaf block.
576
+ * Convert the inode format to extent format if it currently is in btree format,
577
+ * but the extent list is small enough that it fits into the extent format.
578
+ *
579
+ * Since the extents are already in-core, all we have to do is give up the space
580
+ * for the btree root and pitch the leaf block.
584581 */
585582 STATIC int /* error */
586583 xfs_bmap_btree_to_extents(
587
- xfs_trans_t *tp, /* transaction pointer */
588
- xfs_inode_t *ip, /* incore inode pointer */
589
- xfs_btree_cur_t *cur, /* btree cursor */
584
+ struct xfs_trans *tp, /* transaction pointer */
585
+ struct xfs_inode *ip, /* incore inode pointer */
586
+ struct xfs_btree_cur *cur, /* btree cursor */
590587 int *logflagsp, /* inode logging flags */
591588 int whichfork) /* data or attr fork */
592589 {
593
- /* REFERENCED */
590
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
591
+ struct xfs_mount *mp = ip->i_mount;
592
+ struct xfs_btree_block *rblock = ifp->if_broot;
594593 struct xfs_btree_block *cblock;/* child btree block */
595594 xfs_fsblock_t cbno; /* child block number */
596595 xfs_buf_t *cbp; /* child block's buffer */
597596 int error; /* error return value */
598
- struct xfs_ifork *ifp; /* inode fork data */
599
- xfs_mount_t *mp; /* mount point structure */
600597 __be64 *pp; /* ptr to block address */
601
- struct xfs_btree_block *rblock;/* root btree block */
602598 struct xfs_owner_info oinfo;
603599
604
- mp = ip->i_mount;
605
- ifp = XFS_IFORK_PTR(ip, whichfork);
600
+ /* check if we actually need the extent format first: */
601
+ if (!xfs_bmap_wants_extents(ip, whichfork))
602
+ return 0;
603
+
604
+ ASSERT(cur);
606605 ASSERT(whichfork != XFS_COW_FORK);
607606 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
608
- ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE);
609
- rblock = ifp->if_broot;
607
+ ASSERT(ifp->if_format == XFS_DINODE_FMT_BTREE);
610608 ASSERT(be16_to_cpu(rblock->bb_level) == 1);
611609 ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1);
612610 ASSERT(xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0) == 1);
611
+
613612 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, ifp->if_broot_bytes);
614613 cbno = be64_to_cpu(*pp);
615
- *logflagsp = 0;
616614 #ifdef DEBUG
617
- XFS_WANT_CORRUPTED_RETURN(cur->bc_mp,
618
- xfs_btree_check_lptr(cur, cbno, 1));
615
+ if (XFS_IS_CORRUPT(cur->bc_mp, !xfs_btree_check_lptr(cur, cbno, 1)))
616
+ return -EFSCORRUPTED;
619617 #endif
620
- error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp, XFS_BMAP_BTREE_REF,
618
+ error = xfs_btree_read_bufl(mp, tp, cbno, &cbp, XFS_BMAP_BTREE_REF,
621619 &xfs_bmbt_buf_ops);
622620 if (error)
623621 return error;
....@@ -634,8 +632,8 @@
634632 xfs_iroot_realloc(ip, -1, whichfork);
635633 ASSERT(ifp->if_broot == NULL);
636634 ASSERT((ifp->if_flags & XFS_IFBROOT) == 0);
637
- XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
638
- *logflagsp = XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
635
+ ifp->if_format = XFS_DINODE_FMT_EXTENTS;
636
+ *logflagsp |= XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
639637 return 0;
640638 }
641639
....@@ -670,7 +668,7 @@
670668 mp = ip->i_mount;
671669 ASSERT(whichfork != XFS_COW_FORK);
672670 ifp = XFS_IFORK_PTR(ip, whichfork);
673
- ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS);
671
+ ASSERT(ifp->if_format == XFS_DINODE_FMT_EXTENTS);
674672
675673 /*
676674 * Make space in the inode incore. This needs to be undone if we fail
....@@ -690,11 +688,11 @@
690688 * Need a cursor. Can't allocate until bb_level is filled in.
691689 */
692690 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
693
- cur->bc_private.b.flags = wasdel ? XFS_BTCUR_BPRV_WASDEL : 0;
691
+ cur->bc_ino.flags = wasdel ? XFS_BTCUR_BMBT_WASDEL : 0;
694692 /*
695693 * Convert to a btree with two levels, one record in root.
696694 */
697
- XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE);
695
+ ifp->if_format = XFS_DINODE_FMT_BTREE;
698696 memset(&args, 0, sizeof(args));
699697 args.tp = tp;
700698 args.mp = mp;
....@@ -727,14 +725,14 @@
727725 ASSERT(tp->t_firstblock == NULLFSBLOCK ||
728726 args.agno >= XFS_FSB_TO_AGNO(mp, tp->t_firstblock));
729727 tp->t_firstblock = args.fsbno;
730
- cur->bc_private.b.allocated++;
728
+ cur->bc_ino.allocated++;
731729 ip->i_d.di_nblocks++;
732730 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L);
733
- abp = xfs_btree_get_bufl(mp, tp, args.fsbno, 0);
734
- if (!abp) {
735
- error = -EFSCORRUPTED;
731
+ error = xfs_trans_get_buf(tp, mp->m_ddev_targp,
732
+ XFS_FSB_TO_DADDR(mp, args.fsbno),
733
+ mp->m_bsize, 0, &abp);
734
+ if (error)
736735 goto out_unreserve_dquot;
737
- }
738736
739737 /*
740738 * Fill in the child block.
....@@ -752,7 +750,7 @@
752750 xfs_bmbt_disk_set_all(arp, &rec);
753751 cnt++;
754752 }
755
- ASSERT(cnt == XFS_IFORK_NEXTENTS(ip, whichfork));
753
+ ASSERT(cnt == ifp->if_nextents);
756754 xfs_btree_set_numrecs(ablock, cnt);
757755
758756 /*
....@@ -780,7 +778,7 @@
780778 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
781779 out_root_realloc:
782780 xfs_iroot_realloc(ip, -1, whichfork);
783
- XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
781
+ ifp->if_format = XFS_DINODE_FMT_EXTENTS;
784782 ASSERT(ifp->if_broot == NULL);
785783 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
786784
....@@ -795,22 +793,24 @@
795793 */
796794 void
797795 xfs_bmap_local_to_extents_empty(
796
+ struct xfs_trans *tp,
798797 struct xfs_inode *ip,
799798 int whichfork)
800799 {
801800 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
802801
803802 ASSERT(whichfork != XFS_COW_FORK);
804
- ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
803
+ ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
805804 ASSERT(ifp->if_bytes == 0);
806
- ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0);
805
+ ASSERT(ifp->if_nextents == 0);
807806
808807 xfs_bmap_forkoff_reset(ip, whichfork);
809808 ifp->if_flags &= ~XFS_IFINLINE;
810809 ifp->if_flags |= XFS_IFEXTENTS;
811810 ifp->if_u1.if_root = NULL;
812811 ifp->if_height = 0;
813
- XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
812
+ ifp->if_format = XFS_DINODE_FMT_EXTENTS;
813
+ xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
814814 }
815815
816816
....@@ -840,10 +840,10 @@
840840 */
841841 ASSERT(!(S_ISREG(VFS_I(ip)->i_mode) && whichfork == XFS_DATA_FORK));
842842 ifp = XFS_IFORK_PTR(ip, whichfork);
843
- ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
843
+ ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
844844
845845 if (!ifp->if_bytes) {
846
- xfs_bmap_local_to_extents_empty(ip, whichfork);
846
+ xfs_bmap_local_to_extents_empty(tp, ip, whichfork);
847847 flags = XFS_ILOG_CORE;
848848 goto done;
849849 }
....@@ -876,7 +876,11 @@
876876 ASSERT(args.fsbno != NULLFSBLOCK);
877877 ASSERT(args.len == 1);
878878 tp->t_firstblock = args.fsbno;
879
- bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0);
879
+ error = xfs_trans_get_buf(tp, args.mp->m_ddev_targp,
880
+ XFS_FSB_TO_DADDR(args.mp, args.fsbno),
881
+ args.mp->m_bsize, 0, &bp);
882
+ if (error)
883
+ goto done;
880884
881885 /*
882886 * Initialize the block, copy the data and log the remote buffer.
....@@ -890,7 +894,7 @@
890894
891895 /* account for the change in fork size */
892896 xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
893
- xfs_bmap_local_to_extents_empty(ip, whichfork);
897
+ xfs_bmap_local_to_extents_empty(tp, ip, whichfork);
894898 flags |= XFS_ILOG_CORE;
895899
896900 ifp->if_u1.if_root = NULL;
....@@ -903,7 +907,7 @@
903907 xfs_iext_first(ifp, &icur);
904908 xfs_iext_insert(ip, &icur, &rec, 0);
905909
906
- XFS_IFORK_NEXT_SET(ip, whichfork, 1);
910
+ ifp->if_nextents = 1;
907911 ip->i_d.di_nblocks = 1;
908912 xfs_trans_mod_dquot_byino(tp, ip,
909913 XFS_TRANS_DQ_BCOUNT, 1L);
....@@ -937,14 +941,17 @@
937941 if (error)
938942 goto error0;
939943 /* must be at least one entry */
940
- XFS_WANT_CORRUPTED_GOTO(mp, stat == 1, error0);
944
+ if (XFS_IS_CORRUPT(mp, stat != 1)) {
945
+ error = -EFSCORRUPTED;
946
+ goto error0;
947
+ }
941948 if ((error = xfs_btree_new_iroot(cur, flags, &stat)))
942949 goto error0;
943950 if (stat == 0) {
944951 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
945952 return -ENOSPC;
946953 }
947
- cur->bc_private.b.allocated = 0;
954
+ cur->bc_ino.allocated = 0;
948955 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
949956 }
950957 return 0;
....@@ -965,13 +972,14 @@
965972 xfs_btree_cur_t *cur; /* bmap btree cursor */
966973 int error; /* error return value */
967974
968
- if (ip->i_d.di_nextents * sizeof(xfs_bmbt_rec_t) <= XFS_IFORK_DSIZE(ip))
975
+ if (ip->i_df.if_nextents * sizeof(struct xfs_bmbt_rec) <=
976
+ XFS_IFORK_DSIZE(ip))
969977 return 0;
970978 cur = NULL;
971979 error = xfs_bmap_extents_to_btree(tp, ip, &cur, 0, flags,
972980 XFS_DATA_FORK);
973981 if (cur) {
974
- cur->bc_private.b.allocated = 0;
982
+ cur->bc_ino.allocated = 0;
975983 xfs_btree_del_cursor(cur, error);
976984 }
977985 return error;
....@@ -1026,7 +1034,7 @@
10261034 int size,
10271035 int *version)
10281036 {
1029
- switch (ip->i_d.di_format) {
1037
+ switch (ip->i_df.if_format) {
10301038 case XFS_DINODE_FMT_DEV:
10311039 ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
10321040 break;
....@@ -1084,17 +1092,6 @@
10841092 goto trans_cancel;
10851093 if (XFS_IFORK_Q(ip))
10861094 goto trans_cancel;
1087
- if (ip->i_d.di_anextents != 0) {
1088
- error = -EFSCORRUPTED;
1089
- goto trans_cancel;
1090
- }
1091
- if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) {
1092
- /*
1093
- * For inodes coming from pre-6.2 filesystems.
1094
- */
1095
- ASSERT(ip->i_d.di_aformat == 0);
1096
- ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
1097
- }
10981095
10991096 xfs_trans_ijoin(tp, ip, 0);
11001097 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
....@@ -1102,10 +1099,14 @@
11021099 if (error)
11031100 goto trans_cancel;
11041101 ASSERT(ip->i_afp == NULL);
1105
- ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP);
1102
+
1103
+ ip->i_afp = kmem_cache_zalloc(xfs_ifork_zone,
1104
+ GFP_KERNEL | __GFP_NOFAIL);
1105
+
1106
+ ip->i_afp->if_format = XFS_DINODE_FMT_EXTENTS;
11061107 ip->i_afp->if_flags = XFS_IFEXTENTS;
11071108 logflags = 0;
1108
- switch (ip->i_d.di_format) {
1109
+ switch (ip->i_df.if_format) {
11091110 case XFS_DINODE_FMT_LOCAL:
11101111 error = xfs_bmap_add_attrfork_local(tp, ip, &logflags);
11111112 break;
....@@ -1155,6 +1156,65 @@
11551156 * Internal and external extent tree search functions.
11561157 */
11571158
1159
+struct xfs_iread_state {
1160
+ struct xfs_iext_cursor icur;
1161
+ xfs_extnum_t loaded;
1162
+};
1163
+
1164
+/* Stuff every bmbt record from this block into the incore extent map. */
1165
+static int
1166
+xfs_iread_bmbt_block(
1167
+ struct xfs_btree_cur *cur,
1168
+ int level,
1169
+ void *priv)
1170
+{
1171
+ struct xfs_iread_state *ir = priv;
1172
+ struct xfs_mount *mp = cur->bc_mp;
1173
+ struct xfs_inode *ip = cur->bc_ino.ip;
1174
+ struct xfs_btree_block *block;
1175
+ struct xfs_buf *bp;
1176
+ struct xfs_bmbt_rec *frp;
1177
+ xfs_extnum_t num_recs;
1178
+ xfs_extnum_t j;
1179
+ int whichfork = cur->bc_ino.whichfork;
1180
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
1181
+
1182
+ block = xfs_btree_get_block(cur, level, &bp);
1183
+
1184
+ /* Abort if we find more records than nextents. */
1185
+ num_recs = xfs_btree_get_numrecs(block);
1186
+ if (unlikely(ir->loaded + num_recs > ifp->if_nextents)) {
1187
+ xfs_warn(ip->i_mount, "corrupt dinode %llu, (btree extents).",
1188
+ (unsigned long long)ip->i_ino);
1189
+ xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, block,
1190
+ sizeof(*block), __this_address);
1191
+ return -EFSCORRUPTED;
1192
+ }
1193
+
1194
+ /* Copy records into the incore cache. */
1195
+ frp = XFS_BMBT_REC_ADDR(mp, block, 1);
1196
+ for (j = 0; j < num_recs; j++, frp++, ir->loaded++) {
1197
+ struct xfs_bmbt_irec new;
1198
+ xfs_failaddr_t fa;
1199
+
1200
+ xfs_bmbt_disk_get_all(frp, &new);
1201
+ fa = xfs_bmap_validate_extent(ip, whichfork, &new);
1202
+ if (fa) {
1203
+ xfs_inode_verifier_error(ip, -EFSCORRUPTED,
1204
+ "xfs_iread_extents(2)", frp,
1205
+ sizeof(*frp), fa);
1206
+ return -EFSCORRUPTED;
1207
+ }
1208
+ xfs_iext_insert(ip, &ir->icur, &new,
1209
+ xfs_bmap_fork_to_state(whichfork));
1210
+ trace_xfs_read_extent(ip, &ir->icur,
1211
+ xfs_bmap_fork_to_state(whichfork), _THIS_IP_);
1212
+ xfs_iext_next(ifp, &ir->icur);
1213
+ }
1214
+
1215
+ return 0;
1216
+}
1217
+
11581218 /*
11591219 * Read in extents from a btree-format inode.
11601220 */
....@@ -1164,134 +1224,36 @@
11641224 struct xfs_inode *ip,
11651225 int whichfork)
11661226 {
1167
- struct xfs_mount *mp = ip->i_mount;
1168
- int state = xfs_bmap_fork_to_state(whichfork);
1227
+ struct xfs_iread_state ir;
11691228 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
1170
- xfs_extnum_t nextents = XFS_IFORK_NEXTENTS(ip, whichfork);
1171
- struct xfs_btree_block *block = ifp->if_broot;
1172
- struct xfs_iext_cursor icur;
1173
- struct xfs_bmbt_irec new;
1174
- xfs_fsblock_t bno;
1175
- struct xfs_buf *bp;
1176
- xfs_extnum_t i, j;
1177
- int level;
1178
- __be64 *pp;
1229
+ struct xfs_mount *mp = ip->i_mount;
1230
+ struct xfs_btree_cur *cur;
11791231 int error;
11801232
11811233 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
11821234
1183
- if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) {
1184
- XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
1185
- return -EFSCORRUPTED;
1186
- }
1187
-
1188
- /*
1189
- * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
1190
- */
1191
- level = be16_to_cpu(block->bb_level);
1192
- if (unlikely(level == 0)) {
1193
- XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
1194
- return -EFSCORRUPTED;
1195
- }
1196
- pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes);
1197
- bno = be64_to_cpu(*pp);
1198
-
1199
- /*
1200
- * Go down the tree until leaf level is reached, following the first
1201
- * pointer (leftmost) at each level.
1202
- */
1203
- while (level-- > 0) {
1204
- error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp,
1205
- XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops);
1206
- if (error)
1207
- goto out;
1208
- block = XFS_BUF_TO_BLOCK(bp);
1209
- if (level == 0)
1210
- break;
1211
- pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
1212
- bno = be64_to_cpu(*pp);
1213
- XFS_WANT_CORRUPTED_GOTO(mp,
1214
- xfs_verify_fsbno(mp, bno), out_brelse);
1215
- xfs_trans_brelse(tp, bp);
1216
- }
1217
-
1218
- /*
1219
- * Here with bp and block set to the leftmost leaf node in the tree.
1220
- */
1221
- i = 0;
1222
- xfs_iext_first(ifp, &icur);
1223
-
1224
- /*
1225
- * Loop over all leaf nodes. Copy information to the extent records.
1226
- */
1227
- for (;;) {
1228
- xfs_bmbt_rec_t *frp;
1229
- xfs_fsblock_t nextbno;
1230
- xfs_extnum_t num_recs;
1231
-
1232
- num_recs = xfs_btree_get_numrecs(block);
1233
- if (unlikely(i + num_recs > nextents)) {
1234
- xfs_warn(ip->i_mount,
1235
- "corrupt dinode %Lu, (btree extents).",
1236
- (unsigned long long) ip->i_ino);
1237
- xfs_inode_verifier_error(ip, -EFSCORRUPTED,
1238
- __func__, block, sizeof(*block),
1239
- __this_address);
1240
- error = -EFSCORRUPTED;
1241
- goto out_brelse;
1242
- }
1243
- /*
1244
- * Read-ahead the next leaf block, if any.
1245
- */
1246
- nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
1247
- if (nextbno != NULLFSBLOCK)
1248
- xfs_btree_reada_bufl(mp, nextbno, 1,
1249
- &xfs_bmbt_buf_ops);
1250
- /*
1251
- * Copy records into the extent records.
1252
- */
1253
- frp = XFS_BMBT_REC_ADDR(mp, block, 1);
1254
- for (j = 0; j < num_recs; j++, frp++, i++) {
1255
- xfs_failaddr_t fa;
1256
-
1257
- xfs_bmbt_disk_get_all(frp, &new);
1258
- fa = xfs_bmap_validate_extent(ip, whichfork, &new);
1259
- if (fa) {
1260
- error = -EFSCORRUPTED;
1261
- xfs_inode_verifier_error(ip, error,
1262
- "xfs_iread_extents(2)",
1263
- frp, sizeof(*frp), fa);
1264
- goto out_brelse;
1265
- }
1266
- xfs_iext_insert(ip, &icur, &new, state);
1267
- trace_xfs_read_extent(ip, &icur, state, _THIS_IP_);
1268
- xfs_iext_next(ifp, &icur);
1269
- }
1270
- xfs_trans_brelse(tp, bp);
1271
- bno = nextbno;
1272
- /*
1273
- * If we've reached the end, stop.
1274
- */
1275
- if (bno == NULLFSBLOCK)
1276
- break;
1277
- error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp,
1278
- XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops);
1279
- if (error)
1280
- goto out;
1281
- block = XFS_BUF_TO_BLOCK(bp);
1282
- }
1283
-
1284
- if (i != XFS_IFORK_NEXTENTS(ip, whichfork)) {
1235
+ if (XFS_IS_CORRUPT(mp, ifp->if_format != XFS_DINODE_FMT_BTREE)) {
12851236 error = -EFSCORRUPTED;
12861237 goto out;
12871238 }
1288
- ASSERT(i == xfs_iext_count(ifp));
1239
+
1240
+ ir.loaded = 0;
1241
+ xfs_iext_first(ifp, &ir.icur);
1242
+ cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
1243
+ error = xfs_btree_visit_blocks(cur, xfs_iread_bmbt_block,
1244
+ XFS_BTREE_VISIT_RECORDS, &ir);
1245
+ xfs_btree_del_cursor(cur, error);
1246
+ if (error)
1247
+ goto out;
1248
+
1249
+ if (XFS_IS_CORRUPT(mp, ir.loaded != ifp->if_nextents)) {
1250
+ error = -EFSCORRUPTED;
1251
+ goto out;
1252
+ }
1253
+ ASSERT(ir.loaded == xfs_iext_count(ifp));
12891254
12901255 ifp->if_flags |= XFS_IFEXTENTS;
12911256 return 0;
1292
-
1293
-out_brelse:
1294
- xfs_trans_brelse(tp, bp);
12951257 out:
12961258 xfs_iext_destroy(ifp);
12971259 return error;
....@@ -1318,14 +1280,12 @@
13181280 xfs_fileoff_t lowest, max;
13191281 int error;
13201282
1321
- ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE ||
1322
- XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ||
1323
- XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
1324
-
1325
- if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
1283
+ if (ifp->if_format == XFS_DINODE_FMT_LOCAL) {
13261284 *first_unused = 0;
13271285 return 0;
13281286 }
1287
+
1288
+ ASSERT(xfs_ifork_has_extents(ifp));
13291289
13301290 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
13311291 error = xfs_iread_extents(tp, ip, whichfork);
....@@ -1367,7 +1327,7 @@
13671327 struct xfs_iext_cursor icur;
13681328 int error;
13691329
1370
- switch (XFS_IFORK_FORMAT(ip, whichfork)) {
1330
+ switch (ifp->if_format) {
13711331 case XFS_DINODE_FMT_LOCAL:
13721332 *last_block = 0;
13731333 return 0;
....@@ -1375,7 +1335,8 @@
13751335 case XFS_DINODE_FMT_EXTENTS:
13761336 break;
13771337 default:
1378
- return -EIO;
1338
+ ASSERT(0);
1339
+ return -EFSCORRUPTED;
13791340 }
13801341
13811342 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
....@@ -1465,18 +1426,18 @@
14651426 xfs_fileoff_t *last_block,
14661427 int whichfork)
14671428 {
1429
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
14681430 struct xfs_bmbt_irec rec;
14691431 int is_empty;
14701432 int error;
14711433
14721434 *last_block = 0;
14731435
1474
- if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL)
1436
+ if (ifp->if_format == XFS_DINODE_FMT_LOCAL)
14751437 return 0;
14761438
1477
- if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
1478
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
1479
- return -EIO;
1439
+ if (XFS_IS_CORRUPT(ip->i_mount, !xfs_ifork_has_extents(ifp)))
1440
+ return -EFSCORRUPTED;
14801441
14811442 error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty);
14821443 if (error || is_empty)
....@@ -1493,23 +1454,22 @@
14931454 */
14941455 int /* 1=>1 block, 0=>otherwise */
14951456 xfs_bmap_one_block(
1496
- xfs_inode_t *ip, /* incore inode */
1497
- int whichfork) /* data or attr fork */
1457
+ struct xfs_inode *ip, /* incore inode */
1458
+ int whichfork) /* data or attr fork */
14981459 {
1499
- struct xfs_ifork *ifp; /* inode fork pointer */
1500
- int rval; /* return value */
1501
- xfs_bmbt_irec_t s; /* internal version of extent */
1460
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
1461
+ int rval; /* return value */
1462
+ struct xfs_bmbt_irec s; /* internal version of extent */
15021463 struct xfs_iext_cursor icur;
15031464
15041465 #ifndef DEBUG
15051466 if (whichfork == XFS_DATA_FORK)
15061467 return XFS_ISIZE(ip) == ip->i_mount->m_sb.sb_blocksize;
15071468 #endif /* !DEBUG */
1508
- if (XFS_IFORK_NEXTENTS(ip, whichfork) != 1)
1469
+ if (ifp->if_nextents != 1)
15091470 return 0;
1510
- if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
1471
+ if (ifp->if_format != XFS_DINODE_FMT_EXTENTS)
15111472 return 0;
1512
- ifp = XFS_IFORK_PTR(ip, whichfork);
15131473 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
15141474 xfs_iext_first(ifp, &icur);
15151475 xfs_iext_get_extent(ifp, &icur, &s);
....@@ -1531,10 +1491,11 @@
15311491 struct xfs_bmalloca *bma,
15321492 int whichfork)
15331493 {
1494
+ struct xfs_mount *mp = bma->ip->i_mount;
1495
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork);
15341496 struct xfs_bmbt_irec *new = &bma->got;
15351497 int error; /* error return value */
15361498 int i; /* temp state */
1537
- struct xfs_ifork *ifp; /* inode fork pointer */
15381499 xfs_fileoff_t new_endoff; /* end offset of new entry */
15391500 xfs_bmbt_irec_t r[3]; /* neighbor extent entries */
15401501 /* left is 0, right is 1, prev is 2 */
....@@ -1544,19 +1505,12 @@
15441505 xfs_filblks_t da_old; /* old count del alloc blocks used */
15451506 xfs_filblks_t temp=0; /* value for da_new calculations */
15461507 int tmp_rval; /* partial logging flags */
1547
- struct xfs_mount *mp;
1548
- xfs_extnum_t *nextents;
15491508 struct xfs_bmbt_irec old;
15501509
1551
- mp = bma->ip->i_mount;
1552
- ifp = XFS_IFORK_PTR(bma->ip, whichfork);
15531510 ASSERT(whichfork != XFS_ATTR_FORK);
1554
- nextents = (whichfork == XFS_COW_FORK ? &bma->ip->i_cnextents :
1555
- &bma->ip->i_d.di_nextents);
1556
-
15571511 ASSERT(!isnullstartblock(new->br_startblock));
15581512 ASSERT(!bma->cur ||
1559
- (bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL));
1513
+ (bma->cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL));
15601514
15611515 XFS_STATS_INC(mp, xs_add_exlist);
15621516
....@@ -1644,7 +1598,7 @@
16441598 xfs_iext_remove(bma->ip, &bma->icur, state);
16451599 xfs_iext_prev(ifp, &bma->icur);
16461600 xfs_iext_update_extent(bma->ip, state, &bma->icur, &LEFT);
1647
- (*nextents)--;
1601
+ ifp->if_nextents--;
16481602
16491603 if (bma->cur == NULL)
16501604 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
....@@ -1653,15 +1607,24 @@
16531607 error = xfs_bmbt_lookup_eq(bma->cur, &RIGHT, &i);
16541608 if (error)
16551609 goto done;
1656
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1610
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
1611
+ error = -EFSCORRUPTED;
1612
+ goto done;
1613
+ }
16571614 error = xfs_btree_delete(bma->cur, &i);
16581615 if (error)
16591616 goto done;
1660
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1617
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
1618
+ error = -EFSCORRUPTED;
1619
+ goto done;
1620
+ }
16611621 error = xfs_btree_decrement(bma->cur, 0, &i);
16621622 if (error)
16631623 goto done;
1664
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1624
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
1625
+ error = -EFSCORRUPTED;
1626
+ goto done;
1627
+ }
16651628 error = xfs_bmbt_update(bma->cur, &LEFT);
16661629 if (error)
16671630 goto done;
....@@ -1687,7 +1650,10 @@
16871650 error = xfs_bmbt_lookup_eq(bma->cur, &old, &i);
16881651 if (error)
16891652 goto done;
1690
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1653
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
1654
+ error = -EFSCORRUPTED;
1655
+ goto done;
1656
+ }
16911657 error = xfs_bmbt_update(bma->cur, &LEFT);
16921658 if (error)
16931659 goto done;
....@@ -1717,7 +1683,10 @@
17171683 error = xfs_bmbt_lookup_eq(bma->cur, &RIGHT, &i);
17181684 if (error)
17191685 goto done;
1720
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1686
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
1687
+ error = -EFSCORRUPTED;
1688
+ goto done;
1689
+ }
17211690 error = xfs_bmbt_update(bma->cur, &PREV);
17221691 if (error)
17231692 goto done;
....@@ -1733,8 +1702,8 @@
17331702 PREV.br_startblock = new->br_startblock;
17341703 PREV.br_state = new->br_state;
17351704 xfs_iext_update_extent(bma->ip, state, &bma->icur, &PREV);
1705
+ ifp->if_nextents++;
17361706
1737
- (*nextents)++;
17381707 if (bma->cur == NULL)
17391708 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
17401709 else {
....@@ -1742,11 +1711,17 @@
17421711 error = xfs_bmbt_lookup_eq(bma->cur, new, &i);
17431712 if (error)
17441713 goto done;
1745
- XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
1714
+ if (XFS_IS_CORRUPT(mp, i != 0)) {
1715
+ error = -EFSCORRUPTED;
1716
+ goto done;
1717
+ }
17461718 error = xfs_btree_insert(bma->cur, &i);
17471719 if (error)
17481720 goto done;
1749
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1721
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
1722
+ error = -EFSCORRUPTED;
1723
+ goto done;
1724
+ }
17501725 }
17511726 break;
17521727
....@@ -1777,7 +1752,10 @@
17771752 error = xfs_bmbt_lookup_eq(bma->cur, &old, &i);
17781753 if (error)
17791754 goto done;
1780
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1755
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
1756
+ error = -EFSCORRUPTED;
1757
+ goto done;
1758
+ }
17811759 error = xfs_bmbt_update(bma->cur, &LEFT);
17821760 if (error)
17831761 goto done;
....@@ -1790,7 +1768,8 @@
17901768 * The left neighbor is not contiguous.
17911769 */
17921770 xfs_iext_update_extent(bma->ip, state, &bma->icur, new);
1793
- (*nextents)++;
1771
+ ifp->if_nextents++;
1772
+
17941773 if (bma->cur == NULL)
17951774 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
17961775 else {
....@@ -1798,11 +1777,17 @@
17981777 error = xfs_bmbt_lookup_eq(bma->cur, new, &i);
17991778 if (error)
18001779 goto done;
1801
- XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
1780
+ if (XFS_IS_CORRUPT(mp, i != 0)) {
1781
+ error = -EFSCORRUPTED;
1782
+ goto done;
1783
+ }
18021784 error = xfs_btree_insert(bma->cur, &i);
18031785 if (error)
18041786 goto done;
1805
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1787
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
1788
+ error = -EFSCORRUPTED;
1789
+ goto done;
1790
+ }
18061791 }
18071792
18081793 if (xfs_bmap_needs_btree(bma->ip, whichfork)) {
....@@ -1816,7 +1801,7 @@
18161801 temp = PREV.br_blockcount - new->br_blockcount;
18171802 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp),
18181803 startblockval(PREV.br_startblock) -
1819
- (bma->cur ? bma->cur->bc_private.b.allocated : 0));
1804
+ (bma->cur ? bma->cur->bc_ino.allocated : 0));
18201805
18211806 PREV.br_startoff = new_endoff;
18221807 PREV.br_blockcount = temp;
....@@ -1843,7 +1828,10 @@
18431828 error = xfs_bmbt_lookup_eq(bma->cur, &old, &i);
18441829 if (error)
18451830 goto done;
1846
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1831
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
1832
+ error = -EFSCORRUPTED;
1833
+ goto done;
1834
+ }
18471835 error = xfs_bmbt_update(bma->cur, &RIGHT);
18481836 if (error)
18491837 goto done;
....@@ -1867,7 +1855,8 @@
18671855 * The right neighbor is not contiguous.
18681856 */
18691857 xfs_iext_update_extent(bma->ip, state, &bma->icur, new);
1870
- (*nextents)++;
1858
+ ifp->if_nextents++;
1859
+
18711860 if (bma->cur == NULL)
18721861 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
18731862 else {
....@@ -1875,11 +1864,17 @@
18751864 error = xfs_bmbt_lookup_eq(bma->cur, new, &i);
18761865 if (error)
18771866 goto done;
1878
- XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
1867
+ if (XFS_IS_CORRUPT(mp, i != 0)) {
1868
+ error = -EFSCORRUPTED;
1869
+ goto done;
1870
+ }
18791871 error = xfs_btree_insert(bma->cur, &i);
18801872 if (error)
18811873 goto done;
1882
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1874
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
1875
+ error = -EFSCORRUPTED;
1876
+ goto done;
1877
+ }
18831878 }
18841879
18851880 if (xfs_bmap_needs_btree(bma->ip, whichfork)) {
....@@ -1893,7 +1888,7 @@
18931888 temp = PREV.br_blockcount - new->br_blockcount;
18941889 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp),
18951890 startblockval(PREV.br_startblock) -
1896
- (bma->cur ? bma->cur->bc_private.b.allocated : 0));
1891
+ (bma->cur ? bma->cur->bc_ino.allocated : 0));
18971892
18981893 PREV.br_startblock = nullstartblock(da_new);
18991894 PREV.br_blockcount = temp;
....@@ -1946,7 +1941,7 @@
19461941 xfs_iext_next(ifp, &bma->icur);
19471942 xfs_iext_insert(bma->ip, &bma->icur, &RIGHT, state);
19481943 xfs_iext_insert(bma->ip, &bma->icur, &LEFT, state);
1949
- (*nextents)++;
1944
+ ifp->if_nextents++;
19501945
19511946 if (bma->cur == NULL)
19521947 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
....@@ -1955,11 +1950,17 @@
19551950 error = xfs_bmbt_lookup_eq(bma->cur, new, &i);
19561951 if (error)
19571952 goto done;
1958
- XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
1953
+ if (XFS_IS_CORRUPT(mp, i != 0)) {
1954
+ error = -EFSCORRUPTED;
1955
+ goto done;
1956
+ }
19591957 error = xfs_btree_insert(bma->cur, &i);
19601958 if (error)
19611959 goto done;
1962
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1960
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
1961
+ error = -EFSCORRUPTED;
1962
+ goto done;
1963
+ }
19631964 }
19641965
19651966 if (xfs_bmap_needs_btree(bma->ip, whichfork)) {
....@@ -1988,11 +1989,8 @@
19881989 }
19891990
19901991 /* add reverse mapping unless caller opted out */
1991
- if (!(bma->flags & XFS_BMAPI_NORMAP)) {
1992
- error = xfs_rmap_map_extent(bma->tp, bma->ip, whichfork, new);
1993
- if (error)
1994
- goto done;
1995
- }
1992
+ if (!(bma->flags & XFS_BMAPI_NORMAP))
1993
+ xfs_rmap_map_extent(bma->tp, bma->ip, whichfork, new);
19961994
19971995 /* convert to a btree if necessary */
19981996 if (xfs_bmap_needs_btree(bma->ip, whichfork)) {
....@@ -2007,9 +2005,12 @@
20072005 goto done;
20082006 }
20092007
2008
+ if (da_new != da_old)
2009
+ xfs_mod_delalloc(mp, (int64_t)da_new - da_old);
2010
+
20102011 if (bma->cur) {
2011
- da_new += bma->cur->bc_private.b.allocated;
2012
- bma->cur->bc_private.b.allocated = 0;
2012
+ da_new += bma->cur->bc_ino.allocated;
2013
+ bma->cur->bc_ino.allocated = 0;
20132014 }
20142015
20152016 /* adjust for changes in reserved delayed indirect blocks */
....@@ -2032,7 +2033,7 @@
20322033 /*
20332034 * Convert an unwritten allocation to a real allocation or vice versa.
20342035 */
2035
-STATIC int /* error */
2036
+int /* error */
20362037 xfs_bmap_add_extent_unwritten_real(
20372038 struct xfs_trans *tp,
20382039 xfs_inode_t *ip, /* incore inode pointer */
....@@ -2144,8 +2145,7 @@
21442145 xfs_iext_remove(ip, icur, state);
21452146 xfs_iext_prev(ifp, icur);
21462147 xfs_iext_update_extent(ip, state, icur, &LEFT);
2147
- XFS_IFORK_NEXT_SET(ip, whichfork,
2148
- XFS_IFORK_NEXTENTS(ip, whichfork) - 2);
2148
+ ifp->if_nextents -= 2;
21492149 if (cur == NULL)
21502150 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
21512151 else {
....@@ -2153,19 +2153,34 @@
21532153 error = xfs_bmbt_lookup_eq(cur, &RIGHT, &i);
21542154 if (error)
21552155 goto done;
2156
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2156
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2157
+ error = -EFSCORRUPTED;
2158
+ goto done;
2159
+ }
21572160 if ((error = xfs_btree_delete(cur, &i)))
21582161 goto done;
2159
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2162
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2163
+ error = -EFSCORRUPTED;
2164
+ goto done;
2165
+ }
21602166 if ((error = xfs_btree_decrement(cur, 0, &i)))
21612167 goto done;
2162
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2168
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2169
+ error = -EFSCORRUPTED;
2170
+ goto done;
2171
+ }
21632172 if ((error = xfs_btree_delete(cur, &i)))
21642173 goto done;
2165
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2174
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2175
+ error = -EFSCORRUPTED;
2176
+ goto done;
2177
+ }
21662178 if ((error = xfs_btree_decrement(cur, 0, &i)))
21672179 goto done;
2168
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2180
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2181
+ error = -EFSCORRUPTED;
2182
+ goto done;
2183
+ }
21692184 error = xfs_bmbt_update(cur, &LEFT);
21702185 if (error)
21712186 goto done;
....@@ -2182,8 +2197,7 @@
21822197 xfs_iext_remove(ip, icur, state);
21832198 xfs_iext_prev(ifp, icur);
21842199 xfs_iext_update_extent(ip, state, icur, &LEFT);
2185
- XFS_IFORK_NEXT_SET(ip, whichfork,
2186
- XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
2200
+ ifp->if_nextents--;
21872201 if (cur == NULL)
21882202 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
21892203 else {
....@@ -2191,13 +2205,22 @@
21912205 error = xfs_bmbt_lookup_eq(cur, &PREV, &i);
21922206 if (error)
21932207 goto done;
2194
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2208
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2209
+ error = -EFSCORRUPTED;
2210
+ goto done;
2211
+ }
21952212 if ((error = xfs_btree_delete(cur, &i)))
21962213 goto done;
2197
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2214
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2215
+ error = -EFSCORRUPTED;
2216
+ goto done;
2217
+ }
21982218 if ((error = xfs_btree_decrement(cur, 0, &i)))
21992219 goto done;
2200
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2220
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2221
+ error = -EFSCORRUPTED;
2222
+ goto done;
2223
+ }
22012224 error = xfs_bmbt_update(cur, &LEFT);
22022225 if (error)
22032226 goto done;
....@@ -2216,9 +2239,8 @@
22162239 xfs_iext_remove(ip, icur, state);
22172240 xfs_iext_prev(ifp, icur);
22182241 xfs_iext_update_extent(ip, state, icur, &PREV);
2242
+ ifp->if_nextents--;
22192243
2220
- XFS_IFORK_NEXT_SET(ip, whichfork,
2221
- XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
22222244 if (cur == NULL)
22232245 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
22242246 else {
....@@ -2226,13 +2248,22 @@
22262248 error = xfs_bmbt_lookup_eq(cur, &RIGHT, &i);
22272249 if (error)
22282250 goto done;
2229
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2251
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2252
+ error = -EFSCORRUPTED;
2253
+ goto done;
2254
+ }
22302255 if ((error = xfs_btree_delete(cur, &i)))
22312256 goto done;
2232
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2257
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2258
+ error = -EFSCORRUPTED;
2259
+ goto done;
2260
+ }
22332261 if ((error = xfs_btree_decrement(cur, 0, &i)))
22342262 goto done;
2235
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2263
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2264
+ error = -EFSCORRUPTED;
2265
+ goto done;
2266
+ }
22362267 error = xfs_bmbt_update(cur, &PREV);
22372268 if (error)
22382269 goto done;
....@@ -2255,7 +2286,10 @@
22552286 error = xfs_bmbt_lookup_eq(cur, new, &i);
22562287 if (error)
22572288 goto done;
2258
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2289
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2290
+ error = -EFSCORRUPTED;
2291
+ goto done;
2292
+ }
22592293 error = xfs_bmbt_update(cur, &PREV);
22602294 if (error)
22612295 goto done;
....@@ -2285,7 +2319,10 @@
22852319 error = xfs_bmbt_lookup_eq(cur, &old, &i);
22862320 if (error)
22872321 goto done;
2288
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2322
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2323
+ error = -EFSCORRUPTED;
2324
+ goto done;
2325
+ }
22892326 error = xfs_bmbt_update(cur, &PREV);
22902327 if (error)
22912328 goto done;
....@@ -2310,8 +2347,8 @@
23102347
23112348 xfs_iext_update_extent(ip, state, icur, &PREV);
23122349 xfs_iext_insert(ip, icur, new, state);
2313
- XFS_IFORK_NEXT_SET(ip, whichfork,
2314
- XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
2350
+ ifp->if_nextents++;
2351
+
23152352 if (cur == NULL)
23162353 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
23172354 else {
....@@ -2319,14 +2356,20 @@
23192356 error = xfs_bmbt_lookup_eq(cur, &old, &i);
23202357 if (error)
23212358 goto done;
2322
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2359
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2360
+ error = -EFSCORRUPTED;
2361
+ goto done;
2362
+ }
23232363 error = xfs_bmbt_update(cur, &PREV);
23242364 if (error)
23252365 goto done;
23262366 cur->bc_rec.b = *new;
23272367 if ((error = xfs_btree_insert(cur, &i)))
23282368 goto done;
2329
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2369
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2370
+ error = -EFSCORRUPTED;
2371
+ goto done;
2372
+ }
23302373 }
23312374 break;
23322375
....@@ -2353,7 +2396,10 @@
23532396 error = xfs_bmbt_lookup_eq(cur, &old, &i);
23542397 if (error)
23552398 goto done;
2356
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2399
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2400
+ error = -EFSCORRUPTED;
2401
+ goto done;
2402
+ }
23572403 error = xfs_bmbt_update(cur, &PREV);
23582404 if (error)
23592405 goto done;
....@@ -2377,9 +2423,8 @@
23772423 xfs_iext_update_extent(ip, state, icur, &PREV);
23782424 xfs_iext_next(ifp, icur);
23792425 xfs_iext_insert(ip, icur, new, state);
2426
+ ifp->if_nextents++;
23802427
2381
- XFS_IFORK_NEXT_SET(ip, whichfork,
2382
- XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
23832428 if (cur == NULL)
23842429 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
23852430 else {
....@@ -2387,17 +2432,26 @@
23872432 error = xfs_bmbt_lookup_eq(cur, &old, &i);
23882433 if (error)
23892434 goto done;
2390
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2435
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2436
+ error = -EFSCORRUPTED;
2437
+ goto done;
2438
+ }
23912439 error = xfs_bmbt_update(cur, &PREV);
23922440 if (error)
23932441 goto done;
23942442 error = xfs_bmbt_lookup_eq(cur, new, &i);
23952443 if (error)
23962444 goto done;
2397
- XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
2445
+ if (XFS_IS_CORRUPT(mp, i != 0)) {
2446
+ error = -EFSCORRUPTED;
2447
+ goto done;
2448
+ }
23982449 if ((error = xfs_btree_insert(cur, &i)))
23992450 goto done;
2400
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2451
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2452
+ error = -EFSCORRUPTED;
2453
+ goto done;
2454
+ }
24012455 }
24022456 break;
24032457
....@@ -2421,9 +2475,8 @@
24212475 xfs_iext_next(ifp, icur);
24222476 xfs_iext_insert(ip, icur, &r[1], state);
24232477 xfs_iext_insert(ip, icur, &r[0], state);
2478
+ ifp->if_nextents += 2;
24242479
2425
- XFS_IFORK_NEXT_SET(ip, whichfork,
2426
- XFS_IFORK_NEXTENTS(ip, whichfork) + 2);
24272480 if (cur == NULL)
24282481 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
24292482 else {
....@@ -2431,7 +2484,10 @@
24312484 error = xfs_bmbt_lookup_eq(cur, &old, &i);
24322485 if (error)
24332486 goto done;
2434
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2487
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2488
+ error = -EFSCORRUPTED;
2489
+ goto done;
2490
+ }
24352491 /* new right extent - oldext */
24362492 error = xfs_bmbt_update(cur, &r[1]);
24372493 if (error)
....@@ -2440,7 +2496,10 @@
24402496 cur->bc_rec.b = PREV;
24412497 if ((error = xfs_btree_insert(cur, &i)))
24422498 goto done;
2443
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2499
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2500
+ error = -EFSCORRUPTED;
2501
+ goto done;
2502
+ }
24442503 /*
24452504 * Reset the cursor to the position of the new extent
24462505 * we are about to insert as we can't trust it after
....@@ -2449,11 +2508,17 @@
24492508 error = xfs_bmbt_lookup_eq(cur, new, &i);
24502509 if (error)
24512510 goto done;
2452
- XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
2511
+ if (XFS_IS_CORRUPT(mp, i != 0)) {
2512
+ error = -EFSCORRUPTED;
2513
+ goto done;
2514
+ }
24532515 /* new middle extent - newext */
24542516 if ((error = xfs_btree_insert(cur, &i)))
24552517 goto done;
2456
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2518
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2519
+ error = -EFSCORRUPTED;
2520
+ goto done;
2521
+ }
24572522 }
24582523 break;
24592524
....@@ -2471,9 +2536,7 @@
24712536 }
24722537
24732538 /* update reverse mappings */
2474
- error = xfs_rmap_convert_extent(mp, tp, ip, whichfork, new);
2475
- if (error)
2476
- goto done;
2539
+ xfs_rmap_convert_extent(mp, tp, ip, whichfork, new);
24772540
24782541 /* convert to a btree if necessary */
24792542 if (xfs_bmap_needs_btree(ip, whichfork)) {
....@@ -2489,7 +2552,7 @@
24892552
24902553 /* clear out the allocated field, done with it now in any case. */
24912554 if (cur) {
2492
- cur->bc_private.b.allocated = 0;
2555
+ cur->bc_ino.allocated = 0;
24932556 *curp = cur;
24942557 }
24952558
....@@ -2638,6 +2701,7 @@
26382701 /*
26392702 * Nothing to do for disk quota accounting here.
26402703 */
2704
+ xfs_mod_delalloc(ip->i_mount, (int64_t)newlen - oldlen);
26412705 }
26422706 }
26432707
....@@ -2667,7 +2731,7 @@
26672731 struct xfs_bmbt_irec old;
26682732
26692733 ASSERT(!isnullstartblock(new->br_startblock));
2670
- ASSERT(!cur || !(cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL));
2734
+ ASSERT(!cur || !(cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL));
26712735
26722736 XFS_STATS_INC(mp, xs_add_exlist);
26732737
....@@ -2727,9 +2791,8 @@
27272791 xfs_iext_remove(ip, icur, state);
27282792 xfs_iext_prev(ifp, icur);
27292793 xfs_iext_update_extent(ip, state, icur, &left);
2794
+ ifp->if_nextents--;
27302795
2731
- XFS_IFORK_NEXT_SET(ip, whichfork,
2732
- XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
27332796 if (cur == NULL) {
27342797 rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
27352798 } else {
....@@ -2737,15 +2800,24 @@
27372800 error = xfs_bmbt_lookup_eq(cur, &right, &i);
27382801 if (error)
27392802 goto done;
2740
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2803
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2804
+ error = -EFSCORRUPTED;
2805
+ goto done;
2806
+ }
27412807 error = xfs_btree_delete(cur, &i);
27422808 if (error)
27432809 goto done;
2744
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2810
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2811
+ error = -EFSCORRUPTED;
2812
+ goto done;
2813
+ }
27452814 error = xfs_btree_decrement(cur, 0, &i);
27462815 if (error)
27472816 goto done;
2748
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2817
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2818
+ error = -EFSCORRUPTED;
2819
+ goto done;
2820
+ }
27492821 error = xfs_bmbt_update(cur, &left);
27502822 if (error)
27512823 goto done;
....@@ -2771,7 +2843,10 @@
27712843 error = xfs_bmbt_lookup_eq(cur, &old, &i);
27722844 if (error)
27732845 goto done;
2774
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2846
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2847
+ error = -EFSCORRUPTED;
2848
+ goto done;
2849
+ }
27752850 error = xfs_bmbt_update(cur, &left);
27762851 if (error)
27772852 goto done;
....@@ -2798,7 +2873,10 @@
27982873 error = xfs_bmbt_lookup_eq(cur, &old, &i);
27992874 if (error)
28002875 goto done;
2801
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2876
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2877
+ error = -EFSCORRUPTED;
2878
+ goto done;
2879
+ }
28022880 error = xfs_bmbt_update(cur, &right);
28032881 if (error)
28042882 goto done;
....@@ -2812,8 +2890,8 @@
28122890 * Insert a new entry.
28132891 */
28142892 xfs_iext_insert(ip, icur, new, state);
2815
- XFS_IFORK_NEXT_SET(ip, whichfork,
2816
- XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
2893
+ ifp->if_nextents++;
2894
+
28172895 if (cur == NULL) {
28182896 rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
28192897 } else {
....@@ -2821,21 +2899,24 @@
28212899 error = xfs_bmbt_lookup_eq(cur, new, &i);
28222900 if (error)
28232901 goto done;
2824
- XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
2902
+ if (XFS_IS_CORRUPT(mp, i != 0)) {
2903
+ error = -EFSCORRUPTED;
2904
+ goto done;
2905
+ }
28252906 error = xfs_btree_insert(cur, &i);
28262907 if (error)
28272908 goto done;
2828
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
2909
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
2910
+ error = -EFSCORRUPTED;
2911
+ goto done;
2912
+ }
28292913 }
28302914 break;
28312915 }
28322916
28332917 /* add reverse mapping unless caller opted out */
2834
- if (!(flags & XFS_BMAPI_NORMAP)) {
2835
- error = xfs_rmap_map_extent(tp, ip, whichfork, new);
2836
- if (error)
2837
- goto done;
2838
- }
2918
+ if (!(flags & XFS_BMAPI_NORMAP))
2919
+ xfs_rmap_map_extent(tp, ip, whichfork, new);
28392920
28402921 /* convert to a btree if necessary */
28412922 if (xfs_bmap_needs_btree(ip, whichfork)) {
....@@ -2852,7 +2933,7 @@
28522933
28532934 /* clear out the allocated field, done with it now in any case. */
28542935 if (cur)
2855
- cur->bc_private.b.allocated = 0;
2936
+ cur->bc_ino.allocated = 0;
28562937
28572938 xfs_bmap_check_leaf_extents(cur, ip, whichfork);
28582939 done:
....@@ -3063,7 +3144,7 @@
30633144 mp = ap->ip->i_mount;
30643145 nullfb = ap->tp->t_firstblock == NULLFSBLOCK;
30653146 rt = XFS_IS_REALTIME_INODE(ap->ip) &&
3066
- xfs_alloc_is_userdata(ap->datatype);
3147
+ (ap->datatype & XFS_ALLOC_USERDATA);
30673148 fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp,
30683149 ap->tp->t_firstblock);
30693150 /*
....@@ -3208,11 +3289,12 @@
32083289 pag = xfs_perag_get(mp, ag);
32093290 if (!pag->pagf_init) {
32103291 error = xfs_alloc_pagf_init(mp, tp, ag, XFS_ALLOC_FLAG_TRYLOCK);
3211
- if (error)
3212
- goto out;
3213
-
3214
- if (!pag->pagf_init) {
3215
- *notinit = 1;
3292
+ if (error) {
3293
+ /* Couldn't lock the AGF, so skip this AG. */
3294
+ if (error == -EAGAIN) {
3295
+ *notinit = 1;
3296
+ error = 0;
3297
+ }
32163298 goto out;
32173299 }
32183300 }
....@@ -3350,8 +3432,10 @@
33503432 * already have quota reservation and there's nothing to do
33513433 * yet.
33523434 */
3353
- if (ap->wasdel)
3435
+ if (ap->wasdel) {
3436
+ xfs_mod_delalloc(ap->ip->i_mount, -(int64_t)args->len);
33543437 return;
3438
+ }
33553439
33563440 /*
33573441 * Otherwise, we've allocated blocks in a hole. The transaction
....@@ -3370,8 +3454,10 @@
33703454 /* data/attr fork only */
33713455 ap->ip->i_d.di_nblocks += args->len;
33723456 xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
3373
- if (ap->wasdel)
3457
+ if (ap->wasdel) {
33743458 ap->ip->i_delayed_blks -= args->len;
3459
+ xfs_mod_delalloc(ap->ip->i_mount, -(int64_t)args->len);
3460
+ }
33753461 xfs_trans_mod_dquot_byino(ap->tp, ap->ip,
33763462 ap->wasdel ? XFS_TRANS_DQ_DELBCOUNT : XFS_TRANS_DQ_BCOUNT,
33773463 args->len);
....@@ -3412,7 +3498,7 @@
34123498
34133499 if (ap->flags & XFS_BMAPI_COWFORK)
34143500 align = xfs_get_cowextsz_hint(ap->ip);
3415
- else if (xfs_alloc_is_userdata(ap->datatype))
3501
+ else if (ap->datatype & XFS_ALLOC_USERDATA)
34163502 align = xfs_get_extsz_hint(ap->ip);
34173503 if (align) {
34183504 error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev,
....@@ -3427,7 +3513,7 @@
34273513 fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp,
34283514 ap->tp->t_firstblock);
34293515 if (nullfb) {
3430
- if (xfs_alloc_is_userdata(ap->datatype) &&
3516
+ if ((ap->datatype & XFS_ALLOC_USERDATA) &&
34313517 xfs_inode_is_filestream(ap->ip)) {
34323518 ag = xfs_filestream_lookup_ag(ap->ip);
34333519 ag = (ag != NULLAGNUMBER) ? ag : 0;
....@@ -3456,7 +3542,7 @@
34563542 args.tp = ap->tp;
34573543 args.mp = mp;
34583544 args.fsbno = ap->blkno;
3459
- xfs_rmap_skip_owner_update(&args.oinfo);
3545
+ args.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;
34603546
34613547 /* Trim the allocation back to the maximum an AG can fit. */
34623548 args.maxlen = min(ap->length, mp->m_ag_max_usable);
....@@ -3467,7 +3553,7 @@
34673553 * enough for the request. If one isn't found, then adjust
34683554 * the minimum allocation size to the largest space found.
34693555 */
3470
- if (xfs_alloc_is_userdata(ap->datatype) &&
3556
+ if ((ap->datatype & XFS_ALLOC_USERDATA) &&
34713557 xfs_inode_is_filestream(ap->ip))
34723558 error = xfs_bmap_btalloc_filestreams(ap, &args, &blen);
34733559 else
....@@ -3501,13 +3587,11 @@
35013587 args.mod = args.prod - args.mod;
35023588 }
35033589 /*
3504
- * If we are not low on available data blocks, and the
3505
- * underlying logical volume manager is a stripe, and
3506
- * the file offset is zero then try to allocate data
3507
- * blocks on stripe unit boundary.
3508
- * NOTE: ap->aeof is only set if the allocation length
3509
- * is >= the stripe unit and the allocation offset is
3510
- * at the end of file.
3590
+ * If we are not low on available data blocks, and the underlying
3591
+ * logical volume manager is a stripe, and the file offset is zero then
3592
+ * try to allocate data blocks on stripe unit boundary. NOTE: ap->aeof
3593
+ * is only set if the allocation length is >= the stripe unit and the
3594
+ * allocation offset is at the end of file.
35113595 */
35123596 if (!(ap->tp->t_flags & XFS_TRANS_LOWMODE) && ap->aeof) {
35133597 if (!ap->offset) {
....@@ -3515,9 +3599,11 @@
35153599 atype = args.type;
35163600 isaligned = 1;
35173601 /*
3518
- * Adjust for alignment
3602
+ * Adjust minlen to try and preserve alignment if we
3603
+ * can't guarantee an aligned maxlen extent.
35193604 */
3520
- if (blen > args.alignment && blen <= args.maxlen)
3605
+ if (blen > args.alignment &&
3606
+ blen <= args.maxlen + args.alignment)
35213607 args.minlen = blen - args.alignment;
35223608 args.minalignslop = 0;
35233609 } else {
....@@ -3555,8 +3641,6 @@
35553641 args.wasdel = ap->wasdel;
35563642 args.resv = XFS_AG_RESV_NONE;
35573643 args.datatype = ap->datatype;
3558
- if (ap->datatype & XFS_ALLOC_USERDATA_ZERO)
3559
- args.ip = ap->ip;
35603644
35613645 error = xfs_alloc_vextent(&args);
35623646 if (error)
....@@ -3641,20 +3725,6 @@
36413725 return 0;
36423726 }
36433727
3644
-/*
3645
- * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.
3646
- * It figures out where to ask the underlying allocator to put the new extent.
3647
- */
3648
-STATIC int
3649
-xfs_bmap_alloc(
3650
- struct xfs_bmalloca *ap) /* bmap alloc argument struct */
3651
-{
3652
- if (XFS_IS_REALTIME_INODE(ap->ip) &&
3653
- xfs_alloc_is_userdata(ap->datatype))
3654
- return xfs_bmap_rtalloc(ap);
3655
- return xfs_bmap_btalloc(ap);
3656
-}
3657
-
36583728 /* Trim extent to fit a logical block range. */
36593729 void
36603730 xfs_trim_extent(
....@@ -3686,17 +3756,6 @@
36863756 distance = irec->br_startoff + irec->br_blockcount - end;
36873757 irec->br_blockcount -= distance;
36883758 }
3689
-}
3690
-
3691
-/* trim extent to within eof */
3692
-void
3693
-xfs_trim_extent_eof(
3694
- struct xfs_bmbt_irec *irec,
3695
- struct xfs_inode *ip)
3696
-
3697
-{
3698
- xfs_trim_extent(irec, 0, XFS_B_TO_FSB(ip->i_mount,
3699
- i_size_read(VFS_I(ip))));
37003759 }
37013760
37023761 /*
....@@ -3812,7 +3871,8 @@
38123871 int flags)
38133872 {
38143873 struct xfs_mount *mp = ip->i_mount;
3815
- struct xfs_ifork *ifp;
3874
+ int whichfork = xfs_bmapi_whichfork(flags);
3875
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
38163876 struct xfs_bmbt_irec got;
38173877 xfs_fileoff_t obno;
38183878 xfs_fileoff_t end;
....@@ -3820,50 +3880,22 @@
38203880 int error;
38213881 bool eof = false;
38223882 int n = 0;
3823
- int whichfork = xfs_bmapi_whichfork(flags);
38243883
38253884 ASSERT(*nmap >= 1);
3826
- ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK|XFS_BMAPI_ENTIRE|
3827
- XFS_BMAPI_COWFORK)));
3885
+ ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK | XFS_BMAPI_ENTIRE)));
38283886 ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED|XFS_ILOCK_EXCL));
38293887
3830
- if (unlikely(XFS_TEST_ERROR(
3831
- (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
3832
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
3833
- mp, XFS_ERRTAG_BMAPIFORMAT))) {
3834
- XFS_ERROR_REPORT("xfs_bmapi_read", XFS_ERRLEVEL_LOW, mp);
3888
+ if (WARN_ON_ONCE(!ifp))
38353889 return -EFSCORRUPTED;
3836
- }
3890
+
3891
+ if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
3892
+ XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT))
3893
+ return -EFSCORRUPTED;
38373894
38383895 if (XFS_FORCED_SHUTDOWN(mp))
38393896 return -EIO;
38403897
38413898 XFS_STATS_INC(mp, xs_blk_mapr);
3842
-
3843
- ifp = XFS_IFORK_PTR(ip, whichfork);
3844
- if (!ifp) {
3845
- /* No CoW fork? Return a hole. */
3846
- if (whichfork == XFS_COW_FORK) {
3847
- mval->br_startoff = bno;
3848
- mval->br_startblock = HOLESTARTBLOCK;
3849
- mval->br_blockcount = len;
3850
- mval->br_state = XFS_EXT_NORM;
3851
- *nmap = 1;
3852
- return 0;
3853
- }
3854
-
3855
- /*
3856
- * A missing attr ifork implies that the inode says we're in
3857
- * extents or btree format but failed to pass the inode fork
3858
- * verifier while trying to load it. Treat that as a file
3859
- * corruption too.
3860
- */
3861
-#ifdef DEBUG
3862
- xfs_alert(mp, "%s: inode %llu missing fork %d",
3863
- __func__, ip->i_ino, whichfork);
3864
-#endif /* DEBUG */
3865
- return -EFSCORRUPTED;
3866
- }
38673899
38683900 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
38693901 error = xfs_iread_extents(NULL, ip, whichfork);
....@@ -3991,6 +4023,7 @@
39914023
39924024
39934025 ip->i_delayed_blks += alen;
4026
+ xfs_mod_delalloc(ip->i_mount, alen + indlen);
39944027
39954028 got->br_startoff = aoff;
39964029 got->br_startblock = nullstartblock(indlen);
....@@ -4021,6 +4054,39 @@
40214054 }
40224055
40234056 static int
4057
+xfs_bmap_alloc_userdata(
4058
+ struct xfs_bmalloca *bma)
4059
+{
4060
+ struct xfs_mount *mp = bma->ip->i_mount;
4061
+ int whichfork = xfs_bmapi_whichfork(bma->flags);
4062
+ int error;
4063
+
4064
+ /*
4065
+ * Set the data type being allocated. For the data fork, the first data
4066
+ * in the file is treated differently to all other allocations. For the
4067
+ * attribute fork, we only need to ensure the allocated range is not on
4068
+ * the busy list.
4069
+ */
4070
+ bma->datatype = XFS_ALLOC_NOBUSY;
4071
+ if (whichfork == XFS_DATA_FORK) {
4072
+ bma->datatype |= XFS_ALLOC_USERDATA;
4073
+ if (bma->offset == 0)
4074
+ bma->datatype |= XFS_ALLOC_INITIAL_USER_DATA;
4075
+
4076
+ if (mp->m_dalign && bma->length >= mp->m_dalign) {
4077
+ error = xfs_bmap_isaeof(bma, whichfork);
4078
+ if (error)
4079
+ return error;
4080
+ }
4081
+
4082
+ if (XFS_IS_REALTIME_INODE(bma->ip))
4083
+ return xfs_bmap_rtalloc(bma);
4084
+ }
4085
+
4086
+ return xfs_bmap_btalloc(bma);
4087
+}
4088
+
4089
+static int
40244090 xfs_bmapi_allocate(
40254091 struct xfs_bmalloca *bma)
40264092 {
....@@ -4039,7 +4105,8 @@
40394105 if (bma->wasdel) {
40404106 bma->length = (xfs_extlen_t)bma->got.br_blockcount;
40414107 bma->offset = bma->got.br_startoff;
4042
- xfs_iext_peek_prev_extent(ifp, &bma->icur, &bma->prev);
4108
+ if (!xfs_iext_peek_prev_extent(ifp, &bma->icur, &bma->prev))
4109
+ bma->prev.br_startoff = NULLFILEOFF;
40434110 } else {
40444111 bma->length = XFS_FILBLKS_MIN(bma->length, MAXEXTLEN);
40454112 if (!bma->eof)
....@@ -4047,43 +4114,24 @@
40474114 bma->got.br_startoff - bma->offset);
40484115 }
40494116
4050
- /*
4051
- * Set the data type being allocated. For the data fork, the first data
4052
- * in the file is treated differently to all other allocations. For the
4053
- * attribute fork, we only need to ensure the allocated range is not on
4054
- * the busy list.
4055
- */
4056
- if (!(bma->flags & XFS_BMAPI_METADATA)) {
4057
- bma->datatype = XFS_ALLOC_NOBUSY;
4058
- if (whichfork == XFS_DATA_FORK) {
4059
- if (bma->offset == 0)
4060
- bma->datatype |= XFS_ALLOC_INITIAL_USER_DATA;
4061
- else
4062
- bma->datatype |= XFS_ALLOC_USERDATA;
4063
- }
4064
- if (bma->flags & XFS_BMAPI_ZERO)
4065
- bma->datatype |= XFS_ALLOC_USERDATA_ZERO;
4066
- }
4117
+ if (bma->flags & XFS_BMAPI_CONTIG)
4118
+ bma->minlen = bma->length;
4119
+ else
4120
+ bma->minlen = 1;
40674121
4068
- bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1;
4122
+ if (bma->flags & XFS_BMAPI_METADATA)
4123
+ error = xfs_bmap_btalloc(bma);
4124
+ else
4125
+ error = xfs_bmap_alloc_userdata(bma);
4126
+ if (error || bma->blkno == NULLFSBLOCK)
4127
+ return error;
40694128
4070
- /*
4071
- * Only want to do the alignment at the eof if it is userdata and
4072
- * allocation length is larger than a stripe unit.
4073
- */
4074
- if (mp->m_dalign && bma->length >= mp->m_dalign &&
4075
- !(bma->flags & XFS_BMAPI_METADATA) && whichfork == XFS_DATA_FORK) {
4076
- error = xfs_bmap_isaeof(bma, whichfork);
4129
+ if (bma->flags & XFS_BMAPI_ZERO) {
4130
+ error = xfs_zero_extent(bma->ip, bma->blkno, bma->length);
40774131 if (error)
40784132 return error;
40794133 }
40804134
4081
- error = xfs_bmap_alloc(bma);
4082
- if (error)
4083
- return error;
4084
-
4085
- if (bma->blkno == NULLFSBLOCK)
4086
- return 0;
40874135 if ((ifp->if_flags & XFS_IFBROOT) && !bma->cur)
40884136 bma->cur = xfs_bmbt_init_cursor(mp, bma->tp, bma->ip, whichfork);
40894137 /*
....@@ -4093,26 +4141,15 @@
40934141 bma->nallocs++;
40944142
40954143 if (bma->cur)
4096
- bma->cur->bc_private.b.flags =
4097
- bma->wasdel ? XFS_BTCUR_BPRV_WASDEL : 0;
4144
+ bma->cur->bc_ino.flags =
4145
+ bma->wasdel ? XFS_BTCUR_BMBT_WASDEL : 0;
40984146
40994147 bma->got.br_startoff = bma->offset;
41004148 bma->got.br_startblock = bma->blkno;
41014149 bma->got.br_blockcount = bma->length;
41024150 bma->got.br_state = XFS_EXT_NORM;
41034151
4104
- /*
4105
- * In the data fork, a wasdelay extent has been initialized, so
4106
- * shouldn't be flagged as unwritten.
4107
- *
4108
- * For the cow fork, however, we convert delalloc reservations
4109
- * (extents allocated for speculative preallocation) to
4110
- * allocated unwritten extents, and only convert the unwritten
4111
- * extents to real extents when we're about to write the data.
4112
- */
4113
- if ((!bma->wasdel || (bma->flags & XFS_BMAPI_COWFORK)) &&
4114
- (bma->flags & XFS_BMAPI_PREALLOC) &&
4115
- xfs_sb_version_hasextflgbit(&mp->m_sb))
4152
+ if (bma->flags & XFS_BMAPI_PREALLOC)
41164153 bma->got.br_state = XFS_EXT_UNWRITTEN;
41174154
41184155 if (bma->wasdel)
....@@ -4220,6 +4257,48 @@
42204257 return 0;
42214258 }
42224259
4260
+static inline xfs_extlen_t
4261
+xfs_bmapi_minleft(
4262
+ struct xfs_trans *tp,
4263
+ struct xfs_inode *ip,
4264
+ int fork)
4265
+{
4266
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, fork);
4267
+
4268
+ if (tp && tp->t_firstblock != NULLFSBLOCK)
4269
+ return 0;
4270
+ if (ifp->if_format != XFS_DINODE_FMT_BTREE)
4271
+ return 1;
4272
+ return be16_to_cpu(ifp->if_broot->bb_level) + 1;
4273
+}
4274
+
4275
+/*
4276
+ * Log whatever the flags say, even if error. Otherwise we might miss detecting
4277
+ * a case where the data is changed, there's an error, and it's not logged so we
4278
+ * don't shutdown when we should. Don't bother logging extents/btree changes if
4279
+ * we converted to the other format.
4280
+ */
4281
+static void
4282
+xfs_bmapi_finish(
4283
+ struct xfs_bmalloca *bma,
4284
+ int whichfork,
4285
+ int error)
4286
+{
4287
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork);
4288
+
4289
+ if ((bma->logflags & xfs_ilog_fext(whichfork)) &&
4290
+ ifp->if_format != XFS_DINODE_FMT_EXTENTS)
4291
+ bma->logflags &= ~xfs_ilog_fext(whichfork);
4292
+ else if ((bma->logflags & xfs_ilog_fbroot(whichfork)) &&
4293
+ ifp->if_format != XFS_DINODE_FMT_BTREE)
4294
+ bma->logflags &= ~xfs_ilog_fbroot(whichfork);
4295
+
4296
+ if (bma->logflags)
4297
+ xfs_trans_log_inode(bma->tp, bma->ip, bma->logflags);
4298
+ if (bma->cur)
4299
+ xfs_btree_del_cursor(bma->cur, error);
4300
+}
4301
+
42234302 /*
42244303 * Map file blocks to filesystem blocks, and allocate blocks or convert the
42254304 * extent state if necessary. Details behaviour is controlled by the flags
....@@ -4237,15 +4316,19 @@
42374316 struct xfs_bmbt_irec *mval, /* output: map values */
42384317 int *nmap) /* i/o: mval size/count */
42394318 {
4319
+ struct xfs_bmalloca bma = {
4320
+ .tp = tp,
4321
+ .ip = ip,
4322
+ .total = total,
4323
+ };
42404324 struct xfs_mount *mp = ip->i_mount;
4241
- struct xfs_ifork *ifp;
4242
- struct xfs_bmalloca bma = { NULL }; /* args for xfs_bmap_alloc */
4325
+ int whichfork = xfs_bmapi_whichfork(flags);
4326
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
42434327 xfs_fileoff_t end; /* end of mapped file region */
42444328 bool eof = false; /* after the end of extents */
42454329 int error; /* error return */
42464330 int n; /* current extent index */
42474331 xfs_fileoff_t obno; /* old block number (offset) */
4248
- int whichfork; /* data or attr fork */
42494332
42504333 #ifdef DEBUG
42514334 xfs_fileoff_t orig_bno; /* original block number value */
....@@ -4260,15 +4343,12 @@
42604343 orig_mval = mval;
42614344 orig_nmap = *nmap;
42624345 #endif
4263
- whichfork = xfs_bmapi_whichfork(flags);
42644346
42654347 ASSERT(*nmap >= 1);
42664348 ASSERT(*nmap <= XFS_BMAP_MAX_NMAP);
4267
- ASSERT(tp != NULL ||
4268
- (flags & (XFS_BMAPI_CONVERT | XFS_BMAPI_COWFORK)) ==
4269
- (XFS_BMAPI_CONVERT | XFS_BMAPI_COWFORK));
4349
+ ASSERT(tp != NULL);
42704350 ASSERT(len > 0);
4271
- ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL);
4351
+ ASSERT(ifp->if_format != XFS_DINODE_FMT_LOCAL);
42724352 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
42734353 ASSERT(!(flags & XFS_BMAPI_REMAP));
42744354
....@@ -4284,29 +4364,15 @@
42844364 ASSERT((flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)) !=
42854365 (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO));
42864366
4287
- if (unlikely(XFS_TEST_ERROR(
4288
- (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
4289
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
4290
- mp, XFS_ERRTAG_BMAPIFORMAT))) {
4291
- XFS_ERROR_REPORT("xfs_bmapi_write", XFS_ERRLEVEL_LOW, mp);
4367
+ if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
4368
+ XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
42924369 return -EFSCORRUPTED;
42934370 }
42944371
42954372 if (XFS_FORCED_SHUTDOWN(mp))
42964373 return -EIO;
42974374
4298
- ifp = XFS_IFORK_PTR(ip, whichfork);
4299
-
43004375 XFS_STATS_INC(mp, xs_blk_mapw);
4301
-
4302
- if (!tp || tp->t_firstblock == NULLFSBLOCK) {
4303
- if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE)
4304
- bma.minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1;
4305
- else
4306
- bma.minleft = 1;
4307
- } else {
4308
- bma.minleft = 0;
4309
- }
43104376
43114377 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
43124378 error = xfs_iread_extents(tp, ip, whichfork);
....@@ -4314,19 +4380,15 @@
43144380 goto error0;
43154381 }
43164382
4317
- n = 0;
4318
- end = bno + len;
4319
- obno = bno;
4320
-
43214383 if (!xfs_iext_lookup_extent(ip, ifp, bno, &bma.icur, &bma.got))
43224384 eof = true;
43234385 if (!xfs_iext_peek_prev_extent(ifp, &bma.icur, &bma.prev))
43244386 bma.prev.br_startoff = NULLFILEOFF;
4325
- bma.tp = tp;
4326
- bma.ip = ip;
4327
- bma.total = total;
4328
- bma.datatype = 0;
4387
+ bma.minleft = xfs_bmapi_minleft(tp, ip, whichfork);
43294388
4389
+ n = 0;
4390
+ end = bno + len;
4391
+ obno = bno;
43304392 while (bno < end && n < *nmap) {
43314393 bool need_alloc = false, wasdelay = false;
43324394
....@@ -4340,26 +4402,7 @@
43404402 ASSERT(!((flags & XFS_BMAPI_CONVERT) &&
43414403 (flags & XFS_BMAPI_COWFORK)));
43424404
4343
- if (flags & XFS_BMAPI_DELALLOC) {
4344
- /*
4345
- * For the COW fork we can reasonably get a
4346
- * request for converting an extent that races
4347
- * with other threads already having converted
4348
- * part of it, as there converting COW to
4349
- * regular blocks is not protected using the
4350
- * IOLOCK.
4351
- */
4352
- ASSERT(flags & XFS_BMAPI_COWFORK);
4353
- if (!(flags & XFS_BMAPI_COWFORK)) {
4354
- error = -EIO;
4355
- goto error0;
4356
- }
4357
-
4358
- if (eof || bno >= end)
4359
- break;
4360
- } else {
4361
- need_alloc = true;
4362
- }
4405
+ need_alloc = true;
43634406 } else if (isnullstartblock(bma.got.br_startblock)) {
43644407 wasdelay = true;
43654408 }
....@@ -4368,8 +4411,7 @@
43684411 * First, deal with the hole before the allocated space
43694412 * that we found, if any.
43704413 */
4371
- if ((need_alloc || wasdelay) &&
4372
- !(flags & XFS_BMAPI_CONVERT_ONLY)) {
4414
+ if (need_alloc || wasdelay) {
43734415 bma.eof = eof;
43744416 bma.conv = !!(flags & XFS_BMAPI_CONVERT);
43754417 bma.wasdel = wasdelay;
....@@ -4400,12 +4442,9 @@
44004442 * If this is a CoW allocation, record the data in
44014443 * the refcount btree for orphan recovery.
44024444 */
4403
- if (whichfork == XFS_COW_FORK) {
4404
- error = xfs_refcount_alloc_cow_extent(tp,
4405
- bma.blkno, bma.length);
4406
- if (error)
4407
- goto error0;
4408
- }
4445
+ if (whichfork == XFS_COW_FORK)
4446
+ xfs_refcount_alloc_cow_extent(tp, bma.blkno,
4447
+ bma.length);
44094448 }
44104449
44114450 /* Deal with the allocated space we found. */
....@@ -4437,49 +4476,144 @@
44374476 }
44384477 *nmap = n;
44394478
4440
- /*
4441
- * Transform from btree to extents, give it cur.
4442
- */
4443
- if (xfs_bmap_wants_extents(ip, whichfork)) {
4444
- int tmp_logflags = 0;
4479
+ error = xfs_bmap_btree_to_extents(tp, ip, bma.cur, &bma.logflags,
4480
+ whichfork);
4481
+ if (error)
4482
+ goto error0;
44454483
4446
- ASSERT(bma.cur);
4447
- error = xfs_bmap_btree_to_extents(tp, ip, bma.cur,
4448
- &tmp_logflags, whichfork);
4449
- bma.logflags |= tmp_logflags;
4450
- if (error)
4451
- goto error0;
4452
- }
4453
-
4454
- ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE ||
4455
- XFS_IFORK_NEXTENTS(ip, whichfork) >
4456
- XFS_IFORK_MAXEXT(ip, whichfork));
4457
- error = 0;
4484
+ ASSERT(ifp->if_format != XFS_DINODE_FMT_BTREE ||
4485
+ ifp->if_nextents > XFS_IFORK_MAXEXT(ip, whichfork));
4486
+ xfs_bmapi_finish(&bma, whichfork, 0);
4487
+ xfs_bmap_validate_ret(orig_bno, orig_len, orig_flags, orig_mval,
4488
+ orig_nmap, *nmap);
4489
+ return 0;
44584490 error0:
4459
- /*
4460
- * Log everything. Do this after conversion, there's no point in
4461
- * logging the extent records if we've converted to btree format.
4462
- */
4463
- if ((bma.logflags & xfs_ilog_fext(whichfork)) &&
4464
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
4465
- bma.logflags &= ~xfs_ilog_fext(whichfork);
4466
- else if ((bma.logflags & xfs_ilog_fbroot(whichfork)) &&
4467
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)
4468
- bma.logflags &= ~xfs_ilog_fbroot(whichfork);
4469
- /*
4470
- * Log whatever the flags say, even if error. Otherwise we might miss
4471
- * detecting a case where the data is changed, there's an error,
4472
- * and it's not logged so we don't shutdown when we should.
4473
- */
4474
- if (bma.logflags)
4475
- xfs_trans_log_inode(tp, ip, bma.logflags);
4491
+ xfs_bmapi_finish(&bma, whichfork, error);
4492
+ return error;
4493
+}
44764494
4477
- if (bma.cur) {
4478
- xfs_btree_del_cursor(bma.cur, error);
4495
+/*
4496
+ * Convert an existing delalloc extent to real blocks based on file offset. This
4497
+ * attempts to allocate the entire delalloc extent and may require multiple
4498
+ * invocations to allocate the target offset if a large enough physical extent
4499
+ * is not available.
4500
+ */
4501
+int
4502
+xfs_bmapi_convert_delalloc(
4503
+ struct xfs_inode *ip,
4504
+ int whichfork,
4505
+ xfs_off_t offset,
4506
+ struct iomap *iomap,
4507
+ unsigned int *seq)
4508
+{
4509
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
4510
+ struct xfs_mount *mp = ip->i_mount;
4511
+ xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset);
4512
+ struct xfs_bmalloca bma = { NULL };
4513
+ uint16_t flags = 0;
4514
+ struct xfs_trans *tp;
4515
+ int error;
4516
+
4517
+ if (whichfork == XFS_COW_FORK)
4518
+ flags |= IOMAP_F_SHARED;
4519
+
4520
+ /*
4521
+ * Space for the extent and indirect blocks was reserved when the
4522
+ * delalloc extent was created so there's no need to do so here.
4523
+ */
4524
+ error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, 0, 0,
4525
+ XFS_TRANS_RESERVE, &tp);
4526
+ if (error)
4527
+ return error;
4528
+
4529
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
4530
+ xfs_trans_ijoin(tp, ip, 0);
4531
+
4532
+ if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &bma.icur, &bma.got) ||
4533
+ bma.got.br_startoff > offset_fsb) {
4534
+ /*
4535
+ * No extent found in the range we are trying to convert. This
4536
+ * should only happen for the COW fork, where another thread
4537
+ * might have moved the extent to the data fork in the meantime.
4538
+ */
4539
+ WARN_ON_ONCE(whichfork != XFS_COW_FORK);
4540
+ error = -EAGAIN;
4541
+ goto out_trans_cancel;
44794542 }
4480
- if (!error)
4481
- xfs_bmap_validate_ret(orig_bno, orig_len, orig_flags, orig_mval,
4482
- orig_nmap, *nmap);
4543
+
4544
+ /*
4545
+ * If we find a real extent here we raced with another thread converting
4546
+ * the extent. Just return the real extent at this offset.
4547
+ */
4548
+ if (!isnullstartblock(bma.got.br_startblock)) {
4549
+ xfs_bmbt_to_iomap(ip, iomap, &bma.got, flags);
4550
+ *seq = READ_ONCE(ifp->if_seq);
4551
+ goto out_trans_cancel;
4552
+ }
4553
+
4554
+ bma.tp = tp;
4555
+ bma.ip = ip;
4556
+ bma.wasdel = true;
4557
+ bma.offset = bma.got.br_startoff;
4558
+ bma.length = max_t(xfs_filblks_t, bma.got.br_blockcount, MAXEXTLEN);
4559
+ bma.minleft = xfs_bmapi_minleft(tp, ip, whichfork);
4560
+
4561
+ /*
4562
+ * When we're converting the delalloc reservations backing dirty pages
4563
+ * in the page cache, we must be careful about how we create the new
4564
+ * extents:
4565
+ *
4566
+ * New CoW fork extents are created unwritten, turned into real extents
4567
+ * when we're about to write the data to disk, and mapped into the data
4568
+ * fork after the write finishes. End of story.
4569
+ *
4570
+ * New data fork extents must be mapped in as unwritten and converted
4571
+ * to real extents after the write succeeds to avoid exposing stale
4572
+ * disk contents if we crash.
4573
+ */
4574
+ bma.flags = XFS_BMAPI_PREALLOC;
4575
+ if (whichfork == XFS_COW_FORK)
4576
+ bma.flags |= XFS_BMAPI_COWFORK;
4577
+
4578
+ if (!xfs_iext_peek_prev_extent(ifp, &bma.icur, &bma.prev))
4579
+ bma.prev.br_startoff = NULLFILEOFF;
4580
+
4581
+ error = xfs_bmapi_allocate(&bma);
4582
+ if (error)
4583
+ goto out_finish;
4584
+
4585
+ error = -ENOSPC;
4586
+ if (WARN_ON_ONCE(bma.blkno == NULLFSBLOCK))
4587
+ goto out_finish;
4588
+ error = -EFSCORRUPTED;
4589
+ if (WARN_ON_ONCE(!xfs_valid_startblock(ip, bma.got.br_startblock)))
4590
+ goto out_finish;
4591
+
4592
+ XFS_STATS_ADD(mp, xs_xstrat_bytes, XFS_FSB_TO_B(mp, bma.length));
4593
+ XFS_STATS_INC(mp, xs_xstrat_quick);
4594
+
4595
+ ASSERT(!isnullstartblock(bma.got.br_startblock));
4596
+ xfs_bmbt_to_iomap(ip, iomap, &bma.got, flags);
4597
+ *seq = READ_ONCE(ifp->if_seq);
4598
+
4599
+ if (whichfork == XFS_COW_FORK)
4600
+ xfs_refcount_alloc_cow_extent(tp, bma.blkno, bma.length);
4601
+
4602
+ error = xfs_bmap_btree_to_extents(tp, ip, bma.cur, &bma.logflags,
4603
+ whichfork);
4604
+ if (error)
4605
+ goto out_finish;
4606
+
4607
+ xfs_bmapi_finish(&bma, whichfork, 0);
4608
+ error = xfs_trans_commit(tp);
4609
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
4610
+ return error;
4611
+
4612
+out_finish:
4613
+ xfs_bmapi_finish(&bma, whichfork, error);
4614
+out_trans_cancel:
4615
+ xfs_trans_cancel(tp);
4616
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
44834617 return error;
44844618 }
44854619
....@@ -4509,11 +4643,8 @@
45094643 ASSERT((flags & (XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC)) !=
45104644 (XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC));
45114645
4512
- if (unlikely(XFS_TEST_ERROR(
4513
- (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
4514
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
4515
- mp, XFS_ERRTAG_BMAPIFORMAT))) {
4516
- XFS_ERROR_REPORT("xfs_bmapi_remap", XFS_ERRLEVEL_LOW, mp);
4646
+ if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
4647
+ XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
45174648 return -EFSCORRUPTED;
45184649 }
45194650
....@@ -4537,7 +4668,7 @@
45374668
45384669 if (ifp->if_flags & XFS_IFBROOT) {
45394670 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
4540
- cur->bc_private.b.flags = 0;
4671
+ cur->bc_ino.flags = 0;
45414672 }
45424673
45434674 got.br_startoff = bno;
....@@ -4553,18 +4684,12 @@
45534684 if (error)
45544685 goto error0;
45554686
4556
- if (xfs_bmap_wants_extents(ip, whichfork)) {
4557
- int tmp_logflags = 0;
4558
-
4559
- error = xfs_bmap_btree_to_extents(tp, ip, cur,
4560
- &tmp_logflags, whichfork);
4561
- logflags |= tmp_logflags;
4562
- }
4687
+ error = xfs_bmap_btree_to_extents(tp, ip, cur, &logflags, whichfork);
45634688
45644689 error0:
4565
- if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS)
4690
+ if (ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS)
45664691 logflags &= ~XFS_ILOG_DEXT;
4567
- else if (ip->i_d.di_format != XFS_DINODE_FMT_BTREE)
4692
+ else if (ip->i_df.if_format != XFS_DINODE_FMT_BTREE)
45684693 logflags &= ~XFS_ILOG_DBROOT;
45694694
45704695 if (logflags)
....@@ -4781,8 +4906,10 @@
47814906 da_diff = da_old - da_new;
47824907 if (!isrt)
47834908 da_diff += del->br_blockcount;
4784
- if (da_diff)
4909
+ if (da_diff) {
47854910 xfs_mod_fdblocks(mp, da_diff, false);
4911
+ xfs_mod_delalloc(mp, -da_diff);
4912
+ }
47864913 return error;
47874914 }
47884915
....@@ -4912,9 +5039,8 @@
49125039 * conversion to btree format, since the transaction will be dirty then.
49135040 */
49145041 if (tp->t_blk_res == 0 &&
4915
- XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
4916
- XFS_IFORK_NEXTENTS(ip, whichfork) >=
4917
- XFS_IFORK_MAXEXT(ip, whichfork) &&
5042
+ ifp->if_format == XFS_DINODE_FMT_EXTENTS &&
5043
+ ifp->if_nextents >= XFS_IFORK_MAXEXT(ip, whichfork) &&
49185044 del->br_startoff > got.br_startoff && del_endoff < got_endoff)
49195045 return -ENOSPC;
49205046
....@@ -4953,7 +5079,10 @@
49535079 error = xfs_bmbt_lookup_eq(cur, &got, &i);
49545080 if (error)
49555081 goto done;
4956
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
5082
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
5083
+ error = -EFSCORRUPTED;
5084
+ goto done;
5085
+ }
49575086 }
49585087
49595088 if (got.br_startoff == del->br_startoff)
....@@ -4968,8 +5097,8 @@
49685097 */
49695098 xfs_iext_remove(ip, icur, state);
49705099 xfs_iext_prev(ifp, icur);
4971
- XFS_IFORK_NEXT_SET(ip, whichfork,
4972
- XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
5100
+ ifp->if_nextents--;
5101
+
49735102 flags |= XFS_ILOG_CORE;
49745103 if (!cur) {
49755104 flags |= xfs_ilog_fext(whichfork);
....@@ -4977,7 +5106,10 @@
49775106 }
49785107 if ((error = xfs_btree_delete(cur, &i)))
49795108 goto done;
4980
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
5109
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
5110
+ error = -EFSCORRUPTED;
5111
+ goto done;
5112
+ }
49815113 break;
49825114 case BMAP_LEFT_FILLING:
49835115 /*
....@@ -5048,7 +5180,10 @@
50485180 error = xfs_bmbt_lookup_eq(cur, &got, &i);
50495181 if (error)
50505182 goto done;
5051
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
5183
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
5184
+ error = -EFSCORRUPTED;
5185
+ goto done;
5186
+ }
50525187 /*
50535188 * Update the btree record back
50545189 * to the original value.
....@@ -5065,29 +5200,28 @@
50655200 error = -ENOSPC;
50665201 goto done;
50675202 }
5068
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
5203
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
5204
+ error = -EFSCORRUPTED;
5205
+ goto done;
5206
+ }
50695207 } else
50705208 flags |= xfs_ilog_fext(whichfork);
5071
- XFS_IFORK_NEXT_SET(ip, whichfork,
5072
- XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
5209
+
5210
+ ifp->if_nextents++;
50735211 xfs_iext_next(ifp, icur);
50745212 xfs_iext_insert(ip, icur, &new, state);
50755213 break;
50765214 }
50775215
50785216 /* remove reverse mapping */
5079
- error = xfs_rmap_unmap_extent(tp, ip, whichfork, del);
5080
- if (error)
5081
- goto done;
5217
+ xfs_rmap_unmap_extent(tp, ip, whichfork, del);
50825218
50835219 /*
50845220 * If we need to, add to list of extents to delete.
50855221 */
50865222 if (do_fx && !(bflags & XFS_BMAPI_REMAP)) {
50875223 if (xfs_is_reflink_inode(ip) && whichfork == XFS_DATA_FORK) {
5088
- error = xfs_refcount_decrease_extent(tp, del);
5089
- if (error)
5090
- goto done;
5224
+ xfs_refcount_decrease_extent(tp, del);
50915225 } else {
50925226 __xfs_bmap_add_free(tp, del->br_startblock,
50935227 del->br_blockcount, NULL,
....@@ -5136,7 +5270,7 @@
51365270 int isrt; /* freeing in rt area */
51375271 int logflags; /* transaction logging flags */
51385272 xfs_extlen_t mod; /* rt extent offset */
5139
- struct xfs_mount *mp; /* mount structure */
5273
+ struct xfs_mount *mp = ip->i_mount;
51405274 int tmp_logflags; /* partial logging flags */
51415275 int wasdel; /* was a delayed alloc extent */
51425276 int whichfork; /* data or attribute fork */
....@@ -5153,14 +5287,8 @@
51535287 whichfork = xfs_bmapi_whichfork(flags);
51545288 ASSERT(whichfork != XFS_COW_FORK);
51555289 ifp = XFS_IFORK_PTR(ip, whichfork);
5156
- if (unlikely(
5157
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
5158
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) {
5159
- XFS_ERROR_REPORT("xfs_bunmapi", XFS_ERRLEVEL_LOW,
5160
- ip->i_mount);
5290
+ if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)))
51615291 return -EFSCORRUPTED;
5162
- }
5163
- mp = ip->i_mount;
51645292 if (XFS_FORCED_SHUTDOWN(mp))
51655293 return -EIO;
51665294
....@@ -5197,9 +5325,9 @@
51975325
51985326 logflags = 0;
51995327 if (ifp->if_flags & XFS_IFBROOT) {
5200
- ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE);
5328
+ ASSERT(ifp->if_format == XFS_DINODE_FMT_BTREE);
52015329 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
5202
- cur->bc_private.b.flags = 0;
5330
+ cur->bc_ino.flags = 0;
52035331 } else
52045332 cur = NULL;
52055333
....@@ -5280,8 +5408,7 @@
52805408 * unmapping part of it. But we can't really
52815409 * get rid of part of a realtime extent.
52825410 */
5283
- if (del.br_state == XFS_EXT_UNWRITTEN ||
5284
- !xfs_sb_version_hasextflgbit(&mp->m_sb)) {
5411
+ if (del.br_state == XFS_EXT_UNWRITTEN) {
52855412 /*
52865413 * This piece is unwritten, or we're not
52875414 * using unwritten extents. Skip over it.
....@@ -5321,20 +5448,20 @@
53215448 }
53225449 div_u64_rem(del.br_startblock, mp->m_sb.sb_rextsize, &mod);
53235450 if (mod) {
5451
+ xfs_extlen_t off = mp->m_sb.sb_rextsize - mod;
5452
+
53245453 /*
53255454 * Realtime extent is lined up at the end but not
53265455 * at the front. We'll get rid of full extents if
53275456 * we can.
53285457 */
5329
- mod = mp->m_sb.sb_rextsize - mod;
5330
- if (del.br_blockcount > mod) {
5331
- del.br_blockcount -= mod;
5332
- del.br_startoff += mod;
5333
- del.br_startblock += mod;
5334
- } else if ((del.br_startoff == start &&
5335
- (del.br_state == XFS_EXT_UNWRITTEN ||
5336
- tp->t_blk_res == 0)) ||
5337
- !xfs_sb_version_hasextflgbit(&mp->m_sb)) {
5458
+ if (del.br_blockcount > off) {
5459
+ del.br_blockcount -= off;
5460
+ del.br_startoff += off;
5461
+ del.br_startblock += off;
5462
+ } else if (del.br_startoff == start &&
5463
+ (del.br_state == XFS_EXT_UNWRITTEN ||
5464
+ tp->t_blk_res == 0)) {
53385465 /*
53395466 * Can't make it unwritten. There isn't
53405467 * a full extent here so just skip it.
....@@ -5349,6 +5476,7 @@
53495476 continue;
53505477 } else if (del.br_state == XFS_EXT_UNWRITTEN) {
53515478 struct xfs_bmbt_irec prev;
5479
+ xfs_fileoff_t unwrite_start;
53525480
53535481 /*
53545482 * This one is already unwritten.
....@@ -5362,12 +5490,13 @@
53625490 ASSERT(!isnullstartblock(prev.br_startblock));
53635491 ASSERT(del.br_startblock ==
53645492 prev.br_startblock + prev.br_blockcount);
5365
- if (prev.br_startoff < start) {
5366
- mod = start - prev.br_startoff;
5367
- prev.br_blockcount -= mod;
5368
- prev.br_startblock += mod;
5369
- prev.br_startoff = start;
5370
- }
5493
+ unwrite_start = max3(start,
5494
+ del.br_startoff - mod,
5495
+ prev.br_startoff);
5496
+ mod = unwrite_start - prev.br_startoff;
5497
+ prev.br_startoff = unwrite_start;
5498
+ prev.br_startblock += mod;
5499
+ prev.br_blockcount -= mod;
53715500 prev.br_state = XFS_EXT_UNWRITTEN;
53725501 error = xfs_bmap_add_extent_unwritten_real(tp,
53735502 ip, whichfork, &icur, &cur,
....@@ -5430,34 +5559,21 @@
54305559 error = xfs_bmap_extents_to_btree(tp, ip, &cur, 0,
54315560 &tmp_logflags, whichfork);
54325561 logflags |= tmp_logflags;
5433
- if (error)
5434
- goto error0;
5435
- }
5436
- /*
5437
- * transform from btree to extents, give it cur
5438
- */
5439
- else if (xfs_bmap_wants_extents(ip, whichfork)) {
5440
- ASSERT(cur != NULL);
5441
- error = xfs_bmap_btree_to_extents(tp, ip, cur, &tmp_logflags,
5562
+ } else {
5563
+ error = xfs_bmap_btree_to_extents(tp, ip, cur, &logflags,
54425564 whichfork);
5443
- logflags |= tmp_logflags;
5444
- if (error)
5445
- goto error0;
54465565 }
5447
- /*
5448
- * transform from extents to local?
5449
- */
5450
- error = 0;
5566
+
54515567 error0:
54525568 /*
54535569 * Log everything. Do this after conversion, there's no point in
54545570 * logging the extent records if we've converted to btree format.
54555571 */
54565572 if ((logflags & xfs_ilog_fext(whichfork)) &&
5457
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
5573
+ ifp->if_format != XFS_DINODE_FMT_EXTENTS)
54585574 logflags &= ~xfs_ilog_fext(whichfork);
54595575 else if ((logflags & xfs_ilog_fbroot(whichfork)) &&
5460
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)
5576
+ ifp->if_format != XFS_DINODE_FMT_BTREE)
54615577 logflags &= ~xfs_ilog_fbroot(whichfork);
54625578 /*
54635579 * Log inode even in the error case, if the transaction
....@@ -5467,7 +5583,7 @@
54675583 xfs_trans_log_inode(tp, ip, logflags);
54685584 if (cur) {
54695585 if (!error)
5470
- cur->bc_private.b.allocated = 0;
5586
+ cur->bc_ino.allocated = 0;
54715587 xfs_btree_del_cursor(cur, error);
54725588 }
54735589 return error;
....@@ -5539,6 +5655,7 @@
55395655 struct xfs_btree_cur *cur,
55405656 int *logflags) /* output */
55415657 {
5658
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
55425659 struct xfs_bmbt_irec new;
55435660 xfs_filblks_t blockcount;
55445661 int error, i;
....@@ -5557,8 +5674,7 @@
55575674 * Update the on-disk extent count, the btree if necessary and log the
55585675 * inode.
55595676 */
5560
- XFS_IFORK_NEXT_SET(ip, whichfork,
5561
- XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
5677
+ ifp->if_nextents--;
55625678 *logflags |= XFS_ILOG_CORE;
55635679 if (!cur) {
55645680 *logflags |= XFS_ILOG_DEXT;
....@@ -5569,36 +5685,43 @@
55695685 error = xfs_bmbt_lookup_eq(cur, got, &i);
55705686 if (error)
55715687 return error;
5572
- XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
5688
+ if (XFS_IS_CORRUPT(mp, i != 1))
5689
+ return -EFSCORRUPTED;
55735690
55745691 error = xfs_btree_delete(cur, &i);
55755692 if (error)
55765693 return error;
5577
- XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
5694
+ if (XFS_IS_CORRUPT(mp, i != 1))
5695
+ return -EFSCORRUPTED;
55785696
55795697 /* lookup and update size of the previous extent */
55805698 error = xfs_bmbt_lookup_eq(cur, left, &i);
55815699 if (error)
55825700 return error;
5583
- XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
5701
+ if (XFS_IS_CORRUPT(mp, i != 1))
5702
+ return -EFSCORRUPTED;
55845703
55855704 error = xfs_bmbt_update(cur, &new);
55865705 if (error)
55875706 return error;
55885707
5708
+ /* change to extent format if required after extent removal */
5709
+ error = xfs_bmap_btree_to_extents(tp, ip, cur, logflags, whichfork);
5710
+ if (error)
5711
+ return error;
5712
+
55895713 done:
55905714 xfs_iext_remove(ip, icur, 0);
5591
- xfs_iext_prev(XFS_IFORK_PTR(ip, whichfork), icur);
5715
+ xfs_iext_prev(ifp, icur);
55925716 xfs_iext_update_extent(ip, xfs_bmap_fork_to_state(whichfork), icur,
55935717 &new);
55945718
55955719 /* update reverse mapping. rmap functions merge the rmaps for us */
5596
- error = xfs_rmap_unmap_extent(tp, ip, whichfork, got);
5597
- if (error)
5598
- return error;
5720
+ xfs_rmap_unmap_extent(tp, ip, whichfork, got);
55995721 memcpy(&new, got, sizeof(new));
56005722 new.br_startoff = left->br_startoff + left->br_blockcount;
5601
- return xfs_rmap_map_extent(tp, ip, whichfork, &new);
5723
+ xfs_rmap_map_extent(tp, ip, whichfork, &new);
5724
+ return 0;
56025725 }
56035726
56045727 static int
....@@ -5624,7 +5747,8 @@
56245747 error = xfs_bmbt_lookup_eq(cur, &prev, &i);
56255748 if (error)
56265749 return error;
5627
- XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
5750
+ if (XFS_IS_CORRUPT(mp, i != 1))
5751
+ return -EFSCORRUPTED;
56285752
56295753 error = xfs_bmbt_update(cur, got);
56305754 if (error)
....@@ -5637,10 +5761,9 @@
56375761 got);
56385762
56395763 /* update reverse mapping */
5640
- error = xfs_rmap_unmap_extent(tp, ip, whichfork, &prev);
5641
- if (error)
5642
- return error;
5643
- return xfs_rmap_map_extent(tp, ip, whichfork, got);
5764
+ xfs_rmap_unmap_extent(tp, ip, whichfork, &prev);
5765
+ xfs_rmap_map_extent(tp, ip, whichfork, got);
5766
+ return 0;
56445767 }
56455768
56465769 int
....@@ -5661,11 +5784,8 @@
56615784 int error = 0;
56625785 int logflags = 0;
56635786
5664
- if (unlikely(XFS_TEST_ERROR(
5665
- (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
5666
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
5667
- mp, XFS_ERRTAG_BMAPIFORMAT))) {
5668
- XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
5787
+ if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
5788
+ XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
56695789 return -EFSCORRUPTED;
56705790 }
56715791
....@@ -5682,15 +5802,17 @@
56825802
56835803 if (ifp->if_flags & XFS_IFBROOT) {
56845804 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
5685
- cur->bc_private.b.flags = 0;
5805
+ cur->bc_ino.flags = 0;
56865806 }
56875807
56885808 if (!xfs_iext_lookup_extent(ip, ifp, *next_fsb, &icur, &got)) {
56895809 *done = true;
56905810 goto del_cursor;
56915811 }
5692
- XFS_WANT_CORRUPTED_GOTO(mp, !isnullstartblock(got.br_startblock),
5693
- del_cursor);
5812
+ if (XFS_IS_CORRUPT(mp, isnullstartblock(got.br_startblock))) {
5813
+ error = -EFSCORRUPTED;
5814
+ goto del_cursor;
5815
+ }
56945816
56955817 new_startoff = got.br_startoff - offset_shift_fsb;
56965818 if (xfs_iext_peek_prev_extent(ifp, &icur, &prev)) {
....@@ -5779,11 +5901,8 @@
57795901 int error = 0;
57805902 int logflags = 0;
57815903
5782
- if (unlikely(XFS_TEST_ERROR(
5783
- (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
5784
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
5785
- mp, XFS_ERRTAG_BMAPIFORMAT))) {
5786
- XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
5904
+ if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
5905
+ XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
57875906 return -EFSCORRUPTED;
57885907 }
57895908
....@@ -5800,7 +5919,7 @@
58005919
58015920 if (ifp->if_flags & XFS_IFBROOT) {
58025921 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
5803
- cur->bc_private.b.flags = 0;
5922
+ cur->bc_ino.flags = 0;
58045923 }
58055924
58065925 if (*next_fsb == NULLFSBLOCK) {
....@@ -5816,11 +5935,13 @@
58165935 goto del_cursor;
58175936 }
58185937 }
5819
- XFS_WANT_CORRUPTED_GOTO(mp, !isnullstartblock(got.br_startblock),
5820
- del_cursor);
5938
+ if (XFS_IS_CORRUPT(mp, isnullstartblock(got.br_startblock))) {
5939
+ error = -EFSCORRUPTED;
5940
+ goto del_cursor;
5941
+ }
58215942
5822
- if (stop_fsb >= got.br_startoff + got.br_blockcount) {
5823
- error = -EIO;
5943
+ if (XFS_IS_CORRUPT(mp, stop_fsb > got.br_startoff)) {
5944
+ error = -EFSCORRUPTED;
58245945 goto del_cursor;
58255946 }
58265947
....@@ -5867,37 +5988,32 @@
58675988 * @split_fsb is a block where the extents is split. If split_fsb lies in a
58685989 * hole or the first block of extents, just return 0.
58695990 */
5870
-STATIC int
5871
-xfs_bmap_split_extent_at(
5991
+int
5992
+xfs_bmap_split_extent(
58725993 struct xfs_trans *tp,
58735994 struct xfs_inode *ip,
58745995 xfs_fileoff_t split_fsb)
58755996 {
58765997 int whichfork = XFS_DATA_FORK;
5998
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
58775999 struct xfs_btree_cur *cur = NULL;
58786000 struct xfs_bmbt_irec got;
58796001 struct xfs_bmbt_irec new; /* split extent */
58806002 struct xfs_mount *mp = ip->i_mount;
5881
- struct xfs_ifork *ifp;
58826003 xfs_fsblock_t gotblkcnt; /* new block count for got */
58836004 struct xfs_iext_cursor icur;
58846005 int error = 0;
58856006 int logflags = 0;
58866007 int i = 0;
58876008
5888
- if (unlikely(XFS_TEST_ERROR(
5889
- (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
5890
- XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
5891
- mp, XFS_ERRTAG_BMAPIFORMAT))) {
5892
- XFS_ERROR_REPORT("xfs_bmap_split_extent_at",
5893
- XFS_ERRLEVEL_LOW, mp);
6009
+ if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
6010
+ XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
58946011 return -EFSCORRUPTED;
58956012 }
58966013
58976014 if (XFS_FORCED_SHUTDOWN(mp))
58986015 return -EIO;
58996016
5900
- ifp = XFS_IFORK_PTR(ip, whichfork);
59016017 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
59026018 /* Read in all the extents */
59036019 error = xfs_iread_extents(tp, ip, whichfork);
....@@ -5920,11 +6036,14 @@
59206036
59216037 if (ifp->if_flags & XFS_IFBROOT) {
59226038 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
5923
- cur->bc_private.b.flags = 0;
6039
+ cur->bc_ino.flags = 0;
59246040 error = xfs_bmbt_lookup_eq(cur, &got, &i);
59256041 if (error)
59266042 goto del_cursor;
5927
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, del_cursor);
6043
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
6044
+ error = -EFSCORRUPTED;
6045
+ goto del_cursor;
6046
+ }
59286047 }
59296048
59306049 got.br_blockcount = gotblkcnt;
....@@ -5942,18 +6061,23 @@
59426061 /* Add new extent */
59436062 xfs_iext_next(ifp, &icur);
59446063 xfs_iext_insert(ip, &icur, &new, 0);
5945
- XFS_IFORK_NEXT_SET(ip, whichfork,
5946
- XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
6064
+ ifp->if_nextents++;
59476065
59486066 if (cur) {
59496067 error = xfs_bmbt_lookup_eq(cur, &new, &i);
59506068 if (error)
59516069 goto del_cursor;
5952
- XFS_WANT_CORRUPTED_GOTO(mp, i == 0, del_cursor);
6070
+ if (XFS_IS_CORRUPT(mp, i != 0)) {
6071
+ error = -EFSCORRUPTED;
6072
+ goto del_cursor;
6073
+ }
59536074 error = xfs_btree_insert(cur, &i);
59546075 if (error)
59556076 goto del_cursor;
5956
- XFS_WANT_CORRUPTED_GOTO(mp, i == 1, del_cursor);
6077
+ if (XFS_IS_CORRUPT(mp, i != 1)) {
6078
+ error = -EFSCORRUPTED;
6079
+ goto del_cursor;
6080
+ }
59576081 }
59586082
59596083 /*
....@@ -5970,40 +6094,12 @@
59706094
59716095 del_cursor:
59726096 if (cur) {
5973
- cur->bc_private.b.allocated = 0;
6097
+ cur->bc_ino.allocated = 0;
59746098 xfs_btree_del_cursor(cur, error);
59756099 }
59766100
59776101 if (logflags)
59786102 xfs_trans_log_inode(tp, ip, logflags);
5979
- return error;
5980
-}
5981
-
5982
-int
5983
-xfs_bmap_split_extent(
5984
- struct xfs_inode *ip,
5985
- xfs_fileoff_t split_fsb)
5986
-{
5987
- struct xfs_mount *mp = ip->i_mount;
5988
- struct xfs_trans *tp;
5989
- int error;
5990
-
5991
- error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write,
5992
- XFS_DIOSTRAT_SPACE_RES(mp, 0), 0, 0, &tp);
5993
- if (error)
5994
- return error;
5995
-
5996
- xfs_ilock(ip, XFS_ILOCK_EXCL);
5997
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
5998
-
5999
- error = xfs_bmap_split_extent_at(tp, ip, split_fsb);
6000
- if (error)
6001
- goto out;
6002
-
6003
- return xfs_trans_commit(tp);
6004
-
6005
-out:
6006
- xfs_trans_cancel(tp);
60076103 return error;
60086104 }
60096105
....@@ -6036,7 +6132,7 @@
60366132 bmap->br_blockcount,
60376133 bmap->br_state);
60386134
6039
- bi = kmem_alloc(sizeof(struct xfs_bmap_intent), KM_SLEEP | KM_NOFS);
6135
+ bi = kmem_alloc(sizeof(struct xfs_bmap_intent), KM_NOFS);
60406136 INIT_LIST_HEAD(&bi->bi_list);
60416137 bi->bi_type = type;
60426138 bi->bi_owner = ip;
....@@ -6048,29 +6144,29 @@
60486144 }
60496145
60506146 /* Map an extent into a file. */
6051
-int
6147
+void
60526148 xfs_bmap_map_extent(
60536149 struct xfs_trans *tp,
60546150 struct xfs_inode *ip,
60556151 struct xfs_bmbt_irec *PREV)
60566152 {
60576153 if (!xfs_bmap_is_update_needed(PREV))
6058
- return 0;
6154
+ return;
60596155
6060
- return __xfs_bmap_add(tp, XFS_BMAP_MAP, ip, XFS_DATA_FORK, PREV);
6156
+ __xfs_bmap_add(tp, XFS_BMAP_MAP, ip, XFS_DATA_FORK, PREV);
60616157 }
60626158
60636159 /* Unmap an extent out of a file. */
6064
-int
6160
+void
60656161 xfs_bmap_unmap_extent(
60666162 struct xfs_trans *tp,
60676163 struct xfs_inode *ip,
60686164 struct xfs_bmbt_irec *PREV)
60696165 {
60706166 if (!xfs_bmap_is_update_needed(PREV))
6071
- return 0;
6167
+ return;
60726168
6073
- return __xfs_bmap_add(tp, XFS_BMAP_UNMAP, ip, XFS_DATA_FORK, PREV);
6169
+ __xfs_bmap_add(tp, XFS_BMAP_UNMAP, ip, XFS_DATA_FORK, PREV);
60746170 }
60756171
60766172 /*
....@@ -6133,6 +6229,11 @@
61336229 xfs_fsblock_t endfsb;
61346230 bool isrt;
61356231
6232
+ if (irec->br_startblock + irec->br_blockcount <= irec->br_startblock)
6233
+ return __this_address;
6234
+ if (irec->br_startoff + irec->br_blockcount <= irec->br_startoff)
6235
+ return __this_address;
6236
+
61366237 isrt = XFS_IS_REALTIME_INODE(ip);
61376238 endfsb = irec->br_startblock + irec->br_blockcount - 1;
61386239 if (isrt && whichfork == XFS_DATA_FORK) {
....@@ -6149,11 +6250,7 @@
61496250 XFS_FSB_TO_AGNO(mp, endfsb))
61506251 return __this_address;
61516252 }
6152
- if (irec->br_state != XFS_EXT_NORM) {
6153
- if (whichfork != XFS_DATA_FORK)
6154
- return __this_address;
6155
- if (!xfs_sb_version_hasextflgbit(&mp->m_sb))
6156
- return __this_address;
6157
- }
6253
+ if (irec->br_state != XFS_EXT_NORM && whichfork != XFS_DATA_FORK)
6254
+ return __this_address;
61586255 return NULL;
61596256 }