From: Yan, Zheng Date: Fri, 20 Oct 2017 09:55:26 +0000 (+0800) Subject: mds: create snaprealm for quota enabled inode X-Git-Tag: v13.0.2~583^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f93f56eda9d989969af4bc173cd512216e159afc;p=ceph-ci.git mds: create snaprealm for quota enabled inode this simplifies client code for find quota enabled inode Signed-off-by: "Yan, Zheng" --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 1c2d66002ea..73662d581d5 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -13525,73 +13525,24 @@ bool Client::ms_get_authorizer(int dest_type, AuthAuthorizer **authorizer, bool Inode *Client::get_quota_root(Inode *in, const UserPerm& perms) { - Inode *cur = in; - utime_t now = ceph_clock_now(); - - while (cur) { - if (cur != in && cur->quota.is_enable()) - break; + Inode *quota_in = root_ancestor; + SnapRealm *realm = in->snaprealm; + while (realm) { + ldout(cct, 10) << __func__ << " realm " << realm->ino << dendl; + if (realm->ino != in->ino) { + auto p = inode_map.find(vinodeno_t(realm->ino, CEPH_NOSNAP)); + if (p == inode_map.end()) + break; - Inode *parent_in = NULL; - if (!cur->dentries.empty()) { - for (auto dn : cur->dentries) { - if (dn->lease_mds >= 0 && - dn->lease_ttl > now && - mds_sessions.count(dn->lease_mds)) { - parent_in = dn->dir->parent_inode; - } else { - Inode *diri = dn->dir->parent_inode; - if (diri->caps_issued_mask(CEPH_CAP_FILE_SHARED) && - diri->shared_gen == dn->cap_shared_gen) { - parent_in = dn->dir->parent_inode; - } - } - if (parent_in) - break; + if (p->second->quota.is_enable()) { + quota_in = p->second; + break; } - } else if (root_parents.count(cur)) { - parent_in = root_parents[cur].get(); - } - - if (parent_in) { - cur = parent_in; - continue; } - - if (cur == root_ancestor) - break; - - // deleted inode - if (cur->nlink == 0) { - cur = root_ancestor; - break; - } - - MetaRequest *req = new MetaRequest(CEPH_MDS_OP_LOOKUPNAME); - filepath path(cur->ino); - req->set_filepath(path); - req->set_inode(cur); - - InodeRef parent_ref; - int ret = make_request(req, perms, &parent_ref); - if (ret < 0) { - ldout(cct, 1) << __func__ << " " << in->vino() - << " failed to find parent of " << cur->vino() - << " err " << ret << dendl; - // FIXME: what to do? - cur = root_ancestor; - break; - } - - now = ceph_clock_now(); - if (cur == in) - cur = parent_ref.get(); - else - cur = in; // start over + realm = realm->pparent; } - - ldout(cct, 10) << __func__ << " " << in->vino() << " -> " << cur->vino() << dendl; - return cur; + ldout(cct, 10) << __func__ << " " << in->vino() << " -> " << quota_in->vino() << dendl; + return quota_in; } /** diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 703ed51448a..4674b2b6a89 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -424,7 +424,7 @@ void CInode::pop_and_dirty_projected_inode(LogSegment *ls) sr_t *CInode::project_snaprealm(snapid_t snapid) { - sr_t *cur_srnode = get_projected_srnode(); + const sr_t *cur_srnode = get_projected_srnode(); sr_t *new_srnode; if (cur_srnode) { diff --git a/src/mds/CInode.h b/src/mds/CInode.h index 6b562f1dd44..2f515a820a2 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -492,19 +492,6 @@ public: else return NULL; } - sr_t *get_projected_srnode() { - if (num_projected_srnodes > 0) { - for (std::list::reverse_iterator p = projected_nodes.rbegin(); - p != projected_nodes.rend(); - ++p) - if ((*p)->snapnode) - return (*p)->snapnode; - } - if (snaprealm) - return &snaprealm->srnode; - else - return NULL; - } void project_past_snaprealm_parent(SnapRealm *newparent); private: diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 22b65ae8761..7f6069ad091 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -3915,11 +3915,12 @@ void Server::handle_client_readdir(MDRequestRef& mdr) */ class C_MDS_inode_update_finish : public ServerLogContext { CInode *in; - bool truncating_smaller, changed_ranges; + bool truncating_smaller, changed_ranges, new_realm; public: C_MDS_inode_update_finish(Server *s, MDRequestRef& r, CInode *i, - bool sm=false, bool cr=false) : - ServerLogContext(s, r), in(i), truncating_smaller(sm), changed_ranges(cr) { } + bool sm=false, bool cr=false, bool nr=false) : + ServerLogContext(s, r), in(i), + truncating_smaller(sm), changed_ranges(cr), new_realm(nr) { } void finish(int r) override { assert(r == 0); @@ -3927,13 +3928,20 @@ public: in->pop_and_dirty_projected_inode(mdr->ls); mdr->apply(); + MDSRank *mds = get_mds(); + // notify any clients if (truncating_smaller && in->inode.is_truncating()) { - get_mds()->locker->issue_truncate(in); - get_mds()->mdcache->truncate_inode(in, mdr->ls); + mds->locker->issue_truncate(in); + mds->mdcache->truncate_inode(in, mdr->ls); } - get_mds()->balancer->hit_inode(mdr->get_mds_stamp(), in, META_POP_IWR); + if (new_realm) { + int op = CEPH_SNAP_OP_SPLIT; + mds->mdcache->do_realm_invalidate_and_update_notify(in, op); + } + + mds->balancer->hit_inode(mdr->get_mds_stamp(), in, META_POP_IWR); server->respond_to_request(mdr, 0); @@ -4670,6 +4678,7 @@ void Server::handle_set_vxattr(MDRequestRef& mdr, CInode *cur, return; } + bool new_realm = false; if (name.compare(0, 15, "ceph.dir.layout") == 0) { if (!cur->is_dir()) { respond_to_request(mdr, -EINVAL); @@ -4735,11 +4744,22 @@ void Server::handle_set_vxattr(MDRequestRef& mdr, CInode *cur, } xlocks.insert(&cur->policylock); + if (quota.is_enable() && !cur->get_projected_srnode()) { + xlocks.insert(&cur->snaplock); + new_realm = true; + } + if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks)) return; pi = cur->project_inode(); pi->quota = quota; + + if (new_realm) { + SnapRealm *realm = cur->find_snaprealm(); + sr_t *newsnap = cur->project_snaprealm(realm->get_newest_seq()); + newsnap->seq = realm->get_newest_seq(); + } mdr->no_early_reply = true; } else if (name.find("ceph.dir.pin") == 0) { if (!cur->is_dir() || cur->is_root()) { @@ -4783,7 +4803,8 @@ void Server::handle_set_vxattr(MDRequestRef& mdr, CInode *cur, mdcache->predirty_journal_parents(mdr, &le->metablob, cur, 0, PREDIRTY_PRIMARY); mdcache->journal_dirty_inode(mdr.get(), &le->metablob, cur); - journal_and_reply(mdr, cur, 0, le, new C_MDS_inode_update_finish(this, mdr, cur)); + journal_and_reply(mdr, cur, 0, le, new C_MDS_inode_update_finish(this, mdr, cur, + false, false, new_realm)); return; }