]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: align quota.max_bytes to 4MB or 4KB
authorXiubo Li <xiubli@redhat.com>
Thu, 30 Jun 2022 07:18:31 +0000 (15:18 +0800)
committerXiubo Li <xiubli@redhat.com>
Wed, 8 Mar 2023 10:56:09 +0000 (18:56 +0800)
The quota.max_bytes must be aligned to 4MB if greater than or equal
to 4MB, otherwise must align to 4KB.

This will make the statfs report correct block size and total blocks,
then the `df` could show expected capacity.

Fixes: https://tracker.ceph.com/issues/56397
Signed-off-by: Xiubo Li <xiubli@redhat.com>
doc/cephfs/quota.rst
src/include/cephfs/types.h
src/mds/Server.cc

index e78173bcc3e6483295e11d25c33fc3ad62b5894c..6ff984f3d9e9aca1043be7f486bad3314fef953e 100644 (file)
@@ -15,10 +15,13 @@ If the extended attributes appear on a directory that means a quota is
 configured there. If they are not present then no quota is set on that
 directory (although one may still be configured on a parent directory).
 
+The value of ``ceph.quota.max_bytes`` must be aligned to 4MB if greater
+than or equal to 4MB, otherwise it must be aligned to 4KB.
+
 To set a quota, set the extended attribute on a CephFS directory with a
 value::
 
-  setfattr -n ceph.quota.max_bytes -v 100000000 /some/dir     # 100 MB
+  setfattr -n ceph.quota.max_bytes -v 104857600 /some/dir     # 100 MB
   setfattr -n ceph.quota.max_files -v 10000 /some/dir         # 10,000 files
 
 ``ceph.quota.max_bytes`` can also be set using human-friendly units::
@@ -33,7 +36,7 @@ To view quota limit::
 
   $ getfattr -n ceph.quota.max_bytes /some/dir
   # file: dir1/
-  ceph.quota.max_bytes="100000000"
+  ceph.quota.max_bytes="104857600"
   $
   $ getfattr -n ceph.quota.max_files /some/dir
   # file: dir1/
index cca0a619305a6d7c10b5b174c6c85fbced2fb6cb..049ef8e3fcf675c2948ee0e98a01d51f9b41196c 100644 (file)
 #define CEPH_FS_ONDISK_MAGIC "ceph fs volume v011"
 #define MAX_MDS                   0x100
 
+#define CEPH_4M_BLOCK_SHIFT 22
+#define CEPH_4M_BLOCK_SIZE (1 << CEPH_4M_BLOCK_SHIFT) // 4MB
+#define CEPH_4K_BLOCK_SHIFT 12
+#define CEPH_4K_BLOCK_SIZE (1 << CEPH_4K_BLOCK_SHIFT) // 4KB
+
+#define IS_ALIGNED(x, a) (((x) & (int64_t(a) - 1)) == 0)
+
 BOOST_STRONG_TYPEDEF(uint64_t, mds_gid_t)
 extern const mds_gid_t MDS_GID_NONE;
 
index cbba6103882e88e75ba7488af60fbeee92bebd4c..d172c1c60913e22a59d41b1eb4ccb000b3f95f9c 100644 (file)
@@ -5779,11 +5779,17 @@ int Server::parse_quota_vxattr(string name, string value, quota_info_t *quota)
           return r;
       }
     } else if (name == "quota.max_bytes") {
+      /*
+       * The "quota.max_bytes" must be aligned to 4MB if greater than or
+       * equal to 4MB, otherwise must be aligned to 4KB.
+       */
       string cast_err;
       int64_t q = strict_iec_cast<int64_t>(value, &cast_err);
-      if(!cast_err.empty()) {
+      if(!cast_err.empty() ||
+         (!IS_ALIGNED(q, CEPH_4M_BLOCK_SIZE) &&
+          (q < CEPH_4M_BLOCK_SIZE && !IS_ALIGNED(q, CEPH_4K_BLOCK_SIZE)))) {
         dout(10) << __func__ << ":  failed to parse quota.max_bytes: "
-        << cast_err << dendl;
+                 << cast_err << dendl;
         return -CEPHFS_EINVAL;
       }
       quota->max_bytes = q;