X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fclient%2FInode.cc;fp=src%2Fceph%2Fsrc%2Fclient%2FInode.cc;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=a3d42254765ce46334960d176ab5a85060c56f85;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/client/Inode.cc b/src/ceph/src/client/Inode.cc deleted file mode 100644 index a3d4225..0000000 --- a/src/ceph/src/client/Inode.cc +++ /dev/null @@ -1,557 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab - -#include "Client.h" -#include "Inode.h" -#include "Dentry.h" -#include "Dir.h" -#include "Fh.h" -#include "MetaSession.h" -#include "ClientSnapRealm.h" - -#include "mds/flock.h" - -Inode::~Inode() -{ - cap_item.remove_myself(); - snaprealm_item.remove_myself(); - - if (snapdir_parent) { - snapdir_parent->flags &= ~I_SNAPDIR_OPEN; - snapdir_parent.reset(); - } - - if (!oset.objects.empty()) { - lsubdout(client->cct, client, 0) << __func__ << ": leftover objects on inode 0x" - << std::hex << ino << std::dec << dendl; - assert(oset.objects.empty()); - } - - delete fcntl_locks; - delete flock_locks; -} - -ostream& operator<<(ostream &out, const Inode &in) -{ - out << in.vino() << "(" - << "faked_ino=" << in.faked_ino - << " ref=" << in._ref - << " ll_ref=" << in.ll_ref - << " cap_refs=" << in.cap_refs - << " open=" << in.open_by_mode - << " mode=" << oct << in.mode << dec - << " size=" << in.size << "/" << in.max_size - << " mtime=" << in.mtime - << " caps=" << ccap_string(in.caps_issued()); - if (!in.caps.empty()) { - out << "("; - for (auto p = in.caps.begin(); p != in.caps.end(); ++p) { - if (p != in.caps.begin()) - out << ','; - out << p->first << '=' << ccap_string(p->second->issued); - } - out << ")"; - } - if (in.dirty_caps) - out << " dirty_caps=" << ccap_string(in.dirty_caps); - if (in.flushing_caps) - out << " flushing_caps=" << ccap_string(in.flushing_caps); - - if (in.flags & I_COMPLETE) - out << " COMPLETE"; - - if (in.is_file()) - out << " " << in.oset; - - if (!in.dn_set.empty()) - out << " parents=" << in.dn_set; - - if (in.is_dir() && in.has_dir_layout()) - out << " has_dir_layout"; - - if (in.quota.is_enable()) - out << " " << in.quota; - - out << ' ' << &in << ")"; - return out; -} - - -void Inode::make_long_path(filepath& p) -{ - if (!dn_set.empty()) { - assert((*dn_set.begin())->dir && (*dn_set.begin())->dir->parent_inode); - (*dn_set.begin())->dir->parent_inode->make_long_path(p); - p.push_dentry((*dn_set.begin())->name); - } else if (snapdir_parent) { - snapdir_parent->make_nosnap_relative_path(p); - string empty; - p.push_dentry(empty); - } else - p = filepath(ino); -} - -/* - * make a filepath suitable for an mds request: - * - if we are non-snapped/live, the ino is sufficient, e.g. #1234 - * - if we are snapped, make filepath relative to first non-snapped parent. - */ -void Inode::make_nosnap_relative_path(filepath& p) -{ - if (snapid == CEPH_NOSNAP) { - p = filepath(ino); - } else if (snapdir_parent) { - snapdir_parent->make_nosnap_relative_path(p); - string empty; - p.push_dentry(empty); - } else if (!dn_set.empty()) { - assert((*dn_set.begin())->dir && (*dn_set.begin())->dir->parent_inode); - (*dn_set.begin())->dir->parent_inode->make_nosnap_relative_path(p); - p.push_dentry((*dn_set.begin())->name); - } else { - p = filepath(ino); - } -} - -void Inode::get_open_ref(int mode) -{ - open_by_mode[mode]++; -} - -bool Inode::put_open_ref(int mode) -{ - //cout << "open_by_mode[" << mode << "] " << open_by_mode[mode] << " -> " << (open_by_mode[mode]-1) << std::endl; - if (--open_by_mode[mode] == 0) - return true; - return false; -} - -void Inode::get_cap_ref(int cap) -{ - int n = 0; - while (cap) { - if (cap & 1) { - int c = 1 << n; - cap_refs[c]++; - //cout << "inode " << *this << " get " << cap_string(c) << " " << (cap_refs[c]-1) << " -> " << cap_refs[c] << std::endl; - } - cap >>= 1; - n++; - } -} - -int Inode::put_cap_ref(int cap) -{ - // if cap is always a single bit (which it seems to be) - // all this logic is equivalent to: - // if (--cap_refs[c]) return false; else return true; - int last = 0; - int n = 0; - while (cap) { - if (cap & 1) { - int c = 1 << n; - if (cap_refs[c] <= 0) { - lderr(client->cct) << "put_cap_ref " << ccap_string(c) << " went negative on " << *this << dendl; - assert(cap_refs[c] > 0); - } - if (--cap_refs[c] == 0) - last |= c; - //cout << "inode " << *this << " put " << cap_string(c) << " " << (cap_refs[c]+1) << " -> " << cap_refs[c] << std::endl; - } - cap >>= 1; - n++; - } - return last; -} - -bool Inode::is_any_caps() -{ - return !caps.empty() || snap_caps; -} - -bool Inode::cap_is_valid(Cap* cap) const -{ - /*cout << "cap_gen " << cap->session-> cap_gen << std::endl - << "session gen " << cap->gen << std::endl - << "cap expire " << cap->session->cap_ttl << std::endl - << "cur time " << ceph_clock_now(cct) << std::endl;*/ - if ((cap->session->cap_gen <= cap->gen) - && (ceph_clock_now() < cap->session->cap_ttl)) { - return true; - } - return false; -} - -int Inode::caps_issued(int *implemented) const -{ - int c = snap_caps; - int i = 0; - for (map::const_iterator it = caps.begin(); - it != caps.end(); - ++it) - if (cap_is_valid(it->second)) { - c |= it->second->issued; - i |= it->second->implemented; - } - if (implemented) - *implemented = i; - return c; -} - -void Inode::touch_cap(Cap *cap) -{ - // move to back of LRU - cap->session->caps.push_back(&cap->cap_item); -} - -void Inode::try_touch_cap(mds_rank_t mds) -{ - if (caps.count(mds)) - touch_cap(caps[mds]); -} - -bool Inode::caps_issued_mask(unsigned mask) -{ - int c = snap_caps; - if ((c & mask) == mask) - return true; - // prefer auth cap - if (auth_cap && - cap_is_valid(auth_cap) && - (auth_cap->issued & mask) == mask) { - touch_cap(auth_cap); - return true; - } - // try any cap - for (map::iterator it = caps.begin(); - it != caps.end(); - ++it) { - if (cap_is_valid(it->second)) { - if ((it->second->issued & mask) == mask) { - touch_cap(it->second); - return true; - } - c |= it->second->issued; - } - } - if ((c & mask) == mask) { - // bah.. touch them all - for (map::iterator it = caps.begin(); - it != caps.end(); - ++it) - touch_cap(it->second); - return true; - } - return false; -} - -int Inode::caps_used() -{ - int w = 0; - for (map::iterator p = cap_refs.begin(); - p != cap_refs.end(); - ++p) - if (p->second) - w |= p->first; - return w; -} - -int Inode::caps_file_wanted() -{ - int want = 0; - for (map::iterator p = open_by_mode.begin(); - p != open_by_mode.end(); - ++p) - if (p->second) - want |= ceph_caps_for_mode(p->first); - return want; -} - -int Inode::caps_wanted() -{ - int want = caps_file_wanted() | caps_used(); - if (want & CEPH_CAP_FILE_BUFFER) - want |= CEPH_CAP_FILE_EXCL; - return want; -} - -int Inode::caps_mds_wanted() -{ - int want = 0; - for (auto it = caps.begin(); it != caps.end(); ++it) - want |= it->second->wanted; - return want; -} - -int Inode::caps_dirty() -{ - return dirty_caps | flushing_caps; -} - -const UserPerm* Inode::get_best_perms() -{ - const UserPerm *perms = NULL; - for (const auto ci : caps) { - const UserPerm& iperm = ci.second->latest_perms; - if (!perms) { // we don't have any, take what's present - perms = &iperm; - } else if (iperm.uid() == uid) { - if (iperm.gid() == gid) { // we have the best possible, return - return &iperm; - } - if (perms->uid() != uid) { // take uid > gid every time - perms = &iperm; - } - } else if (perms->uid() != uid && iperm.gid() == gid) { - perms = &iperm; // a matching gid is better than nothing - } - } - return perms; -} - -bool Inode::have_valid_size() -{ - // RD+RDCACHE or WR+WRBUFFER => valid size - if (caps_issued() & (CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL)) - return true; - return false; -} - -// open Dir for an inode. if it's not open, allocated it (and pin dentry in memory). -Dir *Inode::open_dir() -{ - if (!dir) { - dir = new Dir(this); - lsubdout(client->cct, client, 15) << "open_dir " << dir << " on " << this << dendl; - assert(dn_set.size() < 2); // dirs can't be hard-linked - if (!dn_set.empty()) - (*dn_set.begin())->get(); // pin dentry - get(); // pin inode - } - return dir; -} - -bool Inode::check_mode(const UserPerm& perms, unsigned want) -{ - if (uid == perms.uid()) { - // if uid is owner, owner entry determines access - want = want << 6; - } else if (perms.gid_in_groups(gid)) { - // if a gid or sgid matches the owning group, group entry determines access - want = want << 3; - } - - return (mode & want) == want; -} - -void Inode::get() { - _ref++; - lsubdout(client->cct, client, 15) << "inode.get on " << this << " " << ino << '.' << snapid - << " now " << _ref << dendl; -} - -//private method to put a reference; see Client::put_inode() -int Inode::_put(int n) { - _ref -= n; - lsubdout(client->cct, client, 15) << "inode.put on " << this << " " << ino << '.' << snapid - << " now " << _ref << dendl; - assert(_ref >= 0); - return _ref; -} - - -void Inode::dump(Formatter *f) const -{ - f->dump_stream("ino") << ino; - f->dump_stream("snapid") << snapid; - if (rdev) - f->dump_unsigned("rdev", rdev); - f->dump_stream("ctime") << ctime; - f->dump_stream("btime") << btime; - f->dump_stream("mode") << '0' << std::oct << mode << std::dec; - f->dump_unsigned("uid", uid); - f->dump_unsigned("gid", gid); - f->dump_int("nlink", nlink); - - f->dump_unsigned("size", size); - f->dump_unsigned("max_size", max_size); - f->dump_unsigned("truncate_seq", truncate_seq); - f->dump_unsigned("truncate_size", truncate_size); - f->dump_stream("mtime") << mtime; - f->dump_stream("atime") << atime; - f->dump_unsigned("time_warp_seq", time_warp_seq); - f->dump_unsigned("change_attr", change_attr); - - f->dump_object("layout", layout); - if (is_dir()) { - f->open_object_section("dir_layout"); - ::dump(dir_layout, f); - f->close_section(); - - f->dump_bool("complete", flags & I_COMPLETE); - f->dump_bool("ordered", flags & I_DIR_ORDERED); - - /* FIXME when wip-mds-encoding is merged *** - f->open_object_section("dir_stat"); - dirstat.dump(f); - f->close_section(); - - f->open_object_section("rstat"); - rstat.dump(f); - f->close_section(); - */ - } - - f->dump_unsigned("version", version); - f->dump_unsigned("xattr_version", xattr_version); - f->dump_unsigned("flags", flags); - - if (is_dir()) { - if (!dir_contacts.empty()) { - f->open_object_section("dir_contants"); - for (set::iterator p = dir_contacts.begin(); p != dir_contacts.end(); ++p) - f->dump_int("mds", *p); - f->close_section(); - } - f->dump_int("dir_hashed", (int)dir_hashed); - f->dump_int("dir_replicated", (int)dir_replicated); - } - - f->open_array_section("caps"); - for (map::const_iterator p = caps.begin(); p != caps.end(); ++p) { - f->open_object_section("cap"); - f->dump_int("mds", p->first); - if (p->second == auth_cap) - f->dump_int("auth", 1); - p->second->dump(f); - f->close_section(); - } - f->close_section(); - if (auth_cap) - f->dump_int("auth_cap", auth_cap->session->mds_num); - - f->dump_stream("dirty_caps") << ccap_string(dirty_caps); - if (flushing_caps) { - f->dump_stream("flushings_caps") << ccap_string(flushing_caps); - f->open_object_section("flushing_cap_tid"); - for (map::const_iterator p = flushing_cap_tids.begin(); - p != flushing_cap_tids.end(); - ++p) { - string n(ccap_string(p->second)); - f->dump_unsigned(n.c_str(), p->first); - } - f->close_section(); - } - f->dump_int("shared_gen", shared_gen); - f->dump_int("cache_gen", cache_gen); - if (snap_caps) { - f->dump_int("snap_caps", snap_caps); - f->dump_int("snap_cap_refs", snap_cap_refs); - } - - f->dump_stream("hold_caps_until") << hold_caps_until; - - if (snaprealm) { - f->open_object_section("snaprealm"); - snaprealm->dump(f); - f->close_section(); - } - if (!cap_snaps.empty()) { - for (const auto &p : cap_snaps) { - f->open_object_section("cap_snap"); - f->dump_stream("follows") << p.first; - p.second.dump(f); - f->close_section(); - } - } - - // open - if (!open_by_mode.empty()) { - f->open_array_section("open_by_mode"); - for (map::const_iterator p = open_by_mode.begin(); p != open_by_mode.end(); ++p) { - f->open_object_section("ref"); - f->dump_int("mode", p->first); - f->dump_int("refs", p->second); - f->close_section(); - } - f->close_section(); - } - if (!cap_refs.empty()) { - f->open_array_section("cap_refs"); - for (map::const_iterator p = cap_refs.begin(); p != cap_refs.end(); ++p) { - f->open_object_section("cap_ref"); - f->dump_stream("cap") << ccap_string(p->first); - f->dump_int("refs", p->second); - f->close_section(); - } - f->close_section(); - } - - f->dump_unsigned("reported_size", reported_size); - if (wanted_max_size != max_size) - f->dump_unsigned("wanted_max_size", wanted_max_size); - if (requested_max_size != max_size) - f->dump_unsigned("requested_max_size", requested_max_size); - - f->dump_int("ref", _ref); - f->dump_int("ll_ref", ll_ref); - - if (!dn_set.empty()) { - f->open_array_section("parents"); - for (set::const_iterator p = dn_set.begin(); p != dn_set.end(); ++p) { - f->open_object_section("dentry"); - f->dump_stream("dir_ino") << (*p)->dir->parent_inode->ino; - f->dump_string("name", (*p)->name); - f->close_section(); - } - f->close_section(); - } -} - -void Cap::dump(Formatter *f) const -{ - f->dump_int("mds", session->mds_num); - f->dump_stream("ino") << inode->ino; - f->dump_unsigned("cap_id", cap_id); - f->dump_stream("issued") << ccap_string(issued); - if (implemented != issued) - f->dump_stream("implemented") << ccap_string(implemented); - f->dump_stream("wanted") << ccap_string(wanted); - f->dump_unsigned("seq", seq); - f->dump_unsigned("issue_seq", issue_seq); - f->dump_unsigned("mseq", mseq); - f->dump_unsigned("gen", gen); -} - -void CapSnap::dump(Formatter *f) const -{ - f->dump_stream("ino") << in->ino; - f->dump_stream("issued") << ccap_string(issued); - f->dump_stream("dirty") << ccap_string(dirty); - f->dump_unsigned("size", size); - f->dump_stream("ctime") << ctime; - f->dump_stream("mtime") << mtime; - f->dump_stream("atime") << atime; - f->dump_int("time_warp_seq", time_warp_seq); - f->dump_stream("mode") << '0' << std::oct << mode << std::dec; - f->dump_unsigned("uid", uid); - f->dump_unsigned("gid", gid); - if (!xattrs.empty()) { - f->open_object_section("xattr_lens"); - for (map::const_iterator p = xattrs.begin(); p != xattrs.end(); ++p) - f->dump_int(p->first.c_str(), p->second.length()); - f->close_section(); - } - f->dump_unsigned("xattr_version", xattr_version); - f->dump_int("writing", (int)writing); - f->dump_int("dirty_data", (int)dirty_data); - f->dump_unsigned("flush_tid", flush_tid); -} - -void Inode::set_async_err(int r) -{ - for (const auto &fh : fhs) { - fh->async_err = r; - } -} -