From: Xiubo Li Date: Thu, 12 Jan 2023 01:11:02 +0000 (+0800) Subject: mds: fix and skip submitting invalid osd request X-Git-Tag: v16.2.13~118^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=666667a458b260c31252dee27121ddcf3b012cd2;p=ceph.git mds: fix and skip submitting invalid osd request 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 (cherry picked from commit e268728014700fde6dec1bdf8df3fb0ce226ede4) --- diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index e9b9c38d2558..b5b020f98809 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -2294,6 +2294,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); @@ -2329,7 +2336,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; @@ -2341,7 +2348,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; @@ -2371,7 +2378,7 @@ void CDir::_omap_commit_ops(int r, int op_prio, int64_t metapool, version_t vers off += item.dft_len; 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;