diff options
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.c | 1 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_linux.h | 1 | ||||
| -rw-r--r-- | fs/xfs/xfs_alloc.c | 56 | ||||
| -rw-r--r-- | fs/xfs/xfs_alloc.h | 11 | ||||
| -rw-r--r-- | fs/xfs/xfs_log_cil.c | 5 | ||||
| -rw-r--r-- | fs/xfs/xfs_trans.c | 6 |
6 files changed, 61 insertions, 19 deletions
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 9ef9ed2cfe2..09889035765 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
| @@ -33,7 +33,6 @@ | |||
| 33 | #include <linux/migrate.h> | 33 | #include <linux/migrate.h> |
| 34 | #include <linux/backing-dev.h> | 34 | #include <linux/backing-dev.h> |
| 35 | #include <linux/freezer.h> | 35 | #include <linux/freezer.h> |
| 36 | #include <linux/list_sort.h> | ||
| 37 | 36 | ||
| 38 | #include "xfs_sb.h" | 37 | #include "xfs_sb.h" |
| 39 | #include "xfs_inum.h" | 38 | #include "xfs_inum.h" |
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h index 244be9cbfe7..8633521b3b2 100644 --- a/fs/xfs/linux-2.6/xfs_linux.h +++ b/fs/xfs/linux-2.6/xfs_linux.h | |||
| @@ -70,6 +70,7 @@ | |||
| 70 | #include <linux/ctype.h> | 70 | #include <linux/ctype.h> |
| 71 | #include <linux/writeback.h> | 71 | #include <linux/writeback.h> |
| 72 | #include <linux/capability.h> | 72 | #include <linux/capability.h> |
| 73 | #include <linux/list_sort.h> | ||
| 73 | 74 | ||
| 74 | #include <asm/page.h> | 75 | #include <asm/page.h> |
| 75 | #include <asm/div64.h> | 76 | #include <asm/div64.h> |
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 53157d4d5e8..44a51a7b4c3 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c | |||
| @@ -2964,24 +2964,60 @@ fail: | |||
| 2964 | *rlen = 0; | 2964 | *rlen = 0; |
| 2965 | } | 2965 | } |
| 2966 | 2966 | ||
| 2967 | void | 2967 | static void |
| 2968 | xfs_alloc_busy_clear( | 2968 | xfs_alloc_busy_clear_one( |
| 2969 | struct xfs_mount *mp, | 2969 | struct xfs_mount *mp, |
| 2970 | struct xfs_perag *pag, | ||
| 2970 | struct xfs_busy_extent *busyp) | 2971 | struct xfs_busy_extent *busyp) |
| 2971 | { | 2972 | { |
| 2972 | struct xfs_perag *pag; | ||
| 2973 | |||
| 2974 | list_del_init(&busyp->list); | ||
| 2975 | |||
| 2976 | pag = xfs_perag_get(mp, busyp->agno); | ||
| 2977 | spin_lock(&pag->pagb_lock); | ||
| 2978 | if (busyp->length) { | 2973 | if (busyp->length) { |
| 2979 | trace_xfs_alloc_busy_clear(mp, busyp->agno, busyp->bno, | 2974 | trace_xfs_alloc_busy_clear(mp, busyp->agno, busyp->bno, |
| 2980 | busyp->length); | 2975 | busyp->length); |
| 2981 | rb_erase(&busyp->rb_node, &pag->pagb_tree); | 2976 | rb_erase(&busyp->rb_node, &pag->pagb_tree); |
| 2982 | } | 2977 | } |
| 2983 | spin_unlock(&pag->pagb_lock); | ||
| 2984 | xfs_perag_put(pag); | ||
| 2985 | 2978 | ||
| 2979 | list_del_init(&busyp->list); | ||
| 2986 | kmem_free(busyp); | 2980 | kmem_free(busyp); |
| 2987 | } | 2981 | } |
| 2982 | |||
| 2983 | void | ||
| 2984 | xfs_alloc_busy_clear( | ||
| 2985 | struct xfs_mount *mp, | ||
| 2986 | struct list_head *list) | ||
| 2987 | { | ||
| 2988 | struct xfs_busy_extent *busyp, *n; | ||
| 2989 | struct xfs_perag *pag = NULL; | ||
| 2990 | xfs_agnumber_t agno = NULLAGNUMBER; | ||
| 2991 | |||
| 2992 | list_for_each_entry_safe(busyp, n, list, list) { | ||
| 2993 | if (busyp->agno != agno) { | ||
| 2994 | if (pag) { | ||
| 2995 | spin_unlock(&pag->pagb_lock); | ||
| 2996 | xfs_perag_put(pag); | ||
| 2997 | } | ||
| 2998 | pag = xfs_perag_get(mp, busyp->agno); | ||
| 2999 | spin_lock(&pag->pagb_lock); | ||
| 3000 | agno = busyp->agno; | ||
| 3001 | } | ||
| 3002 | |||
| 3003 | xfs_alloc_busy_clear_one(mp, pag, busyp); | ||
| 3004 | } | ||
| 3005 | |||
| 3006 | if (pag) { | ||
| 3007 | spin_unlock(&pag->pagb_lock); | ||
| 3008 | xfs_perag_put(pag); | ||
| 3009 | } | ||
| 3010 | } | ||
| 3011 | |||
| 3012 | /* | ||
| 3013 | * Callback for list_sort to sort busy extents by the AG they reside in. | ||
| 3014 | */ | ||
| 3015 | int | ||
| 3016 | xfs_busy_extent_ag_cmp( | ||
| 3017 | void *priv, | ||
| 3018 | struct list_head *a, | ||
| 3019 | struct list_head *b) | ||
| 3020 | { | ||
| 3021 | return container_of(a, struct xfs_busy_extent, list)->agno - | ||
| 3022 | container_of(b, struct xfs_busy_extent, list)->agno; | ||
| 3023 | } | ||
diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h index de5e27c9517..240ad288f2f 100644 --- a/fs/xfs/xfs_alloc.h +++ b/fs/xfs/xfs_alloc.h | |||
| @@ -140,7 +140,7 @@ xfs_alloc_busy_insert(struct xfs_trans *tp, xfs_agnumber_t agno, | |||
| 140 | xfs_agblock_t bno, xfs_extlen_t len); | 140 | xfs_agblock_t bno, xfs_extlen_t len); |
| 141 | 141 | ||
| 142 | void | 142 | void |
| 143 | xfs_alloc_busy_clear(struct xfs_mount *mp, struct xfs_busy_extent *busyp); | 143 | xfs_alloc_busy_clear(struct xfs_mount *mp, struct list_head *list); |
| 144 | 144 | ||
| 145 | int | 145 | int |
| 146 | xfs_alloc_busy_search(struct xfs_mount *mp, xfs_agnumber_t agno, | 146 | xfs_alloc_busy_search(struct xfs_mount *mp, xfs_agnumber_t agno, |
| @@ -149,6 +149,15 @@ xfs_alloc_busy_search(struct xfs_mount *mp, xfs_agnumber_t agno, | |||
| 149 | void | 149 | void |
| 150 | xfs_alloc_busy_reuse(struct xfs_mount *mp, xfs_agnumber_t agno, | 150 | xfs_alloc_busy_reuse(struct xfs_mount *mp, xfs_agnumber_t agno, |
| 151 | xfs_agblock_t fbno, xfs_extlen_t flen, bool userdata); | 151 | xfs_agblock_t fbno, xfs_extlen_t flen, bool userdata); |
| 152 | |||
| 153 | int | ||
| 154 | xfs_busy_extent_ag_cmp(void *priv, struct list_head *a, struct list_head *b); | ||
| 155 | |||
| 156 | static inline void xfs_alloc_busy_sort(struct list_head *list) | ||
| 157 | { | ||
| 158 | list_sort(NULL, list, xfs_busy_extent_ag_cmp); | ||
| 159 | } | ||
| 160 | |||
| 152 | #endif /* __KERNEL__ */ | 161 | #endif /* __KERNEL__ */ |
| 153 | 162 | ||
| 154 | /* | 163 | /* |
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index 9ca59be0897..7d56e88a3f0 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c | |||
| @@ -361,13 +361,12 @@ xlog_cil_committed( | |||
| 361 | int abort) | 361 | int abort) |
| 362 | { | 362 | { |
| 363 | struct xfs_cil_ctx *ctx = args; | 363 | struct xfs_cil_ctx *ctx = args; |
| 364 | struct xfs_busy_extent *busyp, *n; | ||
| 365 | 364 | ||
| 366 | xfs_trans_committed_bulk(ctx->cil->xc_log->l_ailp, ctx->lv_chain, | 365 | xfs_trans_committed_bulk(ctx->cil->xc_log->l_ailp, ctx->lv_chain, |
| 367 | ctx->start_lsn, abort); | 366 | ctx->start_lsn, abort); |
| 368 | 367 | ||
| 369 | list_for_each_entry_safe(busyp, n, &ctx->busy_extents, list) | 368 | xfs_alloc_busy_sort(&ctx->busy_extents); |
| 370 | xfs_alloc_busy_clear(ctx->cil->xc_log->l_mp, busyp); | 369 | xfs_alloc_busy_clear(ctx->cil->xc_log->l_mp, &ctx->busy_extents); |
| 371 | 370 | ||
| 372 | spin_lock(&ctx->cil->xc_cil_lock); | 371 | spin_lock(&ctx->cil->xc_cil_lock); |
| 373 | list_del(&ctx->committing); | 372 | list_del(&ctx->committing); |
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 76922793f64..d1f24858ccc 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
| @@ -608,10 +608,8 @@ STATIC void | |||
| 608 | xfs_trans_free( | 608 | xfs_trans_free( |
| 609 | struct xfs_trans *tp) | 609 | struct xfs_trans *tp) |
| 610 | { | 610 | { |
| 611 | struct xfs_busy_extent *busyp, *n; | 611 | xfs_alloc_busy_sort(&tp->t_busy); |
| 612 | 612 | xfs_alloc_busy_clear(tp->t_mountp, &tp->t_busy); | |
| 613 | list_for_each_entry_safe(busyp, n, &tp->t_busy, list) | ||
| 614 | xfs_alloc_busy_clear(tp->t_mountp, busyp); | ||
| 615 | 613 | ||
| 616 | atomic_dec(&tp->t_mountp->m_active_trans); | 614 | atomic_dec(&tp->t_mountp->m_active_trans); |
| 617 | xfs_trans_free_dqinfo(tp); | 615 | xfs_trans_free_dqinfo(tp); |
