aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_bmap_util.c16
-rw-r--r--fs/xfs/xfs_bmap_util.h13
2 files changed, 20 insertions, 9 deletions
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 296160b8e78c..47a9daa7b4e6 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -258,14 +258,23 @@ xfs_bmapi_allocate_worker(
258 struct xfs_bmalloca *args = container_of(work, 258 struct xfs_bmalloca *args = container_of(work,
259 struct xfs_bmalloca, work); 259 struct xfs_bmalloca, work);
260 unsigned long pflags; 260 unsigned long pflags;
261 unsigned long new_pflags = PF_FSTRANS;
261 262
262 /* we are in a transaction context here */ 263 /*
263 current_set_flags_nested(&pflags, PF_FSTRANS); 264 * we are in a transaction context here, but may also be doing work
265 * in kswapd context, and hence we may need to inherit that state
266 * temporarily to ensure that we don't block waiting for memory reclaim
267 * in any way.
268 */
269 if (args->kswapd)
270 new_pflags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD;
271
272 current_set_flags_nested(&pflags, new_pflags);
264 273
265 args->result = __xfs_bmapi_allocate(args); 274 args->result = __xfs_bmapi_allocate(args);
266 complete(args->done); 275 complete(args->done);
267 276
268 current_restore_flags_nested(&pflags, PF_FSTRANS); 277 current_restore_flags_nested(&pflags, new_pflags);
269} 278}
270 279
271/* 280/*
@@ -284,6 +293,7 @@ xfs_bmapi_allocate(
284 293
285 294
286 args->done = &done; 295 args->done = &done;
296 args->kswapd = current_is_kswapd();
287 INIT_WORK_ONSTACK(&args->work, xfs_bmapi_allocate_worker); 297 INIT_WORK_ONSTACK(&args->work, xfs_bmapi_allocate_worker);
288 queue_work(xfs_alloc_wq, &args->work); 298 queue_work(xfs_alloc_wq, &args->work);
289 wait_for_completion(&done); 299 wait_for_completion(&done);
diff --git a/fs/xfs/xfs_bmap_util.h b/fs/xfs/xfs_bmap_util.h
index 935ed2b24edf..075f72232a64 100644
--- a/fs/xfs/xfs_bmap_util.h
+++ b/fs/xfs/xfs_bmap_util.h
@@ -50,12 +50,13 @@ struct xfs_bmalloca {
50 xfs_extlen_t total; /* total blocks needed for xaction */ 50 xfs_extlen_t total; /* total blocks needed for xaction */
51 xfs_extlen_t minlen; /* minimum allocation size (blocks) */ 51 xfs_extlen_t minlen; /* minimum allocation size (blocks) */
52 xfs_extlen_t minleft; /* amount must be left after alloc */ 52 xfs_extlen_t minleft; /* amount must be left after alloc */
53 char eof; /* set if allocating past last extent */ 53 bool eof; /* set if allocating past last extent */
54 char wasdel; /* replacing a delayed allocation */ 54 bool wasdel; /* replacing a delayed allocation */
55 char userdata;/* set if is user data */ 55 bool userdata;/* set if is user data */
56 char aeof; /* allocated space at eof */ 56 bool aeof; /* allocated space at eof */
57 char conv; /* overwriting unwritten extents */ 57 bool conv; /* overwriting unwritten extents */
58 char stack_switch; 58 bool stack_switch;
59 bool kswapd; /* allocation in kswapd context */
59 int flags; 60 int flags;
60 struct completion *done; 61 struct completion *done;
61 struct work_struct work; 62 struct work_struct work;