xfs: introduce an allocation workqueue
[deliverable/linux.git] / fs / xfs / xfs_alloc.c
index ce84ffd0264c86c77111145075c14fdc11b8a12f..31e90335b83d7d24a4a5fdebcc4f0e1c2ea1027e 100644 (file)
@@ -35,6 +35,7 @@
 #include "xfs_error.h"
 #include "xfs_trace.h"
 
+struct workqueue_struct *xfs_alloc_wq;
 
 #define XFS_ABSDIFF(a,b)       (((a) <= (b)) ? ((b) - (a)) : ((a) - (b)))
 
@@ -2207,7 +2208,7 @@ xfs_alloc_read_agf(
  * group or loop over the allocation groups to find the result.
  */
 int                            /* error */
-xfs_alloc_vextent(
+__xfs_alloc_vextent(
        xfs_alloc_arg_t *args)  /* allocation argument structure */
 {
        xfs_agblock_t   agsize; /* allocation group size */
@@ -2417,6 +2418,37 @@ error0:
        return error;
 }
 
+static void
+xfs_alloc_vextent_worker(
+       struct work_struct      *work)
+{
+       struct xfs_alloc_arg    *args = container_of(work,
+                                               struct xfs_alloc_arg, work);
+       unsigned long           pflags;
+
+       /* we are in a transaction context here */
+       current_set_flags_nested(&pflags, PF_FSTRANS);
+
+       args->result = __xfs_alloc_vextent(args);
+       complete(args->done);
+
+       current_restore_flags_nested(&pflags, PF_FSTRANS);
+}
+
+
+int                            /* error */
+xfs_alloc_vextent(
+       xfs_alloc_arg_t *args)  /* allocation argument structure */
+{
+       DECLARE_COMPLETION_ONSTACK(done);
+
+       args->done = &done;
+       INIT_WORK(&args->work, xfs_alloc_vextent_worker);
+       queue_work(xfs_alloc_wq, &args->work);
+       wait_for_completion(&done);
+       return args->result;
+}
+
 /*
  * Free an extent.
  * Just break up the extent address and hand off to xfs_free_ag_extent
This page took 0.027912 seconds and 5 git commands to generate.