OPTION(mds_kill_journal_expire_at, OPT_INT, 0)
OPTION(mds_kill_journal_replay_at, OPT_INT, 0)
OPTION(mds_kill_create_at, OPT_INT, 0)
-OPTION(mds_open_remote_link_mode, OPT_INT, 0)
OPTION(mds_inject_traceless_reply_probability, OPT_DOUBLE, 0) /* percentage
of MDS modify replies to skip sending the
client a trace on [0-1]*/
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-
-#include "mds/Anchor.h"
-
-#include "common/Formatter.h"
-
-void Anchor::encode(bufferlist &bl) const
-{
- ENCODE_START(2, 2, bl);
- ::encode(ino, bl);
- ::encode(dirino, bl);
- ::encode(dn_hash, bl);
- ::encode(nref, bl);
- ::encode(updated, bl);
- ENCODE_FINISH(bl);
-}
-
-void Anchor::decode(bufferlist::iterator &bl)
-{
- DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl);
- ::decode(ino, bl);
- ::decode(dirino, bl);
- ::decode(dn_hash, bl);
- ::decode(nref, bl);
- ::decode(updated, bl);
- DECODE_FINISH(bl);
-}
-
-void Anchor::dump(Formatter *f) const
-{
- f->dump_unsigned("ino", ino);
- f->dump_unsigned("dirino", dirino);
- f->dump_unsigned("dn_hash", dn_hash);
- f->dump_unsigned("num_ref", nref);
- f->dump_unsigned("updated", updated);
-}
-
-void Anchor::generate_test_instances(list<Anchor*>& ls)
-{
- ls.push_back(new Anchor);
- ls.push_back(new Anchor);
- ls.back()->ino = 1;
- ls.back()->dirino = 2;
- ls.back()->dn_hash = 3;
- ls.back()->nref = 4;
- ls.back()->updated = 5;
-}
-
-ostream& operator<<(ostream& out, const Anchor &a)
-{
- return out << "a(" << a.ino << " " << a.dirino << "/" << a.dn_hash << " " << a.nref << " v" << a.updated << ")";
-}
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-
-#ifndef CEPH_ANCHOR_H
-#define CEPH_ANCHOR_H
-
-#include <string>
-using std::string;
-
-#include "include/types.h"
-#include "mdstypes.h"
-#include "include/buffer.h"
-
-
-// identifies a anchor table mutation
-
-namespace ceph {
- class Formatter;
-}
-
-// anchor type
-
-class Anchor {
-public:
- inodeno_t ino; // anchored ino
- inodeno_t dirino;
- __u32 dn_hash;
- int nref; // reference count
- version_t updated;
-
- Anchor() : dn_hash(0), nref(0), updated(0) {}
- Anchor(inodeno_t i, inodeno_t di, __u32 hash, int nr, version_t u) :
- ino(i), dirino(di), dn_hash(hash), nref(nr), updated(u) { }
-
- void encode(bufferlist &bl) const;
- void decode(bufferlist::iterator &bl);
- void dump(Formatter *f) const;
- static void generate_test_instances(list<Anchor*>& ls);
-};
-WRITE_CLASS_ENCODER(Anchor)
-
-ostream& operator<<(ostream& out, const Anchor &a);
-
-#endif
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-
-#include "AnchorClient.h"
-#include "MDSMap.h"
-#include "LogSegment.h"
-#include "MDS.h"
-#include "msg/Messenger.h"
-
-#include "messages/MMDSTableRequest.h"
-
-#include "common/config.h"
-
-#define dout_subsys ceph_subsys_mds
-#undef dout_prefix
-#define dout_prefix *_dout << "mds." << mds->get_nodeid() << ".anchorclient "
-
-
-
-// LOOKUPS
-/* This function DOES NOT put the passed message before returning */
-void AnchorClient::handle_query_result(class MMDSTableRequest *m)
-{
- dout(10) << "handle_anchor_reply " << *m << dendl;
-
- inodeno_t ino;
- vector<Anchor> trace;
-
- bufferlist::iterator p = m->bl.begin();
- ::decode(ino, p);
- ::decode(trace, p);
-
- if (!pending_lookup.count(ino))
- return;
-
- list<_pending_lookup> ls;
- ls.swap(pending_lookup[ino]);
- pending_lookup.erase(ino);
-
- for (list<_pending_lookup>::iterator q = ls.begin(); q != ls.end(); ++q) {
- *q->trace = trace;
- if (q->onfinish) {
- q->onfinish->complete(0);
- }
- }
-}
-
-void AnchorClient::resend_queries()
-{
- // resend any pending lookups.
- for (map<inodeno_t, list<_pending_lookup> >::iterator p = pending_lookup.begin();
- p != pending_lookup.end();
- ++p) {
- dout(10) << "resending lookup on " << p->first << dendl;
- _lookup(p->first);
- }
-}
-
-void AnchorClient::lookup(inodeno_t ino, vector<Anchor>& trace, Context *onfinish)
-{
- _pending_lookup l;
- l.onfinish = onfinish;
- l.trace = &trace;
-
- bool isnew = (pending_lookup.count(ino) == 0);
- pending_lookup[ino].push_back(l);
- if (isnew)
- _lookup(ino);
-}
-
-void AnchorClient::_lookup(inodeno_t ino)
-{
- int ts = mds->mdsmap->get_tableserver();
- if (mds->mdsmap->get_state(ts) < MDSMap::STATE_REJOIN)
- return;
- MMDSTableRequest *req = new MMDSTableRequest(table, TABLESERVER_OP_QUERY, 0, 0);
- ::encode(ino, req->bl);
- mds->send_message_mds(req, ts);
-}
-
-
-// FRIENDLY PREPARE
-
-void AnchorClient::prepare_create(inodeno_t ino, vector<Anchor>& trace,
- version_t *patid, Context *onfinish)
-{
- dout(10) << "prepare_create " << ino << " " << trace << dendl;
- bufferlist bl;
- __u32 op = TABLE_OP_CREATE;
- ::encode(op, bl);
- ::encode(ino, bl);
- ::encode(trace, bl);
- _prepare(bl, patid, 0, onfinish);
-}
-
-void AnchorClient::prepare_destroy(inodeno_t ino,
- version_t *patid, Context *onfinish)
-{
- dout(10) << "prepare_destroy " << ino << dendl;
- bufferlist bl;
- __u32 op = TABLE_OP_DESTROY;
- ::encode(op, bl);
- ::encode(ino, bl);
- _prepare(bl, patid, 0, onfinish);
-}
-
-
-void AnchorClient::prepare_update(inodeno_t ino, vector<Anchor>& trace,
- version_t *patid, Context *onfinish)
-{
- dout(10) << "prepare_update " << ino << " " << trace << dendl;
- bufferlist bl;
- __u32 op = TABLE_OP_UPDATE;
- ::encode(op, bl);
- ::encode(ino, bl);
- ::encode(trace, bl);
- _prepare(bl, patid, 0, onfinish);
-}
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-
-#ifndef CEPH_ANCHORCLIENT_H
-#define CEPH_ANCHORCLIENT_H
-
-#include "MDSTableClient.h"
-#include "Anchor.h"
-
-class Context;
-class MDS;
-class LogSegment;
-
-class AnchorClient : public MDSTableClient {
- // lookups
- struct _pending_lookup {
- vector<Anchor> *trace;
- Context *onfinish;
- };
- map<inodeno_t, list<_pending_lookup> > pending_lookup;
-
-public:
- AnchorClient(MDS *m) : MDSTableClient(m, TABLE_ANCHOR) {}
-
- void handle_query_result(MMDSTableRequest *m);
- void lookup(inodeno_t ino, vector<Anchor>& trace, Context *onfinish);
- void _lookup(inodeno_t ino);
- void resend_queries();
-
- void prepare_create(inodeno_t ino, vector<Anchor>& trace, version_t *atid, Context *onfinish);
- void prepare_destroy(inodeno_t ino, version_t *atid, Context *onfinish);
- void prepare_update(inodeno_t ino, vector<Anchor>& trace, version_t *atid, Context *onfinish);
-};
-
-#endif
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-
-#include "AnchorServer.h"
-#include "MDS.h"
-#include "msg/Messenger.h"
-#include "messages/MMDSTableRequest.h"
-
-#define dout_subsys ceph_subsys_mds
-#undef dout_prefix
-#define dout_prefix *_dout << "mds." << mds->get_nodeid() << ".anchorserver "
-
-// table
-
-void AnchorServer::reset_state()
-{
- anchor_map.clear();
- pending_create.clear();
- pending_destroy.clear();
- pending_update.clear();
- pending_for_mds.clear();
-}
-
-void AnchorServer::dump()
-{
- dout(7) << "dump v " << version << dendl;
- for (map<inodeno_t, Anchor>::iterator it = anchor_map.begin();
- it != anchor_map.end();
- ++it)
- dout(15) << "dump " << it->second << dendl;
-}
-
-void AnchorServer::dump(Formatter *f) const
-{
- f->open_array_section("anchor map");
- for (map<inodeno_t, Anchor>::const_iterator i = anchor_map.begin();
- i != anchor_map.end(); ++i) {
- f->open_object_section("entry");
- f->dump_int("ino", i->first);
- f->open_object_section("Anchor");
- i->second.dump(f);
- f->close_section(); // Anchor
- f->close_section(); // entry
- }
- f->close_section(); // anchor map
-}
-
-void AnchorServer::generate_test_instances(list<AnchorServer*>& ls)
-{
- AnchorServer *sample = new AnchorServer();
- sample->pending_create[0] = 0;
- sample->pending_destroy[0] = 1;
- sample->anchor_map[0] = Anchor();
- ls.push_back(sample);
-}
-
-
-
-/*
- * basic updates
- * Returns true if it changed the anchor_map contents.
- */
-
-bool AnchorServer::add(inodeno_t ino, inodeno_t dirino, __u32 dn_hash,
- bool replace)
-{
- //dout(17) << "add " << ino << " dirfrag " << dirfrag << dendl;
-
- // parent should be there
- assert(MDS_INO_IS_BASE(dirino) || // base case,
- anchor_map.count(dirino)); // or have it
-
- if (anchor_map.count(ino) == 0) {
- // new item
- anchor_map[ino] = Anchor(ino, dirino, dn_hash, 0, version);
- dout(7) << "add added " << anchor_map[ino] << dendl;
- } else if (replace) {
- anchor_map[ino].dirino = dirino;
- anchor_map[ino].dn_hash = dn_hash;
- dout(7) << "add had old Anchor, updated it to "
- << anchor_map[ino] << dendl;
- } else {
- dout(7) << "add had " << anchor_map[ino] << dendl;
- return false;
- }
- return true;
-}
-
-void AnchorServer::inc(inodeno_t ino, int ref)
-{
- dout(7) << "inc " << ino << dendl;
-
- assert(anchor_map.count(ino));
-
- while (1) {
- Anchor &anchor = anchor_map[ino];
- anchor.nref += ref;
- anchor.updated = version;
-
- dout(10) << "inc now " << anchor << dendl;
- ino = anchor.dirino;
-
- if (ino == 0 || MDS_INO_IS_BASE(ino)) break;
- if (anchor_map.count(ino) == 0) break;
- }
-}
-
-void AnchorServer::dec(inodeno_t ino, int ref)
-{
- dout(7) << "dec " << ino << dendl;
- assert(anchor_map.count(ino));
-
- while (true) {
- Anchor &anchor = anchor_map[ino];
- anchor.nref -= ref;
- anchor.updated = version;
-
- if (anchor.nref == 0) {
- dout(10) << "dec removing " << anchor << dendl;
- inodeno_t dirino = anchor.dirino;
- anchor_map.erase(ino);
- ino = dirino;
- } else {
- dout(10) << "dec now " << anchor << dendl;
- ino = anchor.dirino;
- }
-
- if (ino == 0) break;
- if (anchor_map.count(ino) == 0) break;
- }
-}
-
-
-// server
-
-void AnchorServer::_prepare(bufferlist &bl, uint64_t reqid, int bymds)
-{
- bufferlist::iterator p = bl.begin();
- __u32 what;
- inodeno_t ino;
- vector<Anchor> trace;
- ::decode(what, p);
- ::decode(ino, p);
-
- switch (what) {
- case TABLE_OP_CREATE:
- ::decode(trace, p);
- version++;
-
- // make sure trace is in table
- dout(25) << "trace.size=" << trace.size() << dendl;
- for (unsigned i=0; i<trace.size(); i++) {
- add(trace[i].ino, trace[i].dirino, trace[i].dn_hash, false);
- dout(25) << trace[i] << dendl;
- }
- inc(ino);
- pending_create[version] = ino; // so we can undo
- pending_ops[ino].push_back(pair<version_t, Context*>(version, NULL));
- break;
-
- case TABLE_OP_DESTROY:
- version++;
- pending_destroy[version] = ino;
- pending_ops[ino].push_back(pair<version_t, Context*>(version, NULL));
- break;
-
- case TABLE_OP_UPDATE:
- ::decode(trace, p);
- version++;
- pending_update[version].first = ino;
- pending_update[version].second = trace;
- pending_ops[ino].push_back(pair<version_t, Context*>(version, NULL));
- break;
-
- default:
- assert(0);
- }
- //dump();
-}
-
-bool AnchorServer::check_pending(version_t tid, MMDSTableRequest *req, list<Context *>& finished)
-{
- inodeno_t ino;
- if (pending_create.count(tid))
- ino = pending_create[tid];
- else if (pending_destroy.count(tid))
- ino = pending_destroy[tid];
- else if (pending_update.count(tid))
- ino = pending_update[tid].first;
- else
- assert(0);
-
- assert(pending_ops.count(ino));
- list< pair<version_t, Context*> >& pending = pending_ops[ino];
- list< pair<version_t, Context*> >::iterator p = pending.begin();
- if (p->first == tid) {
- assert(p->second == NULL);
- } else {
- while (p != pending.end()) {
- if (p->first == tid)
- break;
- ++p;
- }
- assert(p != pending.end());
- assert(p->second == NULL);
- // not the earliest pending operation, wait if it's a commit
- if (req) {
- p->second = new C_MDS_RetryMessage(mds, req);
- return false;
- }
- }
-
- pending.erase(p);
- if (pending.empty()) {
- pending_ops.erase(ino);
- } else {
- for (p = pending.begin(); p != pending.end() && p->second; ++p) {
- finished.push_back(p->second);
- p->second = NULL;
- }
- }
- return true;
-}
-
-bool AnchorServer::_commit(version_t tid, MMDSTableRequest *req)
-{
- list<Context *> finished;
- if (!check_pending(tid, req, finished))
- return false;
-
- if (pending_create.count(tid)) {
- dout(7) << "commit " << tid << " create " << pending_create[tid] << dendl;
- pending_create.erase(tid);
- }
-
- else if (pending_destroy.count(tid)) {
- inodeno_t ino = pending_destroy[tid];
- dout(7) << "commit " << tid << " destroy " << ino << dendl;
-
- dec(ino); // destroy
-
- pending_destroy.erase(tid);
- }
-
- else if (pending_update.count(tid)) {
- inodeno_t ino = pending_update[tid].first;
- vector<Anchor> &trace = pending_update[tid].second;
-
- if (anchor_map.count(ino)) {
- dout(7) << "commit " << tid << " update " << ino << dendl;
-
- int ref = anchor_map[ino].nref;
- // remove old
- dec(ino, ref);
-
- // add new
- for (unsigned i=0; i<trace.size(); i++)
- add(trace[i].ino, trace[i].dirino, trace[i].dn_hash, true);
- inc(ino, ref);
- } else {
- dout(7) << "commit " << tid << " update " << ino << " -- DNE" << dendl;
- }
-
- pending_update.erase(tid);
- }
- else
- assert(0);
-
- // bump version.
- version++;
- //dump();
-
- mds->queue_waiters(finished);
- return true;
-}
-
-void AnchorServer::_rollback(version_t tid)
-{
- list<Context *> finished;
- check_pending(tid, NULL, finished);
-
- if (pending_create.count(tid)) {
- inodeno_t ino = pending_create[tid];
- dout(7) << "rollback " << tid << " create " << ino << dendl;
- dec(ino);
- pending_create.erase(tid);
- }
-
- else if (pending_destroy.count(tid)) {
- inodeno_t ino = pending_destroy[tid];
- dout(7) << "rollback " << tid << " destroy " << ino << dendl;
- pending_destroy.erase(tid);
- }
-
- else if (pending_update.count(tid)) {
- inodeno_t ino = pending_update[tid].first;
- dout(7) << "rollback " << tid << " update " << ino << dendl;
- pending_update.erase(tid);
- }
- else
- assert(0);
-
- // bump version.
- version++;
- //dump();
- mds->queue_waiters(finished);
-}
-
-/* This function DOES put the passed message before returning */
-void AnchorServer::handle_query(MMDSTableRequest *req)
-{
- bufferlist::iterator p = req->bl.begin();
- inodeno_t ino;
- ::decode(ino, p);
- dout(7) << "handle_lookup " << *req << " ino " << ino << dendl;
-
- vector<Anchor> trace;
- inodeno_t curino = ino;
- while (true) {
- assert(anchor_map.count(curino) == 1);
- Anchor &anchor = anchor_map[curino];
-
- dout(10) << "handle_lookup adding " << anchor << dendl;
- trace.insert(trace.begin(), anchor); // lame FIXME
-
- if (MDS_INO_IS_BASE(anchor.dirino))
- break;
- curino = anchor.dirino;
- }
-
- // reply
- MMDSTableRequest *reply = new MMDSTableRequest(table, TABLESERVER_OP_QUERY_REPLY, req->reqid, version);
- ::encode(ino, reply->bl);
- ::encode(trace, reply->bl);
- mds->send_message(reply, req->get_connection());
-
- req->put();
-}
-
-
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-
-#ifndef CEPH_ANCHORSERVER_H
-#define CEPH_ANCHORSERVER_H
-
-#include "MDSTableServer.h"
-#include "Anchor.h"
-
-class AnchorServer : public MDSTableServer {
- public:
- AnchorServer(MDS *mds) :
- MDSTableServer(mds, TABLE_ANCHOR) {}
-
- // table bits
- map<inodeno_t, Anchor> anchor_map;
-
- // uncommitted operations
- map<version_t, inodeno_t> pending_create;
- map<version_t, inodeno_t> pending_destroy;
- map<version_t, pair<inodeno_t, vector<Anchor> > > pending_update;
- map<inodeno_t, list<pair<version_t, Context*> > > pending_ops;
-
- void reset_state();
- void encode_server_state(bufferlist& bl) const {
- ENCODE_START(2, 2, bl);
- ::encode(anchor_map, bl);
- ::encode(pending_create, bl);
- ::encode(pending_destroy, bl);
- ::encode(pending_update, bl);
- ENCODE_FINISH(bl);
- }
- void decode_server_state(bufferlist::iterator& p) {
- DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, p);
- ::decode(anchor_map, p);
- ::decode(pending_create, p);
- ::decode(pending_destroy, p);
- ::decode(pending_update, p);
- DECODE_FINISH(p);
-
- map<version_t, inodeno_t> sort;
- sort.insert(pending_create.begin(), pending_create.end());
- sort.insert(pending_destroy.begin(), pending_destroy.end());
- for (map<version_t, pair<inodeno_t, vector<Anchor> > >::iterator p = pending_update.begin();
- p != pending_update.end(); ++p)
- sort[p->first] = p->second.first;
- for (map<version_t, inodeno_t>::iterator p = sort.begin(); p != sort.end(); ++p)
- pending_ops[p->second].push_back(pair<version_t, Context*>(p->first, NULL));
- }
-
- bool add(inodeno_t ino, inodeno_t dirino, __u32 dn_hash, bool replace);
- void inc(inodeno_t ino, int ref=1);
- void dec(inodeno_t ino, int ref=1);
- bool check_pending(version_t tid, MMDSTableRequest *req, list<Context *>& finished);
-
- void dump();
- void dump(Formatter *f) const;
- static void generate_test_instances(list<AnchorServer*>& ls);
- // for the dencoder
- AnchorServer() : MDSTableServer(NULL, TABLE_ANCHOR) {}
- void encode(bufferlist& bl) const {
- encode_server_state(bl);
- }
- void decode(bufferlist::iterator& bl) {
- decode_server_state(bl);
- }
-
- // server bits
- void _prepare(bufferlist &bl, uint64_t reqid, int bymds);
- bool _commit(version_t tid, MMDSTableRequest *req=NULL);
- void _rollback(version_t tid);
- void handle_query(MMDSTableRequest *m);
-};
-
-
-#endif
#include "CDentry.h"
#include "CInode.h"
#include "CDir.h"
-#include "Anchor.h"
#include "MDS.h"
#include "MDCache.h"
}
*/
-/** make_anchor_trace
- * construct an anchor trace for this dentry, as if it were linked to *in.
- */
-void CDentry::make_anchor_trace(vector<Anchor>& trace, CInode *in)
-{
- // start with parent dir inode
- dir->inode->make_anchor_trace(trace);
-
- // add this inode (in my dirfrag) to the end
- trace.push_back(Anchor(in->ino(), dir->ino(), get_hash(), 0, 0));
- dout(10) << "make_anchor_trace added " << trace.back() << dendl;
-}
-
-
/*
* we only add ourselves to remote_parents when the linkage is
* active (no longer projected). if the passed dnl is projected,
return dir->is_freezing();
}
-
-void CDentry::adjust_nested_anchors(int by)
-{
- nested_anchors += by;
- dout(20) << "adjust_nested_anchors by " << by << " -> " << nested_anchors << dendl;
- assert(nested_anchors >= 0);
- dir->adjust_nested_anchors(by);
-}
-
-
void CDentry::decode_replica(bufferlist::iterator& p, bool is_new)
{
__u32 nonce;
struct MDRequest;
class Message;
-class Anchor;
-
class CDentry;
class LogSegment;
#ifdef MDS_AUTHPIN_SET
multiset<void*> auth_pin_set;
#endif
- int nested_anchors;
-
friend class Migrator;
friend class Locker;
friend class MDCache;
dir(0),
version(0), projected_version(0),
item_dirty(this),
- auth_pins(0), nested_auth_pins(0), nested_anchors(0),
+ auth_pins(0), nested_auth_pins(0),
lock(this, &lock_type),
versionlock(this, &versionlock_type) {
g_num_dn++;
dir(0),
version(0), projected_version(0),
item_dirty(this),
- auth_pins(0), nested_auth_pins(0), nested_anchors(0),
+ auth_pins(0), nested_auth_pins(0),
lock(this, &lock_type),
versionlock(this, &versionlock_type) {
g_num_dn++;
int get_num_dir_auth_pins();
int get_num_nested_auth_pins() { return nested_auth_pins; }
- void adjust_nested_anchors(int by);
-
// remote links
void link_remote(linkage_t *dnl, CInode *in);
void unlink_remote(linkage_t *dnl);
// misc
void make_path_string(string& s);
void make_path(filepath& fp);
- void make_anchor_trace(vector<class Anchor>& trace, CInode *in);
// -- version --
version_t get_version() { return version; }
out << " ap=" << dir.get_auth_pins()
<< "+" << dir.get_dir_auth_pins()
<< "+" << dir.get_nested_auth_pins();
- if (dir.get_nested_anchors())
- out << " na=" << dir.get_nested_anchors();
out << " state=" << dir.get_state();
if (dir.state_test(CDir::STATE_COMPLETE)) out << "|complete";
dir_auth_pins = 0;
request_pins = 0;
- nested_anchors = 0;
-
dir_rep = REP_NONE;
}
if (in->auth_pins + in->nested_auth_pins)
dn->adjust_nested_auth_pins(in->auth_pins + in->nested_auth_pins, in->auth_pins, NULL);
- if (in->inode.anchored + in->nested_anchors)
- dn->adjust_nested_anchors(in->nested_anchors + in->inode.anchored);
-
// verify open snaprealm parent
if (in->snaprealm)
in->snaprealm->adjust_parent();
if (in->auth_pins + in->nested_auth_pins)
dn->adjust_nested_auth_pins(0 - (in->auth_pins + in->nested_auth_pins), 0 - in->auth_pins, NULL);
- if (in->inode.anchored + in->nested_anchors)
- dn->adjust_nested_anchors(0 - (in->nested_anchors + in->inode.anchored));
-
// detach inode
in->remove_primary_parent(dn);
dn->get_linkage()->inode = 0;
fnode.rstat.rbytes += pi->accounted_rstat.rbytes;
fnode.rstat.rfiles += pi->accounted_rstat.rfiles;
fnode.rstat.rsubdirs += pi->accounted_rstat.rsubdirs;
- fnode.rstat.ranchors += pi->accounted_rstat.ranchors;
- fnode.rstat.rsnaprealms += pi->accounted_rstat.ranchors;
+ fnode.rstat.rsnaprealms += pi->accounted_rstat.rsnaprealms;
if (pi->accounted_rstat.rctime > fnode.rstat.rctime)
fnode.rstat.rctime = pi->accounted_rstat.rctime;
dn->dir->adjust_nested_auth_pins(-ap, -dap, NULL);
}
- nested_anchors += dn->nested_anchors;
if (dn->is_dirty())
num_dirty++;
if (snaps)
in->purge_stale_snap_data(*snaps);
- if (undef_inode) {
- if (inode.anchored)
- dn->adjust_nested_anchors(1);
- } else {
- cache->add_inode( in ); // add
+ if (!undef_inode) {
+ cache->add_inode(in); // add
dn = add_primary_dentry(dname, in, first, last); // link
}
dout(12) << "_fetched got " << *dn << " " << *in << dendl;
}
}
-void CDir::adjust_nested_anchors(int by)
-{
- assert(by);
- nested_anchors += by;
- dout(20) << "adjust_nested_anchors by " << by << " -> " << nested_anchors << dendl;
- assert(nested_anchors >= 0);
- inode->adjust_nested_anchors(by);
-}
-
#ifdef MDS_VERIFY_FRAGSTAT
void CDir::verify_fragstat()
{
int nested_auth_pins, dir_auth_pins;
int request_pins;
- int nested_anchors;
-
// cache control (defined for authority; hints for replicas)
__s32 dir_rep;
set<__s32> dir_rep_by; // if dir_rep == REP_LIST
void adjust_nested_auth_pins(int inc, int dirinc, void *by);
void verify_fragstat();
- int get_nested_anchors() { return nested_anchors; }
- void adjust_nested_anchors(int by);
-
// -- freezing --
bool freeze_tree();
void _freeze_tree();
if (pi->is_truncating())
out << " truncating(" << pi->truncate_from << " to " << pi->truncate_size << ")";
- // anchors
- if (in.is_anchored())
- out << " anc";
- if (in.get_nested_anchors())
- out << " na=" << in.get_nested_anchors();
-
if (in.inode.is_dir()) {
out << " " << in.inode.dirstat;
if (g_conf->mds_debug_scatterstat && in.is_projected()) {
fp = filepath(ino());
}
-void CInode::make_anchor_trace(vector<Anchor>& trace)
-{
- if (get_projected_parent_dn())
- get_projected_parent_dn()->make_anchor_trace(trace, this);
- else
- assert(is_base());
-}
-
void CInode::name_stray_dentry(string& dname)
{
char s[20];
dname = s;
}
-
-
-
version_t CInode::pre_dirty()
{
version_t pv;
::encode(inode.version, bl);
::encode(inode.ctime, bl);
::encode(inode.nlink, bl);
- ::encode(inode.anchored, bl);
break;
case CEPH_LOCK_IDFT:
::decode(tm, p);
if (inode.ctime < tm) inode.ctime = tm;
::decode(inode.nlink, p);
- {
- bool was_anchored = inode.anchored;
- ::decode(inode.anchored, p);
- if (parent && was_anchored != inode.anchored)
- parent->adjust_nested_anchors((int)inode.anchored - (int)was_anchored);
- }
break;
case CEPH_LOCK_IDFT:
parent->adjust_nested_auth_pins(a, 0, by);
}
-void CInode::adjust_nested_anchors(int by)
-{
- assert(by);
- nested_anchors += by;
- dout(20) << "adjust_nested_anchors by " << by << " -> " << nested_anchors << dendl;
- assert(nested_anchors >= 0);
- if (parent)
- parent->adjust_nested_anchors(by);
-}
// authority
void CInode::_decode_base(bufferlist::iterator& p)
{
::decode(first, p);
- bool was_anchored = inode.anchored;
::decode(inode, p);
- if (parent && was_anchored != inode.anchored)
- parent->adjust_nested_anchors((int)inode.anchored - (int)was_anchored);
-
::decode(symlink, p);
::decode(dirfragtree, p);
::decode(xattrs, p);
static const int PIN_DIRFRAG = -1;
static const int PIN_CAPS = 2; // client caps
static const int PIN_IMPORTING = -4; // importing
- static const int PIN_ANCHORING = 5;
- static const int PIN_UNANCHORING = 6;
static const int PIN_OPENINGDIR = 7;
static const int PIN_REMOTEPARENT = 8;
static const int PIN_BATCHOPENJOURNAL = 9;
case PIN_DIRFRAG: return "dirfrag";
case PIN_CAPS: return "caps";
case PIN_IMPORTING: return "importing";
- case PIN_ANCHORING: return "anchoring";
- case PIN_UNANCHORING: return "unanchoring";
case PIN_OPENINGDIR: return "openingdir";
case PIN_REMOTEPARENT: return "remoteparent";
case PIN_BATCHOPENJOURNAL: return "batchopenjournal";
// -- state --
static const int STATE_EXPORTING = (1<<2); // on nonauth bystander.
- static const int STATE_ANCHORING = (1<<3);
- static const int STATE_UNANCHORING = (1<<4);
static const int STATE_OPENINGDIR = (1<<5);
static const int STATE_FREEZING = (1<<7);
static const int STATE_FROZEN = (1<<8);
// -- waiters --
static const uint64_t WAIT_DIR = (1<<0);
- static const uint64_t WAIT_ANCHORED = (1<<1);
- static const uint64_t WAIT_UNANCHORED = (1<<2);
- static const uint64_t WAIT_FROZEN = (1<<3);
- static const uint64_t WAIT_TRUNC = (1<<4);
- static const uint64_t WAIT_FLOCK = (1<<5);
+ static const uint64_t WAIT_FROZEN = (1<<1);
+ static const uint64_t WAIT_TRUNC = (1<<2);
+ static const uint64_t WAIT_FLOCK = (1<<3);
static const uint64_t WAIT_ANY_MASK = (uint64_t)(-1);
#endif
int auth_pin_freeze_allowance;
-private:
- int nested_anchors; // _NOT_ including me!
-
- public:
inode_load_vec_t pop;
// friends
friend class CDir;
friend class CInodeExport;
- public:
// ---------------------------
CInode(MDCache *c, bool auth=true, snapid_t f=2, snapid_t l=CEPH_NOSNAP) :
mdcache(c),
item_dirty_dirfrag_dirfragtree(this),
auth_pins(0), nested_auth_pins(0),
auth_pin_freeze_allowance(0),
- nested_anchors(0),
pop(ceph_clock_now(g_ceph_context)),
versionlock(this, &versionlock_type),
authlock(this, &authlock_type),
bool is_symlink() { return inode.is_symlink(); }
bool is_dir() { return inode.is_dir(); }
- bool is_anchored() { return inode.anchored; }
- bool is_anchoring() { return state_test(STATE_ANCHORING); }
- bool is_unanchoring() { return state_test(STATE_UNANCHORING); }
-
bool is_root() { return inode.ino == MDS_INO_ROOT; }
bool is_stray() { return MDS_INO_IS_STRAY(inode.ino); }
bool is_mdsdir() { return MDS_INO_IS_MDSDIR(inode.ino); }
void make_path_string(string& s, bool force=false, CDentry *use_parent=NULL);
void make_path_string_projected(string& s);
void make_path(filepath& s);
- void make_anchor_trace(vector<class Anchor>& trace);
void name_stray_dentry(string& dname);
void auth_pin(void *by);
void auth_unpin(void *by);
- void adjust_nested_anchors(int by);
- int get_nested_anchors() { return nested_anchors; }
-
// -- freeze --
bool is_freezing_inode() { return state_test(STATE_FREEZING); }
bool is_frozen_inode() { return state_test(STATE_FROZEN); }
class MClientRequest;
-class Anchor;
class Capability;
class LogSegment;
#include "MDBalancer.h"
#include "Migrator.h"
-#include "AnchorClient.h"
#include "SnapClient.h"
#include "MDSMap.h"
return in;
} else {
dout(10) << "get_dentry_inode on remote dn, opening inode for " << *dn << dendl;
- open_remote_ino(dnl->remote_ino, new C_MDS_RetryRequest(this, mdr));
+ open_remote_dentry(dn, projected, new C_MDS_RetryRequest(this, mdr));
return 0;
}
}
-class C_MDC_RetryOpenRemoteIno : public Context {
- MDCache *mdcache;
- inodeno_t ino;
- bool want_xlocked;
- Context *onfinish;
-public:
- C_MDC_RetryOpenRemoteIno(MDCache *mdc, inodeno_t i, Context *c, bool wx) :
- mdcache(mdc), ino(i), want_xlocked(wx), onfinish(c) {}
- void finish(int r) {
- if (mdcache->get_inode(ino)) {
- onfinish->complete(0);
- } else
- mdcache->open_remote_ino(ino, onfinish, want_xlocked);
- }
-};
-
-
-class C_MDC_OpenRemoteIno : public Context {
- MDCache *mdcache;
- inodeno_t ino;
- inodeno_t hadino;
- version_t hadv;
- bool want_xlocked;
- Context *onfinish;
-public:
- vector<Anchor> anchortrace;
-
- C_MDC_OpenRemoteIno(MDCache *mdc, inodeno_t i, bool wx, inodeno_t hi, version_t hv, Context *c) :
- mdcache(mdc), ino(i), hadino(hi), hadv(hv), want_xlocked(wx), onfinish(c) {}
- C_MDC_OpenRemoteIno(MDCache *mdc, inodeno_t i, bool wx, vector<Anchor>& at, Context *c) :
- mdcache(mdc), ino(i), hadino(0), hadv(0), want_xlocked(wx), onfinish(c), anchortrace(at) {}
-
- void finish(int r) {
- assert(r == 0);
- if (r == 0)
- mdcache->open_remote_ino_2(ino, anchortrace, want_xlocked, hadino, hadv, onfinish);
- else {
- onfinish->complete(r);
- }
- }
-};
-
-void MDCache::open_remote_ino(inodeno_t ino, Context *onfinish, bool want_xlocked,
- inodeno_t hadino, version_t hadv)
-{
- dout(7) << "open_remote_ino on " << ino << (want_xlocked ? " want_xlocked":"") << dendl;
-
- C_MDC_OpenRemoteIno *c = new C_MDC_OpenRemoteIno(this, ino, want_xlocked,
- hadino, hadv, onfinish);
- mds->anchorclient->lookup(ino, c->anchortrace, c);
-}
-
-void MDCache::open_remote_ino_2(inodeno_t ino, vector<Anchor>& anchortrace, bool want_xlocked,
- inodeno_t hadino, version_t hadv, Context *onfinish)
-{
- dout(7) << "open_remote_ino_2 on " << ino
- << ", trace depth is " << anchortrace.size() << dendl;
-
- // find deepest cached inode in prefix
- unsigned i = anchortrace.size(); // i := array index + 1
- CInode *in = 0;
- while (1) {
- // inode?
- dout(10) << " " << i << ": " << anchortrace[i-1] << dendl;
- in = get_inode(anchortrace[i-1].ino);
- if (in)
- break;
- i--;
- if (!i) {
- in = get_inode(anchortrace[i].dirino);
- if (!in) {
- dout(0) << "open_remote_ino_2 don't have dir inode " << anchortrace[i].dirino << dendl;
- if (MDS_INO_IS_MDSDIR(anchortrace[i].dirino)) {
- open_foreign_mdsdir(anchortrace[i].dirino, onfinish);
- return;
- }
- assert(in); // hrm!
- }
- break;
- }
- }
- dout(10) << "deepest cached inode at " << i << " is " << *in << dendl;
-
- if (in->ino() == ino) {
- // success
- dout(10) << "open_remote_ino_2 have " << *in << dendl;
- onfinish->complete(0);
- return;
- }
-
- // open dirfrag beneath *in
- frag_t frag = in->dirfragtree[anchortrace[i].dn_hash];
-
- if (!in->dirfragtree.contains(frag)) {
- dout(10) << "frag " << frag << " not valid, requerying anchortable" << dendl;
- open_remote_ino(ino, onfinish, want_xlocked);
- return;
- }
-
- CDir *dir = in->get_dirfrag(frag);
-
- if (!dir && !in->is_auth()) {
- dout(10) << "opening remote dirfrag " << frag << " under " << *in << dendl;
- /* we re-query the anchortable just to avoid a fragtree update race */
- open_remote_dirfrag(in, frag,
- new C_MDC_RetryOpenRemoteIno(this, ino, onfinish, want_xlocked));
- return;
- }
-
- if (!dir && in->is_auth()) {
- if (in->is_frozen_dir()) {
- dout(7) << "traverse: " << *in << " is frozen_dir, waiting" << dendl;
- in->parent->dir->add_waiter(CDir::WAIT_UNFREEZE,
- new C_MDC_RetryOpenRemoteIno(this, ino, onfinish, want_xlocked));
- return;
- }
- dir = in->get_or_open_dirfrag(this, frag);
- }
- assert(dir);
-
- if (dir->is_auth()) {
- if (dir->is_complete()) {
- // make sure we didn't get to the same version anchor 2x in a row
- if (hadv && hadino == anchortrace[i].ino && hadv == anchortrace[i].updated) {
- dout(10) << "expected ino " << anchortrace[i].ino
- << " in complete dir " << *dir
- << ", got same anchor " << anchortrace[i] << " 2x in a row" << dendl;
- onfinish->complete(-ENOENT);
- } else {
- // hrm. requery anchor table.
- dout(10) << "expected ino " << anchortrace[i].ino
- << " in complete dir " << *dir
- << ", requerying anchortable"
- << dendl;
- open_remote_ino(ino, onfinish, want_xlocked,
- anchortrace[i].ino, anchortrace[i].updated);
- }
- } else {
- dout(10) << "need ino " << anchortrace[i].ino
- << ", fetching incomplete dir " << *dir
- << dendl;
- dir->fetch(new C_MDC_OpenRemoteIno(this, ino, want_xlocked, anchortrace, onfinish));
- }
- } else {
- // hmm, discover.
- dout(10) << "have remote dirfrag " << *dir << ", discovering "
- << anchortrace[i].ino << dendl;
- discover_ino(dir, anchortrace[i].ino,
- new C_MDC_RetryOpenRemoteIno(this, ino, onfinish, want_xlocked),
- (want_xlocked && i == anchortrace.size() - 1));
- }
-}
-
-
struct C_MDC_OpenRemoteDentry : public Context {
MDCache *mdc;
CDentry *dn;
inodeno_t ino;
Context *onfinish;
bool want_xlocked;
- int mode;
- C_MDC_OpenRemoteDentry(MDCache *m, CDentry *d, inodeno_t i, Context *f,
- bool wx, int md) :
- mdc(m), dn(d), ino(i), onfinish(f), want_xlocked(wx), mode(md) {}
+ C_MDC_OpenRemoteDentry(MDCache *m, CDentry *d, inodeno_t i, Context *f, bool wx) :
+ mdc(m), dn(d), ino(i), onfinish(f), want_xlocked(wx) {}
void finish(int r) {
- mdc->_open_remote_dentry_finish(dn, ino, onfinish, want_xlocked, mode, r);
+ mdc->_open_remote_dentry_finish(dn, ino, onfinish, want_xlocked, r);
}
};
dout(10) << "open_remote_dentry " << *dn << dendl;
CDentry::linkage_t *dnl = projected ? dn->get_projected_linkage() : dn->get_linkage();
inodeno_t ino = dnl->get_remote_ino();
- int mode = g_conf->mds_open_remote_link_mode;
- Context *fin2 = new C_MDC_OpenRemoteDentry(this, dn, ino, fin, want_xlocked, mode);
- if (mode == 0)
- open_remote_ino(ino, fin2, want_xlocked); // anchor
- else
- open_ino(ino, -1, fin2, true, want_xlocked); // backtrace
+ uint64_t pool = dnl->get_remote_d_type() == DT_DIR ? mds->mdsmap->get_metadata_pool() : -1;
+ Context *fin2 = new C_MDC_OpenRemoteDentry(this, dn, ino, fin, want_xlocked);
+ open_ino(ino, pool, fin2, true, want_xlocked); // backtrace
}
void MDCache::_open_remote_dentry_finish(CDentry *dn, inodeno_t ino, Context *fin,
- bool want_xlocked, int mode, int r)
+ bool want_xlocked, int r)
{
if (r < 0) {
- if (mode == 0) {
dout(0) << "open_remote_dentry_finish bad remote dentry " << *dn << dendl;
dn->state_set(CDentry::STATE_BADREMOTEINO);
- } else {
- dout(7) << "open_remote_dentry_finish failed to open ino " << ino
- << " for " << *dn << ", retry using anchortable" << dendl;
- assert(mode == 1);
- Context *fin2 = new C_MDC_OpenRemoteDentry(this, dn, ino, fin, want_xlocked, 0);
- open_remote_ino(ino, fin2, want_xlocked);
- return;
- }
}
fin->complete(r < 0 ? r : 0);
}
}
}
-
-// --------------------------------------------------------------------
-// ANCHORS
-
-class C_MDC_AnchorPrepared : public Context {
- MDCache *cache;
- CInode *in;
- bool add;
-public:
- version_t atid;
- C_MDC_AnchorPrepared(MDCache *c, CInode *i, bool a) : cache(c), in(i), add(a), atid(0) {}
- void finish(int r) {
- cache->_anchor_prepared(in, atid, add);
- }
-};
-
-void MDCache::anchor_create_prep_locks(MDRequestRef& mdr, CInode *in,
- set<SimpleLock*>& rdlocks, set<SimpleLock*>& xlocks)
-{
- dout(10) << "anchor_create_prep_locks " << *in << dendl;
-
- if (in->is_anchored()) {
- // caller may have already xlocked it.. if so, that will suffice!
- if (xlocks.count(&in->linklock) == 0)
- rdlocks.insert(&in->linklock);
- } else {
- xlocks.insert(&in->linklock);
-
- // path components too!
- CDentry *dn = in->get_projected_parent_dn();
- while (dn) {
- rdlocks.insert(&dn->lock);
- dn = dn->get_dir()->get_inode()->get_parent_dn();
- }
- }
-}
-
-void MDCache::anchor_create(MDRequestRef& mdr, CInode *in, Context *onfinish)
-{
- assert(in->is_auth());
- dout(10) << "anchor_create " << *in << dendl;
-
- // auth pin
- if (!in->can_auth_pin() &&
- !mdr->is_auth_pinned(in)) {
- dout(7) << "anchor_create not authpinnable, waiting on " << *in << dendl;
- in->add_waiter(CInode::WAIT_UNFREEZE, onfinish);
- return;
- }
-
- // wait
- in->add_waiter(CInode::WAIT_ANCHORED, onfinish);
-
- // already anchoring?
- if (in->state_test(CInode::STATE_ANCHORING)) {
- dout(7) << "anchor_create already anchoring " << *in << dendl;
- return;
- }
-
- dout(7) << "anchor_create " << *in << dendl;
-
- // auth: do it
- in->state_set(CInode::STATE_ANCHORING);
- in->get(CInode::PIN_ANCHORING);
- in->auth_pin(this);
-
- // make trace
- vector<Anchor> trace;
- in->make_anchor_trace(trace);
- if (trace.empty()) {
- assert(MDS_INO_IS_BASE(in->ino()));
- trace.push_back(Anchor(in->ino(), in->ino(), 0, 0, 0));
- }
-
- // do it
- C_MDC_AnchorPrepared *fin = new C_MDC_AnchorPrepared(this, in, true);
- mds->anchorclient->prepare_create(in->ino(), trace, &fin->atid, fin);
-}
-
-void MDCache::anchor_destroy(CInode *in, Context *onfinish)
-{
- assert(in->is_auth());
-
- // auth pin
- if (!in->can_auth_pin()/* &&
- !mdr->is_auth_pinned(in)*/) {
- dout(7) << "anchor_destroy not authpinnable, waiting on " << *in << dendl;
- in->add_waiter(CInode::WAIT_UNFREEZE, onfinish);
- return;
- }
-
- dout(7) << "anchor_destroy " << *in << dendl;
-
- // wait
- if (onfinish)
- in->add_waiter(CInode::WAIT_UNANCHORED, onfinish);
-
- // already anchoring?
- if (in->state_test(CInode::STATE_UNANCHORING)) {
- dout(7) << "anchor_destroy already unanchoring " << *in << dendl;
- return;
- }
-
- // auth: do it
- in->state_set(CInode::STATE_UNANCHORING);
- in->get(CInode::PIN_UNANCHORING);
- in->auth_pin(this);
-
- // do it
- C_MDC_AnchorPrepared *fin = new C_MDC_AnchorPrepared(this, in, false);
- mds->anchorclient->prepare_destroy(in->ino(), &fin->atid, fin);
-}
-
-class C_MDC_AnchorLogged : public Context {
- MDCache *cache;
- CInode *in;
- version_t atid;
- MutationRef mut;
-public:
- C_MDC_AnchorLogged(MDCache *c, CInode *i, version_t t, MutationRef& m) :
- cache(c), in(i), atid(t), mut(m) {}
- void finish(int r) {
- cache->_anchor_logged(in, atid, mut);
- }
-};
-
-void MDCache::_anchor_prepared(CInode *in, version_t atid, bool add)
-{
- dout(10) << "_anchor_prepared " << *in << " atid " << atid
- << " " << (add ? "create":"destroy") << dendl;
- assert(in->inode.anchored == !add);
-
- // update the logged inode copy
- inode_t *pi = in->project_inode();
- if (add) {
- pi->anchored = true;
- pi->rstat.ranchors++;
- } else {
- pi->anchored = false;
- pi->rstat.ranchors--;
- }
- pi->version = in->pre_dirty();
-
- MutationRef mut(new MutationImpl);
- mut->ls = mds->mdlog->get_current_segment();
- EUpdate *le = new EUpdate(mds->mdlog, add ? "anchor_create":"anchor_destroy");
- mds->mdlog->start_entry(le);
- predirty_journal_parents(mut, &le->metablob, in, 0, PREDIRTY_PRIMARY);
- journal_dirty_inode(mut.get(), &le->metablob, in);
- le->metablob.add_table_transaction(TABLE_ANCHOR, atid);
- mds->mdlog->submit_entry(le, new C_MDC_AnchorLogged(this, in, atid, mut));
- mds->mdlog->flush();
-}
-
-
-void MDCache::_anchor_logged(CInode *in, version_t atid, MutationRef& mut)
-{
- dout(10) << "_anchor_logged on " << *in << dendl;
-
- // unpin
- if (in->state_test(CInode::STATE_ANCHORING)) {
- in->state_clear(CInode::STATE_ANCHORING);
- in->put(CInode::PIN_ANCHORING);
- if (in->parent)
- in->parent->adjust_nested_anchors(1);
- } else if (in->state_test(CInode::STATE_UNANCHORING)) {
- in->state_clear(CInode::STATE_UNANCHORING);
- in->put(CInode::PIN_UNANCHORING);
- if (in->parent)
- in->parent->adjust_nested_anchors(-1);
- }
- in->auth_unpin(this);
-
- // apply update to cache
- in->pop_and_dirty_projected_inode(mut->ls);
- mut->apply();
-
- // tell the anchortable we've committed
- mds->anchorclient->commit(atid, mut->ls);
-
- // drop locks and finish
- mds->locker->drop_locks(mut.get());
- mut->cleanup();
-
- // trigger waiters
- in->finish_waiting(CInode::WAIT_ANCHORED|CInode::WAIT_UNANCHORED, 0);
-}
-
-
// -------------------------------------------------------------------------------
// SNAPREALMS
dout(10) << "snaprealm_create " << *in << dendl;
assert(!in->snaprealm);
- if (!in->inode.anchored) {
- mds->mdcache->anchor_create(mdr, in, new C_MDS_RetryRequest(mds->mdcache, mdr));
- return;
- }
-
// allocate an id..
if (!mdr->more()->stid) {
mds->snapclient->prepare_create_realm(in->ino(), &mdr->more()->stid, &mdr->more()->snapidbl,
dout(10) << "purge_stray " << *dn << " " << *in << dendl;
assert(!dn->is_replicated());
- // anchored?
- if (in->inode.anchored) {
- anchor_destroy(in, new C_MDC_EvalStray(this, dn));
- return;
- }
-
dn->state_set(CDentry::STATE_PURGING);
dn->get(CDentry::PIN_PURGING);
in->state_set(CInode::STATE_PURGING);
void open_remote_dirfrag(CInode *diri, frag_t fg, Context *fin);
CInode *get_dentry_inode(CDentry *dn, MDRequestRef& mdr, bool projected=false);
- void open_remote_ino(inodeno_t ino, Context *fin, bool want_xlocked=false,
- inodeno_t hadino=0, version_t hadv=0);
- void open_remote_ino_2(inodeno_t ino,
- vector<Anchor>& anchortrace, bool want_xlocked,
- inodeno_t hadino, version_t hadv, Context *onfinish);
bool parallel_fetch(map<inodeno_t,filepath>& pathmap, set<inodeno_t>& missing);
bool parallel_fetch_traverse_dir(inodeno_t ino, filepath& path,
void open_remote_dentry(CDentry *dn, bool projected, Context *fin,
bool want_xlocked=false);
void _open_remote_dentry_finish(CDentry *dn, inodeno_t ino, Context *fin,
- bool want_xlocked, int mode, int r);
+ bool want_xlocked, int r);
void make_trace(vector<CDentry*>& trace, CInode *in);
void handle_find_ino_reply(MMDSFindInoReply *m);
void kick_find_ino_peers(int who);
- // -- anchors --
-public:
- void anchor_create_prep_locks(MDRequestRef& mdr, CInode *in, set<SimpleLock*>& rdlocks,
- set<SimpleLock*>& xlocks);
- void anchor_create(MDRequestRef& mdr, CInode *in, Context *onfinish);
- void anchor_destroy(CInode *in, Context *onfinish);
-protected:
- void _anchor_prepared(CInode *in, version_t atid, bool add);
- void _anchor_logged(CInode *in, version_t atid, MutationRef& mut);
- friend class C_MDC_AnchorPrepared;
- friend class C_MDC_AnchorLogged;
-
// -- snaprealms --
public:
void snaprealm_create(MDRequestRef& mdr, CInode *in);
#include "MDBalancer.h"
#include "Migrator.h"
-#include "AnchorServer.h"
-#include "AnchorClient.h"
#include "SnapServer.h"
#include "SnapClient.h"
inotable = new InoTable(this);
snapserver = new SnapServer(this);
snapclient = new SnapClient(this);
- anchorserver = new AnchorServer(this);
- anchorclient = new AnchorClient(this);
server = new Server(this);
locker = new Locker(this, mdcache);
if (mdlog) { delete mdlog; mdlog = NULL; }
if (balancer) { delete balancer; balancer = NULL; }
if (inotable) { delete inotable; inotable = NULL; }
- if (anchorserver) { delete anchorserver; anchorserver = NULL; }
if (snapserver) { delete snapserver; snapserver = NULL; }
if (snapclient) { delete snapclient; snapclient = NULL; }
- if (anchorclient) { delete anchorclient; anchorclient = NULL; }
if (osdmap) { delete osdmap; osdmap = 0; }
if (mdsmap) { delete mdsmap; mdsmap = 0; }
MDSTableClient *MDS::get_table_client(int t)
{
switch (t) {
- case TABLE_ANCHOR: return anchorclient;
+ case TABLE_ANCHOR: return NULL;
case TABLE_SNAP: return snapclient;
default: assert(0);
}
MDSTableServer *MDS::get_table_server(int t)
{
switch (t) {
- case TABLE_ANCHOR: return anchorserver;
+ case TABLE_ANCHOR: return NULL;
case TABLE_SNAP: return snapserver;
default: assert(0);
}
// initialize tables
if (mdsmap->get_tableserver() == whoami) {
- dout(10) << "boot_create creating fresh anchortable" << dendl;
- anchorserver->reset();
- anchorserver->save(fin.new_sub());
-
dout(10) << "boot_create creating fresh snaptable" << dendl;
snapserver->reset();
snapserver->save(fin.new_sub());
dout(2) << "boot_start " << step << ": opening sessionmap" << dendl;
sessionmap.load(gather.new_sub());
- if (mdsmap->get_tableserver() == whoami) {
- dout(2) << "boot_start " << step << ": opening anchor table" << dendl;
- anchorserver->load(gather.new_sub());
+ dout(2) << "boot_start " << step << ": opening mds log" << dendl;
+ mdlog->open(gather.new_sub());
- dout(2) << "boot_start " << step << ": opening snap table" << dendl;
+ if (mdsmap->get_tableserver() == whoami) {
+ dout(2) << "boot_start " << step << ": opening snap table" << dendl;
snapserver->load(gather.new_sub());
}
-
- dout(2) << "boot_start " << step << ": opening mds log" << dendl;
- mdlog->open(gather.new_sub());
+
gather.activate();
}
break;
dout(1) << "recovery_done -- successful recovery!" << dendl;
assert(is_clientreplay() || is_active());
- // kick anchortable (resent AGREEs)
+ // kick snaptable (resent AGREEs)
if (mdsmap->get_tableserver() == whoami) {
set<int> active;
- mdsmap->get_mds_set(active, MDSMap::STATE_CLIENTREPLAY);
- mdsmap->get_mds_set(active, MDSMap::STATE_ACTIVE);
- mdsmap->get_mds_set(active, MDSMap::STATE_STOPPING);
- anchorserver->finish_recovery(active);
+ mdsmap->get_clientreplay_or_active_or_stopping_mds_set(active);
snapserver->finish_recovery(active);
}
mdcache->handle_mds_recovery(who);
if (mdsmap->get_tableserver() == whoami) {
- anchorserver->handle_mds_recovery(who);
snapserver->handle_mds_recovery(who);
}
mdcache->handle_mds_failure(who);
- anchorclient->handle_mds_failure(who);
snapclient->handle_mds_failure(who);
}
class InoTable;
class SnapServer;
class SnapClient;
-class AnchorServer;
-class AnchorClient;
class MDSTableServer;
class MDSTableClient;
InoTable *inotable;
- AnchorServer *anchorserver;
- AnchorClient *anchorclient;
-
SnapServer *snapserver;
SnapClient *snapclient;
// who am i etc
int get_nodeid() { return whoami; }
+ uint64_t get_metadata_pool() { return mdsmap->get_metadata_pool(); }
MDSMap *get_mds_map() { return mdsmap; }
OSDMap *get_osd_map() { return osdmap; }
feature_incompat.insert(MDS_FEATURE_INCOMPAT_ENCODING);
feature_incompat.insert(MDS_FEATURE_INCOMPAT_OMAPDIRFRAG);
feature_incompat.insert(MDS_FEATURE_INCOMPAT_INLINE);
+ feature_incompat.insert(MDS_FEATURE_INCOMPAT_NOANCHOR);
return CompatSet(feature_compat, feature_ro_compat, feature_incompat);
}
feature_incompat.insert(MDS_FEATURE_INCOMPAT_DIRINODE);
feature_incompat.insert(MDS_FEATURE_INCOMPAT_ENCODING);
feature_incompat.insert(MDS_FEATURE_INCOMPAT_OMAPDIRFRAG);
+ feature_incompat.insert(MDS_FEATURE_INCOMPAT_NOANCHOR);
return CompatSet(feature_compat, feature_ro_compat, feature_incompat);
}
#define MDS_FEATURE_INCOMPAT_ENCODING CompatSet::Feature(5, "mds uses versioned encoding")
#define MDS_FEATURE_INCOMPAT_OMAPDIRFRAG CompatSet::Feature(6, "dirfrag is stored in omap")
#define MDS_FEATURE_INCOMPAT_INLINE CompatSet::Feature(7, "mds uses inline data")
+#define MDS_FEATURE_INCOMPAT_NOANCHOR CompatSet::Feature(8, "no anchor table")
class MDSMap {
public:
// at least this osdmap to ensure the blacklist propagates.
utime_t created, modified;
- int32_t tableserver; // which MDS has anchortable, snaptable
+ int32_t tableserver; // which MDS has snaptable
int32_t root; // which MDS has root directory
__u32 session_timeout;
libmds_la_SOURCES = \
- mds/Anchor.cc \
mds/Capability.cc \
mds/Dumper.cc \
mds/Resetter.cc \
mds/InoTable.cc \
mds/MDSTableClient.cc \
mds/MDSTableServer.cc \
- mds/AnchorServer.cc \
- mds/AnchorClient.cc \
mds/SnapRealm.cc \
mds/SnapServer.cc \
mds/snap.cc \
mds/flock.h \
mds/locks.c \
mds/locks.h \
- mds/Anchor.h \
- mds/AnchorClient.h \
- mds/AnchorServer.h \
mds/CDentry.h \
mds/CDir.h \
mds/CInode.h \
// for rename
set<int> extra_witnesses; // replica list from srcdn auth (rename)
int srcdn_auth_mds;
- version_t src_reanchor_atid; // src->dst
- version_t dst_reanchor_atid; // dst->stray
bufferlist inode_import;
version_t inode_import_v;
CInode* rename_inode;
dirfrag_t fragment_base;
More() :
- srcdn_auth_mds(-1),
- src_reanchor_atid(0), dst_reanchor_atid(0), inode_import_v(0),
- rename_inode(0), is_freeze_authpin(false), is_ambiguous_auth(false),
+ srcdn_auth_mds(-1), inode_import_v(0), rename_inode(0),
+ is_freeze_authpin(false), is_ambiguous_auth(false),
is_remote_frozen_authpin(false), is_inode_exporter(false),
flock_was_waiting(false), stid(0), slave_commit(0), export_dir(NULL) { }
} *_more;
#include "MDLog.h"
#include "Migrator.h"
#include "MDBalancer.h"
-#include "AnchorClient.h"
#include "InoTable.h"
#include "SnapClient.h"
#include "Mutation.h"
reply_request(mdr, -EINVAL);
return;
}
-
- xlocks.insert(&targeti->linklock);
- // take any locks needed for anchor creation/verification
- // NOTE: we do this on the master even if the anchor/link update may happen
- // on the slave. That means we may have out of date anchor state on our
- // end. That's fine: either, we xlock when we don't need to (slow but
- // not a problem), or we rdlock when we need to xlock, but then discover we
- // need to xlock and on our next pass through we adjust the locks (this works
- // as long as the linklock rdlock isn't the very last lock we take).
- mds->mdcache->anchor_create_prep_locks(mdr, targeti, rdlocks, xlocks);
+ xlocks.insert(&targeti->linklock);
if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks))
return;
if (mdr->now == utime_t())
mdr->now = ceph_clock_now(g_ceph_context);
- // does the target need an anchor?
- if (targeti->is_auth()) {
- if (targeti->is_anchored()) {
- dout(7) << "target anchored already (nlink=" << targeti->inode.nlink << "), sweet" << dendl;
- }
- else {
- dout(7) << "target needs anchor, nlink=" << targeti->inode.nlink << ", creating anchor" << dendl;
-
- mdcache->anchor_create(mdr, targeti,
- new C_MDS_RetryRequest(mdcache, mdr));
- return;
- }
- }
-
// go!
assert(g_conf->mds_kill_link_at != 1);
le->metablob.add_null_dentry(dn, true);
}
- if (mdr->more()->dst_reanchor_atid)
- le->metablob.add_table_transaction(TABLE_ANCHOR, mdr->more()->dst_reanchor_atid);
-
journal_and_reply(mdr, targeti, dn, le, new C_MDS_link_remote_finish(mds, mdr, inc, dn, targeti));
}
mds->mdcache->send_dentry_unlink(dn, NULL, null_ref);
}
- // commit anchor update?
- if (mdr->more()->dst_reanchor_atid)
- mds->anchorclient->commit(mdr->more()->dst_reanchor_atid, mdr->ls);
-
// bump target popularity
mds->balancer->hit_inode(mdr->now, targeti, META_POP_IWR);
mds->balancer->hit_dir(mdr->now, dn->get_dir(), META_POP_IWR);
mdr->auth_pin(targeti);
//assert(0); // test hack: make sure master can handle a slave that fails to prepare...
-
- // anchor?
- if (mdr->slave_request->get_op() == MMDSSlaveRequest::OP_LINKPREP) {
-
- // NOTE: the master took any locks needed for anchor creation/verification.
-
- if (targeti->is_anchored()) {
- dout(7) << "target anchored already (nlink=" << targeti->inode.nlink << "), sweet" << dendl;
- }
- else {
- dout(7) << "target needs anchor, nlink=" << targeti->inode.nlink << ", creating anchor" << dendl;
- mdcache->anchor_create(mdr, targeti,
- new C_MDS_RetryRequest(mdcache, mdr));
- return;
- }
- }
-
assert(g_conf->mds_kill_link_at != 5);
// journal it
rdlocks.insert(&in->filelock); // to verify it's empty
mds->locker->include_snap_rdlocks(rdlocks, dnl->get_inode());
- // if we unlink a snapped multiversion inode and are creating a
- // remote link to it, it must be anchored. this mirrors the logic
- // in MDCache::journal_cow_dentry().
- bool need_snap_dentry =
- dnl->is_primary() &&
- in->is_multiversion() &&
- in->find_snaprealm()->get_newest_seq() + 1 > dn->first;
- if (need_snap_dentry) {
- dout(10) << " i need to be anchored because i am multiversion and will get a remote cow dentry" << dendl;
- mds->mdcache->anchor_create_prep_locks(mdr, in, rdlocks, xlocks);
- }
-
if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks))
return;
if (mdr->now == utime_t())
mdr->now = ceph_clock_now(g_ceph_context);
- // NOTE: this is non-optimal. we create an anchor at the old
- // location, and then change it. we can do better, but it's more
- // complicated. this is fine for now.
- if (need_snap_dentry && !in->is_anchored()) {
- mdcache->anchor_create(mdr, in, new C_MDS_RetryRequest(mdcache, mdr));
- return;
- }
-
- // get stray dn ready?
- if (dnl->is_primary()) {
- if (!mdr->more()->dst_reanchor_atid && in->is_anchored()) {
- dout(10) << "reanchoring to stray " << *dnl->get_inode() << dendl;
- vector<Anchor> trace;
- straydn->make_anchor_trace(trace, dnl->get_inode());
- mds->anchorclient->prepare_update(dnl->get_inode()->ino(), trace, &mdr->more()->dst_reanchor_atid,
- new C_MDS_RetryRequest(mdcache, mdr));
- return;
- }
- }
-
if (in->is_dir() && in->has_subtree_root_dirfrag()) {
// subtree root auths need to be witnesses
set<int> witnesses;
le->metablob.renamed_dirino = in->ino();
}
- if (mdr->more()->dst_reanchor_atid)
- le->metablob.add_table_transaction(TABLE_ANCHOR, mdr->more()->dst_reanchor_atid);
-
dn->push_projected_linkage();
if (in->is_dir()) {
if (straydn && straydnl->get_inode()->is_dir())
mdcache->adjust_subtree_after_rename(straydnl->get_inode(), dn->get_dir(), true);
- // commit anchor update?
- if (mdr->more()->dst_reanchor_atid)
- mds->anchorclient->commit(mdr->more()->dst_reanchor_atid, mdr->ls);
-
// bump pop
mds->balancer->hit_dir(mdr->now, dn->get_dir(), META_POP_IWR);
else
rdlocks.insert(&srci->snaplock);
- // take any locks needed for anchor creation/verification
- mds->mdcache->anchor_create_prep_locks(mdr, srci, rdlocks, xlocks);
-
CInode *auth_pin_freeze = !srcdn->is_auth() && srcdnl->is_primary() ? srci : NULL;
if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks,
&remote_wrlocks, auth_pin_freeze))
if (mdr->now == utime_t())
mdr->now = ceph_clock_now(g_ceph_context);
- // -- prepare anchor updates --
- if (!linkmerge || srcdnl->is_primary()) {
- C_GatherBuilder anchorgather(g_ceph_context);
-
- if (srcdnl->is_primary() &&
- (srcdnl->get_inode()->is_anchored() ||
- (srcdnl->get_inode()->is_dir() && (srcdnl->get_inode()->inode.rstat.ranchors ||
- srcdnl->get_inode()->nested_anchors ||
- !mdcache->is_leaf_subtree(mdcache->get_projected_subtree_root(srcdn->get_dir()))))) &&
- !mdr->more()->src_reanchor_atid) {
- dout(10) << "reanchoring src->dst " << *srcdnl->get_inode() << dendl;
- vector<Anchor> trace;
- destdn->make_anchor_trace(trace, srcdnl->get_inode());
- mds->anchorclient->prepare_update(srcdnl->get_inode()->ino(),
- trace, &mdr->more()->src_reanchor_atid,
- anchorgather.new_sub());
- }
- if (destdnl->is_primary() &&
- destdnl->get_inode()->is_anchored() &&
- !mdr->more()->dst_reanchor_atid) {
- dout(10) << "reanchoring dst->stray " << *destdnl->get_inode() << dendl;
-
- assert(straydn);
- vector<Anchor> trace;
- straydn->make_anchor_trace(trace, destdnl->get_inode());
-
- mds->anchorclient->prepare_update(destdnl->get_inode()->ino(), trace,
- &mdr->more()->dst_reanchor_atid, anchorgather.new_sub());
- }
-
- if (anchorgather.has_subs()) {
- anchorgather.set_finisher(new C_MDS_RetryRequest(mdcache, mdr));
- anchorgather.activate();
- return; // waiting for anchor prepares
- }
-
- assert(g_conf->mds_kill_rename_at != 2);
- }
-
// -- prepare witnesses --
// do srcdn auth last
if (!mdr->more()->slaves.empty() && in->is_dir())
assert(g_conf->mds_kill_rename_at != 6);
- // commit anchor updates?
- if (mdr->more()->src_reanchor_atid)
- mds->anchorclient->commit(mdr->more()->src_reanchor_atid, mdr->ls);
- if (mdr->more()->dst_reanchor_atid)
- mds->anchorclient->commit(mdr->more()->dst_reanchor_atid, mdr->ls);
-
// bump popularity
mds->balancer->hit_dir(mdr->now, srcdn->get_dir(), META_POP_IWR);
if (destdnl->is_remote() && in->is_auth())
if (srcdnl->is_primary() && destdn->is_auth())
srci->first = destdn->first;
- // anchor updates?
- if (mdr->more()->src_reanchor_atid)
- metablob->add_table_transaction(TABLE_ANCHOR, mdr->more()->src_reanchor_atid);
- if (mdr->more()->dst_reanchor_atid)
- metablob->add_table_transaction(TABLE_ANCHOR, mdr->more()->dst_reanchor_atid);
-
if (oldin && oldin->is_dir())
mdcache->project_subtree_rename(oldin, destdn->get_dir(), straydn->get_dir());
if (srci->is_dir())
pf->rstat.rbytes += linkunlink * rstat.rbytes;
pf->rstat.rfiles += linkunlink * rstat.rfiles;
pf->rstat.rsubdirs += linkunlink * rstat.rsubdirs;
- pf->rstat.ranchors += linkunlink * rstat.ranchors;
pf->rstat.rsnaprealms += linkunlink * rstat.rsnaprealms;
}
if (pf->fragstat.mtime == ctime) {
rdlocks.erase(&diri->snaplock);
xlocks.insert(&diri->snaplock);
- // we need to anchor... get these locks up front!
- mds->mdcache->anchor_create_prep_locks(mdr, diri, rdlocks, xlocks);
-
if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks))
return;
if (mdr->now == utime_t())
mdr->now = ceph_clock_now(g_ceph_context);
- // anchor
- if (!diri->is_anchored()) {
- mdcache->anchor_create(mdr, diri, new C_MDS_RetryRequest(mdcache, mdr));
- return;
- }
-
// allocate a snapid
if (!mdr->more()->stid) {
// prepare an stid
<< p->second.ino << dendl;
CInode *parent = mdcache->get_inode(p->second.ino);
if (!parent) {
- mdcache->open_remote_ino(p->second.ino, finish);
+ mdcache->open_ino(p->second.ino, mdcache->mds->mdsmap->get_metadata_pool(), finish);
return false;
}
assert(parent->snaprealm); // hmm!
void SnapServer::handle_query(MMDSTableRequest *req)
{
- /* bufferlist::iterator p = req->bl.begin();
- inodeno_t curino;
- ::decode(curino, p);
- dout(7) << "handle_lookup " << *req << " ino " << curino << dendl;
-
- vector<Anchor> trace;
- while (true) {
- assert(anchor_map.count(curino) == 1);
- Anchor &anchor = anchor_map[curino];
-
- dout(10) << "handle_lookup adding " << anchor << dendl;
- trace.insert(trace.begin(), anchor); // lame FIXME
-
- if (anchor.dirino < MDS_INO_BASE) break;
- curino = anchor.dirino;
- }
-
- // reply
- MMDSTableRequest *reply = new MMDSTableRequest(table, TABLE_OP_QUERY_REPLY, req->reqid, version);
- ::encode(curino, req->bl);
- ::encode(trace, req->bl);
- mds->send_message_mds(reply, req->get_source().num());
-
- */
req->put();
}
p != pending_commit_tids.end();
++p) {
MDSTableClient *client = mds->get_table_client(p->first);
+ assert(client);
for (ceph::unordered_set<version_t>::iterator q = p->second.begin();
q != p->second.end();
++q) {
p != tablev.end();
++p) {
MDSTableServer *server = mds->get_table_server(p->first);
+ assert(server);
if (p->second > server->get_committed_version()) {
dout(10) << "try_to_expire waiting for " << get_mdstable_name(p->first)
<< " to save, need " << p->second << dendl;
(*p)->add_waiter(CInode::WAIT_TRUNC, gather_bld.new_sub());
}
- // FIXME client requests...?
- // audit handling of anchor transactions?
-
if (gather_bld.has_subs()) {
dout(6) << "LogSegment(" << offset << ").try_to_expire waiting" << dendl;
mds->mdlog->flush();
void EMetaBlob::update_segment(LogSegment *ls)
{
- // atids?
- //for (list<version_t>::iterator p = atids.begin(); p != atids.end(); ++p)
- // ls->pending_commit_atids[*p] = ls;
- // -> handled directly by AnchorClient
-
// dirty inode mtimes
// -> handled directly by Server.cc, replay()
if (p->is_dirty()) in->_mark_dirty(logseg);
dout(10) << "EMetaBlob.replay added " << *in << dendl;
} else {
- if (in->get_parent_dn() && in->inode.anchored != p->inode.anchored)
- in->get_parent_dn()->adjust_nested_anchors((int)p->inode.anchored - (int)in->inode.anchored);
p->update_inode(mds, in);
if (dn->get_linkage()->get_inode() != in && in->get_parent_dn()) {
dout(10) << "EMetaBlob.replay unlinking " << *in << dendl;
dout(10) << "EMetaBlob.replay noting " << get_mdstable_name(p->first)
<< " transaction " << p->second << dendl;
MDSTableClient *client = mds->get_table_client(p->first);
- client->got_journaled_agree(p->second, logseg);
+ if (client)
+ client->got_journaled_agree(p->second, logseg);
}
// opened ino?
void ETableServer::replay(MDS *mds)
{
MDSTableServer *server = mds->get_table_server(table);
+ if (!server)
+ return;
+
if (server->get_version() >= version) {
dout(10) << "ETableServer.replay " << get_mdstable_name(table)
<< " " << get_mdstableserver_opname(op)
<< " tid " << tid << dendl;
MDSTableClient *client = mds->get_table_client(table);
+ if (!client)
+ return;
+
assert(op == TABLESERVER_OP_ACK);
client->got_journaled_ack(tid);
}
void nest_info_t::encode(bufferlist &bl) const
{
- ENCODE_START(2, 2, bl);
+ ENCODE_START(3, 2, bl);
::encode(version, bl);
::encode(rbytes, bl);
::encode(rfiles, bl);
::encode(rsubdirs, bl);
- ::encode(ranchors, bl);
+ {
+ // removed field
+ int64_t ranchors = 0;
+ ::encode(ranchors, bl);
+ }
::encode(rsnaprealms, bl);
::encode(rctime, bl);
ENCODE_FINISH(bl);
void nest_info_t::decode(bufferlist::iterator &bl)
{
- DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl);
+ DECODE_START_LEGACY_COMPAT_LEN(3, 2, 2, bl);
::decode(version, bl);
::decode(rbytes, bl);
::decode(rfiles, bl);
::decode(rsubdirs, bl);
- ::decode(ranchors, bl);
+ {
+ int64_t ranchors;
+ ::decode(ranchors, bl);
+ }
::decode(rsnaprealms, bl);
::decode(rctime, bl);
DECODE_FINISH(bl);
f->dump_unsigned("rbytes", rbytes);
f->dump_unsigned("rfiles", rfiles);
f->dump_unsigned("rsubdirs", rsubdirs);
- f->dump_unsigned("ranchors", ranchors);
f->dump_unsigned("rsnaprealms", rsnaprealms);
f->dump_stream("rctime") << rctime;
}
ls.back()->rbytes = 2;
ls.back()->rfiles = 3;
ls.back()->rsubdirs = 4;
- ls.back()->ranchors = 5;
ls.back()->rsnaprealms = 6;
ls.back()->rctime = utime_t(7, 8);
}
out << " rc" << n.rctime;
if (n.rbytes)
out << " b" << n.rbytes;
- if (n.ranchors)
- out << " a" << n.ranchors;
if (n.rsnaprealms)
out << " sr" << n.rsnaprealms;
if (n.rfiles || n.rsubdirs)
::encode(gid, bl);
::encode(nlink, bl);
- ::encode(anchored, bl);
+ {
+ // removed field
+ bool anchored = 0;
+ ::encode(anchored, bl);
+ }
::encode(dir_layout, bl);
::encode(layout, bl);
::decode(gid, p);
::decode(nlink, p);
- ::decode(anchored, p);
+ {
+ bool anchored;
+ ::decode(anchored, p);
+ }
if (struct_v >= 4)
::decode(dir_layout, p);
f->dump_unsigned("uid", uid);
f->dump_unsigned("gid", gid);
f->dump_unsigned("nlink", nlink);
- f->dump_unsigned("anchored", (int)anchored);
f->open_object_section("dir_layout");
::dump(dir_layout, f);
int64_t rsubdirs;
int64_t rsize() const { return rfiles + rsubdirs; }
- int64_t ranchors; // for dirstat, includes inode's anchored flag.
int64_t rsnaprealms;
- nest_info_t() : rbytes(0), rfiles(0), rsubdirs(0),
- ranchors(0), rsnaprealms(0) {}
+ nest_info_t() : rbytes(0), rfiles(0), rsubdirs(0), rsnaprealms(0) {}
void zero() {
*this = nest_info_t();
rbytes += fac*other.rbytes;
rfiles += fac*other.rfiles;
rsubdirs += fac*other.rsubdirs;
- ranchors += fac*other.ranchors;
rsnaprealms += fac*other.rsnaprealms;
}
rbytes += cur.rbytes - acc.rbytes;
rfiles += cur.rfiles - acc.rfiles;
rsubdirs += cur.rsubdirs - acc.rsubdirs;
- ranchors += cur.ranchors - acc.ranchors;
rsnaprealms += cur.rsnaprealms - acc.rsnaprealms;
}
// nlink
int32_t nlink;
- bool anchored; // auth only?
// file (data access)
ceph_dir_layout dir_layout; // [dir only]
version_t backtrace_version;
inode_t() : ino(0), rdev(0),
- mode(0), uid(0), gid(0),
- nlink(0), anchored(false),
+ mode(0), uid(0), gid(0), nlink(0),
size(0), max_size_ever(0),
truncate_seq(0), truncate_size(0), truncate_from(0),
truncate_pending(0),
#include "osdc/Journaler.h"
TYPE(Journaler::Header)
-#include "mds/Anchor.h"
-TYPE(Anchor)
-
#include "mds/snap.h"
TYPE(SnapInfo)
TYPE(snaplink_t)
#include "mds/Capability.h"
TYPE_NOCOPY(Capability)
-#include "mds/AnchorServer.h"
-TYPEWITHSTRAYDATA(AnchorServer)
-
#include "mds/InoTable.h"
TYPE(InoTable)