Empty `stales` and `to_remove` causes `size` to be initialized with
sizeof(fnode_t). If the encoded inode size (plus fnode_t size) exceeds
max_dir_commit_size, commit_one() is called as a non-header update
with empty `_set` and `_rm` sets causing the MDS to assert.
While this patch prevents the assert, it is unknown at this point as
to why the encoded inode size is so large. We have seen it before
once, but there is lack of debug information to dig into. This fix
will prevent the assert, however, the MDS would go read-only due to
the large rados operation size, but at least we will have a live
system to debug at that point.
Fixes: http://tracker.ceph.com/issues/76455
Signed-off-by: Venky Shankar <vshankar@redhat.com>
}
unsigned size = item.key.length() + bl.length() + 2 * sizeof(__u32);
- if (write_size > 0 && write_size + size > max_write_size)
- commit_one();
+ if (write_size > 0 && write_size + size > max_write_size) {
+ if (!_set.empty() || !_rm.empty()) {
+ commit_one();
+ } else {
+ dout(1) << "skipping empty commit, inode size exceeded max_dir_commit_size ("
+ << size << " vs. " << max_write_size << ")" << dendl;
+ }
+ }
write_size += size;
_set[std::move(item.key)] = std::move(bl);