ceph: don't check for quotas on MDS stray dirs
authorJeff Layton <jlayton@kernel.org>
Tue, 9 Nov 2021 14:54:49 +0000 (09:54 -0500)
committerIlya Dryomov <idryomov@gmail.com>
Thu, 13 Jan 2022 12:40:07 +0000 (13:40 +0100)
玮文 胡 reported seeing the WARN_RATELIMIT pop when writing to an
inode that had been transplanted into the stray dir. The client was
trying to look up the quotarealm info from the parent and that tripped
the warning.

Change the ceph_vino_is_reserved helper to not throw a warning for
MDS stray directories (0x100 - 0x1ff), only for reserved dirs that
are not in that range.

Also, fix ceph_has_realms_with_quotas to return false when encountering
a reserved inode.

URL: https://tracker.ceph.com/issues/53180
Reported-by: Hu Weiwen <sehuww@mail.scut.edu.cn>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Luis Henriques <lhenriques@suse.de>
Reviewed-by: Xiubo Li <xiubli@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
fs/ceph/quota.c
fs/ceph/super.h

index 24ae13e..a338a3e 100644 (file)
@@ -30,6 +30,9 @@ static inline bool ceph_has_realms_with_quotas(struct inode *inode)
        /* if root is the real CephFS root, we don't have quota realms */
        if (root && ceph_ino(root) == CEPH_INO_ROOT)
                return false;
+       /* MDS stray dirs have no quota realms */
+       if (ceph_vino_is_reserved(ceph_inode(inode)->i_vino))
+               return false;
        /* otherwise, we can't know for sure */
        return true;
 }
index 533189b..5ec465a 100644 (file)
@@ -539,19 +539,23 @@ static inline int ceph_ino_compare(struct inode *inode, void *data)
  *
  * These come from src/mds/mdstypes.h in the ceph sources.
  */
-#define CEPH_MAX_MDS           0x100
-#define CEPH_NUM_STRAY         10
+#define CEPH_MAX_MDS                   0x100
+#define CEPH_NUM_STRAY                 10
 #define CEPH_MDS_INO_MDSDIR_OFFSET     (1 * CEPH_MAX_MDS)
+#define CEPH_MDS_INO_LOG_OFFSET                (2 * CEPH_MAX_MDS)
 #define CEPH_INO_SYSTEM_BASE           ((6*CEPH_MAX_MDS) + (CEPH_MAX_MDS * CEPH_NUM_STRAY))
 
 static inline bool ceph_vino_is_reserved(const struct ceph_vino vino)
 {
-       if (vino.ino < CEPH_INO_SYSTEM_BASE &&
-           vino.ino >= CEPH_MDS_INO_MDSDIR_OFFSET) {
-               WARN_RATELIMIT(1, "Attempt to access reserved inode number 0x%llx", vino.ino);
-               return true;
-       }
-       return false;
+       if (vino.ino >= CEPH_INO_SYSTEM_BASE ||
+           vino.ino < CEPH_MDS_INO_MDSDIR_OFFSET)
+               return false;
+
+       /* Don't warn on mdsdirs */
+       WARN_RATELIMIT(vino.ino >= CEPH_MDS_INO_LOG_OFFSET,
+                       "Attempt to access reserved inode number 0x%llx",
+                       vino.ino);
+       return true;
 }
 
 static inline struct inode *ceph_find_inode(struct super_block *sb,