]> git.proxmox.com Git - ceph.git/blame - ceph/src/mds/MDSContext.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / mds / MDSContext.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2012 Red Hat
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15
16#include "MDSRank.h"
17
18#include "MDSContext.h"
19
20#include "common/dout.h"
21#define dout_context g_ceph_context
22#define dout_subsys ceph_subsys_mds
23
11fdf7f2 24void MDSContext::complete(int r) {
7c673cae 25 MDSRank *mds = get_mds();
11fdf7f2 26 ceph_assert(mds != nullptr);
9f95a23c 27 ceph_assert(ceph_mutex_is_locked_by_me(mds->mds_lock));
11fdf7f2 28 dout(10) << "MDSContext::complete: " << typeid(*this).name() << dendl;
20effc67 29 mds->heartbeat_reset();
11fdf7f2 30 return Context::complete(r);
7c673cae
FG
31}
32
33void MDSInternalContextWrapper::finish(int r)
34{
35 fin->complete(r);
36}
37
e306af50
TL
38struct MDSIOContextList {
39 elist<MDSIOContextBase*> list;
40 ceph::spinlock lock;
41 MDSIOContextList() : list(member_offset(MDSIOContextBase, list_item)) {}
42 ~MDSIOContextList() {
43 list.clear(); // avoid assertion in elist's destructor
44 }
45} ioctx_list;
91327a77
AA
46
47MDSIOContextBase::MDSIOContextBase(bool track)
48{
49 created_at = ceph::coarse_mono_clock::now();
50 if (track) {
e306af50
TL
51 ioctx_list.lock.lock();
52 ioctx_list.list.push_back(&list_item);
53 ioctx_list.lock.unlock();
91327a77
AA
54 }
55}
56
57MDSIOContextBase::~MDSIOContextBase()
58{
e306af50 59 ioctx_list.lock.lock();
91327a77 60 list_item.remove_myself();
e306af50 61 ioctx_list.lock.unlock();
91327a77
AA
62}
63
64bool MDSIOContextBase::check_ios_in_flight(ceph::coarse_mono_time cutoff,
65 std::string& slow_count,
66 ceph::coarse_mono_time& oldest)
67{
68 static const unsigned MAX_COUNT = 100;
69 unsigned slow = 0;
70
e306af50
TL
71 ioctx_list.lock.lock();
72 for (elist<MDSIOContextBase*>::iterator p = ioctx_list.list.begin(); !p.end(); ++p) {
91327a77
AA
73 MDSIOContextBase *c = *p;
74 if (c->created_at >= cutoff)
75 break;
76 ++slow;
77 if (slow > MAX_COUNT)
78 break;
79 if (slow == 1)
80 oldest = c->created_at;
81 }
e306af50 82 ioctx_list.lock.unlock();
91327a77
AA
83
84 if (slow > 0) {
85 if (slow > MAX_COUNT)
86 slow_count = std::to_string(MAX_COUNT) + "+";
87 else
88 slow_count = std::to_string(slow);
89 return true;
90 } else {
91 return false;
92 }
93}
94
7c673cae
FG
95void MDSIOContextBase::complete(int r) {
96 MDSRank *mds = get_mds();
97
98 dout(10) << "MDSIOContextBase::complete: " << typeid(*this).name() << dendl;
11fdf7f2 99 ceph_assert(mds != NULL);
9f95a23c
TL
100 // Note, MDSIOContext is passed outside the MDS and, strangely, we grab the
101 // lock here when MDSContext::complete would otherwise assume the lock is
102 // already acquired.
11fdf7f2 103 std::lock_guard l(mds->mds_lock);
91327a77 104
7c673cae
FG
105 if (mds->is_daemon_stopping()) {
106 dout(4) << "MDSIOContextBase::complete: dropping for stopping "
107 << typeid(*this).name() << dendl;
e306af50
TL
108 return;
109 }
110
b3b6e05e
TL
111 // It's possible that the osd op requests will be stuck and then times out
112 // after "rados_osd_op_timeout", the mds won't know what we should it, just
113 // respawn it.
114 if (r == -CEPHFS_EBLOCKLISTED || r == -CEPHFS_ETIMEDOUT) {
115 derr << "MDSIOContextBase: failed with " << r << ", restarting..." << dendl;
7c673cae
FG
116 mds->respawn();
117 } else {
118 MDSContext::complete(r);
119 }
120}
121
122void MDSLogContextBase::complete(int r) {
123 MDLog *mdlog = get_mds()->mdlog;
124 uint64_t safe_pos = write_pos;
125 pre_finish(r);
f67539c2 126 // MDSIOContext::complete() free this
7c673cae 127 MDSIOContextBase::complete(r);
f67539c2 128 // safe_pos must be updated after MDSIOContext::complete() call
7c673cae
FG
129 mdlog->set_safe_pos(safe_pos);
130}
131
7c673cae
FG
132void MDSIOContextWrapper::finish(int r)
133{
134 fin->complete(r);
135}
136
137void C_IO_Wrapper::complete(int r)
138{
139 if (async) {
140 async = false;
141 get_mds()->finisher->queue(this, r);
142 } else {
143 MDSIOContext::complete(r);
144 }
145}