Merge the two structures to track a freed extent into a single one, to simply tracking the flow in the extent free code and reduce the amount of required memory allocations. Signed-off-by: Christoph Hellwig <hch@xxxxxx> diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index c1cf6a3..656991d 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c @@ -2579,37 +2579,41 @@ error0: return error; } -/* - * Free an extent. - * Just break up the extent address and hand off to xfs_free_ag_extent - * after fixing up the freelist. - */ -int /* error */ -xfs_free_extent( - xfs_trans_t *tp, /* transaction pointer */ - xfs_fsblock_t bno, /* starting block number of extent */ - xfs_extlen_t len) /* length of extent */ +struct xfs_freed_extent * +xfs_freed_extent_alloc( + xfs_agnumber_t agno, + xfs_agblock_t bno, + xfs_extlen_t len, + unsigned int flags) +{ + struct xfs_freed_extent *new; + + new = kmem_zone_zalloc(xfs_freed_extent_zone, KM_SLEEP); + if (!new) + return NULL; + + new->agno = agno; + new->bno = bno; + new->length = len; + INIT_LIST_HEAD(&new->list); + new->flags = flags; + return new; +} + +int +__xfs_free_extent( + struct xfs_trans *tp, + struct xfs_freed_extent *free) { xfs_alloc_arg_t args; int error; - ASSERT(len != 0); + ASSERT(free->length != 0); memset(&args, 0, sizeof(xfs_alloc_arg_t)); args.tp = tp; args.mp = tp->t_mountp; - - /* - * validate that the block number is legal - the enables us to detect - * and handle a silent filesystem corruption rather than crashing. - */ - args.agno = XFS_FSB_TO_AGNO(args.mp, bno); - if (args.agno >= args.mp->m_sb.sb_agcount) - return EFSCORRUPTED; - - args.agbno = XFS_FSB_TO_AGBNO(args.mp, bno); - if (args.agbno >= args.mp->m_sb.sb_agblocks) - return EFSCORRUPTED; - + args.agno = free->agno; + args.agbno = free->bno; args.pag = xfs_perag_get(args.mp, args.agno); ASSERT(args.pag); @@ -2618,16 +2622,45 @@ xfs_free_extent( goto error0; /* validate the extent size is legal now we have the agf locked */ - if (args.agbno + len > + if (args.agbno + free->length > be32_to_cpu(XFS_BUF_TO_AGF(args.agbp)->agf_length)) { error = EFSCORRUPTED; goto error0; } - error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0); - if (!error) - xfs_extent_busy_insert(tp, args.agno, args.agbno, len, 0); + error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, + free->length, 0); error0: xfs_perag_put(args.pag); return error; } + +int +xfs_free_extent( + struct xfs_trans *tp, + xfs_fsblock_t bno, + xfs_extlen_t len) +{ + struct xfs_mount *mp = tp->t_mountp; + xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, bno); + xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, bno); + struct xfs_freed_extent *free; + int error; + + /* + * validate that the block number is legal - the enables us to detect + * and handle a silent filesystem corruption rather than crashing. + */ + if (agno >= mp->m_sb.sb_agcount) + return EFSCORRUPTED; + if (agbno >= mp->m_sb.sb_agblocks) + return EFSCORRUPTED; + + free = xfs_freed_extent_alloc(agno, agbno, len, 0); + error = __xfs_free_extent(tp, free); + if (!error) { + xfs_extent_busy_insert(tp, free); + list_add(&free->list, &tp->t_busy); + } + return error; +} diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h index feacb06..4aa7f8c 100644 --- a/fs/xfs/xfs_alloc.h +++ b/fs/xfs/xfs_alloc.h @@ -122,6 +122,17 @@ typedef struct xfs_alloc_arg { xfs_fsblock_t firstblock; /* io first block allocated */ } xfs_alloc_arg_t; +struct xfs_freed_extent { + struct rb_node rb_node; /* ag by-bno indexed search tree */ + struct list_head list; /* transaction busy extent list */ + xfs_agnumber_t agno; + xfs_agblock_t bno; + xfs_extlen_t length; + unsigned int flags; +#define XFS_EXTENT_DISCARDED 0x01 /* undergoing a discard op. */ +#define XFS_EXTENT_SKIP_DISCARD 0x02 /* do not discard */ +}; + /* * Defines for userdata */ @@ -210,6 +221,11 @@ xfs_free_extent( xfs_fsblock_t bno, /* starting block number of extent */ xfs_extlen_t len); /* length of extent */ +int +__xfs_free_extent( + struct xfs_trans *tp, + struct xfs_freed_extent *free); + int /* error */ xfs_alloc_lookup_le( struct xfs_btree_cur *cur, /* btree cursor */ @@ -231,4 +247,13 @@ xfs_alloc_get_rec( xfs_extlen_t *len, /* output: length of extent */ int *stat); /* output: success/failure */ +struct xfs_freed_extent * +xfs_freed_extent_alloc( + xfs_agnumber_t agno, + xfs_agblock_t bno, + xfs_extlen_t len, + unsigned int flags); + +extern kmem_zone_t *xfs_freed_extent_zone; + #endif /* __XFS_ALLOC_H__ */ diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c index cc1eadc..ce3041a 100644 --- a/fs/xfs/xfs_alloc_btree.c +++ b/fs/xfs/xfs_alloc_btree.c @@ -107,21 +107,24 @@ xfs_allocbt_free_block( struct xfs_btree_cur *cur, struct xfs_buf *bp) { + struct xfs_trans *tp = cur->bc_tp; struct xfs_buf *agbp = cur->bc_private.a.agbp; struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); + struct xfs_freed_extent *free; xfs_agblock_t bno; int error; bno = xfs_daddr_to_agbno(cur->bc_mp, XFS_BUF_ADDR(bp)); - error = xfs_alloc_put_freelist(cur->bc_tp, agbp, NULL, bno, 1); + error = xfs_alloc_put_freelist(tp, agbp, NULL, bno, 1); if (error) return error; - xfs_extent_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1, - XFS_EXTENT_BUSY_SKIP_DISCARD); - xfs_trans_agbtree_delta(cur->bc_tp, -1); + free = xfs_freed_extent_alloc(be32_to_cpu(agf->agf_seqno), bno, 1, + XFS_EXTENT_SKIP_DISCARD); + xfs_extent_busy_insert(tp, free); + list_add(&free->list, &tp->t_busy); - xfs_trans_binval(cur->bc_tp, bp); + xfs_trans_binval(tp, bp); return 0; } diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 5b6092e..9c2c00c 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -50,7 +50,7 @@ #include "xfs_filestream.h" -kmem_zone_t *xfs_bmap_free_item_zone; +kmem_zone_t *xfs_freed_extent_zone; /* * Miscellaneous helper functions @@ -588,10 +588,6 @@ xfs_bmap_validate_ret( #endif /* DEBUG */ /* - * bmap free list manipulation functions - */ - -/* * Add the extent to the list of extents to be free at transaction end. * The list is maintained sorted (by block number). */ @@ -602,58 +598,22 @@ xfs_bmap_add_free( xfs_bmap_free_t *flist, /* list of extents */ xfs_mount_t *mp) /* mount point structure */ { - xfs_bmap_free_item_t *cur; /* current (next) element */ - xfs_bmap_free_item_t *new; /* new element */ - xfs_bmap_free_item_t *prev; /* previous element */ -#ifdef DEBUG - xfs_agnumber_t agno; - xfs_agblock_t agbno; + xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, bno); + xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, bno); + struct xfs_freed_extent *new; ASSERT(bno != NULLFSBLOCK); ASSERT(len > 0); ASSERT(len <= MAXEXTLEN); ASSERT(!isnullstartblock(bno)); - agno = XFS_FSB_TO_AGNO(mp, bno); - agbno = XFS_FSB_TO_AGBNO(mp, bno); ASSERT(agno < mp->m_sb.sb_agcount); ASSERT(agbno < mp->m_sb.sb_agblocks); ASSERT(len < mp->m_sb.sb_agblocks); ASSERT(agbno + len <= mp->m_sb.sb_agblocks); -#endif - ASSERT(xfs_bmap_free_item_zone != NULL); - new = kmem_zone_alloc(xfs_bmap_free_item_zone, KM_SLEEP); - new->xbfi_startblock = bno; - new->xbfi_blockcount = (xfs_extlen_t)len; - for (prev = NULL, cur = flist->xbf_first; - cur != NULL; - prev = cur, cur = cur->xbfi_next) { - if (cur->xbfi_startblock >= bno) - break; - } - if (prev) - prev->xbfi_next = new; - else - flist->xbf_first = new; - new->xbfi_next = cur; - flist->xbf_count++; -} -/* - * Remove the entry "free" from the free item list. Prev points to the - * previous entry, unless "free" is the head of the list. - */ -void -xfs_bmap_del_free( - xfs_bmap_free_t *flist, /* free item list header */ - xfs_bmap_free_item_t *prev, /* previous item on list, if any */ - xfs_bmap_free_item_t *free) /* list item to be freed */ -{ - if (prev) - prev->xbfi_next = free->xbfi_next; - else - flist->xbf_first = free->xbfi_next; - flist->xbf_count--; - kmem_zone_free(xfs_bmap_free_item_zone, free); + new = xfs_freed_extent_alloc(agno, agbno, len, 0); + list_add_tail(&new->list, &flist->xbf_list); + flist->xbf_count++; } /* @@ -663,16 +623,14 @@ void xfs_bmap_cancel( xfs_bmap_free_t *flist) /* list of bmap_free_items */ { - xfs_bmap_free_item_t *free; /* free list item */ - xfs_bmap_free_item_t *next; + struct xfs_freed_extent *free, *n; - if (flist->xbf_count == 0) - return; - ASSERT(flist->xbf_first != NULL); - for (free = flist->xbf_first; free; free = next) { - next = free->xbfi_next; - xfs_bmap_del_free(flist, NULL, free); + list_for_each_entry_safe(free, n, &flist->xbf_list, list) { + list_del(&free->list); + flist->xbf_count--; + kmem_zone_free(xfs_freed_extent_zone, free); } + ASSERT(flist->xbf_count == 0); } diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h index f84bd7a..73cedc4 100644 --- a/fs/xfs/xfs_bmap.h +++ b/fs/xfs/xfs_bmap.h @@ -25,19 +25,6 @@ struct xfs_inode; struct xfs_mount; struct xfs_trans; -extern kmem_zone_t *xfs_bmap_free_item_zone; - -/* - * List of extents to be free "later". - * The list is kept sorted on xbf_startblock. - */ -typedef struct xfs_bmap_free_item -{ - xfs_fsblock_t xbfi_startblock;/* starting fs block number */ - xfs_extlen_t xbfi_blockcount;/* number of blocks in extent */ - struct xfs_bmap_free_item *xbfi_next; /* link to next entry */ -} xfs_bmap_free_item_t; - /* * Header for free extent list. * @@ -52,9 +39,8 @@ typedef struct xfs_bmap_free_item * transaction reservations have been made then this algorithm will eventually * find all the space it needs. */ -typedef struct xfs_bmap_free -{ - xfs_bmap_free_item_t *xbf_first; /* list of to-be-free extents */ +typedef struct xfs_bmap_free { + struct list_head xbf_list; int xbf_count; /* count of items on list */ int xbf_low; /* alloc in low mode */ } xfs_bmap_free_t; @@ -103,8 +89,10 @@ static inline int xfs_bmapi_aflag(int w) static inline void xfs_bmap_init(xfs_bmap_free_t *flp, xfs_fsblock_t *fbp) { - ((flp)->xbf_first = NULL, (flp)->xbf_count = 0, \ - (flp)->xbf_low = 0, *(fbp) = NULLFSBLOCK); + INIT_LIST_HEAD(&flp->xbf_list); + flp->xbf_count = 0; + flp->xbf_low = 0; + *fbp = NULLFSBLOCK; } /* diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 01f6a64..ade325f 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -59,6 +59,22 @@ xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb) XFS_FSB_TO_DADDR((ip)->i_mount, (fsb))); } +STATIC int +xfs_freed_extent_cmp( + void *priv, + struct list_head *la, + struct list_head *lb) +{ + struct xfs_freed_extent *a = + container_of(la, struct xfs_freed_extent, list); + struct xfs_freed_extent *b = + container_of(lb, struct xfs_freed_extent, list); + + if (a->agno == b->agno) + return a->bno - b->bno; + return a->agno - b->agno; +} + /* * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi * caller. Frees all the extents that need freeing, which must be done @@ -74,13 +90,12 @@ xfs_bmap_finish( xfs_bmap_free_t *flist, /* i/o: list extents to free */ int *committed) /* xact committed or not */ { + struct xfs_mount *mp = (*tp)->t_mountp; + struct xfs_freed_extent *free; xfs_efd_log_item_t *efd; /* extent free data */ xfs_efi_log_item_t *efi; /* extent free intention */ int error; /* error return value */ - xfs_bmap_free_item_t *free; /* free extent item */ struct xfs_trans_res tres; /* new log reservation */ - xfs_mount_t *mp; /* filesystem mount structure */ - xfs_bmap_free_item_t *next; /* next item on free list */ xfs_trans_t *ntp; /* new transaction pointer */ ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); @@ -90,9 +105,14 @@ xfs_bmap_finish( } ntp = *tp; efi = xfs_trans_get_efi(ntp, flist->xbf_count); - for (free = flist->xbf_first; free; free = free->xbfi_next) - xfs_trans_log_efi_extent(ntp, efi, free->xbfi_startblock, - free->xbfi_blockcount); + + list_sort(NULL, &flist->xbf_list, xfs_freed_extent_cmp); + + list_for_each_entry(free, &flist->xbf_list, list) { + xfs_trans_log_efi_extent(ntp, efi, + XFS_AGB_TO_FSB(mp, free->agno, free->bno), + free->length); + } tres.tr_logres = ntp->t_log_res; tres.tr_logcount = ntp->t_log_count; @@ -118,10 +138,10 @@ xfs_bmap_finish( if (error) return error; efd = xfs_trans_get_efd(ntp, efi, flist->xbf_count); - for (free = flist->xbf_first; free != NULL; free = next) { - next = free->xbfi_next; - if ((error = xfs_free_extent(ntp, free->xbfi_startblock, - free->xbfi_blockcount))) { + + list_for_each_entry(free, &flist->xbf_list, list) { + error = __xfs_free_extent(ntp, free); + if (error) { /* * The bmap free list will be cleaned up at a * higher level. The EFI will be canceled when @@ -130,7 +150,6 @@ xfs_bmap_finish( * happens, since this transaction may not be * dirty yet. */ - mp = ntp->t_mountp; if (!XFS_FORCED_SHUTDOWN(mp)) xfs_force_shutdown(mp, (error == EFSCORRUPTED) ? @@ -138,10 +157,13 @@ xfs_bmap_finish( SHUTDOWN_META_IO_ERROR); return error; } - xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock, - free->xbfi_blockcount); - xfs_bmap_del_free(flist, NULL, free); + + xfs_trans_log_efd_extent(ntp, efd, + XFS_AGB_TO_FSB(mp, free->agno, free->bno), + free->length); } + + list_splice_init(&flist->xbf_list, &ntp->t_busy); return 0; } @@ -826,7 +848,7 @@ xfs_bmap_punch_delalloc_range( if (error) break; - ASSERT(!flist.xbf_count && !flist.xbf_first); + ASSERT(!flist.xbf_count && list_empty(&flist.xbf_list)); next_block: start_fsb++; remaining--; diff --git a/fs/xfs/xfs_bmap_util.h b/fs/xfs/xfs_bmap_util.h index 935ed2b..ffb26ea 100644 --- a/fs/xfs/xfs_bmap_util.h +++ b/fs/xfs/xfs_bmap_util.h @@ -21,7 +21,6 @@ /* Kernel only BMAP related definitions and functions */ struct xfs_bmbt_irec; -struct xfs_bmap_free_item; struct xfs_ifork; struct xfs_inode; struct xfs_mount; @@ -80,9 +79,6 @@ int xfs_getbmap(struct xfs_inode *ip, struct getbmapx *bmv, xfs_bmap_format_t formatter, void *arg); /* functions in xfs_bmap.c that are only needed by xfs_bmap_util.c */ -void xfs_bmap_del_free(struct xfs_bmap_free *flist, - struct xfs_bmap_free_item *prev, - struct xfs_bmap_free_item *free); int xfs_bmap_extsize_align(struct xfs_mount *mp, struct xfs_bmbt_irec *gotp, struct xfs_bmbt_irec *prevp, xfs_extlen_t extsz, int rt, int eof, int delay, int convert, diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c index 4f11ef0..e3d0f18 100644 --- a/fs/xfs/xfs_discard.c +++ b/fs/xfs/xfs_discard.c @@ -215,7 +215,7 @@ xfs_discard_extents( struct xfs_mount *mp, struct list_head *list) { - struct xfs_extent_busy *busyp; + struct xfs_freed_extent *busyp; int error = 0; list_for_each_entry(busyp, list, list) { diff --git a/fs/xfs/xfs_extent_busy.c b/fs/xfs/xfs_extent_busy.c index fd22f69..f4711ee 100644 --- a/fs/xfs/xfs_extent_busy.c +++ b/fs/xfs/xfs_extent_busy.c @@ -35,51 +35,29 @@ void xfs_extent_busy_insert( struct xfs_trans *tp, - xfs_agnumber_t agno, - xfs_agblock_t bno, - xfs_extlen_t len, - unsigned int flags) + struct xfs_freed_extent *new) { - struct xfs_extent_busy *new; - struct xfs_extent_busy *busyp; + struct xfs_freed_extent *busyp; struct xfs_perag *pag; struct rb_node **rbp; struct rb_node *parent = NULL; - new = kmem_zalloc(sizeof(struct xfs_extent_busy), KM_MAYFAIL); - if (!new) { - /* - * No Memory! Since it is now not possible to track the free - * block, make this a synchronous transaction to insure that - * the block is not reused before this transaction commits. - */ - trace_xfs_extent_busy_enomem(tp->t_mountp, agno, bno, len); - xfs_trans_set_sync(tp); - return; - } - - new->agno = agno; - new->bno = bno; - new->length = len; - INIT_LIST_HEAD(&new->list); - new->flags = flags; - /* trace before insert to be able to see failed inserts */ - trace_xfs_extent_busy(tp->t_mountp, agno, bno, len); + trace_xfs_extent_busy(tp->t_mountp, new->agno, new->bno, new->length); pag = xfs_perag_get(tp->t_mountp, new->agno); spin_lock(&pag->pagb_lock); rbp = &pag->pagb_tree.rb_node; while (*rbp) { parent = *rbp; - busyp = rb_entry(parent, struct xfs_extent_busy, rb_node); + busyp = rb_entry(parent, struct xfs_freed_extent, rb_node); if (new->bno < busyp->bno) { rbp = &(*rbp)->rb_left; ASSERT(new->bno + new->length <= busyp->bno); } else if (new->bno > busyp->bno) { rbp = &(*rbp)->rb_right; - ASSERT(bno >= busyp->bno + busyp->length); + ASSERT(new->bno >= busyp->bno + busyp->length); } else { ASSERT(0); } @@ -88,7 +66,6 @@ xfs_extent_busy_insert( rb_link_node(&new->rb_node, parent, rbp); rb_insert_color(&new->rb_node, &pag->pagb_tree); - list_add(&new->list, &tp->t_busy); spin_unlock(&pag->pagb_lock); xfs_perag_put(pag); } @@ -111,7 +88,7 @@ xfs_extent_busy_search( { struct xfs_perag *pag; struct rb_node *rbp; - struct xfs_extent_busy *busyp; + struct xfs_freed_extent *busyp; int match = 0; pag = xfs_perag_get(mp, agno); @@ -121,7 +98,7 @@ xfs_extent_busy_search( /* find closest start bno overlap */ while (rbp) { - busyp = rb_entry(rbp, struct xfs_extent_busy, rb_node); + busyp = rb_entry(rbp, struct xfs_freed_extent, rb_node); if (bno < busyp->bno) { /* may overlap, but exact start block is lower */ if (bno + len > busyp->bno) @@ -158,7 +135,7 @@ STATIC bool xfs_extent_busy_update_extent( struct xfs_mount *mp, struct xfs_perag *pag, - struct xfs_extent_busy *busyp, + struct xfs_freed_extent *busyp, xfs_agblock_t fbno, xfs_extlen_t flen, bool userdata) __releases(&pag->pagb_lock) @@ -173,7 +150,7 @@ xfs_extent_busy_update_extent( * performing the discard a chance to mark the extent unbusy * and retry. */ - if (busyp->flags & XFS_EXTENT_BUSY_DISCARDED) { + if (busyp->flags & XFS_EXTENT_DISCARDED) { spin_unlock(&pag->pagb_lock); delay(1); spin_lock(&pag->pagb_lock); @@ -320,8 +297,8 @@ xfs_extent_busy_reuse( restart: rbp = pag->pagb_tree.rb_node; while (rbp) { - struct xfs_extent_busy *busyp = - rb_entry(rbp, struct xfs_extent_busy, rb_node); + struct xfs_freed_extent *busyp = + rb_entry(rbp, struct xfs_freed_extent, rb_node); xfs_agblock_t bbno = busyp->bno; xfs_agblock_t bend = bbno + busyp->length; @@ -367,8 +344,8 @@ restart: flen = len; rbp = args->pag->pagb_tree.rb_node; while (rbp && flen >= args->minlen) { - struct xfs_extent_busy *busyp = - rb_entry(rbp, struct xfs_extent_busy, rb_node); + struct xfs_freed_extent *busyp = + rb_entry(rbp, struct xfs_freed_extent, rb_node); xfs_agblock_t fend = fbno + flen; xfs_agblock_t bbno = busyp->bno; xfs_agblock_t bend = bbno + busyp->length; @@ -386,7 +363,7 @@ restart: * extent instead of trimming the allocation. */ if (!args->userdata && - !(busyp->flags & XFS_EXTENT_BUSY_DISCARDED)) { + !(busyp->flags & XFS_EXTENT_DISCARDED)) { if (!xfs_extent_busy_update_extent(args->mp, args->pag, busyp, fbno, flen, false)) @@ -540,7 +517,7 @@ STATIC void xfs_extent_busy_clear_one( struct xfs_mount *mp, struct xfs_perag *pag, - struct xfs_extent_busy *busyp) + struct xfs_freed_extent *busyp) { if (busyp->length) { trace_xfs_extent_busy_clear(mp, busyp->agno, busyp->bno, @@ -549,7 +526,7 @@ xfs_extent_busy_clear_one( } list_del_init(&busyp->list); - kmem_free(busyp); + kmem_zone_free(xfs_freed_extent_zone, busyp); } /* @@ -563,7 +540,7 @@ xfs_extent_busy_clear( struct list_head *list, bool do_discard) { - struct xfs_extent_busy *busyp, *n; + struct xfs_freed_extent *busyp, *n; struct xfs_perag *pag = NULL; xfs_agnumber_t agno = NULLAGNUMBER; @@ -579,8 +556,8 @@ xfs_extent_busy_clear( } if (do_discard && busyp->length && - !(busyp->flags & XFS_EXTENT_BUSY_SKIP_DISCARD)) - busyp->flags = XFS_EXTENT_BUSY_DISCARDED; + !(busyp->flags & XFS_EXTENT_SKIP_DISCARD)) + busyp->flags = XFS_EXTENT_DISCARDED; else xfs_extent_busy_clear_one(mp, pag, busyp); } @@ -600,6 +577,6 @@ xfs_extent_busy_ag_cmp( struct list_head *a, struct list_head *b) { - return container_of(a, struct xfs_extent_busy, list)->agno - - container_of(b, struct xfs_extent_busy, list)->agno; + return container_of(a, struct xfs_freed_extent, list)->agno - + container_of(b, struct xfs_freed_extent, list)->agno; } diff --git a/fs/xfs/xfs_extent_busy.h b/fs/xfs/xfs_extent_busy.h index bfff284..ccc8a13 100644 --- a/fs/xfs/xfs_extent_busy.h +++ b/fs/xfs/xfs_extent_busy.h @@ -20,31 +20,13 @@ #ifndef __XFS_EXTENT_BUSY_H__ #define __XFS_EXTENT_BUSY_H__ +struct xfs_freed_extent; struct xfs_mount; struct xfs_trans; struct xfs_alloc_arg; -/* - * Busy block/extent entry. Indexed by a rbtree in perag to mark blocks that - * have been freed but whose transactions aren't committed to disk yet. - * - * Note that we use the transaction ID to record the transaction, not the - * transaction structure itself. See xfs_extent_busy_insert() for details. - */ -struct xfs_extent_busy { - struct rb_node rb_node; /* ag by-bno indexed search tree */ - struct list_head list; /* transaction busy extent list */ - xfs_agnumber_t agno; - xfs_agblock_t bno; - xfs_extlen_t length; - unsigned int flags; -#define XFS_EXTENT_BUSY_DISCARDED 0x01 /* undergoing a discard op. */ -#define XFS_EXTENT_BUSY_SKIP_DISCARD 0x02 /* do not discard */ -}; - void -xfs_extent_busy_insert(struct xfs_trans *tp, xfs_agnumber_t agno, - xfs_agblock_t bno, xfs_extlen_t len, unsigned int flags); +xfs_extent_busy_insert(struct xfs_trans *tp, struct xfs_freed_extent *free); void xfs_extent_busy_clear(struct xfs_mount *mp, struct list_head *list, diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index f317488..a674664 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1581,15 +1581,15 @@ xfs_init_zones(void) if (!xfs_log_ticket_zone) goto out_destroy_ioend_pool; - xfs_bmap_free_item_zone = kmem_zone_init(sizeof(xfs_bmap_free_item_t), - "xfs_bmap_free_item"); - if (!xfs_bmap_free_item_zone) + xfs_freed_extent_zone = kmem_zone_init(sizeof(struct xfs_freed_extent), + "xfs_freed_extent"); + if (!xfs_freed_extent_zone) goto out_destroy_log_ticket_zone; xfs_btree_cur_zone = kmem_zone_init(sizeof(xfs_btree_cur_t), "xfs_btree_cur"); if (!xfs_btree_cur_zone) - goto out_destroy_bmap_free_item_zone; + goto out_destroy_freed_extent_zone; xfs_da_state_zone = kmem_zone_init(sizeof(xfs_da_state_t), "xfs_da_state"); @@ -1671,8 +1671,8 @@ xfs_init_zones(void) kmem_zone_destroy(xfs_da_state_zone); out_destroy_btree_cur_zone: kmem_zone_destroy(xfs_btree_cur_zone); - out_destroy_bmap_free_item_zone: - kmem_zone_destroy(xfs_bmap_free_item_zone); + out_destroy_freed_extent_zone: + kmem_zone_destroy(xfs_freed_extent_zone); out_destroy_log_ticket_zone: kmem_zone_destroy(xfs_log_ticket_zone); out_destroy_ioend_pool: @@ -1702,7 +1702,7 @@ xfs_destroy_zones(void) kmem_zone_destroy(xfs_ifork_zone); kmem_zone_destroy(xfs_da_state_zone); kmem_zone_destroy(xfs_btree_cur_zone); - kmem_zone_destroy(xfs_bmap_free_item_zone); + kmem_zone_destroy(xfs_freed_extent_zone); kmem_zone_destroy(xfs_log_ticket_zone); mempool_destroy(xfs_ioend_pool); kmem_zone_destroy(xfs_ioend_zone); diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index a4ae41c..2dfe819 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -1313,7 +1313,6 @@ DEFINE_EVENT(xfs_extent_busy_class, name, \ xfs_agblock_t agbno, xfs_extlen_t len), \ TP_ARGS(mp, agno, agbno, len)) DEFINE_BUSY_EVENT(xfs_extent_busy); -DEFINE_BUSY_EVENT(xfs_extent_busy_enomem); DEFINE_BUSY_EVENT(xfs_extent_busy_force); DEFINE_BUSY_EVENT(xfs_extent_busy_reuse); DEFINE_BUSY_EVENT(xfs_extent_busy_clear); _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs