• Home
  • Raw
  • Download

Lines Matching +full:ip +full:- +full:block

1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
58 int maxrootrecs; /* max records in root block */ in xfs_bmap_compute_maxlevels()
59 int minleafrecs; /* min records in leaf block */ in xfs_bmap_compute_maxlevels()
60 int minnoderecs; /* min records in node block */ in xfs_bmap_compute_maxlevels()
61 int sz; /* root block size */ in xfs_bmap_compute_maxlevels()
65 * leaf entries, is controlled by the size of the on-disk extent count. in xfs_bmap_compute_maxlevels()
69 * (xfs_default_attroffset(ip) >> 3) because we could have mounted with in xfs_bmap_compute_maxlevels()
83 minleafrecs = mp->m_bmap_dmnr[0]; in xfs_bmap_compute_maxlevels()
84 minnoderecs = mp->m_bmap_dmnr[1]; in xfs_bmap_compute_maxlevels()
92 mp->m_bm_maxlevels[whichfork] = level; in xfs_bmap_compute_maxlevels()
93 ASSERT(mp->m_bm_maxlevels[whichfork] <= xfs_bmbt_maxlevels_ondisk()); in xfs_bmap_compute_maxlevels()
100 if (mp->m_sb.sb_inodesize == 256) in xfs_bmap_compute_attr_offset()
101 return XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS); in xfs_bmap_compute_attr_offset()
111 cur->bc_rec.b = *irec; in xfs_bmbt_lookup_eq()
120 cur->bc_rec.b.br_startoff = 0; in xfs_bmbt_lookup_first()
121 cur->bc_rec.b.br_startblock = 0; in xfs_bmbt_lookup_first()
122 cur->bc_rec.b.br_blockcount = 0; in xfs_bmbt_lookup_first()
129 static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork) in xfs_bmap_needs_btree() argument
131 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmap_needs_btree()
134 ifp->if_format == XFS_DINODE_FMT_EXTENTS && in xfs_bmap_needs_btree()
135 ifp->if_nextents > XFS_IFORK_MAXEXT(ip, whichfork); in xfs_bmap_needs_btree()
141 static inline bool xfs_bmap_wants_extents(struct xfs_inode *ip, int whichfork) in xfs_bmap_wants_extents() argument
143 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmap_wants_extents()
146 ifp->if_format == XFS_DINODE_FMT_BTREE && in xfs_bmap_wants_extents()
147 ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork); in xfs_bmap_wants_extents()
166 * Compute the worst-case number of indirect blocks that will be used
167 * for ip's delayed extent of length "len".
171 xfs_inode_t *ip, /* incore inode pointer */ in xfs_bmap_worst_indlen() argument
179 mp = ip->i_mount; in xfs_bmap_worst_indlen()
180 maxrecs = mp->m_bmap_dmxr[0]; in xfs_bmap_worst_indlen()
184 len += maxrecs - 1; in xfs_bmap_worst_indlen()
188 return rval + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - in xfs_bmap_worst_indlen()
189 level - 1; in xfs_bmap_worst_indlen()
191 maxrecs = mp->m_bmap_dmxr[1]; in xfs_bmap_worst_indlen()
201 struct xfs_inode *ip) in xfs_default_attroffset() argument
203 if (ip->i_df.if_format == XFS_DINODE_FMT_DEV) in xfs_default_attroffset()
205 return M_IGEO(ip->i_mount)->attr_fork_offset; in xfs_default_attroffset()
210 * from local to extent format - we reset it where possible to make space
215 xfs_inode_t *ip, in xfs_bmap_forkoff_reset() argument
219 ip->i_df.if_format != XFS_DINODE_FMT_DEV && in xfs_bmap_forkoff_reset()
220 ip->i_df.if_format != XFS_DINODE_FMT_BTREE) { in xfs_bmap_forkoff_reset()
221 uint dfl_forkoff = xfs_default_attroffset(ip) >> 3; in xfs_bmap_forkoff_reset()
223 if (dfl_forkoff > ip->i_forkoff) in xfs_bmap_forkoff_reset()
224 ip->i_forkoff = dfl_forkoff; in xfs_bmap_forkoff_reset()
240 for (i = 0; i < cur->bc_maxlevels; i++) { in xfs_bmap_get_bp()
241 if (!cur->bc_levels[i].bp) in xfs_bmap_get_bp()
243 if (xfs_buf_daddr(cur->bc_levels[i].bp) == bno) in xfs_bmap_get_bp()
244 return cur->bc_levels[i].bp; in xfs_bmap_get_bp()
248 list_for_each_entry(lip, &cur->bc_tp->t_items, li_trans) { in xfs_bmap_get_bp()
251 if (bip->bli_item.li_type == XFS_LI_BUF && in xfs_bmap_get_bp()
252 xfs_buf_daddr(bip->bli_buf) == bno) in xfs_bmap_get_bp()
253 return bip->bli_buf; in xfs_bmap_get_bp()
261 struct xfs_btree_block *block, in xfs_check_block() argument
267 __be64 *pp, *thispa; /* pointer to block address */ in xfs_check_block()
270 ASSERT(be16_to_cpu(block->bb_level) > 0); in xfs_check_block()
273 for( i = 1; i <= xfs_btree_get_numrecs(block); i++) { in xfs_check_block()
274 dmxr = mp->m_bmap_dmxr[0]; in xfs_check_block()
275 keyp = XFS_BMBT_KEY_ADDR(mp, block, i); in xfs_check_block()
278 ASSERT(be64_to_cpu(prevp->br_startoff) < in xfs_check_block()
279 be64_to_cpu(keyp->br_startoff)); in xfs_check_block()
284 * Compare the block numbers to see if there are dups. in xfs_check_block()
287 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, i, sz); in xfs_check_block()
289 pp = XFS_BMBT_PTR_ADDR(mp, block, i, dmxr); in xfs_check_block()
291 for (j = i+1; j <= be16_to_cpu(block->bb_numrecs); j++) { in xfs_check_block()
293 thispa = XFS_BMAP_BROOT_PTR_ADDR(mp, block, j, sz); in xfs_check_block()
295 thispa = XFS_BMBT_PTR_ADDR(mp, block, j, dmxr); in xfs_check_block()
309 * Check that the extents for the inode ip are in the right order in all
318 xfs_inode_t *ip, /* incore inode pointer */ in xfs_bmap_check_leaf_extents() argument
321 struct xfs_mount *mp = ip->i_mount; in xfs_bmap_check_leaf_extents()
322 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmap_check_leaf_extents()
323 struct xfs_btree_block *block; /* current btree block */ in xfs_bmap_check_leaf_extents() local
324 xfs_fsblock_t bno; /* block # of "block" */ in xfs_bmap_check_leaf_extents()
325 struct xfs_buf *bp; /* buffer for "block" */ in xfs_bmap_check_leaf_extents()
329 __be64 *pp; /* pointer to block address */ in xfs_bmap_check_leaf_extents()
331 xfs_bmbt_rec_t last = {0, 0}; /* last extent in prev block */ in xfs_bmap_check_leaf_extents()
335 if (ifp->if_format != XFS_DINODE_FMT_BTREE) in xfs_bmap_check_leaf_extents()
339 if (ip->i_df.if_nextents > 10000) in xfs_bmap_check_leaf_extents()
343 block = ifp->if_broot; in xfs_bmap_check_leaf_extents()
347 level = be16_to_cpu(block->bb_level); in xfs_bmap_check_leaf_extents()
349 xfs_check_block(block, mp, 1, ifp->if_broot_bytes); in xfs_bmap_check_leaf_extents()
350 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes); in xfs_bmap_check_leaf_extents()
354 ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); in xfs_bmap_check_leaf_extents()
355 ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); in xfs_bmap_check_leaf_extents()
361 while (level-- > 0) { in xfs_bmap_check_leaf_extents()
373 block = XFS_BUF_TO_BLOCK(bp); in xfs_bmap_check_leaf_extents()
378 * Check this block for basic sanity (increasing keys and in xfs_bmap_check_leaf_extents()
382 xfs_check_block(block, mp, 0, 0); in xfs_bmap_check_leaf_extents()
383 pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); in xfs_bmap_check_leaf_extents()
386 error = -EFSCORRUPTED; in xfs_bmap_check_leaf_extents()
396 * Here with bp and block set to the leftmost leaf node in the tree. in xfs_bmap_check_leaf_extents()
408 num_recs = xfs_btree_get_numrecs(block); in xfs_bmap_check_leaf_extents()
411 * Read-ahead the next leaf block, if any. in xfs_bmap_check_leaf_extents()
414 nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib); in xfs_bmap_check_leaf_extents()
418 * If we had a previous block, the last entry should in xfs_bmap_check_leaf_extents()
422 ep = XFS_BMBT_REC_ADDR(mp, block, 1); in xfs_bmap_check_leaf_extents()
429 nextp = XFS_BMBT_REC_ADDR(mp, block, j + 1); in xfs_bmap_check_leaf_extents()
459 block = XFS_BUF_TO_BLOCK(bp); in xfs_bmap_check_leaf_extents()
508 mval[i - 1].br_startoff + mval[i - 1].br_blockcount == in xfs_bmap_validate_ret()
518 #define xfs_bmap_check_leaf_extents(cur, ip, whichfork) do { } while (0) argument
530 * Since the extents are already in-core, all we have to do is give up the space
531 * for the btree root and pitch the leaf block.
536 struct xfs_inode *ip, /* incore inode pointer */ in xfs_bmap_btree_to_extents() argument
541 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmap_btree_to_extents()
542 struct xfs_mount *mp = ip->i_mount; in xfs_bmap_btree_to_extents()
543 struct xfs_btree_block *rblock = ifp->if_broot; in xfs_bmap_btree_to_extents()
544 struct xfs_btree_block *cblock;/* child btree block */ in xfs_bmap_btree_to_extents()
545 xfs_fsblock_t cbno; /* child block number */ in xfs_bmap_btree_to_extents()
546 struct xfs_buf *cbp; /* child block's buffer */ in xfs_bmap_btree_to_extents()
548 __be64 *pp; /* ptr to block address */ in xfs_bmap_btree_to_extents()
552 if (!xfs_bmap_wants_extents(ip, whichfork)) in xfs_bmap_btree_to_extents()
557 ASSERT(ifp->if_format == XFS_DINODE_FMT_BTREE); in xfs_bmap_btree_to_extents()
558 ASSERT(be16_to_cpu(rblock->bb_level) == 1); in xfs_bmap_btree_to_extents()
559 ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1); in xfs_bmap_btree_to_extents()
560 ASSERT(xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0) == 1); in xfs_bmap_btree_to_extents()
562 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, ifp->if_broot_bytes); in xfs_bmap_btree_to_extents()
565 if (XFS_IS_CORRUPT(cur->bc_mp, !xfs_btree_check_lptr(cur, cbno, 1))) in xfs_bmap_btree_to_extents()
566 return -EFSCORRUPTED; in xfs_bmap_btree_to_extents()
576 xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, whichfork); in xfs_bmap_btree_to_extents()
577 error = xfs_free_extent_later(cur->bc_tp, cbno, 1, &oinfo, in xfs_bmap_btree_to_extents()
582 ip->i_nblocks--; in xfs_bmap_btree_to_extents()
583 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); in xfs_bmap_btree_to_extents()
585 if (cur->bc_levels[0].bp == cbp) in xfs_bmap_btree_to_extents()
586 cur->bc_levels[0].bp = NULL; in xfs_bmap_btree_to_extents()
587 xfs_iroot_realloc(ip, -1, whichfork); in xfs_bmap_btree_to_extents()
588 ASSERT(ifp->if_broot == NULL); in xfs_bmap_btree_to_extents()
589 ifp->if_format = XFS_DINODE_FMT_EXTENTS; in xfs_bmap_btree_to_extents()
595 * Convert an extents-format file into a btree-format file.
596 * The new file will have a root block (in the inode) and a single child block.
601 struct xfs_inode *ip, /* incore inode pointer */ in xfs_bmap_extents_to_btree() argument
607 struct xfs_btree_block *ablock; /* allocated (child) bt block */ in xfs_bmap_extents_to_btree()
611 struct xfs_btree_block *block; /* btree root block */ in xfs_bmap_extents_to_btree() local
615 struct xfs_bmbt_key *kp; /* root block key pointer */ in xfs_bmap_extents_to_btree()
617 xfs_bmbt_ptr_t *pp; /* root block address pointer */ in xfs_bmap_extents_to_btree()
622 mp = ip->i_mount; in xfs_bmap_extents_to_btree()
624 ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmap_extents_to_btree()
625 ASSERT(ifp->if_format == XFS_DINODE_FMT_EXTENTS); in xfs_bmap_extents_to_btree()
631 xfs_iroot_realloc(ip, 1, whichfork); in xfs_bmap_extents_to_btree()
636 block = ifp->if_broot; in xfs_bmap_extents_to_btree()
637 xfs_btree_init_block_int(mp, block, XFS_BUF_DADDR_NULL, in xfs_bmap_extents_to_btree()
638 XFS_BTNUM_BMAP, 1, 1, ip->i_ino, in xfs_bmap_extents_to_btree()
643 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); in xfs_bmap_extents_to_btree()
644 cur->bc_ino.flags = wasdel ? XFS_BTCUR_BMBT_WASDEL : 0; in xfs_bmap_extents_to_btree()
648 ifp->if_format = XFS_DINODE_FMT_BTREE; in xfs_bmap_extents_to_btree()
652 xfs_rmap_ino_bmbt_owner(&args.oinfo, ip->i_ino, whichfork); in xfs_bmap_extents_to_btree()
658 XFS_INO_TO_FSB(mp, ip->i_ino)); in xfs_bmap_extents_to_btree()
666 error = -ENOSPC; in xfs_bmap_extents_to_btree()
670 cur->bc_ino.allocated++; in xfs_bmap_extents_to_btree()
671 ip->i_nblocks++; in xfs_bmap_extents_to_btree()
672 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); in xfs_bmap_extents_to_btree()
673 error = xfs_trans_get_buf(tp, mp->m_ddev_targp, in xfs_bmap_extents_to_btree()
675 mp->m_bsize, 0, &abp); in xfs_bmap_extents_to_btree()
680 * Fill in the child block. in xfs_bmap_extents_to_btree()
682 abp->b_ops = &xfs_bmbt_buf_ops; in xfs_bmap_extents_to_btree()
685 XFS_BTNUM_BMAP, 0, 0, ip->i_ino, in xfs_bmap_extents_to_btree()
695 ASSERT(cnt == ifp->if_nextents); in xfs_bmap_extents_to_btree()
701 kp = XFS_BMBT_KEY_ADDR(mp, block, 1); in xfs_bmap_extents_to_btree()
703 kp->br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(arp)); in xfs_bmap_extents_to_btree()
704 pp = XFS_BMBT_PTR_ADDR(mp, block, 1, xfs_bmbt_get_maxrecs(cur, in xfs_bmap_extents_to_btree()
705 be16_to_cpu(block->bb_level))); in xfs_bmap_extents_to_btree()
713 xfs_btree_log_recs(cur, abp, 1, be16_to_cpu(ablock->bb_numrecs)); in xfs_bmap_extents_to_btree()
720 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); in xfs_bmap_extents_to_btree()
722 xfs_iroot_realloc(ip, -1, whichfork); in xfs_bmap_extents_to_btree()
723 ifp->if_format = XFS_DINODE_FMT_EXTENTS; in xfs_bmap_extents_to_btree()
724 ASSERT(ifp->if_broot == NULL); in xfs_bmap_extents_to_btree()
734 * (The bmap-level manipulations are ok, though).
739 struct xfs_inode *ip, in xfs_bmap_local_to_extents_empty() argument
742 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmap_local_to_extents_empty()
745 ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); in xfs_bmap_local_to_extents_empty()
746 ASSERT(ifp->if_bytes == 0); in xfs_bmap_local_to_extents_empty()
747 ASSERT(ifp->if_nextents == 0); in xfs_bmap_local_to_extents_empty()
749 xfs_bmap_forkoff_reset(ip, whichfork); in xfs_bmap_local_to_extents_empty()
750 ifp->if_u1.if_root = NULL; in xfs_bmap_local_to_extents_empty()
751 ifp->if_height = 0; in xfs_bmap_local_to_extents_empty()
752 ifp->if_format = XFS_DINODE_FMT_EXTENTS; in xfs_bmap_local_to_extents_empty()
753 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); in xfs_bmap_local_to_extents_empty()
760 xfs_inode_t *ip, /* incore inode pointer */ in xfs_bmap_local_to_extents() argument
766 struct xfs_inode *ip, in xfs_bmap_local_to_extents() argument
773 struct xfs_buf *bp; /* buffer for extent block */ in xfs_bmap_local_to_extents()
781 ASSERT(!(S_ISREG(VFS_I(ip)->i_mode) && whichfork == XFS_DATA_FORK)); in xfs_bmap_local_to_extents()
782 ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmap_local_to_extents()
783 ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); in xfs_bmap_local_to_extents()
785 if (!ifp->if_bytes) { in xfs_bmap_local_to_extents()
786 xfs_bmap_local_to_extents_empty(tp, ip, whichfork); in xfs_bmap_local_to_extents()
795 args.mp = ip->i_mount; in xfs_bmap_local_to_extents()
798 xfs_rmap_ino_owner(&args.oinfo, ip->i_ino, whichfork, 0); in xfs_bmap_local_to_extents()
801 * Allocate a block. We know we need only one, since the in xfs_bmap_local_to_extents()
807 XFS_INO_TO_FSB(args.mp, ip->i_ino)); in xfs_bmap_local_to_extents()
814 error = xfs_trans_get_buf(tp, args.mp->m_ddev_targp, in xfs_bmap_local_to_extents()
816 args.mp->m_bsize, 0, &bp); in xfs_bmap_local_to_extents()
821 * Initialize the block, copy the data and log the remote buffer. in xfs_bmap_local_to_extents()
828 init_fn(tp, bp, ip, ifp); in xfs_bmap_local_to_extents()
831 xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); in xfs_bmap_local_to_extents()
832 xfs_bmap_local_to_extents_empty(tp, ip, whichfork); in xfs_bmap_local_to_extents()
835 ifp->if_u1.if_root = NULL; in xfs_bmap_local_to_extents()
836 ifp->if_height = 0; in xfs_bmap_local_to_extents()
843 xfs_iext_insert(ip, &icur, &rec, 0); in xfs_bmap_local_to_extents()
845 ifp->if_nextents = 1; in xfs_bmap_local_to_extents()
846 ip->i_nblocks = 1; in xfs_bmap_local_to_extents()
847 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); in xfs_bmap_local_to_extents()
861 xfs_inode_t *ip, /* incore inode pointer */ in xfs_bmap_add_attrfork_btree() argument
864 struct xfs_btree_block *block = ip->i_df.if_broot; in xfs_bmap_add_attrfork_btree() local
870 mp = ip->i_mount; in xfs_bmap_add_attrfork_btree()
872 if (XFS_BMAP_BMDR_SPACE(block) <= xfs_inode_data_fork_size(ip)) in xfs_bmap_add_attrfork_btree()
875 cur = xfs_bmbt_init_cursor(mp, tp, ip, XFS_DATA_FORK); in xfs_bmap_add_attrfork_btree()
881 error = -EFSCORRUPTED; in xfs_bmap_add_attrfork_btree()
888 return -ENOSPC; in xfs_bmap_add_attrfork_btree()
890 cur->bc_ino.allocated = 0; in xfs_bmap_add_attrfork_btree()
905 struct xfs_inode *ip, /* incore inode pointer */ in xfs_bmap_add_attrfork_extents() argument
911 if (ip->i_df.if_nextents * sizeof(struct xfs_bmbt_rec) <= in xfs_bmap_add_attrfork_extents()
912 xfs_inode_data_fork_size(ip)) in xfs_bmap_add_attrfork_extents()
915 error = xfs_bmap_extents_to_btree(tp, ip, &cur, 0, flags, in xfs_bmap_add_attrfork_extents()
918 cur->bc_ino.allocated = 0; in xfs_bmap_add_attrfork_extents()
927 * conversion. Some are basic and only require special block initialisation
932 * formatting callout. It should be possible - it's just a very complex
938 struct xfs_inode *ip, /* incore inode pointer */ in xfs_bmap_add_attrfork_local() argument
943 if (ip->i_df.if_bytes <= xfs_inode_data_fork_size(ip)) in xfs_bmap_add_attrfork_local()
946 if (S_ISDIR(VFS_I(ip)->i_mode)) { in xfs_bmap_add_attrfork_local()
948 dargs.geo = ip->i_mount->m_dir_geo; in xfs_bmap_add_attrfork_local()
949 dargs.dp = ip; in xfs_bmap_add_attrfork_local()
950 dargs.total = dargs.geo->fsbcount; in xfs_bmap_add_attrfork_local()
956 if (S_ISLNK(VFS_I(ip)->i_mode)) in xfs_bmap_add_attrfork_local()
957 return xfs_bmap_local_to_extents(tp, ip, 1, flags, in xfs_bmap_add_attrfork_local()
963 return -EFSCORRUPTED; in xfs_bmap_add_attrfork_local()
971 struct xfs_inode *ip, in xfs_bmap_set_attrforkoff() argument
975 int default_size = xfs_default_attroffset(ip) >> 3; in xfs_bmap_set_attrforkoff()
977 switch (ip->i_df.if_format) { in xfs_bmap_set_attrforkoff()
979 ip->i_forkoff = default_size; in xfs_bmap_set_attrforkoff()
984 ip->i_forkoff = xfs_attr_shortform_bytesfit(ip, size); in xfs_bmap_set_attrforkoff()
985 if (!ip->i_forkoff) in xfs_bmap_set_attrforkoff()
986 ip->i_forkoff = default_size; in xfs_bmap_set_attrforkoff()
987 else if (xfs_has_attr2(ip->i_mount) && version) in xfs_bmap_set_attrforkoff()
992 return -EINVAL; in xfs_bmap_set_attrforkoff()
999 * Convert inode from non-attributed to attributed.
1000 * Must not be in a transaction, ip must not be locked.
1004 xfs_inode_t *ip, /* incore inode pointer */ in xfs_bmap_add_attrfork() argument
1015 ASSERT(xfs_inode_has_attr_fork(ip) == 0); in xfs_bmap_add_attrfork()
1017 mp = ip->i_mount; in xfs_bmap_add_attrfork()
1018 ASSERT(!XFS_NOT_DQATTACHED(mp, ip)); in xfs_bmap_add_attrfork()
1022 error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_addafork, blks, 0, in xfs_bmap_add_attrfork()
1026 if (xfs_inode_has_attr_fork(ip)) in xfs_bmap_add_attrfork()
1029 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); in xfs_bmap_add_attrfork()
1030 error = xfs_bmap_set_attrforkoff(ip, size, &version); in xfs_bmap_add_attrfork()
1034 xfs_ifork_init_attr(ip, XFS_DINODE_FMT_EXTENTS, 0); in xfs_bmap_add_attrfork()
1036 switch (ip->i_df.if_format) { in xfs_bmap_add_attrfork()
1038 error = xfs_bmap_add_attrfork_local(tp, ip, &logflags); in xfs_bmap_add_attrfork()
1041 error = xfs_bmap_add_attrfork_extents(tp, ip, &logflags); in xfs_bmap_add_attrfork()
1044 error = xfs_bmap_add_attrfork_btree(tp, ip, &logflags); in xfs_bmap_add_attrfork()
1051 xfs_trans_log_inode(tp, ip, logflags); in xfs_bmap_add_attrfork()
1058 spin_lock(&mp->m_sb_lock); in xfs_bmap_add_attrfork()
1067 spin_unlock(&mp->m_sb_lock); in xfs_bmap_add_attrfork()
1073 xfs_iunlock(ip, XFS_ILOCK_EXCL); in xfs_bmap_add_attrfork()
1078 xfs_iunlock(ip, XFS_ILOCK_EXCL); in xfs_bmap_add_attrfork()
1093 struct xfs_inode *ip, in xfs_bmap_complain_bad_rec() argument
1098 struct xfs_mount *mp = ip->i_mount; in xfs_bmap_complain_bad_rec()
1110 ip->i_ino, forkname, fa); in xfs_bmap_complain_bad_rec()
1112 "Offset 0x%llx, start block 0x%llx, block count 0x%llx state 0x%x", in xfs_bmap_complain_bad_rec()
1113 irec->br_startoff, irec->br_startblock, irec->br_blockcount, in xfs_bmap_complain_bad_rec()
1114 irec->br_state); in xfs_bmap_complain_bad_rec()
1116 return -EFSCORRUPTED; in xfs_bmap_complain_bad_rec()
1119 /* Stuff every bmbt record from this block into the incore extent map. */
1127 struct xfs_mount *mp = cur->bc_mp; in xfs_iread_bmbt_block()
1128 struct xfs_inode *ip = cur->bc_ino.ip; in xfs_iread_bmbt_block() local
1129 struct xfs_btree_block *block; in xfs_iread_bmbt_block() local
1134 int whichfork = cur->bc_ino.whichfork; in xfs_iread_bmbt_block()
1135 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_iread_bmbt_block()
1137 block = xfs_btree_get_block(cur, level, &bp); in xfs_iread_bmbt_block()
1140 num_recs = xfs_btree_get_numrecs(block); in xfs_iread_bmbt_block()
1141 if (unlikely(ir->loaded + num_recs > ifp->if_nextents)) { in xfs_iread_bmbt_block()
1142 xfs_warn(ip->i_mount, "corrupt dinode %llu, (btree extents).", in xfs_iread_bmbt_block()
1143 (unsigned long long)ip->i_ino); in xfs_iread_bmbt_block()
1144 xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, block, in xfs_iread_bmbt_block()
1145 sizeof(*block), __this_address); in xfs_iread_bmbt_block()
1146 return -EFSCORRUPTED; in xfs_iread_bmbt_block()
1150 frp = XFS_BMBT_REC_ADDR(mp, block, 1); in xfs_iread_bmbt_block()
1151 for (j = 0; j < num_recs; j++, frp++, ir->loaded++) { in xfs_iread_bmbt_block()
1156 fa = xfs_bmap_validate_extent(ip, whichfork, &new); in xfs_iread_bmbt_block()
1158 xfs_inode_verifier_error(ip, -EFSCORRUPTED, in xfs_iread_bmbt_block()
1161 return xfs_bmap_complain_bad_rec(ip, whichfork, fa, in xfs_iread_bmbt_block()
1164 xfs_iext_insert(ip, &ir->icur, &new, in xfs_iread_bmbt_block()
1166 trace_xfs_read_extent(ip, &ir->icur, in xfs_iread_bmbt_block()
1168 xfs_iext_next(ifp, &ir->icur); in xfs_iread_bmbt_block()
1175 * Read in extents from a btree-format inode.
1180 struct xfs_inode *ip, in xfs_iread_extents() argument
1184 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_iread_extents()
1185 struct xfs_mount *mp = ip->i_mount; in xfs_iread_extents()
1192 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); in xfs_iread_extents()
1196 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); in xfs_iread_extents()
1203 if (XFS_IS_CORRUPT(mp, ir.loaded != ifp->if_nextents)) { in xfs_iread_extents()
1204 error = -EFSCORRUPTED; in xfs_iread_extents()
1213 smp_store_release(&ifp->if_needextents, 0); in xfs_iread_extents()
1221 * Returns the relative block number of the first unused block(s) in the given
1223 * lowest-address hole if the fork has holes, else the first block past the end
1224 * of fork. Return 0 if the fork is currently local (in-inode).
1229 struct xfs_inode *ip, /* incore inode */ in xfs_bmap_first_unused() argument
1231 xfs_fileoff_t *first_unused, /* unused block */ in xfs_bmap_first_unused()
1234 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmap_first_unused()
1241 if (ifp->if_format == XFS_DINODE_FMT_LOCAL) { in xfs_bmap_first_unused()
1248 error = xfs_iread_extents(tp, ip, whichfork); in xfs_bmap_first_unused()
1258 got.br_startoff - max >= len) in xfs_bmap_first_unused()
1269 * Returns the file-relative block number of the last block - 1 before
1277 struct xfs_inode *ip, /* incore inode */ in xfs_bmap_last_before() argument
1278 xfs_fileoff_t *last_block, /* last block */ in xfs_bmap_last_before()
1281 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmap_last_before()
1286 switch (ifp->if_format) { in xfs_bmap_last_before()
1295 return -EFSCORRUPTED; in xfs_bmap_last_before()
1298 error = xfs_iread_extents(tp, ip, whichfork); in xfs_bmap_last_before()
1302 if (!xfs_iext_lookup_extent_before(ip, ifp, last_block, &icur, &got)) in xfs_bmap_last_before()
1310 struct xfs_inode *ip, in xfs_bmap_last_extent() argument
1315 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmap_last_extent()
1319 error = xfs_iread_extents(tp, ip, whichfork); in xfs_bmap_last_extent()
1334 * blocks at the end of the file which do not start at the previous data block,
1337 * Returns 1 in bma->aeof if the file (fork) is empty as any new write will be
1349 bma->aeof = false; in xfs_bmap_isaeof()
1350 error = xfs_bmap_last_extent(NULL, bma->ip, whichfork, &rec, in xfs_bmap_isaeof()
1356 bma->aeof = true; in xfs_bmap_isaeof()
1364 bma->aeof = bma->offset >= rec.br_startoff + rec.br_blockcount || in xfs_bmap_isaeof()
1365 (bma->offset >= rec.br_startoff && in xfs_bmap_isaeof()
1371 * Returns the file-relative block number of the first block past eof in
1377 struct xfs_inode *ip, in xfs_bmap_last_offset() argument
1381 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmap_last_offset()
1388 if (ifp->if_format == XFS_DINODE_FMT_LOCAL) in xfs_bmap_last_offset()
1391 if (XFS_IS_CORRUPT(ip->i_mount, !xfs_ifork_has_extents(ifp))) in xfs_bmap_last_offset()
1392 return -EFSCORRUPTED; in xfs_bmap_last_offset()
1394 error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty); in xfs_bmap_last_offset()
1414 struct xfs_mount *mp = bma->ip->i_mount; in xfs_bmap_add_extent_delay_real()
1415 struct xfs_ifork *ifp = xfs_ifork_ptr(bma->ip, whichfork); in xfs_bmap_add_extent_delay_real()
1416 struct xfs_bmbt_irec *new = &bma->got; in xfs_bmap_add_extent_delay_real()
1431 ASSERT(!isnullstartblock(new->br_startblock)); in xfs_bmap_add_extent_delay_real()
1432 ASSERT(!bma->cur || in xfs_bmap_add_extent_delay_real()
1433 (bma->cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL)); in xfs_bmap_add_extent_delay_real()
1444 xfs_iext_get_extent(ifp, &bma->icur, &PREV); in xfs_bmap_add_extent_delay_real()
1445 new_endoff = new->br_startoff + new->br_blockcount; in xfs_bmap_add_extent_delay_real()
1447 ASSERT(PREV.br_startoff <= new->br_startoff); in xfs_bmap_add_extent_delay_real()
1457 if (PREV.br_startoff == new->br_startoff) in xfs_bmap_add_extent_delay_real()
1466 if (xfs_iext_peek_prev_extent(ifp, &bma->icur, &LEFT)) { in xfs_bmap_add_extent_delay_real()
1473 LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff && in xfs_bmap_add_extent_delay_real()
1474 LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock && in xfs_bmap_add_extent_delay_real()
1475 LEFT.br_state == new->br_state && in xfs_bmap_add_extent_delay_real()
1476 LEFT.br_blockcount + new->br_blockcount <= XFS_MAX_BMBT_EXTLEN) in xfs_bmap_add_extent_delay_real()
1482 * Also check for all-three-contiguous being too large. in xfs_bmap_add_extent_delay_real()
1484 if (xfs_iext_peek_next_extent(ifp, &bma->icur, &RIGHT)) { in xfs_bmap_add_extent_delay_real()
1492 new->br_startblock + new->br_blockcount == RIGHT.br_startblock && in xfs_bmap_add_extent_delay_real()
1493 new->br_state == RIGHT.br_state && in xfs_bmap_add_extent_delay_real()
1494 new->br_blockcount + RIGHT.br_blockcount <= XFS_MAX_BMBT_EXTLEN && in xfs_bmap_add_extent_delay_real()
1499 LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount in xfs_bmap_add_extent_delay_real()
1517 xfs_iext_remove(bma->ip, &bma->icur, state); in xfs_bmap_add_extent_delay_real()
1518 xfs_iext_remove(bma->ip, &bma->icur, state); in xfs_bmap_add_extent_delay_real()
1519 xfs_iext_prev(ifp, &bma->icur); in xfs_bmap_add_extent_delay_real()
1520 xfs_iext_update_extent(bma->ip, state, &bma->icur, &LEFT); in xfs_bmap_add_extent_delay_real()
1521 ifp->if_nextents--; in xfs_bmap_add_extent_delay_real()
1523 if (bma->cur == NULL) in xfs_bmap_add_extent_delay_real()
1527 error = xfs_bmbt_lookup_eq(bma->cur, &RIGHT, &i); in xfs_bmap_add_extent_delay_real()
1531 error = -EFSCORRUPTED; in xfs_bmap_add_extent_delay_real()
1534 error = xfs_btree_delete(bma->cur, &i); in xfs_bmap_add_extent_delay_real()
1538 error = -EFSCORRUPTED; in xfs_bmap_add_extent_delay_real()
1541 error = xfs_btree_decrement(bma->cur, 0, &i); in xfs_bmap_add_extent_delay_real()
1545 error = -EFSCORRUPTED; in xfs_bmap_add_extent_delay_real()
1548 error = xfs_bmbt_update(bma->cur, &LEFT); in xfs_bmap_add_extent_delay_real()
1562 xfs_iext_remove(bma->ip, &bma->icur, state); in xfs_bmap_add_extent_delay_real()
1563 xfs_iext_prev(ifp, &bma->icur); in xfs_bmap_add_extent_delay_real()
1564 xfs_iext_update_extent(bma->ip, state, &bma->icur, &LEFT); in xfs_bmap_add_extent_delay_real()
1566 if (bma->cur == NULL) in xfs_bmap_add_extent_delay_real()
1570 error = xfs_bmbt_lookup_eq(bma->cur, &old, &i); in xfs_bmap_add_extent_delay_real()
1574 error = -EFSCORRUPTED; in xfs_bmap_add_extent_delay_real()
1577 error = xfs_bmbt_update(bma->cur, &LEFT); in xfs_bmap_add_extent_delay_real()
1587 * with delay -> unwritten extent allocation here because the in xfs_bmap_add_extent_delay_real()
1590 PREV.br_startblock = new->br_startblock; in xfs_bmap_add_extent_delay_real()
1592 PREV.br_state = new->br_state; in xfs_bmap_add_extent_delay_real()
1594 xfs_iext_next(ifp, &bma->icur); in xfs_bmap_add_extent_delay_real()
1595 xfs_iext_remove(bma->ip, &bma->icur, state); in xfs_bmap_add_extent_delay_real()
1596 xfs_iext_prev(ifp, &bma->icur); in xfs_bmap_add_extent_delay_real()
1597 xfs_iext_update_extent(bma->ip, state, &bma->icur, &PREV); in xfs_bmap_add_extent_delay_real()
1599 if (bma->cur == NULL) in xfs_bmap_add_extent_delay_real()
1603 error = xfs_bmbt_lookup_eq(bma->cur, &RIGHT, &i); in xfs_bmap_add_extent_delay_real()
1607 error = -EFSCORRUPTED; in xfs_bmap_add_extent_delay_real()
1610 error = xfs_bmbt_update(bma->cur, &PREV); in xfs_bmap_add_extent_delay_real()
1622 PREV.br_startblock = new->br_startblock; in xfs_bmap_add_extent_delay_real()
1623 PREV.br_state = new->br_state; in xfs_bmap_add_extent_delay_real()
1624 xfs_iext_update_extent(bma->ip, state, &bma->icur, &PREV); in xfs_bmap_add_extent_delay_real()
1625 ifp->if_nextents++; in xfs_bmap_add_extent_delay_real()
1627 if (bma->cur == NULL) in xfs_bmap_add_extent_delay_real()
1631 error = xfs_bmbt_lookup_eq(bma->cur, new, &i); in xfs_bmap_add_extent_delay_real()
1635 error = -EFSCORRUPTED; in xfs_bmap_add_extent_delay_real()
1638 error = xfs_btree_insert(bma->cur, &i); in xfs_bmap_add_extent_delay_real()
1642 error = -EFSCORRUPTED; in xfs_bmap_add_extent_delay_real()
1654 temp = PREV.br_blockcount - new->br_blockcount; in xfs_bmap_add_extent_delay_real()
1655 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp), in xfs_bmap_add_extent_delay_real()
1658 LEFT.br_blockcount += new->br_blockcount; in xfs_bmap_add_extent_delay_real()
1661 PREV.br_startoff += new->br_blockcount; in xfs_bmap_add_extent_delay_real()
1664 xfs_iext_update_extent(bma->ip, state, &bma->icur, &PREV); in xfs_bmap_add_extent_delay_real()
1665 xfs_iext_prev(ifp, &bma->icur); in xfs_bmap_add_extent_delay_real()
1666 xfs_iext_update_extent(bma->ip, state, &bma->icur, &LEFT); in xfs_bmap_add_extent_delay_real()
1668 if (bma->cur == NULL) in xfs_bmap_add_extent_delay_real()
1672 error = xfs_bmbt_lookup_eq(bma->cur, &old, &i); in xfs_bmap_add_extent_delay_real()
1676 error = -EFSCORRUPTED; in xfs_bmap_add_extent_delay_real()
1679 error = xfs_bmbt_update(bma->cur, &LEFT); in xfs_bmap_add_extent_delay_real()
1690 xfs_iext_update_extent(bma->ip, state, &bma->icur, new); in xfs_bmap_add_extent_delay_real()
1691 ifp->if_nextents++; in xfs_bmap_add_extent_delay_real()
1693 if (bma->cur == NULL) in xfs_bmap_add_extent_delay_real()
1697 error = xfs_bmbt_lookup_eq(bma->cur, new, &i); in xfs_bmap_add_extent_delay_real()
1701 error = -EFSCORRUPTED; in xfs_bmap_add_extent_delay_real()
1704 error = xfs_btree_insert(bma->cur, &i); in xfs_bmap_add_extent_delay_real()
1708 error = -EFSCORRUPTED; in xfs_bmap_add_extent_delay_real()
1713 if (xfs_bmap_needs_btree(bma->ip, whichfork)) { in xfs_bmap_add_extent_delay_real()
1714 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, in xfs_bmap_add_extent_delay_real()
1715 &bma->cur, 1, &tmp_rval, whichfork); in xfs_bmap_add_extent_delay_real()
1721 temp = PREV.br_blockcount - new->br_blockcount; in xfs_bmap_add_extent_delay_real()
1722 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp), in xfs_bmap_add_extent_delay_real()
1723 startblockval(PREV.br_startblock) - in xfs_bmap_add_extent_delay_real()
1724 (bma->cur ? bma->cur->bc_ino.allocated : 0)); in xfs_bmap_add_extent_delay_real()
1729 xfs_iext_next(ifp, &bma->icur); in xfs_bmap_add_extent_delay_real()
1730 xfs_iext_insert(bma->ip, &bma->icur, &PREV, state); in xfs_bmap_add_extent_delay_real()
1731 xfs_iext_prev(ifp, &bma->icur); in xfs_bmap_add_extent_delay_real()
1740 RIGHT.br_startoff = new->br_startoff; in xfs_bmap_add_extent_delay_real()
1741 RIGHT.br_startblock = new->br_startblock; in xfs_bmap_add_extent_delay_real()
1742 RIGHT.br_blockcount += new->br_blockcount; in xfs_bmap_add_extent_delay_real()
1744 if (bma->cur == NULL) in xfs_bmap_add_extent_delay_real()
1748 error = xfs_bmbt_lookup_eq(bma->cur, &old, &i); in xfs_bmap_add_extent_delay_real()
1752 error = -EFSCORRUPTED; in xfs_bmap_add_extent_delay_real()
1755 error = xfs_bmbt_update(bma->cur, &RIGHT); in xfs_bmap_add_extent_delay_real()
1760 temp = PREV.br_blockcount - new->br_blockcount; in xfs_bmap_add_extent_delay_real()
1761 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp), in xfs_bmap_add_extent_delay_real()
1767 xfs_iext_update_extent(bma->ip, state, &bma->icur, &PREV); in xfs_bmap_add_extent_delay_real()
1768 xfs_iext_next(ifp, &bma->icur); in xfs_bmap_add_extent_delay_real()
1769 xfs_iext_update_extent(bma->ip, state, &bma->icur, &RIGHT); in xfs_bmap_add_extent_delay_real()
1777 xfs_iext_update_extent(bma->ip, state, &bma->icur, new); in xfs_bmap_add_extent_delay_real()
1778 ifp->if_nextents++; in xfs_bmap_add_extent_delay_real()
1780 if (bma->cur == NULL) in xfs_bmap_add_extent_delay_real()
1784 error = xfs_bmbt_lookup_eq(bma->cur, new, &i); in xfs_bmap_add_extent_delay_real()
1788 error = -EFSCORRUPTED; in xfs_bmap_add_extent_delay_real()
1791 error = xfs_btree_insert(bma->cur, &i); in xfs_bmap_add_extent_delay_real()
1795 error = -EFSCORRUPTED; in xfs_bmap_add_extent_delay_real()
1800 if (xfs_bmap_needs_btree(bma->ip, whichfork)) { in xfs_bmap_add_extent_delay_real()
1801 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, in xfs_bmap_add_extent_delay_real()
1802 &bma->cur, 1, &tmp_rval, whichfork); in xfs_bmap_add_extent_delay_real()
1808 temp = PREV.br_blockcount - new->br_blockcount; in xfs_bmap_add_extent_delay_real()
1809 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp), in xfs_bmap_add_extent_delay_real()
1810 startblockval(PREV.br_startblock) - in xfs_bmap_add_extent_delay_real()
1811 (bma->cur ? bma->cur->bc_ino.allocated : 0)); in xfs_bmap_add_extent_delay_real()
1815 xfs_iext_insert(bma->ip, &bma->icur, &PREV, state); in xfs_bmap_add_extent_delay_real()
1816 xfs_iext_next(ifp, &bma->icur); in xfs_bmap_add_extent_delay_real()
1849 PREV.br_startoff + PREV.br_blockcount - new_endoff; in xfs_bmap_add_extent_delay_real()
1851 nullstartblock(xfs_bmap_worst_indlen(bma->ip, in xfs_bmap_add_extent_delay_real()
1855 PREV.br_blockcount = new->br_startoff - PREV.br_startoff; in xfs_bmap_add_extent_delay_real()
1857 nullstartblock(xfs_bmap_worst_indlen(bma->ip, in xfs_bmap_add_extent_delay_real()
1859 xfs_iext_update_extent(bma->ip, state, &bma->icur, &PREV); in xfs_bmap_add_extent_delay_real()
1861 xfs_iext_next(ifp, &bma->icur); in xfs_bmap_add_extent_delay_real()
1862 xfs_iext_insert(bma->ip, &bma->icur, &RIGHT, state); in xfs_bmap_add_extent_delay_real()
1863 xfs_iext_insert(bma->ip, &bma->icur, &LEFT, state); in xfs_bmap_add_extent_delay_real()
1864 ifp->if_nextents++; in xfs_bmap_add_extent_delay_real()
1866 if (bma->cur == NULL) in xfs_bmap_add_extent_delay_real()
1870 error = xfs_bmbt_lookup_eq(bma->cur, new, &i); in xfs_bmap_add_extent_delay_real()
1874 error = -EFSCORRUPTED; in xfs_bmap_add_extent_delay_real()
1877 error = xfs_btree_insert(bma->cur, &i); in xfs_bmap_add_extent_delay_real()
1881 error = -EFSCORRUPTED; in xfs_bmap_add_extent_delay_real()
1886 if (xfs_bmap_needs_btree(bma->ip, whichfork)) { in xfs_bmap_add_extent_delay_real()
1887 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, in xfs_bmap_add_extent_delay_real()
1888 &bma->cur, 1, &tmp_rval, whichfork); in xfs_bmap_add_extent_delay_real()
1912 if (!(bma->flags & XFS_BMAPI_NORMAP)) in xfs_bmap_add_extent_delay_real()
1913 xfs_rmap_map_extent(bma->tp, bma->ip, whichfork, new); in xfs_bmap_add_extent_delay_real()
1916 if (xfs_bmap_needs_btree(bma->ip, whichfork)) { in xfs_bmap_add_extent_delay_real()
1919 ASSERT(bma->cur == NULL); in xfs_bmap_add_extent_delay_real()
1920 error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, in xfs_bmap_add_extent_delay_real()
1921 &bma->cur, da_old > 0, &tmp_logflags, in xfs_bmap_add_extent_delay_real()
1923 bma->logflags |= tmp_logflags; in xfs_bmap_add_extent_delay_real()
1929 xfs_mod_delalloc(mp, (int64_t)da_new - da_old); in xfs_bmap_add_extent_delay_real()
1931 if (bma->cur) { in xfs_bmap_add_extent_delay_real()
1932 da_new += bma->cur->bc_ino.allocated; in xfs_bmap_add_extent_delay_real()
1933 bma->cur->bc_ino.allocated = 0; in xfs_bmap_add_extent_delay_real()
1939 error = xfs_mod_fdblocks(mp, (int64_t)(da_old - da_new), in xfs_bmap_add_extent_delay_real()
1943 xfs_bmap_check_leaf_extents(bma->cur, bma->ip, whichfork); in xfs_bmap_add_extent_delay_real()
1946 bma->logflags |= rval; in xfs_bmap_add_extent_delay_real()
1959 xfs_inode_t *ip, /* incore inode pointer */ in xfs_bmap_add_extent_unwritten_real() argument
1975 struct xfs_mount *mp = ip->i_mount; in xfs_bmap_add_extent_unwritten_real()
1981 ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmap_add_extent_unwritten_real()
1983 ASSERT(!isnullstartblock(new->br_startblock)); in xfs_bmap_add_extent_unwritten_real()
1996 ASSERT(new->br_state != PREV.br_state); in xfs_bmap_add_extent_unwritten_real()
1997 new_endoff = new->br_startoff + new->br_blockcount; in xfs_bmap_add_extent_unwritten_real()
1998 ASSERT(PREV.br_startoff <= new->br_startoff); in xfs_bmap_add_extent_unwritten_real()
2005 if (PREV.br_startoff == new->br_startoff) in xfs_bmap_add_extent_unwritten_real()
2021 LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff && in xfs_bmap_add_extent_unwritten_real()
2022 LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock && in xfs_bmap_add_extent_unwritten_real()
2023 LEFT.br_state == new->br_state && in xfs_bmap_add_extent_unwritten_real()
2024 LEFT.br_blockcount + new->br_blockcount <= XFS_MAX_BMBT_EXTLEN) in xfs_bmap_add_extent_unwritten_real()
2030 * Also check for all-three-contiguous being too large. in xfs_bmap_add_extent_unwritten_real()
2040 new->br_startblock + new->br_blockcount == RIGHT.br_startblock && in xfs_bmap_add_extent_unwritten_real()
2041 new->br_state == RIGHT.br_state && in xfs_bmap_add_extent_unwritten_real()
2042 new->br_blockcount + RIGHT.br_blockcount <= XFS_MAX_BMBT_EXTLEN && in xfs_bmap_add_extent_unwritten_real()
2047 LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount in xfs_bmap_add_extent_unwritten_real()
2064 xfs_iext_remove(ip, icur, state); in xfs_bmap_add_extent_unwritten_real()
2065 xfs_iext_remove(ip, icur, state); in xfs_bmap_add_extent_unwritten_real()
2067 xfs_iext_update_extent(ip, state, icur, &LEFT); in xfs_bmap_add_extent_unwritten_real()
2068 ifp->if_nextents -= 2; in xfs_bmap_add_extent_unwritten_real()
2077 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2083 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2089 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2095 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2101 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2117 xfs_iext_remove(ip, icur, state); in xfs_bmap_add_extent_unwritten_real()
2119 xfs_iext_update_extent(ip, state, icur, &LEFT); in xfs_bmap_add_extent_unwritten_real()
2120 ifp->if_nextents--; in xfs_bmap_add_extent_unwritten_real()
2129 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2135 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2141 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2156 PREV.br_state = new->br_state; in xfs_bmap_add_extent_unwritten_real()
2159 xfs_iext_remove(ip, icur, state); in xfs_bmap_add_extent_unwritten_real()
2161 xfs_iext_update_extent(ip, state, icur, &PREV); in xfs_bmap_add_extent_unwritten_real()
2162 ifp->if_nextents--; in xfs_bmap_add_extent_unwritten_real()
2172 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2178 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2184 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2199 PREV.br_state = new->br_state; in xfs_bmap_add_extent_unwritten_real()
2200 xfs_iext_update_extent(ip, state, icur, &PREV); in xfs_bmap_add_extent_unwritten_real()
2210 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2224 LEFT.br_blockcount += new->br_blockcount; in xfs_bmap_add_extent_unwritten_real()
2227 PREV.br_startoff += new->br_blockcount; in xfs_bmap_add_extent_unwritten_real()
2228 PREV.br_startblock += new->br_blockcount; in xfs_bmap_add_extent_unwritten_real()
2229 PREV.br_blockcount -= new->br_blockcount; in xfs_bmap_add_extent_unwritten_real()
2231 xfs_iext_update_extent(ip, state, icur, &PREV); in xfs_bmap_add_extent_unwritten_real()
2233 xfs_iext_update_extent(ip, state, icur, &LEFT); in xfs_bmap_add_extent_unwritten_real()
2243 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2264 PREV.br_startoff += new->br_blockcount; in xfs_bmap_add_extent_unwritten_real()
2265 PREV.br_startblock += new->br_blockcount; in xfs_bmap_add_extent_unwritten_real()
2266 PREV.br_blockcount -= new->br_blockcount; in xfs_bmap_add_extent_unwritten_real()
2268 xfs_iext_update_extent(ip, state, icur, &PREV); in xfs_bmap_add_extent_unwritten_real()
2269 xfs_iext_insert(ip, icur, new, state); in xfs_bmap_add_extent_unwritten_real()
2270 ifp->if_nextents++; in xfs_bmap_add_extent_unwritten_real()
2280 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2286 cur->bc_rec.b = *new; in xfs_bmap_add_extent_unwritten_real()
2290 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2302 PREV.br_blockcount -= new->br_blockcount; in xfs_bmap_add_extent_unwritten_real()
2304 RIGHT.br_startoff = new->br_startoff; in xfs_bmap_add_extent_unwritten_real()
2305 RIGHT.br_startblock = new->br_startblock; in xfs_bmap_add_extent_unwritten_real()
2306 RIGHT.br_blockcount += new->br_blockcount; in xfs_bmap_add_extent_unwritten_real()
2308 xfs_iext_update_extent(ip, state, icur, &PREV); in xfs_bmap_add_extent_unwritten_real()
2310 xfs_iext_update_extent(ip, state, icur, &RIGHT); in xfs_bmap_add_extent_unwritten_real()
2320 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2341 PREV.br_blockcount -= new->br_blockcount; in xfs_bmap_add_extent_unwritten_real()
2343 xfs_iext_update_extent(ip, state, icur, &PREV); in xfs_bmap_add_extent_unwritten_real()
2345 xfs_iext_insert(ip, icur, new, state); in xfs_bmap_add_extent_unwritten_real()
2346 ifp->if_nextents++; in xfs_bmap_add_extent_unwritten_real()
2356 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2366 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2372 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2385 PREV.br_blockcount = new->br_startoff - PREV.br_startoff; in xfs_bmap_add_extent_unwritten_real()
2390 old.br_startoff + old.br_blockcount - new_endoff; in xfs_bmap_add_extent_unwritten_real()
2391 r[1].br_startblock = new->br_startblock + new->br_blockcount; in xfs_bmap_add_extent_unwritten_real()
2394 xfs_iext_update_extent(ip, state, icur, &PREV); in xfs_bmap_add_extent_unwritten_real()
2396 xfs_iext_insert(ip, icur, &r[1], state); in xfs_bmap_add_extent_unwritten_real()
2397 xfs_iext_insert(ip, icur, &r[0], state); in xfs_bmap_add_extent_unwritten_real()
2398 ifp->if_nextents += 2; in xfs_bmap_add_extent_unwritten_real()
2408 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2411 /* new right extent - oldext */ in xfs_bmap_add_extent_unwritten_real()
2415 /* new left extent - oldext */ in xfs_bmap_add_extent_unwritten_real()
2416 cur->bc_rec.b = PREV; in xfs_bmap_add_extent_unwritten_real()
2420 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2432 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2435 /* new middle extent - newext */ in xfs_bmap_add_extent_unwritten_real()
2439 error = -EFSCORRUPTED; in xfs_bmap_add_extent_unwritten_real()
2459 xfs_rmap_convert_extent(mp, tp, ip, whichfork, new); in xfs_bmap_add_extent_unwritten_real()
2462 if (xfs_bmap_needs_btree(ip, whichfork)) { in xfs_bmap_add_extent_unwritten_real()
2466 error = xfs_bmap_extents_to_btree(tp, ip, &cur, 0, in xfs_bmap_add_extent_unwritten_real()
2475 cur->bc_ino.allocated = 0; in xfs_bmap_add_extent_unwritten_real()
2479 xfs_bmap_check_leaf_extents(*curp, ip, whichfork); in xfs_bmap_add_extent_unwritten_real()
2493 xfs_inode_t *ip, /* incore inode pointer */ in xfs_bmap_add_extent_hole_delay() argument
2506 ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmap_add_extent_hole_delay()
2507 ASSERT(isnullstartblock(new->br_startblock)); in xfs_bmap_add_extent_hole_delay()
2520 * If it doesn't exist, we're converting the hole at end-of-file. in xfs_bmap_add_extent_hole_delay()
2533 left.br_startoff + left.br_blockcount == new->br_startoff && in xfs_bmap_add_extent_hole_delay()
2534 left.br_blockcount + new->br_blockcount <= XFS_MAX_BMBT_EXTLEN) in xfs_bmap_add_extent_hole_delay()
2538 new->br_startoff + new->br_blockcount == right.br_startoff && in xfs_bmap_add_extent_hole_delay()
2539 new->br_blockcount + right.br_blockcount <= XFS_MAX_BMBT_EXTLEN && in xfs_bmap_add_extent_hole_delay()
2541 (left.br_blockcount + new->br_blockcount + in xfs_bmap_add_extent_hole_delay()
2555 temp = left.br_blockcount + new->br_blockcount + in xfs_bmap_add_extent_hole_delay()
2559 startblockval(new->br_startblock) + in xfs_bmap_add_extent_hole_delay()
2561 newlen = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), in xfs_bmap_add_extent_hole_delay()
2566 xfs_iext_remove(ip, icur, state); in xfs_bmap_add_extent_hole_delay()
2568 xfs_iext_update_extent(ip, state, icur, &left); in xfs_bmap_add_extent_hole_delay()
2577 temp = left.br_blockcount + new->br_blockcount; in xfs_bmap_add_extent_hole_delay()
2580 startblockval(new->br_startblock); in xfs_bmap_add_extent_hole_delay()
2581 newlen = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), in xfs_bmap_add_extent_hole_delay()
2587 xfs_iext_update_extent(ip, state, icur, &left); in xfs_bmap_add_extent_hole_delay()
2596 temp = new->br_blockcount + right.br_blockcount; in xfs_bmap_add_extent_hole_delay()
2597 oldlen = startblockval(new->br_startblock) + in xfs_bmap_add_extent_hole_delay()
2599 newlen = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), in xfs_bmap_add_extent_hole_delay()
2601 right.br_startoff = new->br_startoff; in xfs_bmap_add_extent_hole_delay()
2604 xfs_iext_update_extent(ip, state, icur, &right); in xfs_bmap_add_extent_hole_delay()
2614 xfs_iext_insert(ip, icur, new, state); in xfs_bmap_add_extent_hole_delay()
2619 xfs_mod_fdblocks(ip->i_mount, (int64_t)(oldlen - newlen), in xfs_bmap_add_extent_hole_delay()
2624 xfs_mod_delalloc(ip->i_mount, (int64_t)newlen - oldlen); in xfs_bmap_add_extent_hole_delay()
2634 struct xfs_inode *ip, in xfs_bmap_add_extent_hole_real() argument
2642 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmap_add_extent_hole_real()
2643 struct xfs_mount *mp = ip->i_mount; in xfs_bmap_add_extent_hole_real()
2653 ASSERT(!isnullstartblock(new->br_startblock)); in xfs_bmap_add_extent_hole_real()
2654 ASSERT(!cur || !(cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL)); in xfs_bmap_add_extent_hole_real()
2682 left.br_startoff + left.br_blockcount == new->br_startoff && in xfs_bmap_add_extent_hole_real()
2683 left.br_startblock + left.br_blockcount == new->br_startblock && in xfs_bmap_add_extent_hole_real()
2684 left.br_state == new->br_state && in xfs_bmap_add_extent_hole_real()
2685 left.br_blockcount + new->br_blockcount <= XFS_MAX_BMBT_EXTLEN) in xfs_bmap_add_extent_hole_real()
2689 new->br_startoff + new->br_blockcount == right.br_startoff && in xfs_bmap_add_extent_hole_real()
2690 new->br_startblock + new->br_blockcount == right.br_startblock && in xfs_bmap_add_extent_hole_real()
2691 new->br_state == right.br_state && in xfs_bmap_add_extent_hole_real()
2692 new->br_blockcount + right.br_blockcount <= XFS_MAX_BMBT_EXTLEN && in xfs_bmap_add_extent_hole_real()
2694 left.br_blockcount + new->br_blockcount + in xfs_bmap_add_extent_hole_real()
2709 left.br_blockcount += new->br_blockcount + right.br_blockcount; in xfs_bmap_add_extent_hole_real()
2711 xfs_iext_remove(ip, icur, state); in xfs_bmap_add_extent_hole_real()
2713 xfs_iext_update_extent(ip, state, icur, &left); in xfs_bmap_add_extent_hole_real()
2714 ifp->if_nextents--; in xfs_bmap_add_extent_hole_real()
2724 error = -EFSCORRUPTED; in xfs_bmap_add_extent_hole_real()
2731 error = -EFSCORRUPTED; in xfs_bmap_add_extent_hole_real()
2738 error = -EFSCORRUPTED; in xfs_bmap_add_extent_hole_real()
2754 left.br_blockcount += new->br_blockcount; in xfs_bmap_add_extent_hole_real()
2757 xfs_iext_update_extent(ip, state, icur, &left); in xfs_bmap_add_extent_hole_real()
2767 error = -EFSCORRUPTED; in xfs_bmap_add_extent_hole_real()
2784 right.br_startoff = new->br_startoff; in xfs_bmap_add_extent_hole_real()
2785 right.br_startblock = new->br_startblock; in xfs_bmap_add_extent_hole_real()
2786 right.br_blockcount += new->br_blockcount; in xfs_bmap_add_extent_hole_real()
2787 xfs_iext_update_extent(ip, state, icur, &right); in xfs_bmap_add_extent_hole_real()
2797 error = -EFSCORRUPTED; in xfs_bmap_add_extent_hole_real()
2812 xfs_iext_insert(ip, icur, new, state); in xfs_bmap_add_extent_hole_real()
2813 ifp->if_nextents++; in xfs_bmap_add_extent_hole_real()
2823 error = -EFSCORRUPTED; in xfs_bmap_add_extent_hole_real()
2830 error = -EFSCORRUPTED; in xfs_bmap_add_extent_hole_real()
2839 xfs_rmap_map_extent(tp, ip, whichfork, new); in xfs_bmap_add_extent_hole_real()
2842 if (xfs_bmap_needs_btree(ip, whichfork)) { in xfs_bmap_add_extent_hole_real()
2846 error = xfs_bmap_extents_to_btree(tp, ip, curp, 0, in xfs_bmap_add_extent_hole_real()
2856 cur->bc_ino.allocated = 0; in xfs_bmap_add_extent_hole_real()
2858 xfs_bmap_check_leaf_extents(cur, ip, whichfork); in xfs_bmap_add_extent_hole_real()
2878 int eof, /* is extent at end-of-file? */ in xfs_bmap_extsize_align()
2905 (orig_off >= gotp->br_startoff) && in xfs_bmap_extsize_align()
2906 (orig_end <= gotp->br_startoff + gotp->br_blockcount)) { in xfs_bmap_extsize_align()
2920 align_off -= temp; in xfs_bmap_extsize_align()
2926 align_alen += extsz - temp; in xfs_bmap_extsize_align()
2937 align_alen -= extsz; in xfs_bmap_extsize_align()
2941 * If the previous block overlaps with this proposed allocation in xfs_bmap_extsize_align()
2944 if (prevp->br_startoff != NULLFILEOFF) { in xfs_bmap_extsize_align()
2945 if (prevp->br_startblock == HOLESTARTBLOCK) in xfs_bmap_extsize_align()
2946 prevo = prevp->br_startoff; in xfs_bmap_extsize_align()
2948 prevo = prevp->br_startoff + prevp->br_blockcount; in xfs_bmap_extsize_align()
2954 * If the next block overlaps with this proposed allocation in xfs_bmap_extsize_align()
2957 * This may of course make the start overlap previous block, in xfs_bmap_extsize_align()
2958 * and if we hit the offset 0 limit then the next block in xfs_bmap_extsize_align()
2961 if (!eof && gotp->br_startoff != NULLFILEOFF) { in xfs_bmap_extsize_align()
2962 if ((delay && gotp->br_startblock == HOLESTARTBLOCK) || in xfs_bmap_extsize_align()
2963 (!delay && gotp->br_startblock == DELAYSTARTBLOCK)) in xfs_bmap_extsize_align()
2964 nexto = gotp->br_startoff + gotp->br_blockcount; in xfs_bmap_extsize_align()
2966 nexto = gotp->br_startoff; in xfs_bmap_extsize_align()
2972 align_off = nexto > align_alen ? nexto - align_alen : 0; in xfs_bmap_extsize_align()
2985 align_alen = nexto - align_off; in xfs_bmap_extsize_align()
2992 if (rt && (temp = (align_alen % mp->m_sb.sb_rextsize))) { in xfs_bmap_extsize_align()
2999 align_alen - temp < orig_alen) in xfs_bmap_extsize_align()
3000 return -EINVAL; in xfs_bmap_extsize_align()
3005 align_alen -= temp; in xfs_bmap_extsize_align()
3011 else if (align_off + align_alen - temp >= orig_end) in xfs_bmap_extsize_align()
3012 align_alen -= temp; in xfs_bmap_extsize_align()
3017 align_alen -= orig_off - align_off; in xfs_bmap_extsize_align()
3019 align_alen -= align_alen % mp->m_sb.sb_rextsize; in xfs_bmap_extsize_align()
3025 return -EINVAL; in xfs_bmap_extsize_align()
3034 if (!eof && gotp->br_startoff != NULLFILEOFF) in xfs_bmap_extsize_align()
3035 ASSERT(align_off + align_alen <= gotp->br_startoff); in xfs_bmap_extsize_align()
3036 if (prevp->br_startoff != NULLFILEOFF) in xfs_bmap_extsize_align()
3037 ASSERT(align_off >= prevp->br_startoff + prevp->br_blockcount); in xfs_bmap_extsize_align()
3051 xfs_fsblock_t adjust; /* adjustment to block numbers */ in xfs_bmap_adjacent()
3057 (x) < mp->m_sb.sb_rblocks : \ in xfs_bmap_adjacent()
3059 XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && \ in xfs_bmap_adjacent()
3060 XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks) in xfs_bmap_adjacent()
3062 mp = ap->ip->i_mount; in xfs_bmap_adjacent()
3063 rt = XFS_IS_REALTIME_INODE(ap->ip) && in xfs_bmap_adjacent()
3064 (ap->datatype & XFS_ALLOC_USERDATA); in xfs_bmap_adjacent()
3066 * If allocating at eof, and there's a previous real block, in xfs_bmap_adjacent()
3067 * try to use its last block as our starting point. in xfs_bmap_adjacent()
3069 if (ap->eof && ap->prev.br_startoff != NULLFILEOFF && in xfs_bmap_adjacent()
3070 !isnullstartblock(ap->prev.br_startblock) && in xfs_bmap_adjacent()
3071 ISVALID(ap->prev.br_startblock + ap->prev.br_blockcount, in xfs_bmap_adjacent()
3072 ap->prev.br_startblock)) { in xfs_bmap_adjacent()
3073 ap->blkno = ap->prev.br_startblock + ap->prev.br_blockcount; in xfs_bmap_adjacent()
3077 adjust = ap->offset - in xfs_bmap_adjacent()
3078 (ap->prev.br_startoff + ap->prev.br_blockcount); in xfs_bmap_adjacent()
3080 ISVALID(ap->blkno + adjust, ap->prev.br_startblock)) in xfs_bmap_adjacent()
3081 ap->blkno += adjust; in xfs_bmap_adjacent()
3088 else if (!ap->eof) { in xfs_bmap_adjacent()
3089 xfs_fsblock_t gotbno; /* right side block number */ in xfs_bmap_adjacent()
3091 xfs_fsblock_t prevbno; /* left side block number */ in xfs_bmap_adjacent()
3095 * If there's a previous (left) block, select a requested in xfs_bmap_adjacent()
3096 * start block based on it. in xfs_bmap_adjacent()
3098 if (ap->prev.br_startoff != NULLFILEOFF && in xfs_bmap_adjacent()
3099 !isnullstartblock(ap->prev.br_startblock) && in xfs_bmap_adjacent()
3100 (prevbno = ap->prev.br_startblock + in xfs_bmap_adjacent()
3101 ap->prev.br_blockcount) && in xfs_bmap_adjacent()
3102 ISVALID(prevbno, ap->prev.br_startblock)) { in xfs_bmap_adjacent()
3104 * Calculate gap to end of previous block. in xfs_bmap_adjacent()
3106 adjust = prevdiff = ap->offset - in xfs_bmap_adjacent()
3107 (ap->prev.br_startoff + in xfs_bmap_adjacent()
3108 ap->prev.br_blockcount); in xfs_bmap_adjacent()
3110 * Figure the startblock based on the previous block's in xfs_bmap_adjacent()
3114 * allocating, or using it gives us an invalid block in xfs_bmap_adjacent()
3115 * number, then just use the end of the previous block. in xfs_bmap_adjacent()
3117 if (prevdiff <= XFS_ALLOC_GAP_UNITS * ap->length && in xfs_bmap_adjacent()
3119 ap->prev.br_startblock)) in xfs_bmap_adjacent()
3125 * No previous block or can't follow it, just default. in xfs_bmap_adjacent()
3130 * If there's a following (right) block, select a requested in xfs_bmap_adjacent()
3131 * start block based on it. in xfs_bmap_adjacent()
3133 if (!isnullstartblock(ap->got.br_startblock)) { in xfs_bmap_adjacent()
3135 * Calculate gap to start of next block. in xfs_bmap_adjacent()
3137 adjust = gotdiff = ap->got.br_startoff - ap->offset; in xfs_bmap_adjacent()
3139 * Figure the startblock based on the next block's in xfs_bmap_adjacent()
3142 gotbno = ap->got.br_startblock; in xfs_bmap_adjacent()
3146 * allocating, or using it gives us an invalid block in xfs_bmap_adjacent()
3147 * number, then just use the start of the next block in xfs_bmap_adjacent()
3150 if (gotdiff <= XFS_ALLOC_GAP_UNITS * ap->length && in xfs_bmap_adjacent()
3151 ISVALID(gotbno - gotdiff, gotbno)) in xfs_bmap_adjacent()
3152 gotbno -= adjust; in xfs_bmap_adjacent()
3153 else if (ISVALID(gotbno - ap->length, gotbno)) { in xfs_bmap_adjacent()
3154 gotbno -= ap->length; in xfs_bmap_adjacent()
3155 gotdiff += adjust - ap->length; in xfs_bmap_adjacent()
3160 * No next block, just default. in xfs_bmap_adjacent()
3166 * one, else ap->blkno is already set (to 0 or the inode block). in xfs_bmap_adjacent()
3169 ap->blkno = prevdiff <= gotdiff ? prevbno : gotbno; in xfs_bmap_adjacent()
3171 ap->blkno = prevbno; in xfs_bmap_adjacent()
3173 ap->blkno = gotbno; in xfs_bmap_adjacent()
3195 xfs_alloc_min_freelist(pag->pag_mount, pag), in xfs_bmap_longest_free_extent()
3214 if (blen < ap->minlen) in xfs_bmap_select_minlen()
3215 return ap->minlen; in xfs_bmap_select_minlen()
3222 if (blen < args->maxlen) in xfs_bmap_select_minlen()
3224 return args->maxlen; in xfs_bmap_select_minlen()
3233 struct xfs_mount *mp = args->mp; in xfs_bmap_btalloc_select_lengths()
3238 if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { in xfs_bmap_btalloc_select_lengths()
3239 args->total = ap->minlen; in xfs_bmap_btalloc_select_lengths()
3240 args->minlen = ap->minlen; in xfs_bmap_btalloc_select_lengths()
3244 args->total = ap->total; in xfs_bmap_btalloc_select_lengths()
3245 startag = XFS_FSB_TO_AGNO(mp, ap->blkno); in xfs_bmap_btalloc_select_lengths()
3251 error = xfs_bmap_longest_free_extent(pag, args->tp, blen); in xfs_bmap_btalloc_select_lengths()
3252 if (error && error != -EAGAIN) in xfs_bmap_btalloc_select_lengths()
3255 if (*blen >= args->maxlen) in xfs_bmap_btalloc_select_lengths()
3261 args->minlen = xfs_bmap_select_minlen(ap, args, *blen); in xfs_bmap_btalloc_select_lengths()
3271 if (ap->flags & XFS_BMAPI_COWFORK) { in xfs_bmap_btalloc_accounting()
3273 * COW fork blocks are in-core only and thus are treated as in xfs_bmap_btalloc_accounting()
3274 * in-core quota reservation (like delalloc blocks) even when in xfs_bmap_btalloc_accounting()
3281 if (ap->wasdel) { in xfs_bmap_btalloc_accounting()
3282 xfs_mod_delalloc(ap->ip->i_mount, -(int64_t)args->len); in xfs_bmap_btalloc_accounting()
3288 * has acquired in-core quota reservation for this extent. in xfs_bmap_btalloc_accounting()
3294 ap->ip->i_delayed_blks += args->len; in xfs_bmap_btalloc_accounting()
3295 xfs_trans_mod_dquot_byino(ap->tp, ap->ip, XFS_TRANS_DQ_RES_BLKS, in xfs_bmap_btalloc_accounting()
3296 -(long)args->len); in xfs_bmap_btalloc_accounting()
3301 ap->ip->i_nblocks += args->len; in xfs_bmap_btalloc_accounting()
3302 xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); in xfs_bmap_btalloc_accounting()
3303 if (ap->wasdel) { in xfs_bmap_btalloc_accounting()
3304 ap->ip->i_delayed_blks -= args->len; in xfs_bmap_btalloc_accounting()
3305 xfs_mod_delalloc(ap->ip->i_mount, -(int64_t)args->len); in xfs_bmap_btalloc_accounting()
3307 xfs_trans_mod_dquot_byino(ap->tp, ap->ip, in xfs_bmap_btalloc_accounting()
3308 ap->wasdel ? XFS_TRANS_DQ_DELBCOUNT : XFS_TRANS_DQ_BCOUNT, in xfs_bmap_btalloc_accounting()
3309 args->len); in xfs_bmap_btalloc_accounting()
3317 struct xfs_mount *mp = args->mp; in xfs_bmap_compute_alignments()
3322 if (mp->m_swidth && xfs_has_swalloc(mp)) in xfs_bmap_compute_alignments()
3323 stripe_align = mp->m_swidth; in xfs_bmap_compute_alignments()
3324 else if (mp->m_dalign) in xfs_bmap_compute_alignments()
3325 stripe_align = mp->m_dalign; in xfs_bmap_compute_alignments()
3327 if (ap->flags & XFS_BMAPI_COWFORK) in xfs_bmap_compute_alignments()
3328 align = xfs_get_cowextsz_hint(ap->ip); in xfs_bmap_compute_alignments()
3329 else if (ap->datatype & XFS_ALLOC_USERDATA) in xfs_bmap_compute_alignments()
3330 align = xfs_get_extsz_hint(ap->ip); in xfs_bmap_compute_alignments()
3332 if (xfs_bmap_extsize_align(mp, &ap->got, &ap->prev, align, 0, in xfs_bmap_compute_alignments()
3333 ap->eof, 0, ap->conv, &ap->offset, in xfs_bmap_compute_alignments()
3334 &ap->length)) in xfs_bmap_compute_alignments()
3336 ASSERT(ap->length); in xfs_bmap_compute_alignments()
3341 args->prod = align; in xfs_bmap_compute_alignments()
3342 div_u64_rem(ap->offset, args->prod, &args->mod); in xfs_bmap_compute_alignments()
3343 if (args->mod) in xfs_bmap_compute_alignments()
3344 args->mod = args->prod - args->mod; in xfs_bmap_compute_alignments()
3345 } else if (mp->m_sb.sb_blocksize >= PAGE_SIZE) { in xfs_bmap_compute_alignments()
3346 args->prod = 1; in xfs_bmap_compute_alignments()
3347 args->mod = 0; in xfs_bmap_compute_alignments()
3349 args->prod = PAGE_SIZE >> mp->m_sb.sb_blocklog; in xfs_bmap_compute_alignments()
3350 div_u64_rem(ap->offset, args->prod, &args->mod); in xfs_bmap_compute_alignments()
3351 if (args->mod) in xfs_bmap_compute_alignments()
3352 args->mod = args->prod - args->mod; in xfs_bmap_compute_alignments()
3365 ap->blkno = args->fsbno; in xfs_bmap_process_allocated_extent()
3366 ap->length = args->len; in xfs_bmap_process_allocated_extent()
3379 if (ap->length <= orig_length) in xfs_bmap_process_allocated_extent()
3380 ap->offset = orig_offset; in xfs_bmap_process_allocated_extent()
3381 else if (ap->offset + ap->length < orig_offset + orig_length) in xfs_bmap_process_allocated_extent()
3382 ap->offset = orig_offset + orig_length - ap->length; in xfs_bmap_process_allocated_extent()
3391 struct xfs_mount *mp = ap->ip->i_mount; in xfs_bmap_exact_minlen_extent_alloc()
3392 struct xfs_alloc_arg args = { .tp = ap->tp, .mp = mp }; in xfs_bmap_exact_minlen_extent_alloc()
3397 ASSERT(ap->length); in xfs_bmap_exact_minlen_extent_alloc()
3399 if (ap->minlen != 1) { in xfs_bmap_exact_minlen_extent_alloc()
3400 ap->blkno = NULLFSBLOCK; in xfs_bmap_exact_minlen_extent_alloc()
3401 ap->length = 0; in xfs_bmap_exact_minlen_extent_alloc()
3405 orig_offset = ap->offset; in xfs_bmap_exact_minlen_extent_alloc()
3406 orig_length = ap->length; in xfs_bmap_exact_minlen_extent_alloc()
3420 ap->blkno = XFS_AGB_TO_FSB(mp, 0, 0); in xfs_bmap_exact_minlen_extent_alloc()
3423 args.minlen = args.maxlen = ap->minlen; in xfs_bmap_exact_minlen_extent_alloc()
3424 args.total = ap->total; in xfs_bmap_exact_minlen_extent_alloc()
3429 args.minleft = ap->minleft; in xfs_bmap_exact_minlen_extent_alloc()
3430 args.wasdel = ap->wasdel; in xfs_bmap_exact_minlen_extent_alloc()
3432 args.datatype = ap->datatype; in xfs_bmap_exact_minlen_extent_alloc()
3434 error = xfs_alloc_vextent_first_ag(&args, ap->blkno); in xfs_bmap_exact_minlen_extent_alloc()
3442 ap->blkno = NULLFSBLOCK; in xfs_bmap_exact_minlen_extent_alloc()
3443 ap->length = 0; in xfs_bmap_exact_minlen_extent_alloc()
3450 #define xfs_bmap_exact_minlen_extent_alloc(bma) (-EFSCORRUPTED)
3459 * NOTE: ap->aeof is only set if the allocation length is >= the
3470 struct xfs_mount *mp = args->mp; in xfs_bmap_btalloc_at_eof()
3471 struct xfs_perag *caller_pag = args->pag; in xfs_bmap_btalloc_at_eof()
3475 * If there are already extents in the file, try an exact EOF block in xfs_bmap_btalloc_at_eof()
3480 if (ap->offset) { in xfs_bmap_btalloc_at_eof()
3488 args->alignment = 1; in xfs_bmap_btalloc_at_eof()
3489 if (blen > stripe_align && blen <= args->maxlen) in xfs_bmap_btalloc_at_eof()
3490 nextminlen = blen - stripe_align; in xfs_bmap_btalloc_at_eof()
3492 nextminlen = args->minlen; in xfs_bmap_btalloc_at_eof()
3493 if (nextminlen + stripe_align > args->minlen + 1) in xfs_bmap_btalloc_at_eof()
3494 args->minalignslop = nextminlen + stripe_align - in xfs_bmap_btalloc_at_eof()
3495 args->minlen - 1; in xfs_bmap_btalloc_at_eof()
3497 args->minalignslop = 0; in xfs_bmap_btalloc_at_eof()
3500 args->pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, ap->blkno)); in xfs_bmap_btalloc_at_eof()
3501 error = xfs_alloc_vextent_exact_bno(args, ap->blkno); in xfs_bmap_btalloc_at_eof()
3503 xfs_perag_put(args->pag); in xfs_bmap_btalloc_at_eof()
3504 args->pag = NULL; in xfs_bmap_btalloc_at_eof()
3509 if (args->fsbno != NULLFSBLOCK) in xfs_bmap_btalloc_at_eof()
3515 args->alignment = stripe_align; in xfs_bmap_btalloc_at_eof()
3516 args->minlen = nextminlen; in xfs_bmap_btalloc_at_eof()
3517 args->minalignslop = 0; in xfs_bmap_btalloc_at_eof()
3523 args->alignment = stripe_align; in xfs_bmap_btalloc_at_eof()
3524 if (blen > args->alignment && in xfs_bmap_btalloc_at_eof()
3525 blen <= args->maxlen + args->alignment) in xfs_bmap_btalloc_at_eof()
3526 args->minlen = blen - args->alignment; in xfs_bmap_btalloc_at_eof()
3527 args->minalignslop = 0; in xfs_bmap_btalloc_at_eof()
3531 error = xfs_alloc_vextent_near_bno(args, ap->blkno); in xfs_bmap_btalloc_at_eof()
3533 args->pag = NULL; in xfs_bmap_btalloc_at_eof()
3534 error = xfs_alloc_vextent_start_ag(args, ap->blkno); in xfs_bmap_btalloc_at_eof()
3535 ASSERT(args->pag == NULL); in xfs_bmap_btalloc_at_eof()
3536 args->pag = caller_pag; in xfs_bmap_btalloc_at_eof()
3541 if (args->fsbno != NULLFSBLOCK) in xfs_bmap_btalloc_at_eof()
3546 * original non-aligned state so the caller can proceed on allocation in xfs_bmap_btalloc_at_eof()
3549 args->alignment = 1; in xfs_bmap_btalloc_at_eof()
3556 * allocation whilst still maintaining necessary total block reservation
3572 if (args->minlen > ap->minlen) { in xfs_bmap_btalloc_low_space()
3573 args->minlen = ap->minlen; in xfs_bmap_btalloc_low_space()
3574 error = xfs_alloc_vextent_start_ag(args, ap->blkno); in xfs_bmap_btalloc_low_space()
3575 if (error || args->fsbno != NULLFSBLOCK) in xfs_bmap_btalloc_low_space()
3580 args->total = ap->minlen; in xfs_bmap_btalloc_low_space()
3584 ap->tp->t_flags |= XFS_TRANS_LOWMODE; in xfs_bmap_btalloc_low_space()
3601 ASSERT(args->pag); in xfs_bmap_btalloc_filestreams()
3608 if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { in xfs_bmap_btalloc_filestreams()
3609 args->minlen = ap->minlen; in xfs_bmap_btalloc_filestreams()
3610 ASSERT(args->fsbno == NULLFSBLOCK); in xfs_bmap_btalloc_filestreams()
3614 args->minlen = xfs_bmap_select_minlen(ap, args, blen); in xfs_bmap_btalloc_filestreams()
3615 if (ap->aeof) in xfs_bmap_btalloc_filestreams()
3619 if (!error && args->fsbno == NULLFSBLOCK) in xfs_bmap_btalloc_filestreams()
3620 error = xfs_alloc_vextent_near_bno(args, ap->blkno); in xfs_bmap_btalloc_filestreams()
3630 xfs_perag_rele(args->pag); in xfs_bmap_btalloc_filestreams()
3631 args->pag = NULL; in xfs_bmap_btalloc_filestreams()
3632 if (error || args->fsbno != NULLFSBLOCK) in xfs_bmap_btalloc_filestreams()
3647 ap->blkno = XFS_INO_TO_FSB(args->mp, ap->ip->i_ino); in xfs_bmap_btalloc_best_length()
3665 if (ap->aeof && !(ap->tp->t_flags & XFS_TRANS_LOWMODE)) { in xfs_bmap_btalloc_best_length()
3668 if (error || args->fsbno != NULLFSBLOCK) in xfs_bmap_btalloc_best_length()
3672 error = xfs_alloc_vextent_start_ag(args, ap->blkno); in xfs_bmap_btalloc_best_length()
3673 if (error || args->fsbno != NULLFSBLOCK) in xfs_bmap_btalloc_best_length()
3683 struct xfs_mount *mp = ap->ip->i_mount; in xfs_bmap_btalloc()
3685 .tp = ap->tp, in xfs_bmap_btalloc()
3689 .minleft = ap->minleft, in xfs_bmap_btalloc()
3690 .wasdel = ap->wasdel, in xfs_bmap_btalloc()
3692 .datatype = ap->datatype, in xfs_bmap_btalloc()
3701 ASSERT(ap->length); in xfs_bmap_btalloc()
3702 orig_offset = ap->offset; in xfs_bmap_btalloc()
3703 orig_length = ap->length; in xfs_bmap_btalloc()
3708 args.maxlen = min(ap->length, mp->m_ag_max_usable); in xfs_bmap_btalloc()
3710 if ((ap->datatype & XFS_ALLOC_USERDATA) && in xfs_bmap_btalloc()
3711 xfs_inode_is_filestream(ap->ip)) in xfs_bmap_btalloc()
3722 ap->blkno = NULLFSBLOCK; in xfs_bmap_btalloc()
3723 ap->length = 0; in xfs_bmap_btalloc()
3728 /* Trim extent to fit a logical block range. */
3738 if (irec->br_startoff + irec->br_blockcount <= bno || in xfs_trim_extent()
3739 irec->br_startoff >= end) { in xfs_trim_extent()
3740 irec->br_blockcount = 0; in xfs_trim_extent()
3744 if (irec->br_startoff < bno) { in xfs_trim_extent()
3745 distance = bno - irec->br_startoff; in xfs_trim_extent()
3746 if (isnullstartblock(irec->br_startblock)) in xfs_trim_extent()
3747 irec->br_startblock = DELAYSTARTBLOCK; in xfs_trim_extent()
3748 if (irec->br_startblock != DELAYSTARTBLOCK && in xfs_trim_extent()
3749 irec->br_startblock != HOLESTARTBLOCK) in xfs_trim_extent()
3750 irec->br_startblock += distance; in xfs_trim_extent()
3751 irec->br_startoff += distance; in xfs_trim_extent()
3752 irec->br_blockcount -= distance; in xfs_trim_extent()
3755 if (end < irec->br_startoff + irec->br_blockcount) { in xfs_trim_extent()
3756 distance = irec->br_startoff + irec->br_blockcount - end; in xfs_trim_extent()
3757 irec->br_blockcount -= distance; in xfs_trim_extent()
3776 got->br_startoff + got->br_blockcount <= obno) { in xfs_bmapi_trim_map()
3778 if (isnullstartblock(got->br_startblock)) in xfs_bmapi_trim_map()
3779 mval->br_startblock = DELAYSTARTBLOCK; in xfs_bmapi_trim_map()
3787 mval->br_startoff = *bno; in xfs_bmapi_trim_map()
3788 if (isnullstartblock(got->br_startblock)) in xfs_bmapi_trim_map()
3789 mval->br_startblock = DELAYSTARTBLOCK; in xfs_bmapi_trim_map()
3791 mval->br_startblock = got->br_startblock + in xfs_bmapi_trim_map()
3792 (*bno - got->br_startoff); in xfs_bmapi_trim_map()
3800 mval->br_blockcount = XFS_FILBLKS_MIN(end - *bno, in xfs_bmapi_trim_map()
3801 got->br_blockcount - (*bno - got->br_startoff)); in xfs_bmapi_trim_map()
3802 mval->br_state = got->br_state; in xfs_bmapi_trim_map()
3803 ASSERT(mval->br_blockcount <= len); in xfs_bmapi_trim_map()
3823 ((mval->br_startoff + mval->br_blockcount) <= end)); in xfs_bmapi_update_map()
3824 ASSERT((flags & XFS_BMAPI_ENTIRE) || (mval->br_blockcount <= *len) || in xfs_bmapi_update_map()
3825 (mval->br_startoff < obno)); in xfs_bmapi_update_map()
3827 *bno = mval->br_startoff + mval->br_blockcount; in xfs_bmapi_update_map()
3828 *len = end - *bno; in xfs_bmapi_update_map()
3829 if (*n > 0 && mval->br_startoff == mval[-1].br_startoff) { in xfs_bmapi_update_map()
3831 ASSERT(mval->br_startblock == mval[-1].br_startblock); in xfs_bmapi_update_map()
3832 ASSERT(mval->br_blockcount > mval[-1].br_blockcount); in xfs_bmapi_update_map()
3833 ASSERT(mval->br_state == mval[-1].br_state); in xfs_bmapi_update_map()
3834 mval[-1].br_blockcount = mval->br_blockcount; in xfs_bmapi_update_map()
3835 mval[-1].br_state = mval->br_state; in xfs_bmapi_update_map()
3836 } else if (*n > 0 && mval->br_startblock != DELAYSTARTBLOCK && in xfs_bmapi_update_map()
3837 mval[-1].br_startblock != DELAYSTARTBLOCK && in xfs_bmapi_update_map()
3838 mval[-1].br_startblock != HOLESTARTBLOCK && in xfs_bmapi_update_map()
3839 mval->br_startblock == mval[-1].br_startblock + in xfs_bmapi_update_map()
3840 mval[-1].br_blockcount && in xfs_bmapi_update_map()
3841 mval[-1].br_state == mval->br_state) { in xfs_bmapi_update_map()
3842 ASSERT(mval->br_startoff == in xfs_bmapi_update_map()
3843 mval[-1].br_startoff + mval[-1].br_blockcount); in xfs_bmapi_update_map()
3844 mval[-1].br_blockcount += mval->br_blockcount; in xfs_bmapi_update_map()
3846 mval->br_startblock == DELAYSTARTBLOCK && in xfs_bmapi_update_map()
3847 mval[-1].br_startblock == DELAYSTARTBLOCK && in xfs_bmapi_update_map()
3848 mval->br_startoff == in xfs_bmapi_update_map()
3849 mval[-1].br_startoff + mval[-1].br_blockcount) { in xfs_bmapi_update_map()
3850 mval[-1].br_blockcount += mval->br_blockcount; in xfs_bmapi_update_map()
3851 mval[-1].br_state = mval->br_state; in xfs_bmapi_update_map()
3853 ((mval->br_startoff + mval->br_blockcount) <= in xfs_bmapi_update_map()
3866 struct xfs_inode *ip, in xfs_bmapi_read() argument
3873 struct xfs_mount *mp = ip->i_mount; in xfs_bmapi_read()
3875 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmapi_read()
3886 ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)); in xfs_bmapi_read()
3889 return -EFSCORRUPTED; in xfs_bmapi_read()
3893 return -EFSCORRUPTED; in xfs_bmapi_read()
3896 return -EIO; in xfs_bmapi_read()
3900 error = xfs_iread_extents(NULL, ip, whichfork); in xfs_bmapi_read()
3904 if (!xfs_iext_lookup_extent(ip, ifp, bno, &icur, &got)) in xfs_bmapi_read()
3915 mval->br_startoff = bno; in xfs_bmapi_read()
3916 mval->br_startblock = HOLESTARTBLOCK; in xfs_bmapi_read()
3917 mval->br_blockcount = in xfs_bmapi_read()
3918 XFS_FILBLKS_MIN(len, got.br_startoff - bno); in xfs_bmapi_read()
3919 mval->br_state = XFS_EXT_NORM; in xfs_bmapi_read()
3920 bno += mval->br_blockcount; in xfs_bmapi_read()
3921 len -= mval->br_blockcount; in xfs_bmapi_read()
3945 * global pool and the extent inserted into the inode in-core extent tree.
3958 struct xfs_inode *ip, in xfs_bmapi_reserve_delalloc() argument
3967 struct xfs_mount *mp = ip->i_mount; in xfs_bmapi_reserve_delalloc()
3968 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmapi_reserve_delalloc()
3980 alen = XFS_FILBLKS_MIN(alen, got->br_startoff - aoff); in xfs_bmapi_reserve_delalloc()
3982 prealloc = alen - len; in xfs_bmapi_reserve_delalloc()
3987 xfs_extlen_t extsz = xfs_get_cowextsz_hint(ip); in xfs_bmapi_reserve_delalloc()
3998 * Make a transaction-less quota reservation for delayed allocation in xfs_bmapi_reserve_delalloc()
4002 error = xfs_quota_reserve_blkres(ip, alen); in xfs_bmapi_reserve_delalloc()
4010 indlen = (xfs_extlen_t)xfs_bmap_worst_indlen(ip, alen); in xfs_bmapi_reserve_delalloc()
4013 error = xfs_mod_fdblocks(mp, -((int64_t)alen), false); in xfs_bmapi_reserve_delalloc()
4017 error = xfs_mod_fdblocks(mp, -((int64_t)indlen), false); in xfs_bmapi_reserve_delalloc()
4022 ip->i_delayed_blks += alen; in xfs_bmapi_reserve_delalloc()
4023 xfs_mod_delalloc(ip->i_mount, alen + indlen); in xfs_bmapi_reserve_delalloc()
4025 got->br_startoff = aoff; in xfs_bmapi_reserve_delalloc()
4026 got->br_startblock = nullstartblock(indlen); in xfs_bmapi_reserve_delalloc()
4027 got->br_blockcount = alen; in xfs_bmapi_reserve_delalloc()
4028 got->br_state = XFS_EXT_NORM; in xfs_bmapi_reserve_delalloc()
4030 xfs_bmap_add_extent_hole_delay(ip, whichfork, icur, got); in xfs_bmapi_reserve_delalloc()
4038 xfs_inode_set_eofblocks_tag(ip); in xfs_bmapi_reserve_delalloc()
4040 xfs_inode_set_cowblocks_tag(ip); in xfs_bmapi_reserve_delalloc()
4048 xfs_quota_unreserve_blkres(ip, alen); in xfs_bmapi_reserve_delalloc()
4056 struct xfs_mount *mp = bma->ip->i_mount; in xfs_bmap_alloc_userdata()
4057 int whichfork = xfs_bmapi_whichfork(bma->flags); in xfs_bmap_alloc_userdata()
4066 bma->datatype = XFS_ALLOC_NOBUSY; in xfs_bmap_alloc_userdata()
4068 bma->datatype |= XFS_ALLOC_USERDATA; in xfs_bmap_alloc_userdata()
4069 if (bma->offset == 0) in xfs_bmap_alloc_userdata()
4070 bma->datatype |= XFS_ALLOC_INITIAL_USER_DATA; in xfs_bmap_alloc_userdata()
4072 if (mp->m_dalign && bma->length >= mp->m_dalign) { in xfs_bmap_alloc_userdata()
4078 if (XFS_IS_REALTIME_INODE(bma->ip)) in xfs_bmap_alloc_userdata()
4093 struct xfs_mount *mp = bma->ip->i_mount; in xfs_bmapi_allocate()
4094 int whichfork = xfs_bmapi_whichfork(bma->flags); in xfs_bmapi_allocate()
4095 struct xfs_ifork *ifp = xfs_ifork_ptr(bma->ip, whichfork); in xfs_bmapi_allocate()
4099 ASSERT(bma->length > 0); in xfs_bmapi_allocate()
4105 if (bma->wasdel) { in xfs_bmapi_allocate()
4106 bma->length = (xfs_extlen_t)bma->got.br_blockcount; in xfs_bmapi_allocate()
4107 bma->offset = bma->got.br_startoff; in xfs_bmapi_allocate()
4108 if (!xfs_iext_peek_prev_extent(ifp, &bma->icur, &bma->prev)) in xfs_bmapi_allocate()
4109 bma->prev.br_startoff = NULLFILEOFF; in xfs_bmapi_allocate()
4111 bma->length = XFS_FILBLKS_MIN(bma->length, XFS_MAX_BMBT_EXTLEN); in xfs_bmapi_allocate()
4112 if (!bma->eof) in xfs_bmapi_allocate()
4113 bma->length = XFS_FILBLKS_MIN(bma->length, in xfs_bmapi_allocate()
4114 bma->got.br_startoff - bma->offset); in xfs_bmapi_allocate()
4117 if (bma->flags & XFS_BMAPI_CONTIG) in xfs_bmapi_allocate()
4118 bma->minlen = bma->length; in xfs_bmapi_allocate()
4120 bma->minlen = 1; in xfs_bmapi_allocate()
4122 if (bma->flags & XFS_BMAPI_METADATA) { in xfs_bmapi_allocate()
4131 if (error || bma->blkno == NULLFSBLOCK) in xfs_bmapi_allocate()
4134 if (bma->flags & XFS_BMAPI_ZERO) { in xfs_bmapi_allocate()
4135 error = xfs_zero_extent(bma->ip, bma->blkno, bma->length); in xfs_bmapi_allocate()
4140 if (ifp->if_format == XFS_DINODE_FMT_BTREE && !bma->cur) in xfs_bmapi_allocate()
4141 bma->cur = xfs_bmbt_init_cursor(mp, bma->tp, bma->ip, whichfork); in xfs_bmapi_allocate()
4146 bma->nallocs++; in xfs_bmapi_allocate()
4148 if (bma->cur) in xfs_bmapi_allocate()
4149 bma->cur->bc_ino.flags = in xfs_bmapi_allocate()
4150 bma->wasdel ? XFS_BTCUR_BMBT_WASDEL : 0; in xfs_bmapi_allocate()
4152 bma->got.br_startoff = bma->offset; in xfs_bmapi_allocate()
4153 bma->got.br_startblock = bma->blkno; in xfs_bmapi_allocate()
4154 bma->got.br_blockcount = bma->length; in xfs_bmapi_allocate()
4155 bma->got.br_state = XFS_EXT_NORM; in xfs_bmapi_allocate()
4157 if (bma->flags & XFS_BMAPI_PREALLOC) in xfs_bmapi_allocate()
4158 bma->got.br_state = XFS_EXT_UNWRITTEN; in xfs_bmapi_allocate()
4160 if (bma->wasdel) in xfs_bmapi_allocate()
4163 error = xfs_bmap_add_extent_hole_real(bma->tp, bma->ip, in xfs_bmapi_allocate()
4164 whichfork, &bma->icur, &bma->cur, &bma->got, in xfs_bmapi_allocate()
4165 &bma->logflags, bma->flags); in xfs_bmapi_allocate()
4167 bma->logflags |= tmp_logflags; in xfs_bmapi_allocate()
4176 xfs_iext_get_extent(ifp, &bma->icur, &bma->got); in xfs_bmapi_allocate()
4178 ASSERT(bma->got.br_startoff <= bma->offset); in xfs_bmapi_allocate()
4179 ASSERT(bma->got.br_startoff + bma->got.br_blockcount >= in xfs_bmapi_allocate()
4180 bma->offset + bma->length); in xfs_bmapi_allocate()
4181 ASSERT(bma->got.br_state == XFS_EXT_NORM || in xfs_bmapi_allocate()
4182 bma->got.br_state == XFS_EXT_UNWRITTEN); in xfs_bmapi_allocate()
4194 struct xfs_ifork *ifp = xfs_ifork_ptr(bma->ip, whichfork); in xfs_bmapi_convert_unwritten()
4198 /* check if we need to do unwritten->real conversion */ in xfs_bmapi_convert_unwritten()
4199 if (mval->br_state == XFS_EXT_UNWRITTEN && in xfs_bmapi_convert_unwritten()
4203 /* check if we need to do real->unwritten conversion */ in xfs_bmapi_convert_unwritten()
4204 if (mval->br_state == XFS_EXT_NORM && in xfs_bmapi_convert_unwritten()
4212 ASSERT(mval->br_blockcount <= len); in xfs_bmapi_convert_unwritten()
4213 if (ifp->if_format == XFS_DINODE_FMT_BTREE && !bma->cur) { in xfs_bmapi_convert_unwritten()
4214 bma->cur = xfs_bmbt_init_cursor(bma->ip->i_mount, bma->tp, in xfs_bmapi_convert_unwritten()
4215 bma->ip, whichfork); in xfs_bmapi_convert_unwritten()
4217 mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) in xfs_bmapi_convert_unwritten()
4225 error = xfs_zero_extent(bma->ip, mval->br_startblock, in xfs_bmapi_convert_unwritten()
4226 mval->br_blockcount); in xfs_bmapi_convert_unwritten()
4231 error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, whichfork, in xfs_bmapi_convert_unwritten()
4232 &bma->icur, &bma->cur, mval, &tmp_logflags); in xfs_bmapi_convert_unwritten()
4242 * any on-disk updates to make, so we don't need to log anything. in xfs_bmapi_convert_unwritten()
4245 bma->logflags |= tmp_logflags | XFS_ILOG_CORE; in xfs_bmapi_convert_unwritten()
4254 xfs_iext_get_extent(ifp, &bma->icur, &bma->got); in xfs_bmapi_convert_unwritten()
4260 if (mval->br_blockcount < len) in xfs_bmapi_convert_unwritten()
4261 return -EAGAIN; in xfs_bmapi_convert_unwritten()
4268 struct xfs_inode *ip, in xfs_bmapi_minleft() argument
4271 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, fork); in xfs_bmapi_minleft()
4273 if (tp && tp->t_highest_agno != NULLAGNUMBER) in xfs_bmapi_minleft()
4275 if (ifp->if_format != XFS_DINODE_FMT_BTREE) in xfs_bmapi_minleft()
4277 return be16_to_cpu(ifp->if_broot->bb_level) + 1; in xfs_bmapi_minleft()
4292 struct xfs_ifork *ifp = xfs_ifork_ptr(bma->ip, whichfork); in xfs_bmapi_finish()
4294 if ((bma->logflags & xfs_ilog_fext(whichfork)) && in xfs_bmapi_finish()
4295 ifp->if_format != XFS_DINODE_FMT_EXTENTS) in xfs_bmapi_finish()
4296 bma->logflags &= ~xfs_ilog_fext(whichfork); in xfs_bmapi_finish()
4297 else if ((bma->logflags & xfs_ilog_fbroot(whichfork)) && in xfs_bmapi_finish()
4298 ifp->if_format != XFS_DINODE_FMT_BTREE) in xfs_bmapi_finish()
4299 bma->logflags &= ~xfs_ilog_fbroot(whichfork); in xfs_bmapi_finish()
4301 if (bma->logflags) in xfs_bmapi_finish()
4302 xfs_trans_log_inode(bma->tp, bma->ip, bma->logflags); in xfs_bmapi_finish()
4303 if (bma->cur) in xfs_bmapi_finish()
4304 xfs_btree_del_cursor(bma->cur, error); in xfs_bmapi_finish()
4316 struct xfs_inode *ip, /* incore inode */ in xfs_bmapi_write() argument
4326 .ip = ip, in xfs_bmapi_write()
4329 struct xfs_mount *mp = ip->i_mount; in xfs_bmapi_write()
4331 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmapi_write()
4336 xfs_fileoff_t obno; /* old block number (offset) */ in xfs_bmapi_write()
4339 xfs_fileoff_t orig_bno; /* original block number value */ in xfs_bmapi_write()
4356 ASSERT(ifp->if_format != XFS_DINODE_FMT_LOCAL); in xfs_bmapi_write()
4357 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); in xfs_bmapi_write()
4364 * we can allocate unwritten extents or pre-zero allocated blocks, in xfs_bmapi_write()
4374 return -EFSCORRUPTED; in xfs_bmapi_write()
4378 return -EIO; in xfs_bmapi_write()
4382 error = xfs_iread_extents(tp, ip, whichfork); in xfs_bmapi_write()
4386 if (!xfs_iext_lookup_extent(ip, ifp, bno, &bma.icur, &bma.got)) in xfs_bmapi_write()
4390 bma.minleft = xfs_bmapi_minleft(tp, ip, whichfork); in xfs_bmapi_write()
4429 * check for 32-bit overflows and handle them here. in xfs_bmapi_write()
4459 if (error == -EAGAIN) in xfs_bmapi_write()
4482 error = xfs_bmap_btree_to_extents(tp, ip, bma.cur, &bma.logflags, in xfs_bmapi_write()
4487 ASSERT(ifp->if_format != XFS_DINODE_FMT_BTREE || in xfs_bmapi_write()
4488 ifp->if_nextents > XFS_IFORK_MAXEXT(ip, whichfork)); in xfs_bmapi_write()
4506 struct xfs_inode *ip, in xfs_bmapi_convert_delalloc() argument
4512 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmapi_convert_delalloc()
4513 struct xfs_mount *mp = ip->i_mount; in xfs_bmapi_convert_delalloc()
4527 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, 0, 0, in xfs_bmapi_convert_delalloc()
4532 xfs_ilock(ip, XFS_ILOCK_EXCL); in xfs_bmapi_convert_delalloc()
4533 xfs_trans_ijoin(tp, ip, 0); in xfs_bmapi_convert_delalloc()
4535 error = xfs_iext_count_may_overflow(ip, whichfork, in xfs_bmapi_convert_delalloc()
4537 if (error == -EFBIG) in xfs_bmapi_convert_delalloc()
4538 error = xfs_iext_count_upgrade(tp, ip, in xfs_bmapi_convert_delalloc()
4543 if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &bma.icur, &bma.got) || in xfs_bmapi_convert_delalloc()
4551 error = -EAGAIN; in xfs_bmapi_convert_delalloc()
4560 xfs_bmbt_to_iomap(ip, iomap, &bma.got, 0, flags, in xfs_bmapi_convert_delalloc()
4561 xfs_iomap_inode_sequence(ip, flags)); in xfs_bmapi_convert_delalloc()
4562 *seq = READ_ONCE(ifp->if_seq); in xfs_bmapi_convert_delalloc()
4567 bma.ip = ip; in xfs_bmapi_convert_delalloc()
4572 bma.minleft = xfs_bmapi_minleft(tp, ip, whichfork); in xfs_bmapi_convert_delalloc()
4598 error = -ENOSPC; in xfs_bmapi_convert_delalloc()
4601 error = -EFSCORRUPTED; in xfs_bmapi_convert_delalloc()
4602 if (WARN_ON_ONCE(!xfs_valid_startblock(ip, bma.got.br_startblock))) in xfs_bmapi_convert_delalloc()
4609 xfs_bmbt_to_iomap(ip, iomap, &bma.got, 0, flags, in xfs_bmapi_convert_delalloc()
4610 xfs_iomap_inode_sequence(ip, flags)); in xfs_bmapi_convert_delalloc()
4611 *seq = READ_ONCE(ifp->if_seq); in xfs_bmapi_convert_delalloc()
4616 error = xfs_bmap_btree_to_extents(tp, ip, bma.cur, &bma.logflags, in xfs_bmapi_convert_delalloc()
4623 xfs_iunlock(ip, XFS_ILOCK_EXCL); in xfs_bmapi_convert_delalloc()
4630 xfs_iunlock(ip, XFS_ILOCK_EXCL); in xfs_bmapi_convert_delalloc()
4637 struct xfs_inode *ip, in xfs_bmapi_remap() argument
4643 struct xfs_mount *mp = ip->i_mount; in xfs_bmapi_remap()
4651 ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmapi_remap()
4654 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); in xfs_bmapi_remap()
4662 return -EFSCORRUPTED; in xfs_bmapi_remap()
4666 return -EIO; in xfs_bmapi_remap()
4668 error = xfs_iread_extents(tp, ip, whichfork); in xfs_bmapi_remap()
4672 if (xfs_iext_lookup_extent(ip, ifp, bno, &icur, &got)) { in xfs_bmapi_remap()
4675 ASSERT(got.br_startoff - bno >= len); in xfs_bmapi_remap()
4678 ip->i_nblocks += len; in xfs_bmapi_remap()
4679 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); in xfs_bmapi_remap()
4681 if (ifp->if_format == XFS_DINODE_FMT_BTREE) { in xfs_bmapi_remap()
4682 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); in xfs_bmapi_remap()
4683 cur->bc_ino.flags = 0; in xfs_bmapi_remap()
4694 error = xfs_bmap_add_extent_hole_real(tp, ip, whichfork, &icur, in xfs_bmapi_remap()
4699 error = xfs_bmap_btree_to_extents(tp, ip, cur, &logflags, whichfork); in xfs_bmapi_remap()
4702 if (ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS) in xfs_bmapi_remap()
4704 else if (ip->i_df.if_format != XFS_DINODE_FMT_BTREE) in xfs_bmapi_remap()
4708 xfs_trans_log_inode(tp, ip, logflags); in xfs_bmapi_remap()
4744 stolen = XFS_FILBLKS_MIN(nres - ores, avail); in xfs_bmap_split_indlen()
4770 * is zero, we want to make sure that one gets a block first. The loop in xfs_bmap_split_indlen()
4771 * below starts with len1, so hand len2 a block right off the bat if it in xfs_bmap_split_indlen()
4774 ores -= (len1 + len2); in xfs_bmap_split_indlen()
4775 ASSERT((*indlen1 - len1) + (*indlen2 - len2) >= ores); in xfs_bmap_split_indlen()
4778 ores--; in xfs_bmap_split_indlen()
4783 ores--; in xfs_bmap_split_indlen()
4789 ores--; in xfs_bmap_split_indlen()
4801 struct xfs_inode *ip, in xfs_bmap_del_extent_delay() argument
4807 struct xfs_mount *mp = ip->i_mount; in xfs_bmap_del_extent_delay()
4808 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmap_del_extent_delay()
4819 isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); in xfs_bmap_del_extent_delay()
4820 del_endoff = del->br_startoff + del->br_blockcount; in xfs_bmap_del_extent_delay()
4821 got_endoff = got->br_startoff + got->br_blockcount; in xfs_bmap_del_extent_delay()
4822 da_old = startblockval(got->br_startblock); in xfs_bmap_del_extent_delay()
4825 ASSERT(del->br_blockcount > 0); in xfs_bmap_del_extent_delay()
4826 ASSERT(got->br_startoff <= del->br_startoff); in xfs_bmap_del_extent_delay()
4830 uint64_t rtexts = del->br_blockcount; in xfs_bmap_del_extent_delay()
4832 do_div(rtexts, mp->m_sb.sb_rextsize); in xfs_bmap_del_extent_delay()
4839 * indirect block accounting. in xfs_bmap_del_extent_delay()
4842 error = xfs_quota_unreserve_blkres(ip, del->br_blockcount); in xfs_bmap_del_extent_delay()
4845 ip->i_delayed_blks -= del->br_blockcount; in xfs_bmap_del_extent_delay()
4847 if (got->br_startoff == del->br_startoff) in xfs_bmap_del_extent_delay()
4857 xfs_iext_remove(ip, icur, state); in xfs_bmap_del_extent_delay()
4864 got->br_startoff = del_endoff; in xfs_bmap_del_extent_delay()
4865 got->br_blockcount -= del->br_blockcount; in xfs_bmap_del_extent_delay()
4866 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, in xfs_bmap_del_extent_delay()
4867 got->br_blockcount), da_old); in xfs_bmap_del_extent_delay()
4868 got->br_startblock = nullstartblock((int)da_new); in xfs_bmap_del_extent_delay()
4869 xfs_iext_update_extent(ip, state, icur, got); in xfs_bmap_del_extent_delay()
4875 got->br_blockcount = got->br_blockcount - del->br_blockcount; in xfs_bmap_del_extent_delay()
4876 da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, in xfs_bmap_del_extent_delay()
4877 got->br_blockcount), da_old); in xfs_bmap_del_extent_delay()
4878 got->br_startblock = nullstartblock((int)da_new); in xfs_bmap_del_extent_delay()
4879 xfs_iext_update_extent(ip, state, icur, got); in xfs_bmap_del_extent_delay()
4891 got->br_blockcount = del->br_startoff - got->br_startoff; in xfs_bmap_del_extent_delay()
4892 got_indlen = xfs_bmap_worst_indlen(ip, got->br_blockcount); in xfs_bmap_del_extent_delay()
4894 new.br_blockcount = got_endoff - del_endoff; in xfs_bmap_del_extent_delay()
4895 new_indlen = xfs_bmap_worst_indlen(ip, new.br_blockcount); in xfs_bmap_del_extent_delay()
4899 del->br_blockcount); in xfs_bmap_del_extent_delay()
4901 got->br_startblock = nullstartblock((int)got_indlen); in xfs_bmap_del_extent_delay()
4904 new.br_state = got->br_state; in xfs_bmap_del_extent_delay()
4907 xfs_iext_update_extent(ip, state, icur, got); in xfs_bmap_del_extent_delay()
4909 xfs_iext_insert(ip, icur, &new, state); in xfs_bmap_del_extent_delay()
4911 da_new = got_indlen + new_indlen - stolen; in xfs_bmap_del_extent_delay()
4912 del->br_blockcount -= stolen; in xfs_bmap_del_extent_delay()
4917 da_diff = da_old - da_new; in xfs_bmap_del_extent_delay()
4919 da_diff += del->br_blockcount; in xfs_bmap_del_extent_delay()
4922 xfs_mod_delalloc(mp, -da_diff); in xfs_bmap_del_extent_delay()
4929 struct xfs_inode *ip, in xfs_bmap_del_extent_cow() argument
4934 struct xfs_mount *mp = ip->i_mount; in xfs_bmap_del_extent_cow()
4935 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, XFS_COW_FORK); in xfs_bmap_del_extent_cow()
4942 del_endoff = del->br_startoff + del->br_blockcount; in xfs_bmap_del_extent_cow()
4943 got_endoff = got->br_startoff + got->br_blockcount; in xfs_bmap_del_extent_cow()
4945 ASSERT(del->br_blockcount > 0); in xfs_bmap_del_extent_cow()
4946 ASSERT(got->br_startoff <= del->br_startoff); in xfs_bmap_del_extent_cow()
4948 ASSERT(!isnullstartblock(got->br_startblock)); in xfs_bmap_del_extent_cow()
4950 if (got->br_startoff == del->br_startoff) in xfs_bmap_del_extent_cow()
4960 xfs_iext_remove(ip, icur, state); in xfs_bmap_del_extent_cow()
4967 got->br_startoff = del_endoff; in xfs_bmap_del_extent_cow()
4968 got->br_blockcount -= del->br_blockcount; in xfs_bmap_del_extent_cow()
4969 got->br_startblock = del->br_startblock + del->br_blockcount; in xfs_bmap_del_extent_cow()
4970 xfs_iext_update_extent(ip, state, icur, got); in xfs_bmap_del_extent_cow()
4976 got->br_blockcount -= del->br_blockcount; in xfs_bmap_del_extent_cow()
4977 xfs_iext_update_extent(ip, state, icur, got); in xfs_bmap_del_extent_cow()
4983 got->br_blockcount = del->br_startoff - got->br_startoff; in xfs_bmap_del_extent_cow()
4986 new.br_blockcount = got_endoff - del_endoff; in xfs_bmap_del_extent_cow()
4987 new.br_state = got->br_state; in xfs_bmap_del_extent_cow()
4988 new.br_startblock = del->br_startblock + del->br_blockcount; in xfs_bmap_del_extent_cow()
4990 xfs_iext_update_extent(ip, state, icur, got); in xfs_bmap_del_extent_cow()
4992 xfs_iext_insert(ip, icur, &new, state); in xfs_bmap_del_extent_cow()
4995 ip->i_delayed_blks -= del->br_blockcount; in xfs_bmap_del_extent_cow()
5004 xfs_inode_t *ip, /* incore inode pointer */ in xfs_bmap_del_extent_real() argument
5013 xfs_fsblock_t del_endblock=0; /* first block past del */ in xfs_bmap_del_extent_real()
5023 xfs_filblks_t nblks; /* quota/sb block count */ in xfs_bmap_del_extent_real()
5030 mp = ip->i_mount; in xfs_bmap_del_extent_real()
5033 ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmap_del_extent_real()
5034 ASSERT(del->br_blockcount > 0); in xfs_bmap_del_extent_real()
5036 ASSERT(got.br_startoff <= del->br_startoff); in xfs_bmap_del_extent_real()
5037 del_endoff = del->br_startoff + del->br_blockcount; in xfs_bmap_del_extent_real()
5045 * If it's the case where the directory code is running with no block in xfs_bmap_del_extent_real()
5046 * reservation, and the deleted block is in the middle of its extent, in xfs_bmap_del_extent_real()
5052 if (tp->t_blk_res == 0 && in xfs_bmap_del_extent_real()
5053 ifp->if_format == XFS_DINODE_FMT_EXTENTS && in xfs_bmap_del_extent_real()
5054 ifp->if_nextents >= XFS_IFORK_MAXEXT(ip, whichfork) && in xfs_bmap_del_extent_real()
5055 del->br_startoff > got.br_startoff && del_endoff < got_endoff) in xfs_bmap_del_extent_real()
5056 return -ENOSPC; in xfs_bmap_del_extent_real()
5059 if (whichfork == XFS_DATA_FORK && XFS_IS_REALTIME_INODE(ip)) { in xfs_bmap_del_extent_real()
5061 error = xfs_rtfree_blocks(tp, del->br_startblock, in xfs_bmap_del_extent_real()
5062 del->br_blockcount); in xfs_bmap_del_extent_real()
5073 nblks = del->br_blockcount; in xfs_bmap_del_extent_real()
5075 del_endblock = del->br_startblock + del->br_blockcount; in xfs_bmap_del_extent_real()
5081 error = -EFSCORRUPTED; in xfs_bmap_del_extent_real()
5086 if (got.br_startoff == del->br_startoff) in xfs_bmap_del_extent_real()
5096 xfs_iext_remove(ip, icur, state); in xfs_bmap_del_extent_real()
5098 ifp->if_nextents--; in xfs_bmap_del_extent_real()
5108 error = -EFSCORRUPTED; in xfs_bmap_del_extent_real()
5118 got.br_blockcount -= del->br_blockcount; in xfs_bmap_del_extent_real()
5119 xfs_iext_update_extent(ip, state, icur, &got); in xfs_bmap_del_extent_real()
5132 got.br_blockcount -= del->br_blockcount; in xfs_bmap_del_extent_real()
5133 xfs_iext_update_extent(ip, state, icur, &got); in xfs_bmap_del_extent_real()
5149 got.br_blockcount = del->br_startoff - got.br_startoff; in xfs_bmap_del_extent_real()
5150 xfs_iext_update_extent(ip, state, icur, &got); in xfs_bmap_del_extent_real()
5153 new.br_blockcount = got_endoff - del_endoff; in xfs_bmap_del_extent_real()
5165 cur->bc_rec.b = new; in xfs_bmap_del_extent_real()
5167 if (error && error != -ENOSPC) in xfs_bmap_del_extent_real()
5170 * If get no-space back from btree insert, it tried a in xfs_bmap_del_extent_real()
5171 * split, and we have a zero block reservation. Fix up in xfs_bmap_del_extent_real()
5174 if (error == -ENOSPC) { in xfs_bmap_del_extent_real()
5183 error = -EFSCORRUPTED; in xfs_bmap_del_extent_real()
5197 xfs_iext_update_extent(ip, state, icur, &old); in xfs_bmap_del_extent_real()
5199 error = -ENOSPC; in xfs_bmap_del_extent_real()
5203 error = -EFSCORRUPTED; in xfs_bmap_del_extent_real()
5209 ifp->if_nextents++; in xfs_bmap_del_extent_real()
5211 xfs_iext_insert(ip, icur, &new, state); in xfs_bmap_del_extent_real()
5216 xfs_rmap_unmap_extent(tp, ip, whichfork, del); in xfs_bmap_del_extent_real()
5222 if (xfs_is_reflink_inode(ip) && whichfork == XFS_DATA_FORK) { in xfs_bmap_del_extent_real()
5225 error = __xfs_free_extent_later(tp, del->br_startblock, in xfs_bmap_del_extent_real()
5226 del->br_blockcount, NULL, in xfs_bmap_del_extent_real()
5229 del->br_state == XFS_EXT_UNWRITTEN)); in xfs_bmap_del_extent_real()
5239 ip->i_nblocks -= nblks; in xfs_bmap_del_extent_real()
5244 xfs_trans_mod_dquot_byino(tp, ip, qfield, (long)-nblks); in xfs_bmap_del_extent_real()
5254 * that value. If not all extents in the block range can be removed then
5260 struct xfs_inode *ip, /* incore inode */ in __xfs_bunmapi() argument
5275 struct xfs_mount *mp = ip->i_mount; in __xfs_bunmapi()
5285 trace_xfs_bunmap(ip, start, len, flags, _RET_IP_); in __xfs_bunmapi()
5289 ifp = xfs_ifork_ptr(ip, whichfork); in __xfs_bunmapi()
5291 return -EFSCORRUPTED; in __xfs_bunmapi()
5293 return -EIO; in __xfs_bunmapi()
5295 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); in __xfs_bunmapi()
5299 error = xfs_iread_extents(tp, ip, whichfork); in __xfs_bunmapi()
5308 isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); in __xfs_bunmapi()
5311 if (!xfs_iext_lookup_extent_before(ip, ifp, &end, &icur, &got)) { in __xfs_bunmapi()
5315 end--; in __xfs_bunmapi()
5318 if (ifp->if_format == XFS_DINODE_FMT_BTREE) { in __xfs_bunmapi()
5319 ASSERT(ifp->if_format == XFS_DINODE_FMT_BTREE); in __xfs_bunmapi()
5320 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); in __xfs_bunmapi()
5321 cur->bc_ino.flags = 0; in __xfs_bunmapi()
5329 xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL|XFS_ILOCK_RTBITMAP); in __xfs_bunmapi()
5330 xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL); in __xfs_bunmapi()
5331 xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL|XFS_ILOCK_RTSUM); in __xfs_bunmapi()
5332 xfs_trans_ijoin(tp, mp->m_rsumip, XFS_ILOCK_EXCL); in __xfs_bunmapi()
5336 while (end != (xfs_fileoff_t)-1 && end >= start && in __xfs_bunmapi()
5348 * Is the last block of this extent before the range in __xfs_bunmapi()
5352 got.br_startoff + got.br_blockcount - 1); in __xfs_bunmapi()
5364 del.br_blockcount -= start - got.br_startoff; in __xfs_bunmapi()
5366 del.br_startblock += start - got.br_startoff; in __xfs_bunmapi()
5369 del.br_blockcount = end + 1 - del.br_startoff; in __xfs_bunmapi()
5375 div_u64_rem(sum, mp->m_sb.sb_rextsize, &mod); in __xfs_bunmapi()
5390 end -= mod > del.br_blockcount ? in __xfs_bunmapi()
5404 ASSERT(tp->t_blk_res > 0); in __xfs_bunmapi()
5410 del.br_startoff += del.br_blockcount - mod; in __xfs_bunmapi()
5411 del.br_startblock += del.br_blockcount - mod; in __xfs_bunmapi()
5415 error = xfs_bmap_add_extent_unwritten_real(tp, ip, in __xfs_bunmapi()
5422 div_u64_rem(del.br_startblock, mp->m_sb.sb_rextsize, &mod); in __xfs_bunmapi()
5424 xfs_extlen_t off = mp->m_sb.sb_rextsize - mod; in __xfs_bunmapi()
5432 del.br_blockcount -= off; in __xfs_bunmapi()
5437 tp->t_blk_res == 0)) { in __xfs_bunmapi()
5443 end -= del.br_blockcount; in __xfs_bunmapi()
5467 del.br_startoff - mod, in __xfs_bunmapi()
5469 mod = unwrite_start - prev.br_startoff; in __xfs_bunmapi()
5472 prev.br_blockcount -= mod; in __xfs_bunmapi()
5475 ip, whichfork, &icur, &cur, in __xfs_bunmapi()
5484 ip, whichfork, &icur, &cur, in __xfs_bunmapi()
5494 error = xfs_bmap_del_extent_delay(ip, whichfork, &icur, in __xfs_bunmapi()
5497 error = xfs_bmap_del_extent_real(ip, tp, &icur, cur, in __xfs_bunmapi()
5506 end = del.br_startoff - 1; in __xfs_bunmapi()
5511 if (end != (xfs_fileoff_t)-1 && end >= start) { in __xfs_bunmapi()
5521 if (done || end == (xfs_fileoff_t)-1 || end < start) in __xfs_bunmapi()
5524 *rlen = end - start + 1; in __xfs_bunmapi()
5529 if (xfs_bmap_needs_btree(ip, whichfork)) { in __xfs_bunmapi()
5531 error = xfs_bmap_extents_to_btree(tp, ip, &cur, 0, in __xfs_bunmapi()
5535 error = xfs_bmap_btree_to_extents(tp, ip, cur, &logflags, in __xfs_bunmapi()
5545 ifp->if_format != XFS_DINODE_FMT_EXTENTS) in __xfs_bunmapi()
5548 ifp->if_format != XFS_DINODE_FMT_BTREE) in __xfs_bunmapi()
5555 xfs_trans_log_inode(tp, ip, logflags); in __xfs_bunmapi()
5558 cur->bc_ino.allocated = 0; in __xfs_bunmapi()
5568 struct xfs_inode *ip, in xfs_bunmapi() argument
5577 error = __xfs_bunmapi(tp, ip, bno, &len, flags, nexts); in xfs_bunmapi()
5594 startoff = got->br_startoff - shift; in xfs_bmse_can_merge()
5597 * The extent, once shifted, must be adjacent in-file and on-disk with in xfs_bmse_can_merge()
5600 if ((left->br_startoff + left->br_blockcount != startoff) || in xfs_bmse_can_merge()
5601 (left->br_startblock + left->br_blockcount != got->br_startblock) || in xfs_bmse_can_merge()
5602 (left->br_state != got->br_state) || in xfs_bmse_can_merge()
5603 (left->br_blockcount + got->br_blockcount > XFS_MAX_BMBT_EXTLEN)) in xfs_bmse_can_merge()
5615 * This function assumes the caller has verified a shift-by-merge is possible
5621 struct xfs_inode *ip, in xfs_bmse_merge() argument
5630 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmse_merge()
5634 struct xfs_mount *mp = ip->i_mount; in xfs_bmse_merge()
5636 blockcount = left->br_blockcount + got->br_blockcount; in xfs_bmse_merge()
5638 ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); in xfs_bmse_merge()
5639 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); in xfs_bmse_merge()
5646 * Update the on-disk extent count, the btree if necessary and log the in xfs_bmse_merge()
5649 ifp->if_nextents--; in xfs_bmse_merge()
5661 return -EFSCORRUPTED; in xfs_bmse_merge()
5667 return -EFSCORRUPTED; in xfs_bmse_merge()
5674 return -EFSCORRUPTED; in xfs_bmse_merge()
5681 error = xfs_bmap_btree_to_extents(tp, ip, cur, logflags, whichfork); in xfs_bmse_merge()
5686 xfs_iext_remove(ip, icur, 0); in xfs_bmse_merge()
5688 xfs_iext_update_extent(ip, xfs_bmap_fork_to_state(whichfork), icur, in xfs_bmse_merge()
5692 xfs_rmap_unmap_extent(tp, ip, whichfork, got); in xfs_bmse_merge()
5694 new.br_startoff = left->br_startoff + left->br_blockcount; in xfs_bmse_merge()
5695 xfs_rmap_map_extent(tp, ip, whichfork, &new); in xfs_bmse_merge()
5702 struct xfs_inode *ip, in xfs_bmap_shift_update_extent() argument
5710 struct xfs_mount *mp = ip->i_mount; in xfs_bmap_shift_update_extent()
5716 got->br_startoff = startoff; in xfs_bmap_shift_update_extent()
5723 return -EFSCORRUPTED; in xfs_bmap_shift_update_extent()
5732 xfs_iext_update_extent(ip, xfs_bmap_fork_to_state(whichfork), icur, in xfs_bmap_shift_update_extent()
5736 xfs_rmap_unmap_extent(tp, ip, whichfork, &prev); in xfs_bmap_shift_update_extent()
5737 xfs_rmap_map_extent(tp, ip, whichfork, got); in xfs_bmap_shift_update_extent()
5744 struct xfs_inode *ip, in xfs_bmap_collapse_extents() argument
5750 struct xfs_mount *mp = ip->i_mount; in xfs_bmap_collapse_extents()
5751 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmap_collapse_extents()
5761 return -EFSCORRUPTED; in xfs_bmap_collapse_extents()
5765 return -EIO; in xfs_bmap_collapse_extents()
5767 ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL)); in xfs_bmap_collapse_extents()
5769 error = xfs_iread_extents(tp, ip, whichfork); in xfs_bmap_collapse_extents()
5773 if (ifp->if_format == XFS_DINODE_FMT_BTREE) { in xfs_bmap_collapse_extents()
5774 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); in xfs_bmap_collapse_extents()
5775 cur->bc_ino.flags = 0; in xfs_bmap_collapse_extents()
5778 if (!xfs_iext_lookup_extent(ip, ifp, *next_fsb, &icur, &got)) { in xfs_bmap_collapse_extents()
5783 error = -EFSCORRUPTED; in xfs_bmap_collapse_extents()
5787 new_startoff = got.br_startoff - offset_shift_fsb; in xfs_bmap_collapse_extents()
5790 error = -EINVAL; in xfs_bmap_collapse_extents()
5795 error = xfs_bmse_merge(tp, ip, whichfork, in xfs_bmap_collapse_extents()
5804 error = -EINVAL; in xfs_bmap_collapse_extents()
5809 error = xfs_bmap_shift_update_extent(tp, ip, whichfork, &icur, &got, in xfs_bmap_collapse_extents()
5825 xfs_trans_log_inode(tp, ip, logflags); in xfs_bmap_collapse_extents()
5829 /* Make sure we won't be right-shifting an extent past the maximum bound. */
5832 struct xfs_inode *ip, in xfs_bmap_can_insert_extents() argument
5840 ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); in xfs_bmap_can_insert_extents()
5842 if (xfs_is_shutdown(ip->i_mount)) in xfs_bmap_can_insert_extents()
5843 return -EIO; in xfs_bmap_can_insert_extents()
5845 xfs_ilock(ip, XFS_ILOCK_EXCL); in xfs_bmap_can_insert_extents()
5846 error = xfs_bmap_last_extent(NULL, ip, XFS_DATA_FORK, &got, &is_empty); in xfs_bmap_can_insert_extents()
5849 error = -EINVAL; in xfs_bmap_can_insert_extents()
5850 xfs_iunlock(ip, XFS_ILOCK_EXCL); in xfs_bmap_can_insert_extents()
5858 struct xfs_inode *ip, in xfs_bmap_insert_extents() argument
5865 struct xfs_mount *mp = ip->i_mount; in xfs_bmap_insert_extents()
5866 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmap_insert_extents()
5876 return -EFSCORRUPTED; in xfs_bmap_insert_extents()
5880 return -EIO; in xfs_bmap_insert_extents()
5882 ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL)); in xfs_bmap_insert_extents()
5884 error = xfs_iread_extents(tp, ip, whichfork); in xfs_bmap_insert_extents()
5888 if (ifp->if_format == XFS_DINODE_FMT_BTREE) { in xfs_bmap_insert_extents()
5889 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); in xfs_bmap_insert_extents()
5890 cur->bc_ino.flags = 0; in xfs_bmap_insert_extents()
5901 if (!xfs_iext_lookup_extent(ip, ifp, *next_fsb, &icur, &got)) { in xfs_bmap_insert_extents()
5907 error = -EFSCORRUPTED; in xfs_bmap_insert_extents()
5912 error = -EFSCORRUPTED; in xfs_bmap_insert_extents()
5919 error = -EINVAL; in xfs_bmap_insert_extents()
5933 error = xfs_bmap_shift_update_extent(tp, ip, whichfork, &icur, &got, in xfs_bmap_insert_extents()
5949 xfs_trans_log_inode(tp, ip, logflags); in xfs_bmap_insert_extents()
5954 * Splits an extent into two extents at split_fsb block such that it is the
5955 * first block of the current_ext. @ext is a target extent to be split.
5956 * @split_fsb is a block where the extents is split. If split_fsb lies in a
5957 * hole or the first block of extents, just return 0.
5962 struct xfs_inode *ip, in xfs_bmap_split_extent() argument
5966 struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); in xfs_bmap_split_extent()
5970 struct xfs_mount *mp = ip->i_mount; in xfs_bmap_split_extent()
5971 xfs_fsblock_t gotblkcnt; /* new block count for got */ in xfs_bmap_split_extent()
5979 return -EFSCORRUPTED; in xfs_bmap_split_extent()
5983 return -EIO; in xfs_bmap_split_extent()
5986 error = xfs_iread_extents(tp, ip, whichfork); in xfs_bmap_split_extent()
5993 if (!xfs_iext_lookup_extent(ip, ifp, split_fsb, &icur, &got) || in xfs_bmap_split_extent()
5997 gotblkcnt = split_fsb - got.br_startoff; in xfs_bmap_split_extent()
6000 new.br_blockcount = got.br_blockcount - gotblkcnt; in xfs_bmap_split_extent()
6003 if (ifp->if_format == XFS_DINODE_FMT_BTREE) { in xfs_bmap_split_extent()
6004 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); in xfs_bmap_split_extent()
6005 cur->bc_ino.flags = 0; in xfs_bmap_split_extent()
6010 error = -EFSCORRUPTED; in xfs_bmap_split_extent()
6016 xfs_iext_update_extent(ip, xfs_bmap_fork_to_state(whichfork), &icur, in xfs_bmap_split_extent()
6029 xfs_iext_insert(ip, &icur, &new, 0); in xfs_bmap_split_extent()
6030 ifp->if_nextents++; in xfs_bmap_split_extent()
6037 error = -EFSCORRUPTED; in xfs_bmap_split_extent()
6044 error = -EFSCORRUPTED; in xfs_bmap_split_extent()
6052 if (xfs_bmap_needs_btree(ip, whichfork)) { in xfs_bmap_split_extent()
6056 error = xfs_bmap_extents_to_btree(tp, ip, &cur, 0, in xfs_bmap_split_extent()
6063 cur->bc_ino.allocated = 0; in xfs_bmap_split_extent()
6068 xfs_trans_log_inode(tp, ip, logflags); in xfs_bmap_split_extent()
6077 return bmap->br_startblock != HOLESTARTBLOCK && in xfs_bmap_is_update_needed()
6078 bmap->br_startblock != DELAYSTARTBLOCK; in xfs_bmap_is_update_needed()
6086 struct xfs_inode *ip, in __xfs_bmap_add() argument
6092 trace_xfs_bmap_defer(tp->t_mountp, in __xfs_bmap_add()
6093 XFS_FSB_TO_AGNO(tp->t_mountp, bmap->br_startblock), in __xfs_bmap_add()
6095 XFS_FSB_TO_AGBNO(tp->t_mountp, bmap->br_startblock), in __xfs_bmap_add()
6096 ip->i_ino, whichfork, in __xfs_bmap_add()
6097 bmap->br_startoff, in __xfs_bmap_add()
6098 bmap->br_blockcount, in __xfs_bmap_add()
6099 bmap->br_state); in __xfs_bmap_add()
6102 INIT_LIST_HEAD(&bi->bi_list); in __xfs_bmap_add()
6103 bi->bi_type = type; in __xfs_bmap_add()
6104 bi->bi_owner = ip; in __xfs_bmap_add()
6105 bi->bi_whichfork = whichfork; in __xfs_bmap_add()
6106 bi->bi_bmap = *bmap; in __xfs_bmap_add()
6108 xfs_bmap_update_get_group(tp->t_mountp, bi); in __xfs_bmap_add()
6109 xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_BMAP, &bi->bi_list); in __xfs_bmap_add()
6117 struct xfs_inode *ip, in xfs_bmap_map_extent() argument
6123 __xfs_bmap_add(tp, XFS_BMAP_MAP, ip, XFS_DATA_FORK, PREV); in xfs_bmap_map_extent()
6130 struct xfs_inode *ip, in xfs_bmap_unmap_extent() argument
6136 __xfs_bmap_add(tp, XFS_BMAP_UNMAP, ip, XFS_DATA_FORK, PREV); in xfs_bmap_unmap_extent()
6148 struct xfs_bmbt_irec *bmap = &bi->bi_bmap; in xfs_bmap_finish_one()
6151 ASSERT(tp->t_highest_agno == NULLAGNUMBER); in xfs_bmap_finish_one()
6153 trace_xfs_bmap_deferred(tp->t_mountp, in xfs_bmap_finish_one()
6154 XFS_FSB_TO_AGNO(tp->t_mountp, bmap->br_startblock), in xfs_bmap_finish_one()
6155 bi->bi_type, in xfs_bmap_finish_one()
6156 XFS_FSB_TO_AGBNO(tp->t_mountp, bmap->br_startblock), in xfs_bmap_finish_one()
6157 bi->bi_owner->i_ino, bi->bi_whichfork, in xfs_bmap_finish_one()
6158 bmap->br_startoff, bmap->br_blockcount, in xfs_bmap_finish_one()
6159 bmap->br_state); in xfs_bmap_finish_one()
6161 if (WARN_ON_ONCE(bi->bi_whichfork != XFS_DATA_FORK)) in xfs_bmap_finish_one()
6162 return -EFSCORRUPTED; in xfs_bmap_finish_one()
6164 if (XFS_TEST_ERROR(false, tp->t_mountp, in xfs_bmap_finish_one()
6166 return -EIO; in xfs_bmap_finish_one()
6168 switch (bi->bi_type) { in xfs_bmap_finish_one()
6170 error = xfs_bmapi_remap(tp, bi->bi_owner, bmap->br_startoff, in xfs_bmap_finish_one()
6171 bmap->br_blockcount, bmap->br_startblock, 0); in xfs_bmap_finish_one()
6172 bmap->br_blockcount = 0; in xfs_bmap_finish_one()
6175 error = __xfs_bunmapi(tp, bi->bi_owner, bmap->br_startoff, in xfs_bmap_finish_one()
6176 &bmap->br_blockcount, XFS_BMAPI_REMAP, 1); in xfs_bmap_finish_one()
6180 error = -EFSCORRUPTED; in xfs_bmap_finish_one()
6189 struct xfs_inode *ip, in xfs_bmap_validate_extent() argument
6193 struct xfs_mount *mp = ip->i_mount; in xfs_bmap_validate_extent()
6195 if (!xfs_verify_fileext(mp, irec->br_startoff, irec->br_blockcount)) in xfs_bmap_validate_extent()
6198 if (XFS_IS_REALTIME_INODE(ip) && whichfork == XFS_DATA_FORK) { in xfs_bmap_validate_extent()
6199 if (!xfs_verify_rtext(mp, irec->br_startblock, in xfs_bmap_validate_extent()
6200 irec->br_blockcount)) in xfs_bmap_validate_extent()
6203 if (!xfs_verify_fsbext(mp, irec->br_startblock, in xfs_bmap_validate_extent()
6204 irec->br_blockcount)) in xfs_bmap_validate_extent()
6207 if (irec->br_state != XFS_EXT_NORM && whichfork != XFS_DATA_FORK) in xfs_bmap_validate_extent()
6219 return xfs_bmap_intent_cache != NULL ? 0 : -ENOMEM; in xfs_bmap_intent_init_cache()