Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / client / Inode.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #ifndef CEPH_CLIENT_INODE_H
5 #define CEPH_CLIENT_INODE_H
6
7 #include "include/types.h"
8 #include "include/xlist.h"
9
10 #include "mds/mdstypes.h" // hrm
11
12 #include "osdc/ObjectCacher.h"
13 #include "include/assert.h"
14
15 #include "InodeRef.h"
16 #include "UserPerm.h"
17
18 class Client;
19 struct MetaSession;
20 class Dentry;
21 class Dir;
22 struct SnapRealm;
23 struct Inode;
24 class ceph_lock_state_t;
25 class MetaRequest;
26 class filepath;
27 class Fh;
28
29 struct Cap {
30   MetaSession *session;
31   Inode *inode;
32   xlist<Cap*>::item cap_item;
33
34   uint64_t cap_id;
35   unsigned issued;
36   unsigned implemented;
37   unsigned wanted;   // as known to mds.
38   uint64_t seq, issue_seq;
39   __u32 mseq;  // migration seq
40   __u32 gen;
41   UserPerm latest_perms;
42
43   Cap() : session(NULL), inode(NULL), cap_item(this), cap_id(0), issued(0),
44           implemented(0), wanted(0), seq(0), issue_seq(0), mseq(0), gen(0),
45           latest_perms()  {}
46
47   void dump(Formatter *f) const;
48 };
49
50 struct CapSnap {
51   //snapid_t follows;  // map key
52   InodeRef in;
53   SnapContext context;
54   int issued, dirty;
55
56   uint64_t size;
57   utime_t ctime, btime, mtime, atime;
58   version_t time_warp_seq;
59   uint64_t change_attr;
60   uint32_t   mode;
61   uid_t      uid;
62   gid_t      gid;
63   map<string,bufferptr> xattrs;
64   version_t xattr_version;
65
66   bufferlist inline_data;
67   version_t inline_version;
68
69   bool writing, dirty_data;
70   uint64_t flush_tid;
71
72   explicit CapSnap(Inode *i)
73     : in(i), issued(0), dirty(0), size(0), time_warp_seq(0), change_attr(0),
74       mode(0), uid(0), gid(0), xattr_version(0), inline_version(0),
75       writing(false), dirty_data(false), flush_tid(0)
76   {}
77
78   void dump(Formatter *f) const;
79 };
80
81 // inode flags
82 #define I_COMPLETE      1
83 #define I_DIR_ORDERED   2
84 #define I_CAP_DROPPED   4
85 #define I_SNAPDIR_OPEN  8
86
87 struct Inode {
88   Client *client;
89
90   // -- the actual inode --
91   inodeno_t ino; // ORDER DEPENDENCY: oset
92   snapid_t  snapid;
93   ino_t faked_ino;
94
95   uint32_t   rdev;    // if special file
96
97   // affected by any inode change...
98   utime_t    ctime;   // inode change time
99   utime_t    btime;   // birth time
100
101   // perm (namespace permissions)
102   uint32_t   mode;
103   uid_t      uid;
104   gid_t      gid;
105
106   // nlink
107   int32_t    nlink;
108
109   // file (data access)
110   ceph_dir_layout dir_layout;
111   file_layout_t layout;
112   uint64_t   size;        // on directory, # dentries
113   uint32_t   truncate_seq;
114   uint64_t   truncate_size;
115   utime_t    mtime;   // file data modify time.
116   utime_t    atime;   // file data access time.
117   uint32_t   time_warp_seq;  // count of (potential) mtime/atime timewarps (i.e., utimes())
118   uint64_t   change_attr;
119
120   uint64_t max_size;  // max size we can write to
121
122   // dirfrag, recursive accountin
123   frag_info_t dirstat;
124   nest_info_t rstat;
125
126   // special stuff
127   version_t version;           // auth only
128   version_t xattr_version;
129
130   // inline data
131   version_t  inline_version;
132   bufferlist inline_data;
133
134   bool is_root()    const { return ino == MDS_INO_ROOT; }
135   bool is_symlink() const { return (mode & S_IFMT) == S_IFLNK; }
136   bool is_dir()     const { return (mode & S_IFMT) == S_IFDIR; }
137   bool is_file()    const { return (mode & S_IFMT) == S_IFREG; }
138
139   bool has_dir_layout() const {
140     return layout != file_layout_t();
141   }
142
143   __u32 hash_dentry_name(const string &dn) {
144     int which = dir_layout.dl_dir_hash;
145     if (!which)
146       which = CEPH_STR_HASH_LINUX;
147     assert(ceph_str_hash_valid(which));
148     return ceph_str_hash(which, dn.data(), dn.length());
149   }
150
151   unsigned flags;
152
153   quota_info_t quota;
154
155   bool is_complete_and_ordered() {
156     static const unsigned wants = I_COMPLETE | I_DIR_ORDERED;
157     return (flags & wants) == wants;
158   }
159
160   // about the dir (if this is one!)
161   Dir       *dir;     // if i'm a dir.
162   fragtree_t dirfragtree;
163   set<int>  dir_contacts;
164   uint64_t dir_release_count, dir_ordered_count;
165   bool dir_hashed, dir_replicated;
166
167   // per-mds caps
168   map<mds_rank_t, Cap*> caps;            // mds -> Cap
169   Cap *auth_cap;
170   int64_t cap_dirtier_uid;
171   int64_t cap_dirtier_gid;
172   unsigned dirty_caps, flushing_caps;
173   std::map<ceph_tid_t, int> flushing_cap_tids;
174   int shared_gen, cache_gen;
175   int snap_caps, snap_cap_refs;
176   utime_t hold_caps_until;
177   xlist<Inode*>::item cap_item, flushing_cap_item;
178
179   SnapRealm *snaprealm;
180   xlist<Inode*>::item snaprealm_item;
181   InodeRef snapdir_parent;  // only if we are a snapdir inode
182   map<snapid_t,CapSnap> cap_snaps;   // pending flush to mds
183
184   //int open_by_mode[CEPH_FILE_MODE_NUM];
185   map<int,int> open_by_mode;
186   map<int,int> cap_refs;
187
188   ObjectCacher::ObjectSet oset; // ORDER DEPENDENCY: ino
189
190   uint64_t     reported_size, wanted_max_size, requested_max_size;
191
192   int       _ref;      // ref count. 1 for each dentry, fh that links to me.
193   int       ll_ref;   // separate ref count for ll client
194   set<Dentry*> dn_set;      // if i'm linked to a dentry.
195   string    symlink;  // symlink content, if it's a symlink
196   map<string,bufferptr> xattrs;
197   map<frag_t,int> fragmap;  // known frag -> mds mappings
198
199   list<Cond*>       waitfor_caps;
200   list<Cond*>       waitfor_commit;
201
202   Dentry *get_first_parent() {
203     assert(!dn_set.empty());
204     return *dn_set.begin();
205   }
206
207   void make_long_path(filepath& p);
208   void make_nosnap_relative_path(filepath& p);
209
210   void get();
211   int _put(int n=1);
212
213   int get_num_ref() {
214     return _ref;
215   }
216
217   void ll_get() {
218     ll_ref++;
219   }
220   void ll_put(int n=1) {
221     assert(ll_ref >= n);
222     ll_ref -= n;
223   }
224
225   // file locks
226   ceph_lock_state_t *fcntl_locks;
227   ceph_lock_state_t *flock_locks;
228
229   xlist<MetaRequest*> unsafe_ops;
230
231   std::set<Fh*> fhs;
232
233   Inode(Client *c, vinodeno_t vino, file_layout_t *newlayout)
234     : client(c), ino(vino.ino), snapid(vino.snapid), faked_ino(0),
235       rdev(0), mode(0), uid(0), gid(0), nlink(0),
236       size(0), truncate_seq(1), truncate_size(-1),
237       time_warp_seq(0), change_attr(0), max_size(0), version(0),
238       xattr_version(0), inline_version(0), flags(0),
239       dir(0), dir_release_count(1), dir_ordered_count(1),
240       dir_hashed(false), dir_replicated(false), auth_cap(NULL),
241       cap_dirtier_uid(-1), cap_dirtier_gid(-1),
242       dirty_caps(0), flushing_caps(0), shared_gen(0), cache_gen(0),
243       snap_caps(0), snap_cap_refs(0),
244       cap_item(this), flushing_cap_item(this),
245       snaprealm(0), snaprealm_item(this),
246       oset((void *)this, newlayout->pool_id, this->ino),
247       reported_size(0), wanted_max_size(0), requested_max_size(0),
248       _ref(0), ll_ref(0), dn_set(),
249       fcntl_locks(NULL), flock_locks(NULL)
250   {
251     memset(&dir_layout, 0, sizeof(dir_layout));
252     memset(&quota, 0, sizeof(quota));
253   }
254   ~Inode();
255
256   vinodeno_t vino() const { return vinodeno_t(ino, snapid); }
257
258   struct Compare {
259     bool operator() (Inode* const & left, Inode* const & right) {
260       if (left->ino.val < right->ino.val) {
261         return (left->snapid.val < right->snapid.val);
262       }
263       return false;
264     }
265   };
266
267   bool check_mode(const UserPerm& perms, unsigned want);
268
269   // CAPS --------
270   void get_open_ref(int mode);
271   bool put_open_ref(int mode);
272
273   void get_cap_ref(int cap);
274   int put_cap_ref(int cap);
275   bool is_any_caps();
276   bool cap_is_valid(Cap* cap) const;
277   int caps_issued(int *implemented = 0) const;
278   void touch_cap(Cap *cap);
279   void try_touch_cap(mds_rank_t mds);
280   bool caps_issued_mask(unsigned mask);
281   int caps_used();
282   int caps_file_wanted();
283   int caps_wanted();
284   int caps_mds_wanted();
285   int caps_dirty();
286   const UserPerm *get_best_perms();
287
288   bool have_valid_size();
289   Dir *open_dir();
290
291   void add_fh(Fh *f) {fhs.insert(f);}
292   void rm_fh(Fh *f) {fhs.erase(f);}
293   void set_async_err(int r);
294   void dump(Formatter *f) const;
295 };
296
297 ostream& operator<<(ostream &out, const Inode &in);
298
299 #endif