]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix and skip submitting invalid osd request 49939/head
authorXiubo Li <xiubli@redhat.com>
Thu, 12 Jan 2023 01:11:02 +0000 (09:11 +0800)
committerXiubo Li <xiubli@redhat.com>
Tue, 31 Jan 2023 05:42:12 +0000 (13:42 +0800)
When the first dentry have enough metadata and the size is larger
than max_write_size, it may submitting one invalid osd request to
Rados, which will cause the cephfs to be readonly.

Fixes: https://tracker.ceph.com/issues/58082
Signed-off-by: Xiubo Li <xiubli@redhat.com>
(cherry picked from commit e268728014700fde6dec1bdf8df3fb0ce226ede4)

src/mds/CDir.cc

index 7e18263d85704abe95858a3492c79c561e305bc1..3c527aae4b34b418223c3dc4e65c80737a8d2566 100644 (file)
@@ -2300,6 +2300,13 @@ void CDir::_omap_commit_ops(int r, int op_prio, int64_t metapool, version_t vers
   auto commit_one = [&](bool header=false) {
     ObjectOperation op;
 
+    /*
+     * Shouldn't submit empty op to Rados, which could cause
+     * the cephfs to become readonly.
+     */
+    ceph_assert(header || !_set.empty() || !_rm.empty());
+
+
     // don't create new dirfrag blindly
     if (!_new)
       op.stat(nullptr, nullptr, nullptr);
@@ -2335,7 +2342,7 @@ void CDir::_omap_commit_ops(int r, int op_prio, int64_t metapool, version_t vers
   int count = 0;
   for (auto &key : stales) {
     unsigned size = key.length() + sizeof(__u32);
-    if (write_size + size > max_write_size)
+    if (write_size > 0 && write_size + size > max_write_size)
       commit_one();
 
     write_size += size;
@@ -2347,7 +2354,7 @@ void CDir::_omap_commit_ops(int r, int op_prio, int64_t metapool, version_t vers
 
   for (auto &key : to_remove) {
     unsigned size = key.length() + sizeof(__u32);
-    if (write_size + size > max_write_size)
+    if (write_size > 0 && write_size + size > max_write_size)
       commit_one();
 
     write_size += size;
@@ -2375,7 +2382,7 @@ void CDir::_omap_commit_ops(int r, int op_prio, int64_t metapool, version_t vers
     }
 
     unsigned size = item.key.length() + bl.length() + 2 * sizeof(__u32);
-    if (write_size + size > max_write_size)
+    if (write_size > 0 && write_size + size > max_write_size)
       commit_one();
 
     write_size += size;