summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2019-06-28 22:31:38 -0400
committerDarrick J. Wong <darrick.wong@oracle.com>2019-06-30 12:05:17 -0400
commit73d30d48749f883fbaaf68ef5d774e99ffafda5d (patch)
treebb1fc3ef60bb74dac86f8db0c3e3a80d95d56e65
parentfe64e0d26b1c8096073661851edc99d6370f5e96 (diff)
xfs: remove XFS_TRANS_NOFS
Instead of a magic flag for xfs_trans_alloc, just ensure all callers that can't relclaim through the file system use memalloc_nofs_save to set the per-task nofs flag. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
-rw-r--r--fs/xfs/libxfs/xfs_shared.h1
-rw-r--r--fs/xfs/xfs_aops.c35
-rw-r--r--fs/xfs/xfs_file.c18
-rw-r--r--fs/xfs/xfs_iomap.c2
-rw-r--r--fs/xfs/xfs_reflink.c4
-rw-r--r--fs/xfs/xfs_trans.c4
6 files changed, 41 insertions, 23 deletions
diff --git a/fs/xfs/libxfs/xfs_shared.h b/fs/xfs/libxfs/xfs_shared.h
index b9094709bc79..c45acbd3add9 100644
--- a/fs/xfs/libxfs/xfs_shared.h
+++ b/fs/xfs/libxfs/xfs_shared.h
@@ -65,7 +65,6 @@ void xfs_log_get_max_trans_res(struct xfs_mount *mp,
65#define XFS_TRANS_DQ_DIRTY 0x10 /* at least one dquot in trx dirty */ 65#define XFS_TRANS_DQ_DIRTY 0x10 /* at least one dquot in trx dirty */
66#define XFS_TRANS_RESERVE 0x20 /* OK to use reserved data blocks */ 66#define XFS_TRANS_RESERVE 0x20 /* OK to use reserved data blocks */
67#define XFS_TRANS_NO_WRITECOUNT 0x40 /* do not elevate SB writecount */ 67#define XFS_TRANS_NO_WRITECOUNT 0x40 /* do not elevate SB writecount */
68#define XFS_TRANS_NOFS 0x80 /* pass KM_NOFS to kmem_alloc */
69/* 68/*
70 * LOWMODE is used by the allocator to activate the lowspace algorithm - when 69 * LOWMODE is used by the allocator to activate the lowspace algorithm - when
71 * free space is running low the extent allocator may choose to allocate an 70 * free space is running low the extent allocator may choose to allocate an
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 326294a4918f..137b3a273f3d 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -133,8 +133,7 @@ xfs_setfilesize_trans_alloc(
133 struct xfs_trans *tp; 133 struct xfs_trans *tp;
134 int error; 134 int error;
135 135
136 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 136 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0, &tp);
137 XFS_TRANS_NOFS, &tp);
138 if (error) 137 if (error)
139 return error; 138 return error;
140 139
@@ -235,9 +234,17 @@ xfs_end_ioend(
235 struct xfs_inode *ip = XFS_I(ioend->io_inode); 234 struct xfs_inode *ip = XFS_I(ioend->io_inode);
236 xfs_off_t offset = ioend->io_offset; 235 xfs_off_t offset = ioend->io_offset;
237 size_t size = ioend->io_size; 236 size_t size = ioend->io_size;
237 unsigned int nofs_flag;
238 int error; 238 int error;
239 239
240 /* 240 /*
241 * We can allocate memory here while doing writeback on behalf of
242 * memory reclaim. To avoid memory allocation deadlocks set the
243 * task-wide nofs context for the following operations.
244 */
245 nofs_flag = memalloc_nofs_save();
246
247 /*
241 * Just clean up the in-memory strutures if the fs has been shut down. 248 * Just clean up the in-memory strutures if the fs has been shut down.
242 */ 249 */
243 if (XFS_FORCED_SHUTDOWN(ip->i_mount)) { 250 if (XFS_FORCED_SHUTDOWN(ip->i_mount)) {
@@ -277,6 +284,8 @@ done:
277 list_del_init(&ioend->io_list); 284 list_del_init(&ioend->io_list);
278 xfs_destroy_ioend(ioend, error); 285 xfs_destroy_ioend(ioend, error);
279 } 286 }
287
288 memalloc_nofs_restore(nofs_flag);
280} 289}
281 290
282/* 291/*
@@ -637,21 +646,19 @@ xfs_submit_ioend(
637 struct xfs_ioend *ioend, 646 struct xfs_ioend *ioend,
638 int status) 647 int status)
639{ 648{
649 unsigned int nofs_flag;
650
651 /*
652 * We can allocate memory here while doing writeback on behalf of
653 * memory reclaim. To avoid memory allocation deadlocks set the
654 * task-wide nofs context for the following operations.
655 */
656 nofs_flag = memalloc_nofs_save();
657
640 /* Convert CoW extents to regular */ 658 /* Convert CoW extents to regular */
641 if (!status && ioend->io_fork == XFS_COW_FORK) { 659 if (!status && ioend->io_fork == XFS_COW_FORK) {
642 /*
643 * Yuk. This can do memory allocation, but is not a
644 * transactional operation so everything is done in GFP_KERNEL
645 * context. That can deadlock, because we hold pages in
646 * writeback state and GFP_KERNEL allocations can block on them.
647 * Hence we must operate in nofs conditions here.
648 */
649 unsigned nofs_flag;
650
651 nofs_flag = memalloc_nofs_save();
652 status = xfs_reflink_convert_cow(XFS_I(ioend->io_inode), 660 status = xfs_reflink_convert_cow(XFS_I(ioend->io_inode),
653 ioend->io_offset, ioend->io_size); 661 ioend->io_offset, ioend->io_size);
654 memalloc_nofs_restore(nofs_flag);
655 } 662 }
656 663
657 /* Reserve log space if we might write beyond the on-disk inode size. */ 664 /* Reserve log space if we might write beyond the on-disk inode size. */
@@ -662,6 +669,8 @@ xfs_submit_ioend(
662 !ioend->io_append_trans) 669 !ioend->io_append_trans)
663 status = xfs_setfilesize_trans_alloc(ioend); 670 status = xfs_setfilesize_trans_alloc(ioend);
664 671
672 memalloc_nofs_restore(nofs_flag);
673
665 ioend->io_bio->bi_private = ioend; 674 ioend->io_bio->bi_private = ioend;
666 ioend->io_bio->bi_end_io = xfs_end_bio; 675 ioend->io_bio->bi_end_io = xfs_end_bio;
667 676
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 3041b44e38c6..e93bacbd49ae 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -374,6 +374,7 @@ xfs_dio_write_end_io(
374 struct inode *inode = file_inode(iocb->ki_filp); 374 struct inode *inode = file_inode(iocb->ki_filp);
375 struct xfs_inode *ip = XFS_I(inode); 375 struct xfs_inode *ip = XFS_I(inode);
376 loff_t offset = iocb->ki_pos; 376 loff_t offset = iocb->ki_pos;
377 unsigned int nofs_flag;
377 int error = 0; 378 int error = 0;
378 379
379 trace_xfs_end_io_direct_write(ip, offset, size); 380 trace_xfs_end_io_direct_write(ip, offset, size);
@@ -390,10 +391,17 @@ xfs_dio_write_end_io(
390 */ 391 */
391 XFS_STATS_ADD(ip->i_mount, xs_write_bytes, size); 392 XFS_STATS_ADD(ip->i_mount, xs_write_bytes, size);
392 393
394 /*
395 * We can allocate memory here while doing writeback on behalf of
396 * memory reclaim. To avoid memory allocation deadlocks set the
397 * task-wide nofs context for the following operations.
398 */
399 nofs_flag = memalloc_nofs_save();
400
393 if (flags & IOMAP_DIO_COW) { 401 if (flags & IOMAP_DIO_COW) {
394 error = xfs_reflink_end_cow(ip, offset, size); 402 error = xfs_reflink_end_cow(ip, offset, size);
395 if (error) 403 if (error)
396 return error; 404 goto out;
397 } 405 }
398 406
399 /* 407 /*
@@ -402,8 +410,10 @@ xfs_dio_write_end_io(
402 * earlier allows a racing dio read to find unwritten extents before 410 * earlier allows a racing dio read to find unwritten extents before
403 * they are converted. 411 * they are converted.
404 */ 412 */
405 if (flags & IOMAP_DIO_UNWRITTEN) 413 if (flags & IOMAP_DIO_UNWRITTEN) {
406 return xfs_iomap_write_unwritten(ip, offset, size, true); 414 error = xfs_iomap_write_unwritten(ip, offset, size, true);
415 goto out;
416 }
407 417
408 /* 418 /*
409 * We need to update the in-core inode size here so that we don't end up 419 * We need to update the in-core inode size here so that we don't end up
@@ -425,6 +435,8 @@ xfs_dio_write_end_io(
425 spin_unlock(&ip->i_flags_lock); 435 spin_unlock(&ip->i_flags_lock);
426 } 436 }
427 437
438out:
439 memalloc_nofs_restore(nofs_flag);
428 return error; 440 return error;
429} 441}
430 442
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index b1ef32822bb9..3a4310d7cb59 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -776,7 +776,7 @@ xfs_iomap_write_unwritten(
776 * complete here and might deadlock on the iolock. 776 * complete here and might deadlock on the iolock.
777 */ 777 */
778 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 778 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0,
779 XFS_TRANS_RESERVE | XFS_TRANS_NOFS, &tp); 779 XFS_TRANS_RESERVE, &tp);
780 if (error) 780 if (error)
781 return error; 781 return error;
782 782
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index da0ef8483c13..c4ec7afd1170 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -561,7 +561,7 @@ xfs_reflink_cancel_cow_range(
561 561
562 /* Start a rolling transaction to remove the mappings */ 562 /* Start a rolling transaction to remove the mappings */
563 error = xfs_trans_alloc(ip->i_mount, &M_RES(ip->i_mount)->tr_write, 563 error = xfs_trans_alloc(ip->i_mount, &M_RES(ip->i_mount)->tr_write,
564 0, 0, XFS_TRANS_NOFS, &tp); 564 0, 0, 0, &tp);
565 if (error) 565 if (error)
566 goto out; 566 goto out;
567 567
@@ -620,7 +620,7 @@ xfs_reflink_end_cow_extent(
620 620
621 resblks = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK); 621 resblks = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK);
622 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 622 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0,
623 XFS_TRANS_RESERVE | XFS_TRANS_NOFS, &tp); 623 XFS_TRANS_RESERVE, &tp);
624 if (error) 624 if (error)
625 return error; 625 return error;
626 626
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 5b31e0b400f4..d42a68d8313b 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -263,9 +263,7 @@ xfs_trans_alloc(
263 * GFP_NOFS allocation context so that we avoid lockdep false positives 263 * GFP_NOFS allocation context so that we avoid lockdep false positives
264 * by doing GFP_KERNEL allocations inside sb_start_intwrite(). 264 * by doing GFP_KERNEL allocations inside sb_start_intwrite().
265 */ 265 */
266 tp = kmem_zone_zalloc(xfs_trans_zone, 266 tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP);
267 (flags & XFS_TRANS_NOFS) ? KM_NOFS : KM_SLEEP);
268
269 if (!(flags & XFS_TRANS_NO_WRITECOUNT)) 267 if (!(flags & XFS_TRANS_NO_WRITECOUNT))
270 sb_start_intwrite(mp->m_super); 268 sb_start_intwrite(mp->m_super);
271 269