aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c1
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h1
-rw-r--r--fs/xfs/xfs_alloc.c56
-rw-r--r--fs/xfs/xfs_alloc.h11
-rw-r--r--fs/xfs/xfs_log_cil.c5
-rw-r--r--fs/xfs/xfs_trans.c6
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
2967void 2967static void
2968xfs_alloc_busy_clear( 2968xfs_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
2983void
2984xfs_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 */
3015int
3016xfs_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
142void 142void
143xfs_alloc_busy_clear(struct xfs_mount *mp, struct xfs_busy_extent *busyp); 143xfs_alloc_busy_clear(struct xfs_mount *mp, struct list_head *list);
144 144
145int 145int
146xfs_alloc_busy_search(struct xfs_mount *mp, xfs_agnumber_t agno, 146xfs_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,
149void 149void
150xfs_alloc_busy_reuse(struct xfs_mount *mp, xfs_agnumber_t agno, 150xfs_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
153int
154xfs_busy_extent_ag_cmp(void *priv, struct list_head *a, struct list_head *b);
155
156static 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
608xfs_trans_free( 608xfs_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);