Loading fs/xfs/libxfs/xfs_bmap.c +65 −169 Original line number Diff line number Diff line Loading @@ -1370,97 +1370,6 @@ xfs_bmap_read_extents( return -EFSCORRUPTED; } /* * Search the extent records for the entry containing block bno. * If bno lies in a hole, point to the next entry. If bno lies * past eof, *eofp will be set, and *prevp will contain the last * entry (null if none). Else, *lastxp will be set to the index * of the found entry; *gotp will contain the entry. */ STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */ xfs_bmap_search_multi_extents( xfs_ifork_t *ifp, /* inode fork pointer */ xfs_fileoff_t bno, /* block number searched for */ int *eofp, /* out: end of file found */ xfs_extnum_t *lastxp, /* out: last extent index */ xfs_bmbt_irec_t *gotp, /* out: extent entry found */ xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ { xfs_bmbt_rec_host_t *ep; /* extent record pointer */ xfs_extnum_t lastx; /* last extent index */ /* * Initialize the extent entry structure to catch access to * uninitialized br_startblock field. */ gotp->br_startoff = 0xffa5a5a5a5a5a5a5LL; gotp->br_blockcount = 0xa55a5a5a5a5a5a5aLL; gotp->br_state = XFS_EXT_INVALID; gotp->br_startblock = 0xffffa5a5a5a5a5a5LL; prevp->br_startoff = NULLFILEOFF; ep = xfs_iext_bno_to_ext(ifp, bno, &lastx); if (lastx > 0) { xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), prevp); } if (lastx < xfs_iext_count(ifp)) { xfs_bmbt_get_all(ep, gotp); *eofp = 0; } else { if (lastx > 0) { *gotp = *prevp; } *eofp = 1; ep = NULL; } *lastxp = lastx; return ep; } /* * Search the extents list for the inode, for the extent containing bno. * If bno lies in a hole, point to the next entry. If bno lies past eof, * *eofp will be set, and *prevp will contain the last entry (null if none). * Else, *lastxp will be set to the index of the found * entry; *gotp will contain the entry. */ xfs_bmbt_rec_host_t * /* pointer to found extent entry */ xfs_bmap_search_extents( xfs_inode_t *ip, /* incore inode pointer */ xfs_fileoff_t bno, /* block number searched for */ int fork, /* data or attr fork */ int *eofp, /* out: end of file found */ xfs_extnum_t *lastxp, /* out: last extent index */ xfs_bmbt_irec_t *gotp, /* out: extent entry found */ xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ { xfs_ifork_t *ifp; /* inode fork pointer */ xfs_bmbt_rec_host_t *ep; /* extent record pointer */ XFS_STATS_INC(ip->i_mount, xs_look_exlist); ifp = XFS_IFORK_PTR(ip, fork); ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp); if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) && !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) { xfs_alert_tag(ip->i_mount, XFS_PTAG_FSBLOCK_ZERO, "Access to block zero in inode %llu " "start_block: %llx start_off: %llx " "blkcnt: %llx extent-state: %x lastx: %x", (unsigned long long)ip->i_ino, (unsigned long long)gotp->br_startblock, (unsigned long long)gotp->br_startoff, (unsigned long long)gotp->br_blockcount, gotp->br_state, *lastxp); *lastxp = NULLEXTNUM; *eofp = 1; return NULL; } return ep; } /* * Returns the file-relative block number of the first unused block(s) * in the file with at least "len" logically contiguous blocks free. Loading Loading @@ -1523,44 +1432,44 @@ xfs_bmap_first_unused( */ int /* error */ xfs_bmap_last_before( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode */ struct xfs_trans *tp, /* transaction pointer */ struct xfs_inode *ip, /* incore inode */ xfs_fileoff_t *last_block, /* last block */ int whichfork) /* data or attr fork */ { xfs_fileoff_t bno; /* input file offset */ int eof; /* hit end of file */ xfs_bmbt_rec_host_t *ep; /* pointer to last extent */ int error; /* error return value */ xfs_bmbt_irec_t got; /* current extent value */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_extnum_t lastx; /* last extent used */ xfs_bmbt_irec_t prev; /* previous extent value */ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); struct xfs_bmbt_irec got; xfs_extnum_t idx; int error; if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) return -EIO; if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { switch (XFS_IFORK_FORMAT(ip, whichfork)) { case XFS_DINODE_FMT_LOCAL: *last_block = 0; return 0; case XFS_DINODE_FMT_BTREE: case XFS_DINODE_FMT_EXTENTS: break; default: return -EIO; } ifp = XFS_IFORK_PTR(ip, whichfork); if (!(ifp->if_flags & XFS_IFEXTENTS) && (error = xfs_iread_extents(tp, ip, whichfork))) if (!(ifp->if_flags & XFS_IFEXTENTS)) { error = xfs_iread_extents(tp, ip, whichfork); if (error) return error; bno = *last_block - 1; ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev); if (eof || xfs_bmbt_get_startoff(ep) > bno) { if (prev.br_startoff == NULLFILEOFF) *last_block = 0; else *last_block = prev.br_startoff + prev.br_blockcount; } /* * Otherwise *last_block is already the right answer. */ if (xfs_iext_lookup_extent(ip, ifp, *last_block - 1, &idx, &got)) { if (got.br_startoff <= *last_block - 1) return 0; } if (xfs_iext_get_extent(ifp, idx - 1, &got)) { *last_block = got.br_startoff + got.br_blockcount; return 0; } *last_block = 0; return 0; } Loading Loading @@ -4145,12 +4054,11 @@ xfs_bmapi_read( struct xfs_mount *mp = ip->i_mount; struct xfs_ifork *ifp; struct xfs_bmbt_irec got; struct xfs_bmbt_irec prev; xfs_fileoff_t obno; xfs_fileoff_t end; xfs_extnum_t lastx; xfs_extnum_t idx; int error; int eof; bool eof = false; int n = 0; int whichfork = xfs_bmapi_whichfork(flags); Loading Loading @@ -4190,7 +4098,8 @@ xfs_bmapi_read( return error; } xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev); if (!xfs_iext_lookup_extent(ip, ifp, bno, &idx, &got)) eof = true; end = bno + len; obno = bno; Loading Loading @@ -4221,10 +4130,8 @@ xfs_bmapi_read( break; /* Else go on to the next record. */ if (++lastx < xfs_iext_count(ifp)) xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx), &got); else eof = 1; if (!xfs_iext_get_extent(ifp, ++idx, &got)) eof = true; } *nmap = n; return 0; Loading @@ -4237,7 +4144,6 @@ xfs_bmapi_reserve_delalloc( xfs_fileoff_t aoff, xfs_filblks_t len, struct xfs_bmbt_irec *got, struct xfs_bmbt_irec *prev, xfs_extnum_t *lastx, int eof) { Loading @@ -4259,7 +4165,12 @@ xfs_bmapi_reserve_delalloc( else extsz = xfs_get_extsz_hint(ip); if (extsz) { error = xfs_bmap_extsize_align(mp, got, prev, extsz, rt, eof, struct xfs_bmbt_irec prev; if (!xfs_iext_get_extent(ifp, *lastx - 1, &prev)) prev.br_startoff = NULLFILEOFF; error = xfs_bmap_extsize_align(mp, got, &prev, extsz, rt, eof, 1, 0, &aoff, &alen); ASSERT(!error); } Loading Loading @@ -4349,7 +4260,7 @@ xfs_bmapi_allocate( if (bma->wasdel) { bma->length = (xfs_extlen_t)bma->got.br_blockcount; bma->offset = bma->got.br_startoff; if (bma->idx != NULLEXTNUM && bma->idx) { if (bma->idx) { xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx - 1), &bma->prev); } Loading Loading @@ -4563,7 +4474,7 @@ xfs_bmapi_write( struct xfs_ifork *ifp; struct xfs_bmalloca bma = { NULL }; /* args for xfs_bmap_alloc */ xfs_fileoff_t end; /* end of mapped file region */ int eof; /* after the end of extents */ bool eof = false; /* after the end of extents */ int error; /* error return */ int n; /* current extent index */ xfs_fileoff_t obno; /* old block number (offset) */ Loading Loading @@ -4641,12 +4552,14 @@ xfs_bmapi_write( goto error0; } xfs_bmap_search_extents(ip, bno, whichfork, &eof, &bma.idx, &bma.got, &bma.prev); n = 0; end = bno + len; obno = bno; if (!xfs_iext_lookup_extent(ip, ifp, bno, &bma.idx, &bma.got)) eof = true; if (!xfs_iext_get_extent(ifp, bma.idx - 1, &bma.prev)) bma.prev.br_startoff = NULLFILEOFF; bma.tp = tp; bma.ip = ip; bma.total = total; Loading Loading @@ -4733,11 +4646,8 @@ xfs_bmapi_write( /* Else go on to the next record. */ bma.prev = bma.got; if (++bma.idx < xfs_iext_count(ifp)) { xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma.idx), &bma.got); } else eof = 1; if (!xfs_iext_get_extent(ifp, ++bma.idx, &bma.got)) eof = true; } *nmap = n; Loading Loading @@ -5436,8 +5346,6 @@ __xfs_bunmapi( { xfs_btree_cur_t *cur; /* bmap btree cursor */ xfs_bmbt_irec_t del; /* extent being deleted */ int eof; /* is deleting at eof */ xfs_bmbt_rec_host_t *ep; /* extent record pointer */ int error; /* error return value */ xfs_extnum_t extno; /* extent number in list */ xfs_bmbt_irec_t got; /* current extent record */ Loading @@ -5447,7 +5355,6 @@ __xfs_bunmapi( int logflags; /* transaction logging flags */ xfs_extlen_t mod; /* rt extent offset */ xfs_mount_t *mp; /* mount structure */ xfs_bmbt_irec_t prev; /* previous extent record */ xfs_fileoff_t start; /* first file offset deleted */ int tmp_logflags; /* partial logging flags */ int wasdel; /* was a delayed alloc extent */ Loading Loading @@ -5486,18 +5393,17 @@ __xfs_bunmapi( isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); start = bno; bno = start + len - 1; ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev); /* * Check to see if the given block number is past the end of the * file, back up to the last block if so... */ if (eof) { ep = xfs_iext_get_ext(ifp, --lastx); xfs_bmbt_get_all(ep, &got); if (!xfs_iext_lookup_extent(ip, ifp, bno, &lastx, &got)) { ASSERT(lastx > 0); xfs_iext_get_extent(ifp, --lastx, &got); bno = got.br_startoff + got.br_blockcount - 1; } logflags = 0; if (ifp->if_flags & XFS_IFBROOT) { ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); Loading Loading @@ -5528,8 +5434,7 @@ __xfs_bunmapi( if (got.br_startoff > bno) { if (--lastx < 0) break; ep = xfs_iext_get_ext(ifp, lastx); xfs_bmbt_get_all(ep, &got); xfs_iext_get_extent(ifp, lastx, &got); } /* * Is the last block of this extent before the range Loading @@ -5543,7 +5448,6 @@ __xfs_bunmapi( * Then deal with the (possibly delayed) allocated space * we found. */ ASSERT(ep != NULL); del = got; wasdel = isnullstartblock(del.br_startblock); if (got.br_startoff < start) { Loading Loading @@ -5624,15 +5528,12 @@ __xfs_bunmapi( */ ASSERT(bno >= del.br_blockcount); bno -= del.br_blockcount; if (got.br_startoff > bno) { if (--lastx >= 0) { ep = xfs_iext_get_ext(ifp, lastx); xfs_bmbt_get_all(ep, &got); } } if (got.br_startoff > bno && --lastx >= 0) xfs_iext_get_extent(ifp, lastx, &got); continue; } else if (del.br_state == XFS_EXT_UNWRITTEN) { struct xfs_bmbt_irec prev; /* * This one is already unwritten. * It must have a written left neighbor. Loading @@ -5640,8 +5541,7 @@ __xfs_bunmapi( * try again. */ ASSERT(lastx > 0); xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), &prev); xfs_iext_get_extent(ifp, lastx - 1, &prev); ASSERT(prev.br_state == XFS_EXT_NORM); ASSERT(!isnullstartblock(prev.br_startblock)); ASSERT(del.br_startblock == Loading Loading @@ -5739,13 +5639,9 @@ __xfs_bunmapi( */ if (bno != (xfs_fileoff_t)-1 && bno >= start) { if (lastx >= 0) { ep = xfs_iext_get_ext(ifp, lastx); if (xfs_bmbt_get_startoff(ep) > bno) { if (--lastx >= 0) ep = xfs_iext_get_ext(ifp, lastx); } xfs_bmbt_get_all(ep, &got); xfs_iext_get_extent(ifp, lastx, &got); if (got.br_startoff > bno && --lastx >= 0) xfs_iext_get_extent(ifp, lastx, &got); } extno++; } Loading fs/xfs/libxfs/xfs_bmap.h +1 −6 Original line number Diff line number Diff line Loading @@ -237,14 +237,9 @@ int xfs_bmap_shift_extents(struct xfs_trans *tp, struct xfs_inode *ip, struct xfs_defer_ops *dfops, enum shift_direction direction, int num_exts); int xfs_bmap_split_extent(struct xfs_inode *ip, xfs_fileoff_t split_offset); struct xfs_bmbt_rec_host * xfs_bmap_search_extents(struct xfs_inode *ip, xfs_fileoff_t bno, int fork, int *eofp, xfs_extnum_t *lastxp, struct xfs_bmbt_irec *gotp, struct xfs_bmbt_irec *prevp); int xfs_bmapi_reserve_delalloc(struct xfs_inode *ip, int whichfork, xfs_fileoff_t aoff, xfs_filblks_t len, struct xfs_bmbt_irec *got, struct xfs_bmbt_irec *prev, xfs_extnum_t *lastx, int eof); struct xfs_bmbt_irec *got, xfs_extnum_t *lastx, int eof); enum xfs_bmap_intent_type { XFS_BMAP_MAP = 1, Loading fs/xfs/libxfs/xfs_inode_fork.c +46 −0 Original line number Diff line number Diff line Loading @@ -2003,3 +2003,49 @@ xfs_ifork_init_cow( ip->i_cformat = XFS_DINODE_FMT_EXTENTS; ip->i_cnextents = 0; } /* * Lookup the extent covering bno. * * If there is an extent covering bno return the extent index, and store the * expanded extent structure in *gotp, and the extent index in *idx. * If there is no extent covering bno, but there is an extent after it (e.g. * it lies in a hole) return that extent in *gotp and its index in *idx * instead. * If bno is beyond the last extent return false, and return the index after * the last valid index in *idxp. */ bool xfs_iext_lookup_extent( struct xfs_inode *ip, struct xfs_ifork *ifp, xfs_fileoff_t bno, xfs_extnum_t *idxp, struct xfs_bmbt_irec *gotp) { struct xfs_bmbt_rec_host *ep; XFS_STATS_INC(ip->i_mount, xs_look_exlist); ep = xfs_iext_bno_to_ext(ifp, bno, idxp); if (!ep) return false; xfs_bmbt_get_all(ep, gotp); return true; } /* * Return true if there is an extent at index idx, and return the expanded * extent structure at idx in that case. Else return false. */ bool xfs_iext_get_extent( struct xfs_ifork *ifp, xfs_extnum_t idx, struct xfs_bmbt_irec *gotp) { if (idx < 0 || idx >= xfs_iext_count(ifp)) return false; xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), gotp); return true; } fs/xfs/libxfs/xfs_inode_fork.h +6 −0 Original line number Diff line number Diff line Loading @@ -182,6 +182,12 @@ void xfs_iext_irec_compact_pages(struct xfs_ifork *); void xfs_iext_irec_compact_full(struct xfs_ifork *); void xfs_iext_irec_update_extoffs(struct xfs_ifork *, int, int); bool xfs_iext_lookup_extent(struct xfs_inode *ip, struct xfs_ifork *ifp, xfs_fileoff_t bno, xfs_extnum_t *idxp, struct xfs_bmbt_irec *gotp); bool xfs_iext_get_extent(struct xfs_ifork *ifp, xfs_extnum_t idx, struct xfs_bmbt_irec *gotp); extern struct kmem_zone *xfs_ifork_zone; extern void xfs_ifork_init_cow(struct xfs_inode *ip); Loading fs/xfs/libxfs/xfs_types.h +0 −1 Original line number Diff line number Diff line Loading @@ -57,7 +57,6 @@ typedef __int64_t xfs_sfiloff_t; /* signed block number in a file */ #define NULLAGBLOCK ((xfs_agblock_t)-1) #define NULLAGNUMBER ((xfs_agnumber_t)-1) #define NULLEXTNUM ((xfs_extnum_t)-1) #define NULLCOMMITLSN ((xfs_lsn_t)-1) Loading Loading
fs/xfs/libxfs/xfs_bmap.c +65 −169 Original line number Diff line number Diff line Loading @@ -1370,97 +1370,6 @@ xfs_bmap_read_extents( return -EFSCORRUPTED; } /* * Search the extent records for the entry containing block bno. * If bno lies in a hole, point to the next entry. If bno lies * past eof, *eofp will be set, and *prevp will contain the last * entry (null if none). Else, *lastxp will be set to the index * of the found entry; *gotp will contain the entry. */ STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */ xfs_bmap_search_multi_extents( xfs_ifork_t *ifp, /* inode fork pointer */ xfs_fileoff_t bno, /* block number searched for */ int *eofp, /* out: end of file found */ xfs_extnum_t *lastxp, /* out: last extent index */ xfs_bmbt_irec_t *gotp, /* out: extent entry found */ xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ { xfs_bmbt_rec_host_t *ep; /* extent record pointer */ xfs_extnum_t lastx; /* last extent index */ /* * Initialize the extent entry structure to catch access to * uninitialized br_startblock field. */ gotp->br_startoff = 0xffa5a5a5a5a5a5a5LL; gotp->br_blockcount = 0xa55a5a5a5a5a5a5aLL; gotp->br_state = XFS_EXT_INVALID; gotp->br_startblock = 0xffffa5a5a5a5a5a5LL; prevp->br_startoff = NULLFILEOFF; ep = xfs_iext_bno_to_ext(ifp, bno, &lastx); if (lastx > 0) { xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), prevp); } if (lastx < xfs_iext_count(ifp)) { xfs_bmbt_get_all(ep, gotp); *eofp = 0; } else { if (lastx > 0) { *gotp = *prevp; } *eofp = 1; ep = NULL; } *lastxp = lastx; return ep; } /* * Search the extents list for the inode, for the extent containing bno. * If bno lies in a hole, point to the next entry. If bno lies past eof, * *eofp will be set, and *prevp will contain the last entry (null if none). * Else, *lastxp will be set to the index of the found * entry; *gotp will contain the entry. */ xfs_bmbt_rec_host_t * /* pointer to found extent entry */ xfs_bmap_search_extents( xfs_inode_t *ip, /* incore inode pointer */ xfs_fileoff_t bno, /* block number searched for */ int fork, /* data or attr fork */ int *eofp, /* out: end of file found */ xfs_extnum_t *lastxp, /* out: last extent index */ xfs_bmbt_irec_t *gotp, /* out: extent entry found */ xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ { xfs_ifork_t *ifp; /* inode fork pointer */ xfs_bmbt_rec_host_t *ep; /* extent record pointer */ XFS_STATS_INC(ip->i_mount, xs_look_exlist); ifp = XFS_IFORK_PTR(ip, fork); ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp); if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) && !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) { xfs_alert_tag(ip->i_mount, XFS_PTAG_FSBLOCK_ZERO, "Access to block zero in inode %llu " "start_block: %llx start_off: %llx " "blkcnt: %llx extent-state: %x lastx: %x", (unsigned long long)ip->i_ino, (unsigned long long)gotp->br_startblock, (unsigned long long)gotp->br_startoff, (unsigned long long)gotp->br_blockcount, gotp->br_state, *lastxp); *lastxp = NULLEXTNUM; *eofp = 1; return NULL; } return ep; } /* * Returns the file-relative block number of the first unused block(s) * in the file with at least "len" logically contiguous blocks free. Loading Loading @@ -1523,44 +1432,44 @@ xfs_bmap_first_unused( */ int /* error */ xfs_bmap_last_before( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode */ struct xfs_trans *tp, /* transaction pointer */ struct xfs_inode *ip, /* incore inode */ xfs_fileoff_t *last_block, /* last block */ int whichfork) /* data or attr fork */ { xfs_fileoff_t bno; /* input file offset */ int eof; /* hit end of file */ xfs_bmbt_rec_host_t *ep; /* pointer to last extent */ int error; /* error return value */ xfs_bmbt_irec_t got; /* current extent value */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_extnum_t lastx; /* last extent used */ xfs_bmbt_irec_t prev; /* previous extent value */ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); struct xfs_bmbt_irec got; xfs_extnum_t idx; int error; if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) return -EIO; if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { switch (XFS_IFORK_FORMAT(ip, whichfork)) { case XFS_DINODE_FMT_LOCAL: *last_block = 0; return 0; case XFS_DINODE_FMT_BTREE: case XFS_DINODE_FMT_EXTENTS: break; default: return -EIO; } ifp = XFS_IFORK_PTR(ip, whichfork); if (!(ifp->if_flags & XFS_IFEXTENTS) && (error = xfs_iread_extents(tp, ip, whichfork))) if (!(ifp->if_flags & XFS_IFEXTENTS)) { error = xfs_iread_extents(tp, ip, whichfork); if (error) return error; bno = *last_block - 1; ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev); if (eof || xfs_bmbt_get_startoff(ep) > bno) { if (prev.br_startoff == NULLFILEOFF) *last_block = 0; else *last_block = prev.br_startoff + prev.br_blockcount; } /* * Otherwise *last_block is already the right answer. */ if (xfs_iext_lookup_extent(ip, ifp, *last_block - 1, &idx, &got)) { if (got.br_startoff <= *last_block - 1) return 0; } if (xfs_iext_get_extent(ifp, idx - 1, &got)) { *last_block = got.br_startoff + got.br_blockcount; return 0; } *last_block = 0; return 0; } Loading Loading @@ -4145,12 +4054,11 @@ xfs_bmapi_read( struct xfs_mount *mp = ip->i_mount; struct xfs_ifork *ifp; struct xfs_bmbt_irec got; struct xfs_bmbt_irec prev; xfs_fileoff_t obno; xfs_fileoff_t end; xfs_extnum_t lastx; xfs_extnum_t idx; int error; int eof; bool eof = false; int n = 0; int whichfork = xfs_bmapi_whichfork(flags); Loading Loading @@ -4190,7 +4098,8 @@ xfs_bmapi_read( return error; } xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev); if (!xfs_iext_lookup_extent(ip, ifp, bno, &idx, &got)) eof = true; end = bno + len; obno = bno; Loading Loading @@ -4221,10 +4130,8 @@ xfs_bmapi_read( break; /* Else go on to the next record. */ if (++lastx < xfs_iext_count(ifp)) xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx), &got); else eof = 1; if (!xfs_iext_get_extent(ifp, ++idx, &got)) eof = true; } *nmap = n; return 0; Loading @@ -4237,7 +4144,6 @@ xfs_bmapi_reserve_delalloc( xfs_fileoff_t aoff, xfs_filblks_t len, struct xfs_bmbt_irec *got, struct xfs_bmbt_irec *prev, xfs_extnum_t *lastx, int eof) { Loading @@ -4259,7 +4165,12 @@ xfs_bmapi_reserve_delalloc( else extsz = xfs_get_extsz_hint(ip); if (extsz) { error = xfs_bmap_extsize_align(mp, got, prev, extsz, rt, eof, struct xfs_bmbt_irec prev; if (!xfs_iext_get_extent(ifp, *lastx - 1, &prev)) prev.br_startoff = NULLFILEOFF; error = xfs_bmap_extsize_align(mp, got, &prev, extsz, rt, eof, 1, 0, &aoff, &alen); ASSERT(!error); } Loading Loading @@ -4349,7 +4260,7 @@ xfs_bmapi_allocate( if (bma->wasdel) { bma->length = (xfs_extlen_t)bma->got.br_blockcount; bma->offset = bma->got.br_startoff; if (bma->idx != NULLEXTNUM && bma->idx) { if (bma->idx) { xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma->idx - 1), &bma->prev); } Loading Loading @@ -4563,7 +4474,7 @@ xfs_bmapi_write( struct xfs_ifork *ifp; struct xfs_bmalloca bma = { NULL }; /* args for xfs_bmap_alloc */ xfs_fileoff_t end; /* end of mapped file region */ int eof; /* after the end of extents */ bool eof = false; /* after the end of extents */ int error; /* error return */ int n; /* current extent index */ xfs_fileoff_t obno; /* old block number (offset) */ Loading Loading @@ -4641,12 +4552,14 @@ xfs_bmapi_write( goto error0; } xfs_bmap_search_extents(ip, bno, whichfork, &eof, &bma.idx, &bma.got, &bma.prev); n = 0; end = bno + len; obno = bno; if (!xfs_iext_lookup_extent(ip, ifp, bno, &bma.idx, &bma.got)) eof = true; if (!xfs_iext_get_extent(ifp, bma.idx - 1, &bma.prev)) bma.prev.br_startoff = NULLFILEOFF; bma.tp = tp; bma.ip = ip; bma.total = total; Loading Loading @@ -4733,11 +4646,8 @@ xfs_bmapi_write( /* Else go on to the next record. */ bma.prev = bma.got; if (++bma.idx < xfs_iext_count(ifp)) { xfs_bmbt_get_all(xfs_iext_get_ext(ifp, bma.idx), &bma.got); } else eof = 1; if (!xfs_iext_get_extent(ifp, ++bma.idx, &bma.got)) eof = true; } *nmap = n; Loading Loading @@ -5436,8 +5346,6 @@ __xfs_bunmapi( { xfs_btree_cur_t *cur; /* bmap btree cursor */ xfs_bmbt_irec_t del; /* extent being deleted */ int eof; /* is deleting at eof */ xfs_bmbt_rec_host_t *ep; /* extent record pointer */ int error; /* error return value */ xfs_extnum_t extno; /* extent number in list */ xfs_bmbt_irec_t got; /* current extent record */ Loading @@ -5447,7 +5355,6 @@ __xfs_bunmapi( int logflags; /* transaction logging flags */ xfs_extlen_t mod; /* rt extent offset */ xfs_mount_t *mp; /* mount structure */ xfs_bmbt_irec_t prev; /* previous extent record */ xfs_fileoff_t start; /* first file offset deleted */ int tmp_logflags; /* partial logging flags */ int wasdel; /* was a delayed alloc extent */ Loading Loading @@ -5486,18 +5393,17 @@ __xfs_bunmapi( isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); start = bno; bno = start + len - 1; ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev); /* * Check to see if the given block number is past the end of the * file, back up to the last block if so... */ if (eof) { ep = xfs_iext_get_ext(ifp, --lastx); xfs_bmbt_get_all(ep, &got); if (!xfs_iext_lookup_extent(ip, ifp, bno, &lastx, &got)) { ASSERT(lastx > 0); xfs_iext_get_extent(ifp, --lastx, &got); bno = got.br_startoff + got.br_blockcount - 1; } logflags = 0; if (ifp->if_flags & XFS_IFBROOT) { ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); Loading Loading @@ -5528,8 +5434,7 @@ __xfs_bunmapi( if (got.br_startoff > bno) { if (--lastx < 0) break; ep = xfs_iext_get_ext(ifp, lastx); xfs_bmbt_get_all(ep, &got); xfs_iext_get_extent(ifp, lastx, &got); } /* * Is the last block of this extent before the range Loading @@ -5543,7 +5448,6 @@ __xfs_bunmapi( * Then deal with the (possibly delayed) allocated space * we found. */ ASSERT(ep != NULL); del = got; wasdel = isnullstartblock(del.br_startblock); if (got.br_startoff < start) { Loading Loading @@ -5624,15 +5528,12 @@ __xfs_bunmapi( */ ASSERT(bno >= del.br_blockcount); bno -= del.br_blockcount; if (got.br_startoff > bno) { if (--lastx >= 0) { ep = xfs_iext_get_ext(ifp, lastx); xfs_bmbt_get_all(ep, &got); } } if (got.br_startoff > bno && --lastx >= 0) xfs_iext_get_extent(ifp, lastx, &got); continue; } else if (del.br_state == XFS_EXT_UNWRITTEN) { struct xfs_bmbt_irec prev; /* * This one is already unwritten. * It must have a written left neighbor. Loading @@ -5640,8 +5541,7 @@ __xfs_bunmapi( * try again. */ ASSERT(lastx > 0); xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), &prev); xfs_iext_get_extent(ifp, lastx - 1, &prev); ASSERT(prev.br_state == XFS_EXT_NORM); ASSERT(!isnullstartblock(prev.br_startblock)); ASSERT(del.br_startblock == Loading Loading @@ -5739,13 +5639,9 @@ __xfs_bunmapi( */ if (bno != (xfs_fileoff_t)-1 && bno >= start) { if (lastx >= 0) { ep = xfs_iext_get_ext(ifp, lastx); if (xfs_bmbt_get_startoff(ep) > bno) { if (--lastx >= 0) ep = xfs_iext_get_ext(ifp, lastx); } xfs_bmbt_get_all(ep, &got); xfs_iext_get_extent(ifp, lastx, &got); if (got.br_startoff > bno && --lastx >= 0) xfs_iext_get_extent(ifp, lastx, &got); } extno++; } Loading
fs/xfs/libxfs/xfs_bmap.h +1 −6 Original line number Diff line number Diff line Loading @@ -237,14 +237,9 @@ int xfs_bmap_shift_extents(struct xfs_trans *tp, struct xfs_inode *ip, struct xfs_defer_ops *dfops, enum shift_direction direction, int num_exts); int xfs_bmap_split_extent(struct xfs_inode *ip, xfs_fileoff_t split_offset); struct xfs_bmbt_rec_host * xfs_bmap_search_extents(struct xfs_inode *ip, xfs_fileoff_t bno, int fork, int *eofp, xfs_extnum_t *lastxp, struct xfs_bmbt_irec *gotp, struct xfs_bmbt_irec *prevp); int xfs_bmapi_reserve_delalloc(struct xfs_inode *ip, int whichfork, xfs_fileoff_t aoff, xfs_filblks_t len, struct xfs_bmbt_irec *got, struct xfs_bmbt_irec *prev, xfs_extnum_t *lastx, int eof); struct xfs_bmbt_irec *got, xfs_extnum_t *lastx, int eof); enum xfs_bmap_intent_type { XFS_BMAP_MAP = 1, Loading
fs/xfs/libxfs/xfs_inode_fork.c +46 −0 Original line number Diff line number Diff line Loading @@ -2003,3 +2003,49 @@ xfs_ifork_init_cow( ip->i_cformat = XFS_DINODE_FMT_EXTENTS; ip->i_cnextents = 0; } /* * Lookup the extent covering bno. * * If there is an extent covering bno return the extent index, and store the * expanded extent structure in *gotp, and the extent index in *idx. * If there is no extent covering bno, but there is an extent after it (e.g. * it lies in a hole) return that extent in *gotp and its index in *idx * instead. * If bno is beyond the last extent return false, and return the index after * the last valid index in *idxp. */ bool xfs_iext_lookup_extent( struct xfs_inode *ip, struct xfs_ifork *ifp, xfs_fileoff_t bno, xfs_extnum_t *idxp, struct xfs_bmbt_irec *gotp) { struct xfs_bmbt_rec_host *ep; XFS_STATS_INC(ip->i_mount, xs_look_exlist); ep = xfs_iext_bno_to_ext(ifp, bno, idxp); if (!ep) return false; xfs_bmbt_get_all(ep, gotp); return true; } /* * Return true if there is an extent at index idx, and return the expanded * extent structure at idx in that case. Else return false. */ bool xfs_iext_get_extent( struct xfs_ifork *ifp, xfs_extnum_t idx, struct xfs_bmbt_irec *gotp) { if (idx < 0 || idx >= xfs_iext_count(ifp)) return false; xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), gotp); return true; }
fs/xfs/libxfs/xfs_inode_fork.h +6 −0 Original line number Diff line number Diff line Loading @@ -182,6 +182,12 @@ void xfs_iext_irec_compact_pages(struct xfs_ifork *); void xfs_iext_irec_compact_full(struct xfs_ifork *); void xfs_iext_irec_update_extoffs(struct xfs_ifork *, int, int); bool xfs_iext_lookup_extent(struct xfs_inode *ip, struct xfs_ifork *ifp, xfs_fileoff_t bno, xfs_extnum_t *idxp, struct xfs_bmbt_irec *gotp); bool xfs_iext_get_extent(struct xfs_ifork *ifp, xfs_extnum_t idx, struct xfs_bmbt_irec *gotp); extern struct kmem_zone *xfs_ifork_zone; extern void xfs_ifork_init_cow(struct xfs_inode *ip); Loading
fs/xfs/libxfs/xfs_types.h +0 −1 Original line number Diff line number Diff line Loading @@ -57,7 +57,6 @@ typedef __int64_t xfs_sfiloff_t; /* signed block number in a file */ #define NULLAGBLOCK ((xfs_agblock_t)-1) #define NULLAGNUMBER ((xfs_agnumber_t)-1) #define NULLEXTNUM ((xfs_extnum_t)-1) #define NULLCOMMITLSN ((xfs_lsn_t)-1) Loading