]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
ceph: add ceph_has_realms_with_quotas() check into ceph_quota_update_statfs()
authorViacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Thu, 9 Apr 2026 18:33:23 +0000 (11:33 -0700)
committerViacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Wed, 15 Apr 2026 18:11:34 +0000 (11:11 -0700)
When MDS rejects a session, remove_session_caps() ->
__ceph_remove_cap() -> ceph_change_snap_realm() clears
i_snap_realm for every inode that loses its last cap.
The realm is restored once caps are re-granted after
reconnect. It is not a real error and thsi patch changes
pr_err_ratelimited_client() on doutc().

Every quota methods ceph_quota_is_max_files_exceeded(),
ceph_quota_is_max_bytes_exceeded(),
ceph_quota_is_max_bytes_approaching() calls
ceph_has_realms_with_quotas() check. This patch adds
the missing ceph_has_realms_with_quotas() call into
ceph_quota_update_statfs().

v2
Small cleanup by adding braces for multiline if-else
statements and changing the comments.

Signed-off-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
cc: Alex Markuze <amarkuze@redhat.com>
cc: Ilya Dryomov <idryomov@gmail.com>
cc: Patrick Donnelly <pdonnell@redhat.com>
cc: Ceph Development <ceph-devel@vger.kernel.org>

fs/ceph/quota.c

index 4dc9426643e8346438759c6d3ff8af577a063ecb..67ce1ff1a42101bf13767d5369e7650e2222419e 100644 (file)
@@ -230,10 +230,17 @@ restart:
        realm = ceph_inode(inode)->i_snap_realm;
        if (realm)
                ceph_get_snap_realm(mdsc, realm);
-       else
-               pr_err_ratelimited_client(cl,
-                               "%p %llx.%llx null i_snap_realm\n",
-                               inode, ceph_vinop(inode));
+       else {
+               /*
+                * i_snap_realm is NULL when all caps have been released, e.g.
+                * after an MDS session rejection. This is a transient state;
+                * the realm will be restored once caps are re-granted.
+                * Treat it as "no quota realm found".
+                */
+               doutc(cl, "%p %llx.%llx null i_snap_realm\n",
+                     inode, ceph_vinop(inode));
+       }
+
        while (realm) {
                bool has_inode;
 
@@ -342,10 +349,17 @@ restart:
        realm = ceph_inode(inode)->i_snap_realm;
        if (realm)
                ceph_get_snap_realm(mdsc, realm);
-       else
-               pr_err_ratelimited_client(cl,
-                               "%p %llx.%llx null i_snap_realm\n",
-                               inode, ceph_vinop(inode));
+       else {
+               /*
+                * i_snap_realm is NULL when all caps have been released, e.g.
+                * after an MDS session rejection. This is a transient state;
+                * the realm will be restored once caps are re-granted.
+                * Treat it as "quota not exceeded".
+                */
+               doutc(cl, "%p %llx.%llx null i_snap_realm\n",
+                     inode, ceph_vinop(inode));
+       }
+
        while (realm) {
                bool has_inode;
 
@@ -496,6 +510,9 @@ bool ceph_quota_update_statfs(struct ceph_fs_client *fsc, struct kstatfs *buf)
        u64 total = 0, used, free;
        bool is_updated = false;
 
+       if (!ceph_has_realms_with_quotas(d_inode(fsc->sb->s_root)))
+               return false;
+
        down_read(&mdsc->snap_rwsem);
        get_quota_realm(mdsc, d_inode(fsc->sb->s_root), QUOTA_GET_MAX_BYTES,
                        &realm, true);