X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fclient%2FInode.h;fp=src%2Fceph%2Fsrc%2Fclient%2FInode.h;h=e8ce367aa83504de23142c8fd0ab02b9640b596b;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/client/Inode.h b/src/ceph/src/client/Inode.h new file mode 100644 index 0000000..e8ce367 --- /dev/null +++ b/src/ceph/src/client/Inode.h @@ -0,0 +1,299 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_CLIENT_INODE_H +#define CEPH_CLIENT_INODE_H + +#include "include/types.h" +#include "include/xlist.h" + +#include "mds/mdstypes.h" // hrm + +#include "osdc/ObjectCacher.h" +#include "include/assert.h" + +#include "InodeRef.h" +#include "UserPerm.h" + +class Client; +struct MetaSession; +class Dentry; +class Dir; +struct SnapRealm; +struct Inode; +class ceph_lock_state_t; +class MetaRequest; +class filepath; +class Fh; + +struct Cap { + MetaSession *session; + Inode *inode; + xlist::item cap_item; + + uint64_t cap_id; + unsigned issued; + unsigned implemented; + unsigned wanted; // as known to mds. + uint64_t seq, issue_seq; + __u32 mseq; // migration seq + __u32 gen; + UserPerm latest_perms; + + Cap() : session(NULL), inode(NULL), cap_item(this), cap_id(0), issued(0), + implemented(0), wanted(0), seq(0), issue_seq(0), mseq(0), gen(0), + latest_perms() {} + + void dump(Formatter *f) const; +}; + +struct CapSnap { + //snapid_t follows; // map key + InodeRef in; + SnapContext context; + int issued, dirty; + + uint64_t size; + utime_t ctime, btime, mtime, atime; + version_t time_warp_seq; + uint64_t change_attr; + uint32_t mode; + uid_t uid; + gid_t gid; + map xattrs; + version_t xattr_version; + + bufferlist inline_data; + version_t inline_version; + + bool writing, dirty_data; + uint64_t flush_tid; + + explicit CapSnap(Inode *i) + : in(i), issued(0), dirty(0), size(0), time_warp_seq(0), change_attr(0), + mode(0), uid(0), gid(0), xattr_version(0), inline_version(0), + writing(false), dirty_data(false), flush_tid(0) + {} + + void dump(Formatter *f) const; +}; + +// inode flags +#define I_COMPLETE 1 +#define I_DIR_ORDERED 2 +#define I_CAP_DROPPED 4 +#define I_SNAPDIR_OPEN 8 + +struct Inode { + Client *client; + + // -- the actual inode -- + inodeno_t ino; // ORDER DEPENDENCY: oset + snapid_t snapid; + ino_t faked_ino; + + uint32_t rdev; // if special file + + // affected by any inode change... + utime_t ctime; // inode change time + utime_t btime; // birth time + + // perm (namespace permissions) + uint32_t mode; + uid_t uid; + gid_t gid; + + // nlink + int32_t nlink; + + // file (data access) + ceph_dir_layout dir_layout; + file_layout_t layout; + uint64_t size; // on directory, # dentries + uint32_t truncate_seq; + uint64_t truncate_size; + utime_t mtime; // file data modify time. + utime_t atime; // file data access time. + uint32_t time_warp_seq; // count of (potential) mtime/atime timewarps (i.e., utimes()) + uint64_t change_attr; + + uint64_t max_size; // max size we can write to + + // dirfrag, recursive accountin + frag_info_t dirstat; + nest_info_t rstat; + + // special stuff + version_t version; // auth only + version_t xattr_version; + + // inline data + version_t inline_version; + bufferlist inline_data; + + bool is_root() const { return ino == MDS_INO_ROOT; } + bool is_symlink() const { return (mode & S_IFMT) == S_IFLNK; } + bool is_dir() const { return (mode & S_IFMT) == S_IFDIR; } + bool is_file() const { return (mode & S_IFMT) == S_IFREG; } + + bool has_dir_layout() const { + return layout != file_layout_t(); + } + + __u32 hash_dentry_name(const string &dn) { + int which = dir_layout.dl_dir_hash; + if (!which) + which = CEPH_STR_HASH_LINUX; + assert(ceph_str_hash_valid(which)); + return ceph_str_hash(which, dn.data(), dn.length()); + } + + unsigned flags; + + quota_info_t quota; + + bool is_complete_and_ordered() { + static const unsigned wants = I_COMPLETE | I_DIR_ORDERED; + return (flags & wants) == wants; + } + + // about the dir (if this is one!) + Dir *dir; // if i'm a dir. + fragtree_t dirfragtree; + set dir_contacts; + uint64_t dir_release_count, dir_ordered_count; + bool dir_hashed, dir_replicated; + + // per-mds caps + map caps; // mds -> Cap + Cap *auth_cap; + int64_t cap_dirtier_uid; + int64_t cap_dirtier_gid; + unsigned dirty_caps, flushing_caps; + std::map flushing_cap_tids; + int shared_gen, cache_gen; + int snap_caps, snap_cap_refs; + utime_t hold_caps_until; + xlist::item cap_item, flushing_cap_item; + + SnapRealm *snaprealm; + xlist::item snaprealm_item; + InodeRef snapdir_parent; // only if we are a snapdir inode + map cap_snaps; // pending flush to mds + + //int open_by_mode[CEPH_FILE_MODE_NUM]; + map open_by_mode; + map cap_refs; + + ObjectCacher::ObjectSet oset; // ORDER DEPENDENCY: ino + + uint64_t reported_size, wanted_max_size, requested_max_size; + + int _ref; // ref count. 1 for each dentry, fh that links to me. + int ll_ref; // separate ref count for ll client + set dn_set; // if i'm linked to a dentry. + string symlink; // symlink content, if it's a symlink + map xattrs; + map fragmap; // known frag -> mds mappings + + list waitfor_caps; + list waitfor_commit; + + Dentry *get_first_parent() { + assert(!dn_set.empty()); + return *dn_set.begin(); + } + + void make_long_path(filepath& p); + void make_nosnap_relative_path(filepath& p); + + void get(); + int _put(int n=1); + + int get_num_ref() { + return _ref; + } + + void ll_get() { + ll_ref++; + } + void ll_put(int n=1) { + assert(ll_ref >= n); + ll_ref -= n; + } + + // file locks + ceph_lock_state_t *fcntl_locks; + ceph_lock_state_t *flock_locks; + + xlist unsafe_ops; + + std::set fhs; + + Inode(Client *c, vinodeno_t vino, file_layout_t *newlayout) + : client(c), ino(vino.ino), snapid(vino.snapid), faked_ino(0), + rdev(0), mode(0), uid(0), gid(0), nlink(0), + size(0), truncate_seq(1), truncate_size(-1), + time_warp_seq(0), change_attr(0), max_size(0), version(0), + xattr_version(0), inline_version(0), flags(0), + dir(0), dir_release_count(1), dir_ordered_count(1), + dir_hashed(false), dir_replicated(false), auth_cap(NULL), + cap_dirtier_uid(-1), cap_dirtier_gid(-1), + dirty_caps(0), flushing_caps(0), shared_gen(0), cache_gen(0), + snap_caps(0), snap_cap_refs(0), + cap_item(this), flushing_cap_item(this), + snaprealm(0), snaprealm_item(this), + oset((void *)this, newlayout->pool_id, this->ino), + reported_size(0), wanted_max_size(0), requested_max_size(0), + _ref(0), ll_ref(0), dn_set(), + fcntl_locks(NULL), flock_locks(NULL) + { + memset(&dir_layout, 0, sizeof(dir_layout)); + memset("a, 0, sizeof(quota)); + } + ~Inode(); + + vinodeno_t vino() const { return vinodeno_t(ino, snapid); } + + struct Compare { + bool operator() (Inode* const & left, Inode* const & right) { + if (left->ino.val < right->ino.val) { + return (left->snapid.val < right->snapid.val); + } + return false; + } + }; + + bool check_mode(const UserPerm& perms, unsigned want); + + // CAPS -------- + void get_open_ref(int mode); + bool put_open_ref(int mode); + + void get_cap_ref(int cap); + int put_cap_ref(int cap); + bool is_any_caps(); + bool cap_is_valid(Cap* cap) const; + int caps_issued(int *implemented = 0) const; + void touch_cap(Cap *cap); + void try_touch_cap(mds_rank_t mds); + bool caps_issued_mask(unsigned mask); + int caps_used(); + int caps_file_wanted(); + int caps_wanted(); + int caps_mds_wanted(); + int caps_dirty(); + const UserPerm *get_best_perms(); + + bool have_valid_size(); + Dir *open_dir(); + + void add_fh(Fh *f) {fhs.insert(f);} + void rm_fh(Fh *f) {fhs.erase(f);} + void set_async_err(int r); + void dump(Formatter *f) const; +}; + +ostream& operator<<(ostream &out, const Inode &in); + +#endif