On Fri, Mar 07, 2014 at 02:55:35AM -0800, Christoph Hellwig wrote: > 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); If I follow correctly, the list_add() is removed from xfs_extent_busy_insert() because we use the list field for the bmap flist as well as the t_busy list. It appears we've lost an error check associated with allocation failure in xfs_freed_extent_alloc() (here and at other callers). The current code looks like it handles this by marking the transaction as synchronous. Have we avoided the need for this by using kmem_zone_alloc()? I guess it looks like the sleep param will cause it to continue to retry... > + } > + 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; agbno? > + 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); Was this supposed to go away? > + 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). > */ This comment could be fixed now that the sort is deferred. > @@ -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; Could we just do a comparison here and return +/-1? > + 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 So it seems like technically we could get away with still doing the list migration here an extent at a time, but that would turn this code kind of ugly (e.g., to remove each entry from xbf_list as we go). Also, it appears we no longer do the xfs_extent_busy_insert() in this path..? > @@ -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) > { tp is only used for the mount now, so we can probably replace tp with mp. Brian > - 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 _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs