mds/MDSTableServer.cc \
mds/AnchorServer.cc \
mds/AnchorClient.cc \
- mds/SnapTable.cc \
+ mds/SnapServer.cc \
mds/snap.cc \
mds/SessionMap.cc \
mds/MDLog.cc
#include "mdstypes.h"
#include "include/buffer.h"
-enum {
- ANCHOR_OP_CREATE,
- ANCHOR_OP_DESTROY,
- ANCHOR_OP_UPDATE,
-};
-
-inline const char* get_anchor_opname(int o) {
- switch (o) {
- case ANCHOR_OP_CREATE: return "create";
- case ANCHOR_OP_DESTROY: return "destroy";
- case ANCHOR_OP_UPDATE: return "update";
- default: assert(0); return 0;
- }
-}
-
// identifies a anchor table mutation
*
*/
-#include <iostream>
-using std::cout;
-using std::cerr;
-
#include "AnchorClient.h"
#include "MDSMap.h"
#include "LogSegment.h"
{
dout(10) << "prepare_create " << ino << " " << trace << dendl;
bufferlist bl;
- __u32 op = ANCHOR_OP_CREATE;
+ __u32 op = TABLE_OP_CREATE;
::encode(op, bl);
::encode(ino, bl);
::encode(trace, bl);
{
dout(10) << "prepare_destroy " << ino << dendl;
bufferlist bl;
- __u32 op = ANCHOR_OP_DESTROY;
+ __u32 op = TABLE_OP_DESTROY;
::encode(op, bl);
::encode(ino, bl);
_prepare(bl, patid, onfinish);
{
dout(10) << "prepare_update " << ino << " " << trace << dendl;
bufferlist bl;
- __u32 op = ANCHOR_OP_UPDATE;
+ __u32 op = TABLE_OP_UPDATE;
::encode(op, bl);
::encode(ino, bl);
_prepare(bl, patid, onfinish);
::decode(trace, p);
switch (what) {
- case ANCHOR_OP_CREATE:
+ case TABLE_OP_CREATE:
version++;
// make sure trace is in table
break;
- case ANCHOR_OP_DESTROY:
+ case TABLE_OP_DESTROY:
version++;
pending_destroy[version] = ino;
break;
- case ANCHOR_OP_UPDATE:
+ case TABLE_OP_UPDATE:
version++;
pending_update[version].first = ino;
pending_update[version].second = trace;
else
assert(0);
- pending_for_mds.erase(tid);
-
// bump version.
version++;
//dump();
}
if (snapid == CEPH_SNAPDIR) {
SnapRealm *realm = cur->find_snaprealm();
- snapid = realm->resolve_snapname(path[depth]);
+ snapid = realm->resolve_snapname(path[depth], cur->ino());
dout(10) << "traverse: snap " << path[depth] << " -> " << snapid << dendl;
if (!snapid)
return -ENOENT;
#include "AnchorServer.h"
#include "AnchorClient.h"
+#include "SnapServer.h"
+#include "SnapClient.h"
#include "InoTable.h"
-#include "SnapTable.h"
#include "common/Logger.h"
#include "common/LogType.h"
balancer = new MDBalancer(this);
inotable = new InoTable(this);
- snaptable = new SnapTable(this);
-
+ snapserver = new SnapServer(this);
+ snapclient = new SnapClient(this);
anchorserver = new AnchorServer(this);
anchorclient = new AnchorClient(this);
if (balancer) { delete balancer; balancer = NULL; }
if (inotable) { delete inotable; inotable = NULL; }
if (anchorserver) { delete anchorserver; anchorserver = NULL; }
- if (snaptable) { delete snaptable; snaptable = 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; }
{
switch (t) {
case TABLE_ANCHOR: return anchorclient;
- //case TABLE_SNAP: return snapserver;
+ case TABLE_SNAP: return snapclient;
default: assert(0);
}
}
{
switch (t) {
case TABLE_ANCHOR: return anchorserver;
- //case TABLE_SNAP: return snapserver;
+ case TABLE_SNAP: return snapserver;
default: assert(0);
}
}
if (whoami == 0) {
dout(10) << "boot_create creating fresh snaptable" << dendl;
- snaptable->reset();
- snaptable->save(fin->new_sub());
+ snapserver->reset();
+ snapserver->save(fin->new_sub());
}
}
}
if (whoami == 0) {
dout(2) << "boot_start " << step << ": opening snap table" << dendl;
- snaptable->load(gather->new_sub());
+ snapserver->load(gather->new_sub());
}
dout(2) << "boot_start " << step << ": opening mds log" << dendl;
class MMDSBeacon;
class InoTable;
-class SnapTable;
-
-class MDSTableClient;
-class MDSTableServer;
+class SnapServer;
+class SnapClient;
class AnchorServer;
class AnchorClient;
+class MDSTableServer;
+class MDSTableClient;
+
class MDS : public Dispatcher {
public:
Mutex mds_lock;
AnchorServer *anchorserver;
AnchorClient *anchorclient;
- SnapTable *snaptable;
+ SnapServer *snapserver;
+ SnapClient *snapclient;
MDSTableClient *get_table_client(int t);
MDSTableServer *get_table_server(int t);
*
*/
-#ifndef __SNAPCLIENT_H
-#define __SNAPCLIENT_H
+#ifndef __MDSTABLECLIENT_H
+#define __MDSTABLECLIENT_H
#include <vector>
using std::vector;
if (_is_prepared(tid)) {
_commit(tid);
+ pending_for_mds.erase(tid);
mds->mdlog->submit_entry(new ETableServer(table, TABLE_OP_COMMIT, 0, -1, tid, version));
mds->mdlog->wait_for_sync(new C_Commit(this, req));
}
#include "MDBalancer.h"
#include "AnchorClient.h"
#include "InoTable.h"
-#include "SnapTable.h"
+#include "SnapClient.h"
#include "msg/Messenger.h"
if (snapid != CEPH_NOSNAP && in == snapdiri) {
// do the snap name dentry
- const string& snapname = in->find_snaprealm()->get_snapname(snapid);
+ const string& snapname = in->find_snaprealm()->get_snapname(snapid, in->ino());
dout(10) << " snapname " << snapname << dendl;
::encode(snapname, bl);
encode_empty_lease(bl);
mdr->now = g_clock.now();
// allocate a snapid
- // HACK
- version_t stid;
- snapid_t snapid = mds->snaptable->create(diri->ino(), snapname, mdr->now, &stid);
- dout(10) << " snapid is " << snapid << " stid " << &stid << dendl;
+ if (!mdr->more()->stid) {
+ // prepare an stid
+ mds->snapclient->prepare_create(diri->ino(), snapname, mdr->now,
+ &mdr->more()->stid, new C_MDS_RetryRequest(mds->mdcache, mdr));
+ return;
+ }
+
+ version_t stid = mdr->more()->stid;
+ snapid_t snapid = stid;
+ dout(10) << " snapid/stid is " << snapid << dendl;
// journal
SnapInfo info;
diri->pop_and_dirty_projected_inode(mdr->ls);
mdr->apply();
+ mds->snapclient->commit(mdr->more()->stid, mdr->ls);
+
snapid_t snapid = info.snapid;
// create realm?
#ifndef __SNAPCLIENT_H
#define __SNAPCLIENT_H
-#include <vector>
-using std::vector;
-#include <ext/hash_map>
-using __gnu_cxx::hash_map;
-
-#include "include/types.h"
-#include "msg/Dispatcher.h"
-
+#include "MDSTableClient.h"
#include "snap.h"
class Context;
class MDS;
class LogSegment;
-class MDSTableClient : public Dispatcher {
- MDS *mds;
-
- // prepares
- struct _pending_prepare {
- Context *onfinish;
- version_t *patid;
- bufferlist mutation;
- };
-
- hash_map<metareqid_t, _pending_prepare> pending_prepare;
-
- // pending commits
- map<version_t, LogSegment*> pending_commit;
- map<version_t, list<Context*> > ack_waiters;
-
- void handle_reply(class MAnchor *m);
-
-
+class SnapClient : public MDSTableClient {
+public:
+ SnapClient(MDS *m) : MDSTableClient(m, TABLE_SNAP) {}
+
+ void resend_queries() {}
+ void handle_query_result(MMDSTableRequest *m) {}
+
+ void prepare_create(inodeno_t dirino, const string& name, utime_t stamp,
+ version_t *pstid, Context *onfinish) {
+ bufferlist bl;
+ __u32 op = TABLE_OP_CREATE;
+ ::encode(op, bl);
+ ::encode(dirino, bl);
+ ::encode(name, bl);
+ ::encode(stamp, bl);
+ _prepare(bl, pstid, 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 "SnapServer.h"
+#include "MDS.h"
+
+#include "include/types.h"
+#include "messages/MMDSTableRequest.h"
+
+#include "config.h"
+
+#define dout(x) if (x <= g_conf.debug_mds) *_dout << dbeginl << g_clock.now() << " mds" << mds->get_nodeid() << ".snap: "
+
+void SnapServer::init_inode()
+{
+ ino = MDS_INO_SNAPTABLE;
+ layout = g_default_file_layout;
+}
+
+void SnapServer::reset_state()
+{
+ last_snap = 0;
+ snaps.clear();
+ pending_removal.clear();
+}
+
+snapid_t SnapServer::create(inodeno_t base, const string& name, utime_t stamp, version_t *psnapv)
+{
+ assert(is_active());
+
+ snapid_t sn = ++last_snap;
+ snaps[sn].snapid = sn;
+ snaps[sn].dirino = base;
+ snaps[sn].name = name;
+ snaps[sn].stamp = stamp;
+ *psnapv = ++version;
+
+ dout(10) << "create(" << base << "," << name << ") = " << sn << dendl;
+
+ return sn;
+}
+
+void SnapServer::remove(snapid_t sn)
+{
+ assert(is_active());
+
+ snaps.erase(sn);
+ pending_removal.insert(sn);
+ version++;
+}
+
+
+// SERVER
+
+void SnapServer::_prepare(bufferlist &bl, __u64 reqid, int bymds)
+{
+ bufferlist::iterator p = bl.begin();
+ __u32 what;
+ ::decode(what, p);
+
+ switch (what) {
+ case TABLE_OP_CREATE:
+ {
+ SnapInfo info;
+ ::decode(info.dirino, p);
+ ::decode(info.name, p);
+ ::decode(info.stamp, p);
+ info.snapid = ++version;
+ pending_create[version] = info;
+ }
+ break;
+
+ case TABLE_OP_DESTROY:
+ {
+ snapid_t snapid;
+ ::decode(snapid, p);
+ version++;
+ pending_destroy[version] = snapid;
+ }
+ break;
+
+ default:
+ assert(0);
+ }
+ //dump();
+}
+
+bool SnapServer::_is_prepared(version_t tid)
+{
+ return
+ pending_create.count(tid) ||
+ pending_destroy.count(tid);
+}
+
+void SnapServer::_commit(version_t tid)
+{
+ if (pending_create.count(tid)) {
+ dout(7) << "commit " << tid << " create " << pending_create[tid] << dendl;
+ snaps[pending_create[tid].snapid] = pending_create[tid];
+ pending_create.erase(tid);
+ }
+
+ else if (pending_destroy.count(tid)) {
+ dout(7) << "commit " << tid << " destroy " << pending_destroy[tid] << dendl;
+ snaps.erase(pending_destroy[tid]);
+ pending_destroy.erase(tid);
+ }
+ else
+ assert(0);
+
+ // bump version.
+ version++;
+ //dump();
+}
+
+void SnapServer::_rollback(version_t tid)
+{
+ if (pending_create.count(tid)) {
+ dout(7) << "rollback " << tid << " create " << pending_create[tid] << dendl;
+ pending_create.erase(tid);
+ }
+
+ else if (pending_destroy.count(tid)) {
+ dout(7) << "rollback " << tid << " destroy " << pending_destroy[tid] << dendl;
+ pending_destroy.erase(tid);
+ }
+
+ else
+ assert(0);
+
+ // bump version.
+ version++;
+ //dump();
+}
+
+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());
+
+ */
+ delete req;
+}
+
+
--- /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 __SNAPSERVER_H
+#define __SNAPSERVER_H
+
+#include "MDSTableServer.h"
+#include "snap.h"
+
+class MDS;
+
+class SnapServer : public MDSTableServer {
+public:
+
+protected:
+ snapid_t last_snap;
+ map<snapid_t, SnapInfo> snaps;
+ set<snapid_t> pending_removal;
+
+ map<version_t, SnapInfo> pending_create;
+ map<version_t, snapid_t> pending_destroy;
+
+public:
+ SnapServer(MDS *m) : MDSTableServer(m, TABLE_SNAP) { }
+
+ // alloc or reclaim ids
+ snapid_t create(inodeno_t base, const string& name, utime_t stamp, version_t *snapv);
+ void remove(snapid_t sn);
+
+ void init_inode();
+ void reset_state();
+ void encode_state(bufferlist& bl) {
+ ::encode(last_snap, bl);
+ ::encode(snaps, bl);
+ ::encode(pending_removal, bl);
+ ::encode(pending_create, bl);
+ ::encode(pending_destroy, bl);
+ ::encode(pending_for_mds, bl);
+ }
+ void decode_state(bufferlist::iterator& bl) {
+ ::decode(last_snap, bl);
+ ::decode(snaps, bl);
+ ::decode(pending_removal, bl);
+ ::decode(pending_create, bl);
+ ::decode(pending_destroy, bl);
+ ::decode(pending_for_mds, bl);
+ }
+
+ // server bits
+ void _prepare(bufferlist &bl, __u64 reqid, int bymds);
+ bool _is_prepared(version_t tid);
+ void _commit(version_t tid);
+ void _rollback(version_t tid);
+ void handle_query(MMDSTableRequest *m);
+};
+
+#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 "SnapTable.h"
-#include "MDS.h"
-
-#include "include/types.h"
-
-#include "config.h"
-
-#define dout(x) if (x <= g_conf.debug_mds) *_dout << dbeginl << g_clock.now() << " mds" << mds->get_nodeid() << ".snap: "
-
-void SnapTable::init_inode()
-{
- ino = MDS_INO_SNAPTABLE;
- layout = g_default_file_layout;
-}
-
-void SnapTable::reset_state()
-{
- last_snap = 0;
- snaps.clear();
- pending_removal.clear();
-}
-
-snapid_t SnapTable::create(inodeno_t base, const string& name, utime_t stamp, version_t *psnapv)
-{
- assert(is_active());
-
- snapid_t sn = ++last_snap;
- snaps[sn].snapid = sn;
- snaps[sn].dirino = base;
- snaps[sn].name = name;
- snaps[sn].stamp = stamp;
- *psnapv = ++version;
-
- dout(10) << "create(" << base << "," << name << ") = " << sn << dendl;
-
- return sn;
-}
-
-void SnapTable::remove(snapid_t sn)
-{
- assert(is_active());
-
- snaps.erase(sn);
- pending_removal.insert(sn);
- version++;
-}
-
+++ /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 __SNAPTABLE_H
-#define __SNAPTABLE_H
-
-#include "MDSTable.h"
-#include "include/interval_set.h"
-#include "snap.h"
-
-class MDS;
-
-class SnapTable : public MDSTable {
-public:
-
-protected:
- snapid_t last_snap;
- map<snapid_t, SnapInfo> snaps;
- set<snapid_t> pending_removal;
-
-public:
- SnapTable(MDS *m) : MDSTable(m, "snap") { }
-
- // alloc or reclaim ids
- snapid_t create(inodeno_t base, const string& name, utime_t stamp, version_t *snapv);
- void remove(snapid_t sn);
-
- void init_inode();
- void reset_state();
- void encode_state(bufferlist& bl) {
- ::encode(last_snap, bl);
- ::encode(snaps, bl);
- ::encode(pending_removal, bl);
- }
- void decode_state(bufferlist::iterator& bl) {
- ::decode(last_snap, bl);
- ::decode(snaps, bl);
- ::decode(pending_removal, bl);
- }
-};
-
-#endif
#include "MDCache.h"
#include "Server.h"
#include "Migrator.h"
-#include "InoTable.h"
-#include "SnapTable.h"
+#include "InoTable.h"
#include "MDSTableClient.h"
#include "MDSTableServer.h"
TABLE_OP_ROLLBACK = 7,
};
+enum {
+ TABLE_OP_CREATE,
+ TABLE_OP_UPDATE,
+ TABLE_OP_DESTROY,
+};
+
inline const char *get_mdstable_opname(int op) {
switch (op) {
case TABLE_OP_QUERY: return "query";
return long_name;
}
-const string& SnapRealm::get_snapname(snapid_t snapid, bool actual)
+const string& SnapRealm::get_snapname(snapid_t snapid, inodeno_t atino)
{
if (snaps.count(snapid)) {
- if (actual)
+ if (atino == inode->ino())
return snaps[snapid].name;
else
return snaps[snapid].get_long_name();
assert(oldparent); // call open_parents first!
assert(oldparent->snaprealm);
- return oldparent->snaprealm->get_snapname(snapid, false);
+ return oldparent->snaprealm->get_snapname(snapid, atino);
}
- return parent->get_snapname(snapid, false);
+ return parent->get_snapname(snapid, atino);
}
-snapid_t SnapRealm::resolve_snapname(const string& n, bool actual, snapid_t first, snapid_t last)
+snapid_t SnapRealm::resolve_snapname(const string& n, inodeno_t atino, snapid_t first, snapid_t last)
{
// first try me
dout(10) << "resolve_snapname '" << n << "' in [" << first << "," << last << "]" << dendl;
- snapid_t num;
- if (n[0] == '~') num = atoll(n.c_str()+1);
+ //snapid_t num;
+ //if (n[0] == '~') num = atoll(n.c_str()+1);
+ bool actual = (atino == inode->ino());
string pname;
inodeno_t pdirino;
if (!actual) {
if (next_ < 0) return 0;
pname = n.substr(1, next_ - 1);
pdirino = atoll(n.c_str() + next_ + 1);
- dout(10) << " " << n << " -> " << pname << " dirino " << pdirino << dendl;
+ dout(10) << " " << n << " parses to name '" << pname << "' dirino " << pdirino << dendl;
}
for (map<snapid_t, SnapInfo>::iterator p = snaps.lower_bound(first); // first element >= first
p != snaps.end() && p->first <= last;
p++) {
- if (num && p->second.snapid == num)
- return p->first;
+ dout(15) << " ? " << p->second << dendl;
+ //if (num && p->second.snapid == num)
+ //return p->first;
if (actual && p->second.name == n)
return p->first;
if (!actual && p->second.name == pname && p->second.dirino == pdirino)
assert(oldparent->snaprealm);
thru = MIN(last, p->first);
- snapid_t r = oldparent->snaprealm->resolve_snapname(n, false,
+ snapid_t r = oldparent->snaprealm->resolve_snapname(n, atino,
MAX(first, p->second.first),
thru);
if (r)
++thru;
}
if (thru <= last && parent)
- return parent->resolve_snapname(n, false, thru, last);
+ return parent->resolve_snapname(n, atino, thru, last);
return 0;
}
void build_snap_set(set<snapid_t>& s, snapid_t first, snapid_t last);
void get_snap_info(map<snapid_t,SnapInfo*>& infomap, snapid_t first=0, snapid_t last=CEPH_NOSNAP);
- const string& get_snapname(snapid_t snapid, bool actual=true);
- snapid_t resolve_snapname(const string &name, bool actual=true, snapid_t first=0, snapid_t last=CEPH_NOSNAP);
+ const string& get_snapname(snapid_t snapid, inodeno_t atino);
+ snapid_t resolve_snapname(const string &name, inodeno_t atino, snapid_t first=0, snapid_t last=CEPH_NOSNAP);
const set<snapid_t>& get_snaps();
const vector<snapid_t>& get_snap_vector();