xfs: pass flags and return gc errors from xfs_blockgc_free_quota
authorDarrick J. Wong <djwong@kernel.org>
Sat, 23 Jan 2021 00:48:36 +0000 (16:48 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Wed, 3 Feb 2021 17:18:49 +0000 (09:18 -0800)
Change the signature of xfs_blockgc_free_quota in preparation for the
next few patches.  Callers can now pass EOF_FLAGS into the function to
control scan parameters; and the function will now pass back any
corruption errors seen while scanning, though for our retry loops we'll
just try again unconditionally.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Brian Foster <bfoster@redhat.com>
fs/xfs/xfs_file.c
fs/xfs/xfs_icache.c
fs/xfs/xfs_icache.h

index eade63d..8546dbf 100644 (file)
@@ -702,14 +702,14 @@ write_retry:
         * metadata space. This reduces the chances that the eofblocks scan
         * waits on dirty mappings. Since xfs_flush_inodes() is serialized, this
         * also behaves as a filter to prevent too many eofblocks scans from
-        * running at the same time.
+        * running at the same time.  Use a synchronous scan to increase the
+        * effectiveness of the scan.
         */
        if (ret == -EDQUOT && !cleared_space) {
                xfs_iunlock(ip, iolock);
-               cleared_space = xfs_blockgc_free_quota(ip);
-               if (cleared_space)
-                       goto write_retry;
-               iolock = 0;
+               xfs_blockgc_free_quota(ip, XFS_EOF_FLAGS_SYNC);
+               cleared_space = true;
+               goto write_retry;
        } else if (ret == -ENOSPC && !cleared_space) {
                struct xfs_eofblocks eofb = {0};
 
index aba901d..4a074aa 100644 (file)
@@ -1650,20 +1650,26 @@ xfs_start_block_reaping(
  * with multiple quotas, we don't know exactly which quota caused an allocation
  * failure. We make a best effort by including each quota under low free space
  * conditions (less than 1% free space) in the scan.
+ *
+ * Callers must not hold any inode's ILOCK.  If requesting a synchronous scan
+ * (XFS_EOF_FLAGS_SYNC), the caller also must not hold any inode's IOLOCK or
+ * MMAPLOCK.
  */
-bool
+int
 xfs_blockgc_free_quota(
-       struct xfs_inode        *ip)
+       struct xfs_inode        *ip,
+       unsigned int            eof_flags)
 {
        struct xfs_eofblocks    eofb = {0};
        struct xfs_dquot        *dq;
        bool                    do_work = false;
+       int                     error;
 
        /*
-        * Run a sync scan to increase effectiveness and use the union filter to
-        * cover all applicable quotas in a single scan.
+        * Run a scan to free blocks using the union filter to cover all
+        * applicable quotas in a single scan.
         */
-       eofb.eof_flags = XFS_EOF_FLAGS_UNION | XFS_EOF_FLAGS_SYNC;
+       eofb.eof_flags = XFS_EOF_FLAGS_UNION | eof_flags;
 
        if (XFS_IS_UQUOTA_ENFORCED(ip->i_mount)) {
                dq = xfs_inode_dquot(ip, XFS_DQTYPE_USER);
@@ -1693,9 +1699,11 @@ xfs_blockgc_free_quota(
        }
 
        if (!do_work)
-               return false;
+               return 0;
 
-       xfs_icache_free_eofblocks(ip->i_mount, &eofb);
-       xfs_icache_free_cowblocks(ip->i_mount, &eofb);
-       return true;
+       error = xfs_icache_free_eofblocks(ip->i_mount, &eofb);
+       if (error)
+               return error;
+
+       return xfs_icache_free_cowblocks(ip->i_mount, &eofb);
 }
index 21b726a..d64ea8f 100644 (file)
@@ -54,7 +54,7 @@ long xfs_reclaim_inodes_nr(struct xfs_mount *mp, int nr_to_scan);
 
 void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);
 
-bool xfs_blockgc_free_quota(struct xfs_inode *ip);
+int xfs_blockgc_free_quota(struct xfs_inode *ip, unsigned int eof_flags);
 
 void xfs_inode_set_eofblocks_tag(struct xfs_inode *ip);
 void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip);