diff options
| -rw-r--r-- | fs/xfs/libxfs/xfs_bmap.c | 39 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_bmap.h | 14 | ||||
| -rw-r--r-- | fs/xfs/xfs_bmap_util.c | 32 | ||||
| -rw-r--r-- | fs/xfs/xfs_bmap_util.h | 1 | ||||
| -rw-r--r-- | fs/xfs/xfs_super.c | 5 |
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 | */ |
| 618 | void | 606 | void |
| 619 | xfs_bmap_del_free( | 607 | xfs_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 | */ |
| 635 | void | 619 | void |
| 636 | xfs_bmap_cancel( | 620 | xfs_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 | */ |
| 65 | typedef struct xfs_bmap_free_item | 65 | struct 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 | */ |
| 86 | typedef struct xfs_bmap_free | 86 | typedef 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 | ||
| 142 | static inline void xfs_bmap_init(xfs_bmap_free_t *flp, xfs_fsblock_t *fbp) | 142 | static 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. */ | ||
| 83 | static int | ||
| 84 | xfs_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)); |
| 803 | next_block: | 821 | next_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 */ |
| 45 | void xfs_bmap_del_free(struct xfs_bmap_free *flist, | 45 | void 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); |
| 48 | int xfs_bmap_extsize_align(struct xfs_mount *mp, struct xfs_bmbt_irec *gotp, | 47 | int 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 | ||
