Merge pull request #14991 from ukernel/wip-19828

mds: fix use-after-free in Locker::file_update_finish()

Reviewed-by: John Spray <john.spray@redhat.com>
This commit is contained in:
John Spray 2017-05-15 13:16:35 +01:00 committed by GitHub
commit d63962f194
2 changed files with 19 additions and 22 deletions

View File

@ -1755,27 +1755,26 @@ version_t Locker::issue_file_data_version(CInode *in)
class C_Locker_FileUpdate_finish : public LockerLogContext {
CInode *in;
MutationRef mut;
bool share;
bool share_max;
bool need_issue;
client_t client;
Capability *cap;
MClientCaps *ack;
public:
C_Locker_FileUpdate_finish(Locker *l, CInode *i, MutationRef& m,
bool e=false, client_t c=-1,
Capability *cp = 0,
bool sm=false, bool ni=false, client_t c=-1,
MClientCaps *ac = 0)
: LockerLogContext(l), in(i), mut(m), share(e), client(c), cap(cp),
ack(ac) {
: LockerLogContext(l), in(i), mut(m), share_max(sm), need_issue(ni),
client(c), ack(ac) {
in->get(CInode::PIN_PTRWAITER);
}
void finish(int r) override {
locker->file_update_finish(in, mut, share, client, cap, ack);
locker->file_update_finish(in, mut, share_max, need_issue, client, ack);
in->put(CInode::PIN_PTRWAITER);
}
};
void Locker::file_update_finish(CInode *in, MutationRef& mut, bool share, client_t client,
Capability *cap, MClientCaps *ack)
void Locker::file_update_finish(CInode *in, MutationRef& mut, bool share_max, bool issue_client_cap,
client_t client, MClientCaps *ack)
{
dout(10) << "file_update_finish on " << *in << dendl;
in->pop_and_dirty_projected_inode(mut->ls);
@ -1823,12 +1822,13 @@ void Locker::file_update_finish(CInode *in, MutationRef& mut, bool share, client
eval_cap_gather(in, &need_issue);
}
} else {
if (cap && (cap->wanted() & ~cap->pending()) &&
need_issue.count(in) == 0) { // if we won't issue below anyway
issue_caps(in, cap);
if (issue_client_cap && need_issue.count(in) == 0) {
Capability *cap = in->get_client_cap(client);
if (cap && (cap->wanted() & ~cap->pending()))
issue_caps(in, cap);
}
if (share && in->is_auth() &&
if (share_max && in->is_auth() &&
(in->filelock.gcaps_allowed(CAP_LONER) & (CEPH_CAP_GWR|CEPH_CAP_GBUFFER)))
share_inode_max_size(in);
}
@ -3075,10 +3075,8 @@ void Locker::_do_snap_update(CInode *in, snapid_t snap, int dirty, snapid_t foll
le->metablob.add_client_flush(metareqid_t(m->get_source(), ack->get_client_tid()),
ack->get_oldest_flush_tid());
mds->mdlog->submit_entry(le, new C_Locker_FileUpdate_finish(this, in, mut,
false,
client, NULL,
ack));
mds->mdlog->submit_entry(le, new C_Locker_FileUpdate_finish(this, in, mut, false, false,
client, ack));
}
void Locker::_update_cap_fields(CInode *in, int dirty, MClientCaps *m, inode_t *pi)
@ -3348,9 +3346,8 @@ bool Locker::_do_cap_update(CInode *in, Capability *cap,
ack->get_oldest_flush_tid());
mds->mdlog->submit_entry(le, new C_Locker_FileUpdate_finish(this, in, mut,
change_max,
client, cap,
ack));
change_max, !!cap,
client, ack));
if (need_flush && !*need_flush &&
((change_max && new_max) || // max INCREASE
_need_flush_mdlog(in, dirty)))

View File

@ -248,8 +248,8 @@ public:
protected:
void handle_inode_file_caps(class MInodeFileCaps *m);
void file_update_finish(CInode *in, MutationRef& mut, bool share, client_t client, Capability *cap,
MClientCaps *ack);
void file_update_finish(CInode *in, MutationRef& mut, bool share_max, bool issue_client_cap,
client_t client, MClientCaps *ack);
public:
void calc_new_client_ranges(CInode *in, uint64_t size,
map<client_t, client_writeable_range_t>* new_ranges,