Commit 8e55ba8c authored by Kotresh HR's avatar Kotresh HR Committed by Ilya Dryomov
Browse files

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: default avatarKotresh HR <khiremat@redhat.com>
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent adbed05e
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -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) {
+1 −0
Original line number Diff line number Diff line
@@ -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 */