From: Kotresh HR Date: Wed, 10 Nov 2021 18:00:21 +0000 (+0530) Subject: ceph: Fix incorrect statfs report for small quota X-Git-Tag: v6.6.17~8354^2~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8e55ba8caae5cd380b1c9c81a426602a667e110e;p=platform%2Fkernel%2Flinux-rpi.git ceph: Fix incorrect statfs report for small quota Problem: The statfs reports incorrect free/available space for quota less then CEPH_BLOCK size (4M). Solution: For quota less than CEPH_BLOCK size, smaller block size of 4K is used. But if quota is less than 4K, it is decided to go with binary use/free of 4K block. For quota size less than 4K size, report the total=used=4K,free=0 when quota is full and total=free=4K,used=0 otherwise. Signed-off-by: Kotresh HR Reviewed-by: Jeff Layton Signed-off-by: Ilya Dryomov --- diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c index 620c691..24ae13e 100644 --- a/fs/ceph/quota.c +++ b/fs/ceph/quota.c @@ -494,10 +494,24 @@ bool ceph_quota_update_statfs(struct ceph_fs_client *fsc, struct kstatfs *buf) if (ci->i_max_bytes) { total = ci->i_max_bytes >> CEPH_BLOCK_SHIFT; used = ci->i_rbytes >> CEPH_BLOCK_SHIFT; + /* For quota size less than 4MB, use 4KB block size */ + if (!total) { + total = ci->i_max_bytes >> CEPH_4K_BLOCK_SHIFT; + used = ci->i_rbytes >> CEPH_4K_BLOCK_SHIFT; + buf->f_frsize = 1 << CEPH_4K_BLOCK_SHIFT; + } /* It is possible for a quota to be exceeded. * Report 'zero' in that case */ free = total > used ? total - used : 0; + /* For quota size less than 4KB, report the + * total=used=4KB,free=0 when quota is full + * and total=free=4KB, used=0 otherwise */ + if (!total) { + total = 1; + free = ci->i_max_bytes > ci->i_rbytes ? 1 : 0; + buf->f_frsize = 1 << CEPH_4K_BLOCK_SHIFT; + } } spin_unlock(&ci->i_ceph_lock); if (total) { diff --git a/fs/ceph/super.h b/fs/ceph/super.h index ec6b221..533189b 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -32,6 +32,7 @@ * large volume sizes on 32-bit machines. */ #define CEPH_BLOCK_SHIFT 22 /* 4 MB */ #define CEPH_BLOCK (1 << CEPH_BLOCK_SHIFT) +#define CEPH_4K_BLOCK_SHIFT 12 /* 4 KB */ #define CEPH_MOUNT_OPT_CLEANRECOVER (1<<1) /* auto reonnect (clean mode) after blocklisted */ #define CEPH_MOUNT_OPT_DIRSTAT (1<<4) /* `cat dirname` for stats */