X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fmds%2FSnapRealm.h;fp=src%2Fceph%2Fsrc%2Fmds%2FSnapRealm.h;h=4a99d639140a16d57e66e7d45ba94b5ebac958bf;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/mds/SnapRealm.h b/src/ceph/src/mds/SnapRealm.h new file mode 100644 index 0000000..4a99d63 --- /dev/null +++ b/src/ceph/src/mds/SnapRealm.h @@ -0,0 +1,165 @@ +// -*- 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 + * + * 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_SNAPREALM_H +#define CEPH_MDS_SNAPREALM_H + +#include "mdstypes.h" +#include "snap.h" +#include "include/xlist.h" +#include "include/elist.h" +#include "common/snap_types.h" + +class MDSInternalContextBase; + +struct SnapRealm { +protected: + // cache + mutable snapid_t cached_seq; // max seq over self and all past+present parents. + mutable snapid_t cached_last_created; // max last_created over all past+present parents + mutable snapid_t cached_last_destroyed; + mutable set cached_snaps; + mutable SnapContext cached_snap_context; + mutable bufferlist cached_snap_trace; + + void check_cache() const; + +public: + // realm state + sr_t srnode; + + // in-memory state + MDCache *mdcache; + CInode *inode; + + bool open; // set to true once all past_parents are opened + SnapRealm *parent; + set open_children; // active children that are currently open + set open_past_children; // past children who has pinned me + map > > open_past_parents; // these are explicitly pinned. + unsigned num_open_past_parents; + + + + elist inodes_with_caps; // for efficient realm splits + map* > client_caps; // to identify clients who need snap notifications + + SnapRealm(MDCache *c, CInode *in) : + srnode(), + mdcache(c), inode(in), + open(false), parent(0), + num_open_past_parents(0), + inodes_with_caps(0) + { } + + bool exists(const string &name) const { + for (map::const_iterator p = srnode.snaps.begin(); + p != srnode.snaps.end(); + ++p) { + if (p->second.name == name) + return true; + } + return false; + } + + bool is_open() const { return open; } + void _close_parents() { open = false; } + bool _open_parents(MDSInternalContextBase *retryorfinish, snapid_t first=1, snapid_t last=CEPH_NOSNAP); + bool open_parents(MDSInternalContextBase *retryorfinish); + void _remove_missing_parent(snapid_t snapid, inodeno_t parent, int err); + bool have_past_parents_open(snapid_t first=1, snapid_t last=CEPH_NOSNAP); + void add_open_past_parent(SnapRealm *parent, snapid_t last); + void remove_open_past_parent(inodeno_t ino, snapid_t last); + void close_parents(); + + void prune_past_parents(); + bool has_past_parents() const { return !srnode.past_parents.empty(); } + + void build_snap_set(set& s, + snapid_t& max_seq, snapid_t& max_last_created, snapid_t& max_last_destroyed, + snapid_t first, snapid_t last) const; + void get_snap_info(map& infomap, snapid_t first=0, snapid_t last=CEPH_NOSNAP); + + const bufferlist& get_snap_trace(); + void build_snap_trace(bufferlist& snapbl) const; + + 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& get_snaps() const; + const SnapContext& get_snap_context() const; + void invalidate_cached_snaps() { + cached_seq = 0; + } + snapid_t get_last_created() { + check_cache(); + return cached_last_created; + } + snapid_t get_last_destroyed() { + check_cache(); + return cached_last_destroyed; + } + snapid_t get_newest_snap() { + check_cache(); + if (cached_snaps.empty()) + return 0; + else + return *cached_snaps.rbegin(); + } + snapid_t get_newest_seq() { + check_cache(); + return cached_seq; + } + + snapid_t get_snap_following(snapid_t follows) { + check_cache(); + const set& s = get_snaps(); + set::const_iterator p = s.upper_bound(follows); + if (p != s.end()) + return *p; + return CEPH_NOSNAP; + } + + bool has_snaps_in_range(snapid_t first, snapid_t last) { + check_cache(); + const set& s = get_snaps(); + set::const_iterator p = s.lower_bound(first); + return (p != s.end() && *p <= last); + } + + void adjust_parent(); + + void split_at(SnapRealm *child); + void join(SnapRealm *child); + + void add_cap(client_t client, Capability *cap) { + auto client_caps_entry = client_caps.find(client); + if (client_caps_entry == client_caps.end()) + client_caps_entry = client_caps.emplace(client, + new xlist).first; + client_caps_entry->second->push_back(&cap->item_snaprealm_caps); + } + void remove_cap(client_t client, Capability *cap) { + cap->item_snaprealm_caps.remove_myself(); + if (client_caps[client]->empty()) { + delete client_caps[client]; + client_caps.erase(client); + } + } + +}; + +ostream& operator<<(ostream& out, const SnapRealm &realm); + +#endif