return true;
}
+bool Server::can_handle_charmap(const MDRequestRef& mdr, CDentry* dn)
+{
+ CDir *dir = dn->get_dir();
+ CInode *diri = dir->get_inode();
+ if (auto* csp = diri->get_charmap()) {
+ dout(20) << __func__ << ": with " << *csp << dendl;
+ auto& client_metadata = mdr->session->info.client_metadata;
+ bool allowed = client_metadata.features.test(CEPHFS_FEATURE_CHARMAP);
+ if (!allowed) {
+ dout(5) << " client cannot handle charmap" << dendl;
+ respond_to_request(mdr, -EPERM);
+ return false;
+ }
+ }
+ return true;
+}
+
void Server::handle_client_openc(const MDRequestRef& mdr)
{
const cref_t<MClientRequest> &req = mdr->client_request;
ceph_assert(dnl->is_null());
+ if (!can_handle_charmap(mdr, dn)) {
+ return;
+ }
+
if (req->get_alternate_name().size() > alternate_name_max) {
dout(10) << " alternate_name longer than " << alternate_name_max << dendl;
respond_to_request(mdr, -ENAMETOOLONG);
return;
ceph_assert(dn->get_projected_linkage()->is_null());
+
+ if (!can_handle_charmap(mdr, dn)) {
+ return;
+ }
+
if (req->get_alternate_name().size() > alternate_name_max) {
dout(10) << " alternate_name longer than " << alternate_name_max << dendl;
respond_to_request(mdr, -ENAMETOOLONG);
return;
ceph_assert(dn->get_projected_linkage()->is_null());
+
+ if (!can_handle_charmap(mdr, dn)) {
+ return;
+ }
+
if (req->get_alternate_name().size() > alternate_name_max) {
dout(10) << " alternate_name longer than " << alternate_name_max << dendl;
respond_to_request(mdr, -ENAMETOOLONG);
}
ceph_assert(destdn->get_projected_linkage()->is_null());
+
+ if (!can_handle_charmap(mdr, destdn)) {
+ return;
+ }
+
if (req->get_alternate_name().size() > alternate_name_max) {
dout(10) << " alternate_name longer than " << alternate_name_max << dendl;
respond_to_request(mdr, -ENAMETOOLONG);
CInode *srci = srcdnl->get_inode();
dout(10) << " srci " << *srci << dendl;
+ if (!can_handle_charmap(mdr, destdn)) {
+ return;
+ }
+
// -- some sanity checks --
if (destdn == srcdn) {
dout(7) << "rename src=dest, noop" << dendl;