#include "events/EAnchor.h"
#include "events/EAnchorClient.h"
+#include "events/ESnap.h"
LogEvent *LogEvent::decode(bufferlist& bl)
case EVENT_ANCHOR: le = new EAnchor; break;
case EVENT_ANCHORCLIENT: le = new EAnchorClient; break;
+
+ case EVENT_SNAP: le = new ESnap; break;
+
default:
generic_dout(1) << "uh oh, unknown log event type " << type << dendl;
assert(0);
#define EVENT_ANCHOR 40
#define EVENT_ANCHORCLIENT 41
+#define EVENT_SNAP 50
version_t allocv;
version_t sessionmapv;
version_t anchortablev;
+ version_t snaptablev;
// try to expire
C_Gather *try_to_expire(MDS *mds);
// cons
LogSegment(loff_t off) : offset(off), end(off), num_events(0), trimmable_at(0),
- allocv(0), sessionmapv(0), anchortablev(0)
+ allocv(0), sessionmapv(0), anchortablev(0), snaptablev(0)
{ }
};
assert(is_active());
snapid_t sn = ++last_snap;
+ snaps[sn].snapid = sn;
snaps[sn].base = base;
snaps[sn].name = name;
snaps[sn].stamp = stamp;
#include "MDSTable.h"
#include "include/interval_set.h"
+#include "snap.h"
class MDS;
class SnapTable : public MDSTable {
public:
- struct snapinfo {
- inodeno_t base;
- utime_t stamp;
- string name;
-
- void encode(bufferlist& bl) const {
- ::encode(base, bl);
- ::encode(stamp, bl);
- ::encode(name, bl);
- }
- void decode(bufferlist::iterator& bl) {
- ::decode(base, bl);
- ::decode(stamp, bl);
- ::decode(name, bl);
- }
- };
- WRITE_CLASS_ENCODER(snapinfo)
protected:
snapid_t last_snap;
- map<snapid_t, snapinfo> snaps;
+ map<snapid_t, SnapInfo> snaps;
set<snapid_t> pending_removal;
public:
::decode(pending_removal, bl);
}
};
-WRITE_CLASS_ENCODER(SnapTable::snapinfo)
#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.
+ *
+ */
+
+#ifndef __MDS_ESNAP_H
+#define __MDS_ESNAP_H
+
+#include <assert.h>
+#include "config.h"
+#include "include/types.h"
+
+#include "../LogEvent.h"
+#include "../snap.h"
+
+class ESnap : public LogEvent {
+protected:
+ bool create;
+ SnapInfo snap;
+ version_t version; // table version
+
+ public:
+ ESnap() : LogEvent(EVENT_SNAP) { }
+ ESnap(bool c, SnapInfo &sn, version_t v) :
+ LogEvent(EVENT_SNAP),
+ create(c), snap(sn), version(v) { }
+
+ void encode(bufferlist& bl) const {
+ ::encode(create, bl);
+ ::encode(snap, bl);
+ ::encode(version, bl);
+ }
+ void decode(bufferlist::iterator &bl) {
+ ::decode(create, bl);
+ ::decode(snap, bl);
+ ::decode(version, bl);
+ }
+
+ void print(ostream& out) {
+ out << "ESnap " << (create ? "create":"remove")
+ << " " << snap
+ << " v " << version;
+ }
+
+ void update_segment();
+ void replay(MDS *mds);
+};
+
+#endif
#include "events/EAnchor.h"
#include "events/EAnchorClient.h"
+#include "events/ESnap.h"
+
#include "LogSegment.h"
#include "MDS.h"
#include "AnchorTable.h"
#include "AnchorClient.h"
#include "IdAllocator.h"
+#include "SnapTable.h"
+
#include "Locker.h"
mds->anchortable->save(gather->new_sub());
}
+ // snaptable
+ if (snaptablev > mds->snaptable->get_committed_version()) {
+ dout(10) << "try_to_expire waiting for snap table to save, need " << snaptablev << dendl;
+ if (!gather) gather = new C_Gather;
+ mds->snaptable->save(gather->new_sub());
+ }
+
// FIXME client requests...?
// audit handling of anchor transactions?
if (mds->anchortable->get_version() >= version) {
dout(10) << "EAnchor.replay event " << version
<< " <= table " << mds->anchortable->get_version() << dendl;
- } else {
- dout(10) << " EAnchor.replay event " << version
- << " - 1 == table " << mds->anchortable->get_version() << dendl;
- assert(version-1 == mds->anchortable->get_version());
-
- switch (op) {
- // anchortable
- case ANCHOR_OP_CREATE_PREPARE:
- mds->anchortable->create_prepare(ino, trace, reqmds);
- break;
- case ANCHOR_OP_DESTROY_PREPARE:
- mds->anchortable->destroy_prepare(ino, reqmds);
- break;
- case ANCHOR_OP_UPDATE_PREPARE:
- mds->anchortable->update_prepare(ino, trace, reqmds);
- break;
- case ANCHOR_OP_COMMIT:
- mds->anchortable->commit(atid);
- break;
-
- default:
- assert(0);
- }
+ return;
+ }
+
+ dout(10) << " EAnchor.replay event " << version
+ << " - 1 == table " << mds->anchortable->get_version() << dendl;
+ assert(version-1 == mds->anchortable->get_version());
+
+ switch (op) {
+ // anchortable
+ case ANCHOR_OP_CREATE_PREPARE:
+ mds->anchortable->create_prepare(ino, trace, reqmds);
+ break;
+ case ANCHOR_OP_DESTROY_PREPARE:
+ mds->anchortable->destroy_prepare(ino, reqmds);
+ break;
+ case ANCHOR_OP_UPDATE_PREPARE:
+ mds->anchortable->update_prepare(ino, trace, reqmds);
+ break;
+ case ANCHOR_OP_COMMIT:
+ mds->anchortable->commit(atid);
+ break;
- assert(version == mds->anchortable->get_version());
+ default:
+ assert(0);
}
+
+ assert(version == mds->anchortable->get_version());
}
}
+// -----------------------
+// ESnap
+
+void ESnap::update_segment()
+{
+ _segment->snaptablev = version;
+}
+
+void ESnap::replay(MDS *mds)
+{
+ if (mds->snaptable->get_version() >= version) {
+ dout(10) << "ESnap.replay event " << version
+ << " <= table " << mds->snaptable->get_version() << dendl;
+ return;
+ }
+
+ dout(10) << " ESnap.replay event " << version
+ << " - 1 == table " << mds->snaptable->get_version() << dendl;
+ assert(version-1 == mds->snaptable->get_version());
+
+ if (create) {
+ snapid_t s = mds->snaptable->create(snap.base, snap.name, snap.stamp);
+ assert(s == snap.snapid);
+ } else {
+ mds->snaptable->remove(snap.snapid);
+ }
+
+ assert(version == mds->snaptable->get_version());
+}
+
+
+
// -----------------------
// EUpdate
--- /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_MDS_SNAP_H
+#define __CEPH_MDS_SNAP_H
+
+struct SnapInfo {
+ snapid_t snapid;
+ inodeno_t base;
+ utime_t stamp;
+ string name;
+
+ void encode(bufferlist& bl) const {
+ ::encode(snapid, bl);
+ ::encode(base, bl);
+ ::encode(stamp, bl);
+ ::encode(name, bl);
+ }
+ void decode(bufferlist::iterator& bl) {
+ ::decode(snapid, bl);
+ ::decode(base, bl);
+ ::decode(stamp, bl);
+ ::decode(name, bl);
+ }
+};
+WRITE_CLASS_ENCODER(SnapInfo)
+
+inline ostream& operator<<(ostream& out, const SnapInfo &sn) {
+ return out << "snap(" << sn.snapid << " " << sn.base << " '" << sn.name << "' " << sn.stamp << ")";
+}
+
+#endif