Merge tag 'clang-features-v5.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / fs / xfs / xfs_mount.c
index cb1e2c4..bdfee19 100644 (file)
@@ -1188,6 +1188,7 @@ xfs_mod_fdblocks(
        int64_t                 lcounter;
        long long               res_used;
        s32                     batch;
+       uint64_t                set_aside;
 
        if (delta > 0) {
                /*
@@ -1227,8 +1228,20 @@ xfs_mod_fdblocks(
        else
                batch = XFS_FDBLOCKS_BATCH;
 
+       /*
+        * Set aside allocbt blocks because these blocks are tracked as free
+        * space but not available for allocation. Technically this means that a
+        * single reservation cannot consume all remaining free space, but the
+        * ratio of allocbt blocks to usable free blocks should be rather small.
+        * The tradeoff without this is that filesystems that maintain high
+        * perag block reservations can over reserve physical block availability
+        * and fail physical allocation, which leads to much more serious
+        * problems (i.e. transaction abort, pagecache discards, etc.) than
+        * slightly premature -ENOSPC.
+        */
+       set_aside = mp->m_alloc_set_aside + atomic64_read(&mp->m_allocbt_blks);
        percpu_counter_add_batch(&mp->m_fdblocks, delta, batch);
-       if (__percpu_counter_compare(&mp->m_fdblocks, mp->m_alloc_set_aside,
+       if (__percpu_counter_compare(&mp->m_fdblocks, set_aside,
                                     XFS_FDBLOCKS_BATCH) >= 0) {
                /* we had space! */
                return 0;