From e268728014700fde6dec1bdf8df3fb0ce226ede4 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 12 Jan 2023 09:11:02 +0800 Subject: [PATCH] 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 --- src/mds/CDir.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index d7c5afd83df..e6844cb7a4b 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -2421,6 +2421,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); @@ -2456,7 +2463,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; @@ -2468,7 +2475,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; @@ -2496,7 +2503,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; -- 2.39.5