journal_and_reply(mdr, cur, 0, le, new C_MDS_inode_update_finish(this, mdr, cur));
}
-bool Server::xlock_policylock(const MDRequestRef& mdr, CInode *in, bool want_layout, bool xlock_snaplock)
+bool Server::xlock_policylock(const MDRequestRef& mdr, CInode *in, bool want_layout, bool xlock_snaplock, MutationImpl::LockOpVec lov)
{
if (mdr->locking_state & MutationImpl::ALL_LOCKED)
return true;
- MutationImpl::LockOpVec lov;
lov.add_xlock(&in->policylock);
if (xlock_snaplock)
lov.add_xlock(&in->snaplock);
auto pi = cur->project_inode(mdr);
cur->setxattr_ephemeral_dist(val);
pip = pi.inode.get();
+ } else if (name == "ceph.dir.charmap"sv) {
+ // inheritance / InodeStat
+ if (!cur->is_dir() || cur->is_root()) {
+ respond_to_request(mdr, -EINVAL);
+ return;
+ }
+
+ dout(25) << "not root, is dir" << dendl;
+
+ MutationImpl::LockOpVec lov;
+ lov.add_rdlock(&cur->filelock); // to verify it's empty
+ if (!xlock_policylock(mdr, cur, false, false, std::move(lov)))
+ return;
+
+ if (_dir_is_nonempty(mdr, cur)) {
+ respond_to_request(mdr, -ENOTEMPTY);
+ return;
+ }
+ if (cur->snaprealm && cur->snaprealm->srnode.snaps.size()) {
+ respond_to_request(mdr, -ENOTEMPTY);
+ return;
+ }
+
+ if (is_rmxattr) {
+ if (!cur->get_projected_inode()->has_charmap()) {
+ respond_to_request(mdr, 0);
+ return;
+ }
+ auto pi = cur->project_inode(mdr);
+ pip = pi.inode.get();
+ dout(20) << "deleting charmap metadata" << dendl;
+ pip->del_charmap();
+ } else {
+ respond_to_request(mdr, -EINVAL);
+ return;
+ }
+ } else if (name == "ceph.dir.casesensitive"sv) {
+ if (is_rmxattr) {
+ value = "1";
+ }
+
+ MutationImpl::LockOpVec lov;
+ lov.add_rdlock(&cur->filelock); // to verify it's empty
+ if (!xlock_policylock(mdr, cur, false, false, std::move(lov)))
+ return;
+
+ if (_dir_is_nonempty(mdr, cur)) {
+ respond_to_request(mdr, -ENOTEMPTY);
+ return;
+ }
+ if (cur->snaprealm && cur->snaprealm->srnode.snaps.size()) {
+ respond_to_request(mdr, -ENOTEMPTY);
+ return;
+ }
+
+ bool val;
+ try {
+ val = boost::lexical_cast<bool>(value);
+ } catch (boost::bad_lexical_cast const&) {
+ dout(10) << "bad vxattr value, unable to parse bool for " << name << dendl;
+ respond_to_request(mdr, -EINVAL);
+ return;
+ }
+
+ auto pi = cur->project_inode(mdr);
+ pip = pi.inode.get();
+ auto& c = pip->set_charmap();
+ if (val) {
+ c.mark_casesensitive();
+ dout(20) << "marking case sensitive: " << c << dendl;
+ } else {
+ c.mark_caseinsensitive();
+ dout(20) << "marking case insensitive: " << c << dendl;
+ }
+ } else if (name == "ceph.dir.normalization"sv) {
+ if (is_rmxattr) {
+ value = "";
+ }
+
+ MutationImpl::LockOpVec lov;
+ lov.add_rdlock(&cur->filelock); // to verify it's empty
+ if (!xlock_policylock(mdr, cur, false, false, std::move(lov)))
+ return;
+
+ if (_dir_is_nonempty(mdr, cur)) {
+ respond_to_request(mdr, -ENOTEMPTY);
+ return;
+ }
+ if (cur->snaprealm && cur->snaprealm->srnode.snaps.size()) {
+ respond_to_request(mdr, -ENOTEMPTY);
+ return;
+ }
+
+ auto pi = cur->project_inode(mdr);
+ pip = pi.inode.get();
+ auto& c = pip->set_charmap();
+ if (value.size() > 0) {
+ c.set_normalization(value);
+ } else {
+ c.set_normalization(c.get_default_normalization());
+ }
+ dout(20) << "set normalization: " << c << dendl;
+ } else if (name == "ceph.dir.encoding"sv) {
+ if (is_rmxattr) {
+ value = "";
+ }
+
+ MutationImpl::LockOpVec lov;
+ lov.add_rdlock(&cur->filelock); // to verify it's empty
+ if (!xlock_policylock(mdr, cur, false, false, std::move(lov)))
+ return;
+
+ if (_dir_is_nonempty(mdr, cur)) {
+ respond_to_request(mdr, -ENOTEMPTY);
+ return;
+ }
+ if (cur->snaprealm && cur->snaprealm->srnode.snaps.size()) {
+ respond_to_request(mdr, -ENOTEMPTY);
+ return;
+ }
+
+ auto pi = cur->project_inode(mdr);
+ pip = pi.inode.get();
+ auto& c = pip->set_charmap();
+ if (value.size() > 0) {
+ c.set_encoding(value);
+ } else {
+ c.set_encoding(c.get_default_encoding());
+ }
+ dout(20) << "set encoding: " << c << dendl;
} else {
dout(10) << " unknown vxattr " << name << dendl;
respond_to_request(mdr, -EINVAL);
}
} else if (xattr_name == "ceph.quiesce.block"sv) {
*css << cur->get_projected_inode()->get_quiesce_block();
+ } else if (xattr_name == "ceph.dir.charmap"sv) {
+ auto&& pip = cur->get_projected_inode();
+ if (!pip->has_charmap()) {
+ r = -ENODATA;
+ } else {
+ auto& c = pip->get_charmap();
+ Formatter* f = new JSONFormatter;
+ f->dump_object("charmap", c);
+ f->flush(*css);
+ delete f;
+ }
+ } else if (xattr_name == "ceph.dir.casesensitive"sv) {
+ auto&& pip = cur->get_projected_inode();
+ if (!pip->has_charmap()) {
+ r = -ENODATA;
+ } else {
+ auto& c = pip->get_charmap();
+ *css << c.is_casesensitive();
+ }
+ } else if (xattr_name == "ceph.dir.encoding"sv) {
+ auto&& pip = cur->get_projected_inode();
+ if (!pip->has_charmap()) {
+ r = -ENODATA;
+ } else {
+ auto& c = pip->get_charmap();
+ *css << c.get_encoding();
+ }
+ } else if (xattr_name == "ceph.dir.normalization"sv) {
+ auto&& pip = cur->get_projected_inode();
+ if (!pip->has_charmap()) {
+ r = -ENODATA;
+ } else {
+ auto& c = pip->get_charmap();
+ *css << c.get_normalization();
+ }
} else if (xattr_name.substr(0, 12) == "ceph.dir.pin"sv) {
if (xattr_name == "ceph.dir.pin"sv) {
*css << cur->get_projected_inode()->export_pin;
void handle_client_file_readlock(const MDRequestRef& mdr);
bool xlock_policylock(const MDRequestRef& mdr, CInode *in,
- bool want_layout=false, bool xlock_snaplock=false);
+ bool want_layout=false, bool xlock_snaplock=false,
+ MutationImpl::LockOpVec lov={});
CInode* try_get_auth_inode(const MDRequestRef& mdr, inodeno_t ino);
void handle_client_setattr(const MDRequestRef& mdr);
void handle_client_setlayout(const MDRequestRef& mdr);
xattr_name == "ceph.dir.subvolume" ||
xattr_name == "ceph.dir.pin" ||
xattr_name == "ceph.dir.pin.random" ||
- xattr_name == "ceph.dir.pin.distributed";
+ xattr_name == "ceph.dir.pin.distributed" ||
+ xattr_name == "ceph.dir.charmap"sv ||
+ xattr_name == "ceph.dir.normalization"sv ||
+ xattr_name == "ceph.dir.encoding"sv ||
+ xattr_name == "ceph.dir.casesensitive"sv;
}
static bool is_ceph_dir_vxattr(std::string_view xattr_name) {
- return (xattr_name == "ceph.dir.layout" ||
+ return xattr_name == "ceph.dir.layout" ||
xattr_name == "ceph.dir.layout.json" ||
xattr_name == "ceph.dir.layout.object_size" ||
xattr_name == "ceph.dir.layout.stripe_unit" ||
xattr_name == "ceph.dir.layout.pool_namespace" ||
xattr_name == "ceph.dir.pin" ||
xattr_name == "ceph.dir.pin.random" ||
- xattr_name == "ceph.dir.pin.distributed");
+ xattr_name == "ceph.dir.pin.distributed" ||
+ xattr_name == "ceph.dir.charmap"sv ||
+ xattr_name == "ceph.dir.normalization"sv ||
+ xattr_name == "ceph.dir.encoding"sv ||
+ xattr_name == "ceph.dir.casesensitive"sv;
}
static bool is_ceph_file_vxattr(std::string_view xattr_name) {