From e3654dfc96e3314e37f7bfd098a84b23f1abb9c8 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 19 Aug 2010 10:13:38 -0700 Subject: [PATCH] mds: make null snapflush helper, and call on cap removal too Move remove_client_cap() from MDCache->Locker while we're at it! --- src/mds/Locker.cc | 80 +++++++++++++++++++++++++++++++--------------- src/mds/Locker.h | 5 ++- src/mds/MDCache.cc | 18 ----------- src/mds/MDCache.h | 1 - src/mds/Server.cc | 2 +- 5 files changed, 60 insertions(+), 46 deletions(-) diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index eb6df0beab57e..4e84393c9c455 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -1733,6 +1733,33 @@ void Locker::adjust_cap_wanted(Capability *cap, int wanted, int issue_seq) } + +void Locker::_do_null_snapflush(CInode *head_in, client_t client, snapid_t follows) +{ + dout(10) << "_do_null_snapflish client" << client << " follows " << follows << " on " << *head_in << dendl; + map >::iterator p = head_in->client_need_snapflush.begin(); + while (p != head_in->client_need_snapflush.end()) { + // p->first is the snap inode's ->last + if (follows > p->first) + break; + if (p->second.count(client)) { + dout(10) << " doing async NULL snapflush on " << p->first << " from client" << p->second << dendl; + CInode *sin = mdcache->get_inode(head_in->ino(), p->first); + assert(sin); + _do_snap_update(sin, 0, sin->first - 1, client, NULL, NULL); + head_in->client_need_snapflush[sin->last].erase(client); + if (head_in->client_need_snapflush[sin->last].empty()) { + head_in->client_need_snapflush.erase(p++); + if (head_in->client_need_snapflush.empty()) + head_in->put(CInode::PIN_NEEDSNAPFLUSH); + continue; + } + } + p++; + } +} + + /* * note: we only get these from the client if * - we are calling back previously issued caps (fewer than the client previously had) @@ -1822,7 +1849,7 @@ void Locker::handle_client_caps(MClientCaps *m) ack->set_client_tid(m->get_client_tid()); } - _do_snap_update(in, m->get_dirty(), follows, m, ack); + _do_snap_update(in, m->get_dirty(), follows, client, m, ack); if (in != head_in) { head_in->client_need_snapflush[in->last].erase(client); @@ -1870,26 +1897,7 @@ void Locker::handle_client_caps(MClientCaps *m) // update/release). if (head_in->client_need_snapflush.size()) { if ((cap->issued() & CEPH_CAP_ANY_WR) == 0) { - map >::iterator p = head_in->client_need_snapflush.begin(); - while (p != head_in->client_need_snapflush.end()) { - // p->first is the snap inode's ->last - if (follows > p->first) - break; - if (p->second.count(client)) { - dout(10) << " doing async NULL snapflush on " << p->first << " from client" << p->second << dendl; - CInode *sin = mdcache->get_inode(head_in->ino(), p->first); - assert(sin); - _do_snap_update(sin, 0, sin->first - 1, m, NULL); - head_in->client_need_snapflush[in->last].erase(client); - if (head_in->client_need_snapflush[in->last].empty()) { - head_in->client_need_snapflush.erase(p++); - if (head_in->client_need_snapflush.empty()) - head_in->put(CInode::PIN_NEEDSNAPFLUSH); - continue; - } - } - p++; - } + _do_null_snapflush(head_in, client, follows); } else { dout(10) << " revocation in progress, not making any conclusions about null snapflushes" << dendl; } @@ -2023,7 +2031,7 @@ static uint64_t calc_bounding(uint64_t t) return t + 1; } -void Locker::_do_snap_update(CInode *in, int dirty, snapid_t follows, MClientCaps *m, MClientCaps *ack) +void Locker::_do_snap_update(CInode *in, int dirty, snapid_t follows, client_t client, MClientCaps *m, MClientCaps *ack) { dout(10) << "_do_snap_update dirty " << ccap_string(dirty) << " follows " << follows @@ -2042,8 +2050,6 @@ void Locker::_do_snap_update(CInode *in, int dirty, snapid_t follows, MClientCap return; } - client_t client = m->get_source().num(); - EUpdate *le = new EUpdate(mds->mdlog, "snap flush"); mds->mdlog->start_entry(le); Mutation *mut = new Mutation; @@ -2363,12 +2369,36 @@ void Locker::handle_client_cap_release(MClientCapRelease *m) } dout(7) << "removing cap on " << *in << dendl; - mdcache->remove_client_cap(in, client); + remove_client_cap(in, client); } m->put(); } + +void Locker::remove_client_cap(CInode *in, client_t client) +{ + // clean out any pending snapflush state + if (!in->client_need_snapflush.empty()) + _do_null_snapflush(in, client, 0); + + in->remove_client_cap(client); + + if (in->is_auth()) { + // make sure we clear out the client byte range + if (in->get_projected_inode()->client_ranges.count(client) && + !(in->inode.nlink == 0 && !in->is_any_caps())) // unless it's unlink + stray + check_inode_max_size(in); + } else { + request_inode_file_caps(in); + } + + eval(in, CEPH_CAP_LOCKS); + + mds->mdcache->maybe_eval_stray(in); +} + + void Locker::handle_client_lease(MClientLease *m) { dout(10) << "handle_client_lease " << *m << dendl; diff --git a/src/mds/Locker.h b/src/mds/Locker.h index 4a0be64416347..0fba2c7fab7f7 100644 --- a/src/mds/Locker.h +++ b/src/mds/Locker.h @@ -175,11 +175,14 @@ public: const string& dname); void kick_cap_releases(MDRequest *mdr); + void remove_client_cap(CInode *in, client_t client); + protected: void adjust_cap_wanted(Capability *cap, int wanted, int issue_seq); void handle_client_caps(class MClientCaps *m); void _update_cap_fields(CInode *in, int dirty, MClientCaps *m, inode_t *pi); - void _do_snap_update(CInode *in, int dirty, snapid_t follows, MClientCaps *m, MClientCaps *ack); + void _do_snap_update(CInode *in, int dirty, snapid_t follows, client_t client, MClientCaps *m, MClientCaps *ack); + void _do_null_snapflush(CInode *head_in, client_t client, snapid_t follows); bool _do_cap_update(CInode *in, Capability *cap, int dirty, snapid_t follows, MClientCaps *m, MClientCaps *ack=0); void handle_client_cap_release(class MClientCapRelease *m); diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 5c75be7a2b0d7..c4872fa3198ae 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -5373,24 +5373,6 @@ void MDCache::check_memory_usage() } -void MDCache::remove_client_cap(CInode *in, client_t client) -{ - in->remove_client_cap(client); - - if (in->is_auth()) { - // make sure we clear out the client byte range - if (in->get_projected_inode()->client_ranges.count(client) && - !(in->inode.nlink == 0 && !in->is_any_caps())) // unless it's unlink + stray - mds->locker->check_inode_max_size(in); - } else { - mds->locker->request_inode_file_caps(in); - } - - mds->locker->eval(in, CEPH_CAP_LOCKS); - - maybe_eval_stray(in); -} - // ========================================================================================= // shutdown diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index cb2af3cf0c71f..abb18295432fb 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -473,7 +473,6 @@ public: // -- client caps -- uint64_t last_cap_id; - void remove_client_cap(CInode *in, client_t client); // -- discover -- diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 4b207d5f4f25c..44752a678e820 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -287,7 +287,7 @@ void Server::_session_logged(Session *session, uint64_t state_seq, bool open, ve Capability *cap = session->caps.front(); CInode *in = cap->get_inode(); dout(20) << " killing capability " << ccap_string(cap->issued()) << " on " << *in << dendl; - mds->mdcache->remove_client_cap(in, session->inst.name.num()); + mds->locker->remove_client_cap(in, session->inst.name.num()); } while (!session->leases.empty()) { ClientLease *r = session->leases.front(); -- 2.39.5