mirror of
https://github.com/ceph/ceph
synced 2025-03-11 02:39:05 +00:00
Merge PR #19825 into master
* refs/pull/19825/head: client: properly choose target mds for rmsnap/renamesnap mds: properly setup need_snapflush for snapped inode mds: ignore MClientCaps::FLAG_NO_CAPSNAP Reviewed-by: Patrick Donnelly <pdonnell@redhat.com>
This commit is contained in:
commit
90687e499c
@ -3296,9 +3296,7 @@ void Client::send_cap(Inode *in, MetaSession *session, Cap *cap,
|
||||
m->change_attr = in->change_attr;
|
||||
if (sync)
|
||||
m->flags |= MClientCaps::FLAG_SYNC;
|
||||
if (in->cap_snaps.empty())
|
||||
m->flags |= MClientCaps::FLAG_NO_CAPSNAP;
|
||||
else
|
||||
if (!in->cap_snaps.empty())
|
||||
m->flags |= MClientCaps::FLAG_PENDING_CAPSNAP;
|
||||
|
||||
if (flush & CEPH_CAP_FILE_WR) {
|
||||
@ -11991,6 +11989,7 @@ int Client::_rmdir(Inode *dir, const char *name, const UserPerm& perms)
|
||||
dir->make_nosnap_relative_path(path);
|
||||
path.push_dentry(name);
|
||||
req->set_filepath(path);
|
||||
req->set_inode(dir);
|
||||
|
||||
req->dentry_drop = CEPH_CAP_FILE_SHARED;
|
||||
req->dentry_unless = CEPH_CAP_FILE_EXCL;
|
||||
@ -12010,14 +12009,12 @@ int Client::_rmdir(Inode *dir, const char *name, const UserPerm& perms)
|
||||
res = _lookup(dir, name, 0, &in, perms);
|
||||
if (res < 0)
|
||||
goto fail;
|
||||
if (op == CEPH_MDS_OP_RMDIR) {
|
||||
req->set_inode(dir);
|
||||
req->set_other_inode(in.get());
|
||||
} else {
|
||||
|
||||
if (op == CEPH_MDS_OP_RMSNAP) {
|
||||
unlink(de, true, true);
|
||||
de->put();
|
||||
req->set_other_inode(in.get());
|
||||
}
|
||||
req->set_other_inode(in.get());
|
||||
|
||||
res = make_request(req, perms);
|
||||
|
||||
@ -12144,6 +12141,8 @@ int Client::_rename(Inode *fromdir, const char *fromname, Inode *todir, const ch
|
||||
// dentry manually
|
||||
unlink(oldde, true, true);
|
||||
unlink(de, true, true);
|
||||
|
||||
req->set_inode(todir);
|
||||
}
|
||||
|
||||
res = make_request(req, perm, &target);
|
||||
|
@ -2868,36 +2868,13 @@ void Locker::handle_client_caps(MClientCaps *m)
|
||||
caps &= cap->issued();
|
||||
}
|
||||
|
||||
cap->confirm_receipt(m->get_seq(), caps);
|
||||
dout(10) << " follows " << follows
|
||||
<< " retains " << ccap_string(m->get_caps())
|
||||
<< " dirty " << ccap_string(m->get_dirty())
|
||||
<< " on " << *in << dendl;
|
||||
|
||||
|
||||
// missing/skipped snapflush?
|
||||
// The client MAY send a snapflush if it is issued WR/EXCL caps, but
|
||||
// presently only does so when it has actual dirty metadata. But, we
|
||||
// set up the need_snapflush stuff based on the issued caps.
|
||||
// We can infer that the client WONT send a FLUSHSNAP once they have
|
||||
// released all WR/EXCL caps (the FLUSHSNAP always comes before the cap
|
||||
// update/release).
|
||||
if (!head_in->client_need_snapflush.empty()) {
|
||||
if ((m->flags & MClientCaps::FLAG_NO_CAPSNAP) ||
|
||||
(!(cap->issued() & CEPH_CAP_ANY_FILE_WR) &&
|
||||
!(m->flags & MClientCaps::FLAG_PENDING_CAPSNAP))) {
|
||||
head_in->auth_pin(this); // prevent subtree frozen
|
||||
need_unpin = true;
|
||||
_do_null_snapflush(head_in, client);
|
||||
} else {
|
||||
dout(10) << " revocation in progress, not making any conclusions about null snapflushes" << dendl;
|
||||
}
|
||||
}
|
||||
if (cap->need_snapflush() && (m->flags & MClientCaps::FLAG_NO_CAPSNAP))
|
||||
cap->clear_needsnapflush();
|
||||
|
||||
if (m->get_dirty() && in->is_auth()) {
|
||||
dout(7) << " flush client." << client << " dirty " << ccap_string(m->get_dirty())
|
||||
dout(7) << " flush client." << client << " dirty " << ccap_string(m->get_dirty())
|
||||
<< " seq " << m->get_seq() << " on " << *in << dendl;
|
||||
ack = new MClientCaps(CEPH_CAP_OP_FLUSH_ACK, in->ino(), 0, cap->get_cap_id(), m->get_seq(),
|
||||
m->get_caps(), 0, m->get_dirty(), 0, mds->get_osd_epoch_barrier());
|
||||
@ -2905,8 +2882,33 @@ void Locker::handle_client_caps(MClientCaps *m)
|
||||
ack->set_oldest_flush_tid(m->get_oldest_flush_tid());
|
||||
}
|
||||
|
||||
// filter wanted based on what we could ever give out (given auth/replica status)
|
||||
bool need_flush = m->flags & MClientCaps::FLAG_SYNC;
|
||||
bool updated = in->is_auth() &&
|
||||
_do_cap_update(in, cap, m->get_dirty(), follows, m, ack, &need_flush);
|
||||
|
||||
cap->confirm_receipt(m->get_seq(), caps);
|
||||
|
||||
// missing/skipped snapflush?
|
||||
// The client MAY send a snapflush if it is issued WR/EXCL caps,
|
||||
// but only does so when it has actual dirty metadata. We set up
|
||||
// the need_snapflush stuff based on the issued caps. We can infer
|
||||
// that the client WONT send a FLUSHSNAP once they have released
|
||||
// all WR/EXCL caps (the FLUSHSNAP always comes before the cap
|
||||
// update/release).
|
||||
if (!head_in->client_need_snapflush.empty()) {
|
||||
if (!(cap->issued() & CEPH_CAP_ANY_FILE_WR) &&
|
||||
!(m->flags & MClientCaps::FLAG_PENDING_CAPSNAP)) {
|
||||
head_in->auth_pin(this); // prevent subtree frozen
|
||||
need_unpin = true;
|
||||
_do_null_snapflush(head_in, client);
|
||||
} else {
|
||||
dout(10) << " revocation in progress, not making any conclusions about null snapflushes" << dendl;
|
||||
}
|
||||
}
|
||||
if (cap->need_snapflush() && !(m->flags & MClientCaps::FLAG_PENDING_CAPSNAP))
|
||||
cap->clear_needsnapflush();
|
||||
|
||||
// filter wanted based on what we could ever give out (given auth/replica status)
|
||||
int new_wanted = m->get_wanted() & head_in->get_caps_allowed_ever();
|
||||
if (new_wanted != cap->wanted()) {
|
||||
if (!need_flush && (new_wanted & ~cap->pending())) {
|
||||
@ -2917,8 +2919,7 @@ void Locker::handle_client_caps(MClientCaps *m)
|
||||
adjust_cap_wanted(cap, new_wanted, m->get_issue_seq());
|
||||
}
|
||||
|
||||
if (in->is_auth() &&
|
||||
_do_cap_update(in, cap, m->get_dirty(), follows, m, ack, &need_flush)) {
|
||||
if (updated) {
|
||||
// updated
|
||||
eval(in, CEPH_CAP_LOCKS);
|
||||
|
||||
|
@ -24,7 +24,7 @@ class MClientCaps : public Message {
|
||||
|
||||
public:
|
||||
static const unsigned FLAG_SYNC = (1<<0);
|
||||
static const unsigned FLAG_NO_CAPSNAP = (1<<1);
|
||||
static const unsigned FLAG_NO_CAPSNAP = (1<<1); // unused
|
||||
static const unsigned FLAG_PENDING_CAPSNAP = (1<<2);
|
||||
|
||||
struct ceph_mds_caps_head head;
|
||||
|
Loading…
Reference in New Issue
Block a user