[PATCH] xfs: merge xfs_bmap_free_item and xfs_extent_busy

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux XFS Devel]     [Linux Filesystem Development]     [Filesystem Testing]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux