xfs: remove XFS_TRANS_NOFS
authorChristoph Hellwig <hch@lst.de>
Sat, 29 Jun 2019 02:31:38 +0000 (19:31 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Sun, 30 Jun 2019 16:05:17 +0000 (09:05 -0700)
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>
fs/xfs/libxfs/xfs_shared.h
fs/xfs/xfs_aops.c
fs/xfs/xfs_file.c
fs/xfs/xfs_iomap.c
fs/xfs/xfs_reflink.c
fs/xfs/xfs_trans.c

index b9094709bc799bbb4f32bf403559099972893d29..c45acbd3add94d17ea83b5863cb1312cdb0c9f9b 100644 (file)
@@ -65,7 +65,6 @@ void  xfs_log_get_max_trans_res(struct xfs_mount *mp,
 #define XFS_TRANS_DQ_DIRTY     0x10    /* at least one dquot in trx dirty */
 #define XFS_TRANS_RESERVE      0x20    /* OK to use reserved data blocks */
 #define XFS_TRANS_NO_WRITECOUNT 0x40   /* do not elevate SB writecount */
-#define XFS_TRANS_NOFS         0x80    /* pass KM_NOFS to kmem_alloc */
 /*
  * LOWMODE is used by the allocator to activate the lowspace algorithm - when
  * free space is running low the extent allocator may choose to allocate an
index 326294a4918f770cb7175c3e6e5e3be72dee4ace..137b3a273f3d4670f6d8397ba867484bd6f69709 100644 (file)
@@ -133,8 +133,7 @@ xfs_setfilesize_trans_alloc(
        struct xfs_trans        *tp;
        int                     error;
 
-       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0,
-                               XFS_TRANS_NOFS, &tp);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0, &tp);
        if (error)
                return error;
 
@@ -235,8 +234,16 @@ xfs_end_ioend(
        struct xfs_inode        *ip = XFS_I(ioend->io_inode);
        xfs_off_t               offset = ioend->io_offset;
        size_t                  size = ioend->io_size;
+       unsigned int            nofs_flag;
        int                     error;
 
+       /*
+        * We can allocate memory here while doing writeback on behalf of
+        * memory reclaim.  To avoid memory allocation deadlocks set the
+        * task-wide nofs context for the following operations.
+        */
+       nofs_flag = memalloc_nofs_save();
+
        /*
         * Just clean up the in-memory strutures if the fs has been shut down.
         */
@@ -277,6 +284,8 @@ done:
                list_del_init(&ioend->io_list);
                xfs_destroy_ioend(ioend, error);
        }
+
+       memalloc_nofs_restore(nofs_flag);
 }
 
 /*
@@ -637,21 +646,19 @@ xfs_submit_ioend(
        struct xfs_ioend        *ioend,
        int                     status)
 {
+       unsigned int            nofs_flag;
+
+       /*
+        * We can allocate memory here while doing writeback on behalf of
+        * memory reclaim.  To avoid memory allocation deadlocks set the
+        * task-wide nofs context for the following operations.
+        */
+       nofs_flag = memalloc_nofs_save();
+
        /* Convert CoW extents to regular */
        if (!status && ioend->io_fork == XFS_COW_FORK) {
-               /*
-                * Yuk. This can do memory allocation, but is not a
-                * transactional operation so everything is done in GFP_KERNEL
-                * context. That can deadlock, because we hold pages in
-                * writeback state and GFP_KERNEL allocations can block on them.
-                * Hence we must operate in nofs conditions here.
-                */
-               unsigned nofs_flag;
-
-               nofs_flag = memalloc_nofs_save();
                status = xfs_reflink_convert_cow(XFS_I(ioend->io_inode),
                                ioend->io_offset, ioend->io_size);
-               memalloc_nofs_restore(nofs_flag);
        }
 
        /* Reserve log space if we might write beyond the on-disk inode size. */
@@ -662,6 +669,8 @@ xfs_submit_ioend(
            !ioend->io_append_trans)
                status = xfs_setfilesize_trans_alloc(ioend);
 
+       memalloc_nofs_restore(nofs_flag);
+
        ioend->io_bio->bi_private = ioend;
        ioend->io_bio->bi_end_io = xfs_end_bio;
 
index 3041b44e38c6d2168344129fb3aa4ac22ecb78bc..e93bacbd49aed89946e22effc1c47b3026ec865b 100644 (file)
@@ -374,6 +374,7 @@ xfs_dio_write_end_io(
        struct inode            *inode = file_inode(iocb->ki_filp);
        struct xfs_inode        *ip = XFS_I(inode);
        loff_t                  offset = iocb->ki_pos;
+       unsigned int            nofs_flag;
        int                     error = 0;
 
        trace_xfs_end_io_direct_write(ip, offset, size);
@@ -390,10 +391,17 @@ xfs_dio_write_end_io(
         */
        XFS_STATS_ADD(ip->i_mount, xs_write_bytes, size);
 
+       /*
+        * We can allocate memory here while doing writeback on behalf of
+        * memory reclaim.  To avoid memory allocation deadlocks set the
+        * task-wide nofs context for the following operations.
+        */
+       nofs_flag = memalloc_nofs_save();
+
        if (flags & IOMAP_DIO_COW) {
                error = xfs_reflink_end_cow(ip, offset, size);
                if (error)
-                       return error;
+                       goto out;
        }
 
        /*
@@ -402,8 +410,10 @@ xfs_dio_write_end_io(
         * earlier allows a racing dio read to find unwritten extents before
         * they are converted.
         */
-       if (flags & IOMAP_DIO_UNWRITTEN)
-               return xfs_iomap_write_unwritten(ip, offset, size, true);
+       if (flags & IOMAP_DIO_UNWRITTEN) {
+               error = xfs_iomap_write_unwritten(ip, offset, size, true);
+               goto out;
+       }
 
        /*
         * 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(
                spin_unlock(&ip->i_flags_lock);
        }
 
+out:
+       memalloc_nofs_restore(nofs_flag);
        return error;
 }
 
index b1ef32822bb9ee36b2c8382adb57ae1ec6fb1598..3a4310d7cb59d4901d7519002f7eae03e5170ab5 100644 (file)
@@ -776,7 +776,7 @@ xfs_iomap_write_unwritten(
                 * complete here and might deadlock on the iolock.
                 */
                error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0,
-                               XFS_TRANS_RESERVE | XFS_TRANS_NOFS, &tp);
+                               XFS_TRANS_RESERVE, &tp);
                if (error)
                        return error;
 
index da0ef8483c130a1de1ed665ab92e5c8fb1812a01..c4ec7afd1170a7550df8704b2bb71ae450c927f5 100644 (file)
@@ -561,7 +561,7 @@ xfs_reflink_cancel_cow_range(
 
        /* Start a rolling transaction to remove the mappings */
        error = xfs_trans_alloc(ip->i_mount, &M_RES(ip->i_mount)->tr_write,
-                       0, 0, XFS_TRANS_NOFS, &tp);
+                       0, 0, 0, &tp);
        if (error)
                goto out;
 
@@ -620,7 +620,7 @@ xfs_reflink_end_cow_extent(
 
        resblks = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK);
        error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0,
-                       XFS_TRANS_RESERVE | XFS_TRANS_NOFS, &tp);
+                       XFS_TRANS_RESERVE, &tp);
        if (error)
                return error;
 
index 5b31e0b400f48ab332ce7b26b6ad7855747e63a0..d42a68d8313bdd5721f317a6c64858a67b13d6e6 100644 (file)
@@ -263,9 +263,7 @@ xfs_trans_alloc(
         * GFP_NOFS allocation context so that we avoid lockdep false positives
         * by doing GFP_KERNEL allocations inside sb_start_intwrite().
         */
-       tp = kmem_zone_zalloc(xfs_trans_zone,
-               (flags & XFS_TRANS_NOFS) ? KM_NOFS : KM_SLEEP);
-
+       tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP);
        if (!(flags & XFS_TRANS_NO_WRITECOUNT))
                sb_start_intwrite(mp->m_super);