On Wed, 2021-11-10 at 23:30 +0530, khiremat@xxxxxxxxxx wrote: > From: Kotresh HR <khiremat@xxxxxxxxxx> > > 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 <khiremat@xxxxxxxxxx> > --- > fs/ceph/quota.c | 14 ++++++++++++++ > fs/ceph/super.h | 1 + > 2 files changed, 15 insertions(+) > > diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c > index 620c691af40e..24ae13ea2241 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; > + } We really ought to have the MDS establish a floor for the quota size. <4k quota seems ridiculous. > } > spin_unlock(&ci->i_ceph_lock); > if (total) { > diff --git a/fs/ceph/super.h b/fs/ceph/super.h > index ed51e04739c4..387ee33894db 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 */ This looks good, Kotresh. Nice work. I'll plan to merge this into testing in the near term. Before we merge this into mainline though, it would be good to have a testcase that ensures that this works like we expect with these small quotas. Could you write something for teuthology? Thanks, -- Jeff Layton <jlayton@xxxxxxxxxx>