aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_alloc.c34
-rw-r--r--fs/xfs/xfs_alloc.h5
-rw-r--r--fs/xfs/xfs_super.c16
3 files changed, 54 insertions, 1 deletions
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index ce84ffd0264c..31e90335b83d 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -35,6 +35,7 @@
35#include "xfs_error.h" 35#include "xfs_error.h"
36#include "xfs_trace.h" 36#include "xfs_trace.h"
37 37
38struct workqueue_struct *xfs_alloc_wq;
38 39
39#define XFS_ABSDIFF(a,b) (((a) <= (b)) ? ((b) - (a)) : ((a) - (b))) 40#define XFS_ABSDIFF(a,b) (((a) <= (b)) ? ((b) - (a)) : ((a) - (b)))
40 41
@@ -2207,7 +2208,7 @@ xfs_alloc_read_agf(
2207 * group or loop over the allocation groups to find the result. 2208 * group or loop over the allocation groups to find the result.
2208 */ 2209 */
2209int /* error */ 2210int /* error */
2210xfs_alloc_vextent( 2211__xfs_alloc_vextent(
2211 xfs_alloc_arg_t *args) /* allocation argument structure */ 2212 xfs_alloc_arg_t *args) /* allocation argument structure */
2212{ 2213{
2213 xfs_agblock_t agsize; /* allocation group size */ 2214 xfs_agblock_t agsize; /* allocation group size */
@@ -2417,6 +2418,37 @@ error0:
2417 return error; 2418 return error;
2418} 2419}
2419 2420
2421static void
2422xfs_alloc_vextent_worker(
2423 struct work_struct *work)
2424{
2425 struct xfs_alloc_arg *args = container_of(work,
2426 struct xfs_alloc_arg, work);
2427 unsigned long pflags;
2428
2429 /* we are in a transaction context here */
2430 current_set_flags_nested(&pflags, PF_FSTRANS);
2431
2432 args->result = __xfs_alloc_vextent(args);
2433 complete(args->done);
2434
2435 current_restore_flags_nested(&pflags, PF_FSTRANS);
2436}
2437
2438
2439int /* error */
2440xfs_alloc_vextent(
2441 xfs_alloc_arg_t *args) /* allocation argument structure */
2442{
2443 DECLARE_COMPLETION_ONSTACK(done);
2444
2445 args->done = &done;
2446 INIT_WORK(&args->work, xfs_alloc_vextent_worker);
2447 queue_work(xfs_alloc_wq, &args->work);
2448 wait_for_completion(&done);
2449 return args->result;
2450}
2451
2420/* 2452/*
2421 * Free an extent. 2453 * Free an extent.
2422 * Just break up the extent address and hand off to xfs_free_ag_extent 2454 * Just break up the extent address and hand off to xfs_free_ag_extent
diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h
index 2f52b924be79..ab5d0fd2f535 100644
--- a/fs/xfs/xfs_alloc.h
+++ b/fs/xfs/xfs_alloc.h
@@ -25,6 +25,8 @@ struct xfs_perag;
25struct xfs_trans; 25struct xfs_trans;
26struct xfs_busy_extent; 26struct xfs_busy_extent;
27 27
28extern struct workqueue_struct *xfs_alloc_wq;
29
28/* 30/*
29 * Freespace allocation types. Argument to xfs_alloc_[v]extent. 31 * Freespace allocation types. Argument to xfs_alloc_[v]extent.
30 */ 32 */
@@ -119,6 +121,9 @@ typedef struct xfs_alloc_arg {
119 char isfl; /* set if is freelist blocks - !acctg */ 121 char isfl; /* set if is freelist blocks - !acctg */
120 char userdata; /* set if this is user data */ 122 char userdata; /* set if this is user data */
121 xfs_fsblock_t firstblock; /* io first block allocated */ 123 xfs_fsblock_t firstblock; /* io first block allocated */
124 struct completion *done;
125 struct work_struct work;
126 int result;
122} xfs_alloc_arg_t; 127} xfs_alloc_arg_t;
123 128
124/* 129/*
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 06d23b976f4c..5484888d39c4 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1607,12 +1607,28 @@ xfs_init_workqueues(void)
1607 xfs_syncd_wq = alloc_workqueue("xfssyncd", WQ_NON_REENTRANT, 0); 1607 xfs_syncd_wq = alloc_workqueue("xfssyncd", WQ_NON_REENTRANT, 0);
1608 if (!xfs_syncd_wq) 1608 if (!xfs_syncd_wq)
1609 return -ENOMEM; 1609 return -ENOMEM;
1610
1611 /*
1612 * The allocation workqueue can be used in memory reclaim situations
1613 * (writepage path), and parallelism is only limited by the number of
1614 * AGs in all the filesystems mounted. Hence use the default large
1615 * max_active value for this workqueue.
1616 */
1617 xfs_alloc_wq = alloc_workqueue("xfsalloc", WQ_MEM_RECLAIM, 0);
1618 if (!xfs_alloc_wq)
1619 goto out_destroy_syncd;
1620
1610 return 0; 1621 return 0;
1622
1623out_destroy_syncd:
1624 destroy_workqueue(xfs_syncd_wq);
1625 return -ENOMEM;
1611} 1626}
1612 1627
1613STATIC void 1628STATIC void
1614xfs_destroy_workqueues(void) 1629xfs_destroy_workqueues(void)
1615{ 1630{
1631 destroy_workqueue(xfs_alloc_wq);
1616 destroy_workqueue(xfs_syncd_wq); 1632 destroy_workqueue(xfs_syncd_wq);
1617} 1633}
1618 1634