bcachefs: statfs resports incorrect avail blocks
authorDan Robertson <dan@dlrobertson.com>
Wed, 19 May 2021 00:36:20 +0000 (20:36 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:03 +0000 (17:09 -0400)
The current implementation of bch_statfs does not scale the number of
available blocks provided in f_bavail by the reserve factor. This causes
an allocation of a file of this size to fail.

Signed-off-by: Dan Robertson <dan@dlrobertson.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/buckets.c
fs/bcachefs/buckets.h
fs/bcachefs/fs.c

index afee0594efae1adfe6ae45f8c10b61c9c5352c77..b37cdf7279de6faae587bf9e52cc1a0111966bfc 100644 (file)
@@ -261,18 +261,11 @@ void bch2_fs_usage_to_text(struct printbuf *out,
        }
 }
 
-#define RESERVE_FACTOR 6
-
 static u64 reserve_factor(u64 r)
 {
        return r + (round_up(r, (1 << RESERVE_FACTOR)) >> RESERVE_FACTOR);
 }
 
-static u64 avail_factor(u64 r)
-{
-       return div_u64(r << RESERVE_FACTOR, (1 << RESERVE_FACTOR) + 1);
-}
-
 u64 bch2_fs_sectors_used(struct bch_fs *c, struct bch_fs_usage_online *fs_usage)
 {
        return min(fs_usage->u.hidden +
index 7463e6420b142d35268cc5548b936c9200c569d6..04a2a9310cdd9e9fc4d4ceb7a003d618540d7205 100644 (file)
@@ -294,6 +294,13 @@ static inline int bch2_disk_reservation_get(struct bch_fs *c,
        return bch2_disk_reservation_add(c, res, sectors * nr_replicas, flags);
 }
 
+#define RESERVE_FACTOR 6
+
+static inline u64 avail_factor(u64 r)
+{
+       return div_u64(r << RESERVE_FACTOR, (1 << RESERVE_FACTOR) + 1);
+}
+
 int bch2_dev_buckets_resize(struct bch_fs *, struct bch_dev *, u64);
 void bch2_dev_buckets_free(struct bch_dev *);
 int bch2_dev_buckets_alloc(struct bch_fs *, struct bch_dev *);
index 5eef67358cfb0fa46e80372a63a6822c8443fed6..9a595c205dbf56b3717663555c4f42ba082ec926 100644 (file)
@@ -1274,8 +1274,8 @@ static int bch2_statfs(struct dentry *dentry, struct kstatfs *buf)
        buf->f_type     = BCACHEFS_STATFS_MAGIC;
        buf->f_bsize    = sb->s_blocksize;
        buf->f_blocks   = usage.capacity >> shift;
-       buf->f_bfree    = (usage.capacity - usage.used) >> shift;
-       buf->f_bavail   = buf->f_bfree;
+       buf->f_bfree    = usage.free >> shift;
+       buf->f_bavail   = avail_factor(usage.free) >> shift;
 
        buf->f_files    = usage.nr_inodes + avail_inodes;
        buf->f_ffree    = avail_inodes;