diff options
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_bmap_util.c | 16 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap_util.h | 13 |
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; |