From: Kotresh HR Date: Mon, 8 Mar 2021 12:08:26 +0000 (+0530) Subject: mds: Add full caps to avoid osd full check X-Git-Tag: v16.2.5~69^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=19e1216b4e04830ba010239577ed6ecc217f9121;p=ceph.git mds: Add full caps to avoid osd full check Fixes: https://tracker.ceph.com/issues/50532 Signed-off-by: Kotresh HR (cherry picked from commit 6db81d8479b539d3ca6b98dc244c525e71a36437) --- diff --git a/src/mds/MDSAuthCaps.cc b/src/mds/MDSAuthCaps.cc index dbf96ff30329..b78ebd6615b7 100644 --- a/src/mds/MDSAuthCaps.cc +++ b/src/mds/MDSAuthCaps.cc @@ -85,18 +85,26 @@ struct MDSCapParser : qi::grammar (fs_name)[_val = phoenix::construct(std::string(), _1)]); - // capspec = * | r[w][p][s] + // capspec = * | r[w][f][p][s] capspec = spaces >> ( lit("*")[_val = MDSCapSpec(MDSCapSpec::ALL)] | lit("all")[_val = MDSCapSpec(MDSCapSpec::ALL)] | + (lit("rwfps"))[_val = MDSCapSpec(MDSCapSpec::RWFPS)] + | (lit("rwps"))[_val = MDSCapSpec(MDSCapSpec::RWPS)] | + (lit("rwfp"))[_val = MDSCapSpec(MDSCapSpec::RWFP)] + | + (lit("rwfs"))[_val = MDSCapSpec(MDSCapSpec::RWFS)] + | (lit("rwp"))[_val = MDSCapSpec(MDSCapSpec::RWP)] | (lit("rws"))[_val = MDSCapSpec(MDSCapSpec::RWS)] | + (lit("rwf"))[_val = MDSCapSpec(MDSCapSpec::RWF)] + | (lit("rw"))[_val = MDSCapSpec(MDSCapSpec::RW)] | (lit("r"))[_val = MDSCapSpec(MDSCapSpec::READ)] @@ -271,6 +279,12 @@ bool MDSAuthCaps::is_capable(std::string_view inode_path, } } + if (mask & MAY_FULL) { + if (!grant.spec.allow_full()) { + continue; + } + } + // check unix permissions? if (grant.match.uid == MDSCapMatch::MDS_AUTH_UID_ANY) { return true; @@ -412,6 +426,9 @@ ostream &operator<<(ostream &out, const MDSCapSpec &spec) if (spec.allow_write()) { out << "w"; } + if (spec.allow_full()) { + out << "f"; + } if (spec.allow_set_vxattr()) { out << "p"; } diff --git a/src/mds/MDSAuthCaps.h b/src/mds/MDSAuthCaps.h index fee779a7fa76..395c921fd5fe 100644 --- a/src/mds/MDSAuthCaps.h +++ b/src/mds/MDSAuthCaps.h @@ -34,6 +34,7 @@ enum { MAY_CHGRP = (1 << 5), MAY_SET_VXATTR = (1 << 6), MAY_SNAPSHOT = (1 << 7), + MAY_FULL = (1 << 8), }; // what we can do @@ -45,16 +46,22 @@ struct MDSCapSpec { static const unsigned SET_VXATTR = (1 << 3); // if the capability permits mksnap/rmsnap static const unsigned SNAPSHOT = (1 << 4); + // if the capability permits to bypass osd full check + static const unsigned FULL = (1 << 5); static const unsigned RW = (READ|WRITE); + static const unsigned RWF = (READ|WRITE|FULL); static const unsigned RWP = (READ|WRITE|SET_VXATTR); static const unsigned RWS = (READ|WRITE|SNAPSHOT); + static const unsigned RWFP = (READ|WRITE|FULL|SET_VXATTR); + static const unsigned RWFS = (READ|WRITE|FULL|SNAPSHOT); static const unsigned RWPS = (READ|WRITE|SET_VXATTR|SNAPSHOT); + static const unsigned RWFPS = (READ|WRITE|FULL|SET_VXATTR|SNAPSHOT); MDSCapSpec() = default; MDSCapSpec(unsigned _caps) : caps(_caps) { if (caps & ALL) - caps |= RWPS; + caps |= RWFPS; } bool allow_all() const { @@ -83,6 +90,9 @@ struct MDSCapSpec { bool allow_set_vxattr() const { return (caps & SET_VXATTR); } + bool allow_full() const { + return (caps & FULL); + } private: unsigned caps = 0; }; diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 4869ff2472c4..8f3831cb02b1 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -2511,6 +2511,11 @@ void Server::dispatch_client_request(MDRequestRef& mdr) } if (is_full) { + CInode *cur = try_get_auth_inode(mdr, req->get_filepath().get_ino()); + if (!cur) { + respond_to_request(mdr, -EINVAL); + return; + } if (req->get_op() == CEPH_MDS_OP_SETLAYOUT || req->get_op() == CEPH_MDS_OP_SETDIRLAYOUT || req->get_op() == CEPH_MDS_OP_SETLAYOUT || @@ -2524,9 +2529,13 @@ void Server::dispatch_client_request(MDRequestRef& mdr) (!mdr->has_more() || mdr->more()->witnessed.empty())) // haven't started peer request ) { - dout(20) << __func__ << ": full, responding CEPHFS_ENOSPC to op " << ceph_mds_op_name(req->get_op()) << dendl; - respond_to_request(mdr, -CEPHFS_ENOSPC); - return; + if (check_access(mdr, cur, MAY_FULL)) { + dout(20) << __func__ << ": full, has FULL caps, permitting op " << ceph_mds_op_name(req->get_op()) << dendl; + } else { + dout(20) << __func__ << ": full, responding CEPHFS_ENOSPC to op " << ceph_mds_op_name(req->get_op()) << dendl; + respond_to_request(mdr, -CEPHFS_ENOSPC); + return; + } } else { dout(20) << __func__ << ": full, permitting op " << ceph_mds_op_name(req->get_op()) << dendl; }