]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: specify the quota type when finding the root quota realm
authorXiubo Li <xiubli@redhat.com>
Wed, 29 Jun 2022 09:11:36 +0000 (17:11 +0800)
committerXiubo Li <xiubli@redhat.com>
Fri, 1 Jul 2022 06:01:12 +0000 (14:01 +0800)
Currently if only the quota.files is enabled for the statfs it will
use the wrong quota realm when finding the root quota realm. And vice
versa for the rename. This will specify the quota type for different
cases.

This is from Luis' kernel client's fix.

Fixes: https://tracker.ceph.com/issues/56414
Signed-off-by: Xiubo Li <xiubli@redhat.com>
src/client/Client.cc
src/client/Client.h
src/include/cephfs/types.h

index 539b7b2d5a16db48684b65fc4c6367212dee251b..24318e601c898784cc1fdeb735fe1e6358ea418a 100644 (file)
@@ -11214,7 +11214,7 @@ int Client::statfs(const char *path, struct statvfs *stbuf,
   // quota but we can see a parent of it that does have a quota, we'll
   // respect that one instead.
   ceph_assert(root != nullptr);
-  InodeRef quota_root = root->quota.is_enable() ? root : get_quota_root(root.get(), perms);
+  InodeRef quota_root = root->quota.is_enable(QUOTA_MAX_BYTES) ? root : get_quota_root(root.get(), perms, QUOTA_MAX_BYTES);
 
   // get_quota_root should always give us something if client quotas are
   // enabled
@@ -14076,9 +14076,9 @@ int Client::_rename(Inode *fromdir, const char *fromname, Inode *todir, const ch
   }
   if (cct->_conf.get_val<bool>("client_quota") && fromdir != todir) {
     Inode *fromdir_root =
-      fromdir->quota.is_enable() ? fromdir : get_quota_root(fromdir, perm);
+      fromdir->quota.is_enable(QUOTA_MAX_FILES) ? fromdir : get_quota_root(fromdir, perm, QUOTA_MAX_FILES);
     Inode *todir_root =
-      todir->quota.is_enable() ? todir : get_quota_root(todir, perm);
+      todir->quota.is_enable(QUOTA_MAX_FILES) ? todir : get_quota_root(todir, perm, QUOTA_MAX_FILES);
     if (fromdir_root != todir_root) {
       return -CEPHFS_EXDEV;
     }
@@ -15461,7 +15461,7 @@ bool Client::ms_handle_refused(Connection *con)
   return false;
 }
 
-Inode *Client::get_quota_root(Inode *in, const UserPerm& perms)
+Inode *Client::get_quota_root(Inode *in, const UserPerm& perms, quota_max_t type)
 {
   Inode *quota_in = root_ancestor;
   SnapRealm *realm = in->snaprealm;
@@ -15476,7 +15476,7 @@ Inode *Client::get_quota_root(Inode *in, const UserPerm& perms)
       if (p == inode_map.end())
        break;
 
-      if (p->second->quota.is_enable()) {
+      if (p->second->quota.is_enable(type)) {
        quota_in = p->second;
        break;
       }
index e0e055b6dd1c7e5ada456df0e2ab802b11da5c4c..f84bef5d7fa8aaed0751c3663f0ebd9989a4a966 100644 (file)
@@ -1072,7 +1072,7 @@ protected:
 
   int authenticate();
 
-  Inode* get_quota_root(Inode *in, const UserPerm& perms);
+  Inode* get_quota_root(Inode *in, const UserPerm& perms, quota_max_t type=QUOTA_ANY);
   bool check_quota_condition(Inode *in, const UserPerm& perms,
                             std::function<bool (const Inode &)> test);
   bool is_quota_files_exceeded(Inode *in, const UserPerm& perms);
index 92cb3acb468d07e910fec09692fd81faf6ddb51b..6709e9632dc253aaf4fe35be3a0118797327ee90 100644 (file)
@@ -217,6 +217,12 @@ inline bool operator<(const vinodeno_t &l, const vinodeno_t &r) {
     (l.ino == r.ino && l.snapid < r.snapid);
 }
 
+typedef enum {
+  QUOTA_MAX_FILES,
+  QUOTA_MAX_BYTES,
+  QUOTA_ANY
+} quota_max_t;
+
 struct quota_info_t
 {
   void encode(ceph::buffer::list& bl) const {
@@ -238,8 +244,16 @@ struct quota_info_t
   bool is_valid() const {
     return max_bytes >=0 && max_files >=0;
   }
-  bool is_enable() const {
-    return max_bytes || max_files;
+  bool is_enable(quota_max_t type=QUOTA_ANY) const {
+    switch (type) {
+    case QUOTA_MAX_FILES:
+      return !!max_files;
+    case QUOTA_MAX_BYTES:
+      return !!max_bytes;
+    case QUOTA_ANY:
+    default:
+      return !!max_bytes || !!max_files;
+    }
   }
   void decode_json(JSONObj *obj);