aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2016-06-20 21:53:28 -0400
committerDave Chinner <david@fromorbit.com>2016-06-20 21:53:28 -0400
commite66a4c678e64932eb4befd95a348b9632603d27c (patch)
treea9111f18f7356cd4dd0fc1c841f88b3250b9dcb1
parent4d89e20bf1b12bd5aa6917efc86da723b331deef (diff)
xfs: convert list of extents to free into a regular list
In struct xfs_bmap_free, convert the open-coded free extent list to a regular list, then use list_sort to sort it prior to processing. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c39
-rw-r--r--fs/xfs/libxfs/xfs_bmap.h14
-rw-r--r--fs/xfs/xfs_bmap_util.c32
-rw-r--r--fs/xfs/xfs_bmap_util.h1
-rw-r--r--fs/xfs/xfs_super.c5
5 files changed, 47 insertions, 44 deletions
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 8847496f7ccb..2f2c85cc8117 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -575,9 +575,7 @@ xfs_bmap_add_free(
575 xfs_fsblock_t bno, /* fs block number of extent */ 575 xfs_fsblock_t bno, /* fs block number of extent */
576 xfs_filblks_t len) /* length of extent */ 576 xfs_filblks_t len) /* length of extent */
577{ 577{
578 xfs_bmap_free_item_t *cur; /* current (next) element */ 578 struct xfs_bmap_free_item *new; /* new element */
579 xfs_bmap_free_item_t *new; /* new element */
580 xfs_bmap_free_item_t *prev; /* previous element */
581#ifdef DEBUG 579#ifdef DEBUG
582 xfs_agnumber_t agno; 580 xfs_agnumber_t agno;
583 xfs_agblock_t agbno; 581 xfs_agblock_t agbno;
@@ -597,17 +595,7 @@ xfs_bmap_add_free(
597 new = kmem_zone_alloc(xfs_bmap_free_item_zone, KM_SLEEP); 595 new = kmem_zone_alloc(xfs_bmap_free_item_zone, KM_SLEEP);
598 new->xbfi_startblock = bno; 596 new->xbfi_startblock = bno;
599 new->xbfi_blockcount = (xfs_extlen_t)len; 597 new->xbfi_blockcount = (xfs_extlen_t)len;
600 for (prev = NULL, cur = flist->xbf_first; 598 list_add(&new->xbfi_list, &flist->xbf_flist);
601 cur != NULL;
602 prev = cur, cur = cur->xbfi_next) {
603 if (cur->xbfi_startblock >= bno)
604 break;
605 }
606 if (prev)
607 prev->xbfi_next = new;
608 else
609 flist->xbf_first = new;
610 new->xbfi_next = cur;
611 flist->xbf_count++; 599 flist->xbf_count++;
612} 600}
613 601
@@ -617,14 +605,10 @@ xfs_bmap_add_free(
617 */ 605 */
618void 606void
619xfs_bmap_del_free( 607xfs_bmap_del_free(
620 xfs_bmap_free_t *flist, /* free item list header */ 608 struct xfs_bmap_free *flist, /* free item list header */
621 xfs_bmap_free_item_t *prev, /* previous item on list, if any */ 609 struct xfs_bmap_free_item *free) /* list item to be freed */
622 xfs_bmap_free_item_t *free) /* list item to be freed */
623{ 610{
624 if (prev) 611 list_del(&free->xbfi_list);
625 prev->xbfi_next = free->xbfi_next;
626 else
627 flist->xbf_first = free->xbfi_next;
628 flist->xbf_count--; 612 flist->xbf_count--;
629 kmem_zone_free(xfs_bmap_free_item_zone, free); 613 kmem_zone_free(xfs_bmap_free_item_zone, free);
630} 614}
@@ -634,17 +618,16 @@ xfs_bmap_del_free(
634 */ 618 */
635void 619void
636xfs_bmap_cancel( 620xfs_bmap_cancel(
637 xfs_bmap_free_t *flist) /* list of bmap_free_items */ 621 struct xfs_bmap_free *flist) /* list of bmap_free_items */
638{ 622{
639 xfs_bmap_free_item_t *free; /* free list item */ 623 struct xfs_bmap_free_item *free; /* free list item */
640 xfs_bmap_free_item_t *next;
641 624
642 if (flist->xbf_count == 0) 625 if (flist->xbf_count == 0)
643 return; 626 return;
644 ASSERT(flist->xbf_first != NULL); 627 while (!list_empty(&flist->xbf_flist)) {
645 for (free = flist->xbf_first; free; free = next) { 628 free = list_first_entry(&flist->xbf_flist,
646 next = free->xbfi_next; 629 struct xfs_bmap_free_item, xbfi_list);
647 xfs_bmap_del_free(flist, NULL, free); 630 xfs_bmap_del_free(flist, free);
648 } 631 }
649 ASSERT(flist->xbf_count == 0); 632 ASSERT(flist->xbf_count == 0);
650} 633}
diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h
index e081c7694fae..f1f3ae6c0a3f 100644
--- a/fs/xfs/libxfs/xfs_bmap.h
+++ b/fs/xfs/libxfs/xfs_bmap.h
@@ -62,12 +62,12 @@ struct xfs_bmalloca {
62 * List of extents to be free "later". 62 * List of extents to be free "later".
63 * The list is kept sorted on xbf_startblock. 63 * The list is kept sorted on xbf_startblock.
64 */ 64 */
65typedef struct xfs_bmap_free_item 65struct xfs_bmap_free_item
66{ 66{
67 xfs_fsblock_t xbfi_startblock;/* starting fs block number */ 67 xfs_fsblock_t xbfi_startblock;/* starting fs block number */
68 xfs_extlen_t xbfi_blockcount;/* number of blocks in extent */ 68 xfs_extlen_t xbfi_blockcount;/* number of blocks in extent */
69 struct xfs_bmap_free_item *xbfi_next; /* link to next entry */ 69 struct list_head xbfi_list;
70} xfs_bmap_free_item_t; 70};
71 71
72/* 72/*
73 * Header for free extent list. 73 * Header for free extent list.
@@ -85,7 +85,7 @@ typedef struct xfs_bmap_free_item
85 */ 85 */
86typedef struct xfs_bmap_free 86typedef struct xfs_bmap_free
87{ 87{
88 xfs_bmap_free_item_t *xbf_first; /* list of to-be-free extents */ 88 struct list_head xbf_flist; /* list of to-be-free extents */
89 int xbf_count; /* count of items on list */ 89 int xbf_count; /* count of items on list */
90 int xbf_low; /* alloc in low mode */ 90 int xbf_low; /* alloc in low mode */
91} xfs_bmap_free_t; 91} xfs_bmap_free_t;
@@ -141,8 +141,10 @@ static inline int xfs_bmapi_aflag(int w)
141 141
142static inline void xfs_bmap_init(xfs_bmap_free_t *flp, xfs_fsblock_t *fbp) 142static inline void xfs_bmap_init(xfs_bmap_free_t *flp, xfs_fsblock_t *fbp)
143{ 143{
144 ((flp)->xbf_first = NULL, (flp)->xbf_count = 0, \ 144 INIT_LIST_HEAD(&flp->xbf_flist);
145 (flp)->xbf_low = 0, *(fbp) = NULLFSBLOCK); 145 flp->xbf_count = 0;
146 flp->xbf_low = 0;
147 *fbp = NULLFSBLOCK;
146} 148}
147 149
148/* 150/*
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 586bb64e674b..c53e07a87cd7 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -79,6 +79,23 @@ xfs_zero_extent(
79 GFP_NOFS, true); 79 GFP_NOFS, true);
80} 80}
81 81
82/* Sort bmap items by AG. */
83static int
84xfs_bmap_free_list_cmp(
85 void *priv,
86 struct list_head *a,
87 struct list_head *b)
88{
89 struct xfs_mount *mp = priv;
90 struct xfs_bmap_free_item *ra;
91 struct xfs_bmap_free_item *rb;
92
93 ra = container_of(a, struct xfs_bmap_free_item, xbfi_list);
94 rb = container_of(b, struct xfs_bmap_free_item, xbfi_list);
95 return XFS_FSB_TO_AGNO(mp, ra->xbfi_startblock) -
96 XFS_FSB_TO_AGNO(mp, rb->xbfi_startblock);
97}
98
82/* 99/*
83 * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi 100 * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi
84 * caller. Frees all the extents that need freeing, which must be done 101 * caller. Frees all the extents that need freeing, which must be done
@@ -99,14 +116,15 @@ xfs_bmap_finish(
99 int error; /* error return value */ 116 int error; /* error return value */
100 int committed;/* xact committed or not */ 117 int committed;/* xact committed or not */
101 struct xfs_bmap_free_item *free; /* free extent item */ 118 struct xfs_bmap_free_item *free; /* free extent item */
102 struct xfs_bmap_free_item *next; /* next item on free list */
103 119
104 ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); 120 ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES);
105 if (flist->xbf_count == 0) 121 if (flist->xbf_count == 0)
106 return 0; 122 return 0;
107 123
124 list_sort((*tp)->t_mountp, &flist->xbf_flist, xfs_bmap_free_list_cmp);
125
108 efi = xfs_trans_get_efi(*tp, flist->xbf_count); 126 efi = xfs_trans_get_efi(*tp, flist->xbf_count);
109 for (free = flist->xbf_first; free; free = free->xbfi_next) 127 list_for_each_entry(free, &flist->xbf_flist, xbfi_list)
110 xfs_trans_log_efi_extent(*tp, efi, free->xbfi_startblock, 128 xfs_trans_log_efi_extent(*tp, efi, free->xbfi_startblock,
111 free->xbfi_blockcount); 129 free->xbfi_blockcount);
112 130
@@ -138,15 +156,15 @@ xfs_bmap_finish(
138 * on error. 156 * on error.
139 */ 157 */
140 efd = xfs_trans_get_efd(*tp, efi, flist->xbf_count); 158 efd = xfs_trans_get_efd(*tp, efi, flist->xbf_count);
141 for (free = flist->xbf_first; free != NULL; free = next) { 159 while (!list_empty(&flist->xbf_flist)) {
142 next = free->xbfi_next; 160 free = list_first_entry(&flist->xbf_flist,
143 161 struct xfs_bmap_free_item, xbfi_list);
144 error = xfs_trans_free_extent(*tp, efd, free->xbfi_startblock, 162 error = xfs_trans_free_extent(*tp, efd, free->xbfi_startblock,
145 free->xbfi_blockcount); 163 free->xbfi_blockcount);
146 if (error) 164 if (error)
147 return error; 165 return error;
148 166
149 xfs_bmap_del_free(flist, NULL, free); 167 xfs_bmap_del_free(flist, free);
150 } 168 }
151 169
152 return 0; 170 return 0;
@@ -799,7 +817,7 @@ xfs_bmap_punch_delalloc_range(
799 if (error) 817 if (error)
800 break; 818 break;
801 819
802 ASSERT(!flist.xbf_count && !flist.xbf_first); 820 ASSERT(!flist.xbf_count && list_empty(&flist.xbf_flist));
803next_block: 821next_block:
804 start_fsb++; 822 start_fsb++;
805 remaining--; 823 remaining--;
diff --git a/fs/xfs/xfs_bmap_util.h b/fs/xfs/xfs_bmap_util.h
index af97d9a1dfb4..4ec85d1043a0 100644
--- a/fs/xfs/xfs_bmap_util.h
+++ b/fs/xfs/xfs_bmap_util.h
@@ -43,7 +43,6 @@ int xfs_getbmap(struct xfs_inode *ip, struct getbmapx *bmv,
43 43
44/* functions in xfs_bmap.c that are only needed by xfs_bmap_util.c */ 44/* functions in xfs_bmap.c that are only needed by xfs_bmap_util.c */
45void xfs_bmap_del_free(struct xfs_bmap_free *flist, 45void xfs_bmap_del_free(struct xfs_bmap_free *flist,
46 struct xfs_bmap_free_item *prev,
47 struct xfs_bmap_free_item *free); 46 struct xfs_bmap_free_item *free);
48int xfs_bmap_extsize_align(struct xfs_mount *mp, struct xfs_bmbt_irec *gotp, 47int xfs_bmap_extsize_align(struct xfs_mount *mp, struct xfs_bmbt_irec *gotp,
49 struct xfs_bmbt_irec *prevp, xfs_extlen_t extsz, 48 struct xfs_bmbt_irec *prevp, xfs_extlen_t extsz,
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 2d2810851871..5f3c7299532b 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1700,8 +1700,9 @@ xfs_init_zones(void)
1700 if (!xfs_log_ticket_zone) 1700 if (!xfs_log_ticket_zone)
1701 goto out_free_ioend_bioset; 1701 goto out_free_ioend_bioset;
1702 1702
1703 xfs_bmap_free_item_zone = kmem_zone_init(sizeof(xfs_bmap_free_item_t), 1703 xfs_bmap_free_item_zone = kmem_zone_init(
1704 "xfs_bmap_free_item"); 1704 sizeof(struct xfs_bmap_free_item),
1705 "xfs_bmap_free_item");
1705 if (!xfs_bmap_free_item_zone) 1706 if (!xfs_bmap_free_item_zone)
1706 goto out_destroy_log_ticket_zone; 1707 goto out_destroy_log_ticket_zone;
1707 1708