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 9ef9ed2cfe2e..098890357659 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 244be9cbfe78..8633521b3b2e 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 53157d4d5e8b..44a51a7b4c3a 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 de5e27c95170..240ad288f2f9 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 9ca59be08977..7d56e88a3f0e 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 76922793f64f..d1f24858ccc4 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); |