1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_CLIENT_INODE_H
5 #define CEPH_CLIENT_INODE_H
9 #include "include/compat.h"
10 #include "include/ceph_assert.h"
11 #include "include/types.h"
12 #include "include/xlist.h"
14 #include "mds/flock.h"
15 #include "mds/mdstypes.h" // hrm
16 #include "include/cephfs/types.h"
18 #include "osdc/ObjectCacher.h"
21 #include "MetaSession.h"
23 #include "Delegation.h"
37 Cap(Inode
&i
, MetaSession
*s
) : inode(i
),
42 s
->caps
.push_back(&cap_item
);
45 cap_item
.remove_myself();
49 // move to back of LRU
50 session
->caps
.push_back(&cap_item
);
53 void dump(Formatter
*f
) const;
59 unsigned implemented
= 0;
60 unsigned wanted
= 0; // as known to mds.
62 uint64_t issue_seq
= 0;
63 __u32 mseq
= 0; // migration seq
65 UserPerm latest_perms
;
68 /* Note that this Cap will not move (see Inode::caps):
71 * The insert members shall not affect the validity of iterators and
72 * references to the container, and the erase members shall invalidate only
73 * iterators and references to the erased elements.
75 xlist
<Cap
*>::item cap_item
;
79 //snapid_t follows; // map key
82 int issued
= 0, dirty
= 0;
85 utime_t ctime
, btime
, mtime
, atime
;
86 version_t time_warp_seq
= 0;
87 uint64_t change_attr
= 0;
91 std::map
<std::string
,bufferptr
> xattrs
;
92 version_t xattr_version
= 0;
94 bufferlist inline_data
;
95 version_t inline_version
= 0;
97 bool writing
= false, dirty_data
= false;
98 uint64_t flush_tid
= 0;
100 explicit CapSnap(Inode
*i
)
104 void dump(Formatter
*f
) const;
108 #define I_COMPLETE (1 << 0)
109 #define I_DIR_ORDERED (1 << 1)
110 #define I_SNAPDIR_OPEN (1 << 2)
111 #define I_KICK_FLUSH (1 << 3)
112 #define I_CAP_DROPPED (1 << 4)
113 #define I_ERROR_FILELOCK (1 << 5)
115 struct Inode
: RefCountedObject
{
116 ceph::coarse_mono_time hold_caps_until
;
119 // -- the actual inode --
120 inodeno_t ino
; // ORDER DEPENDENCY: oset
124 uint32_t rdev
= 0; // if special file
126 // affected by any inode change...
127 utime_t ctime
; // inode change time
128 utime_t btime
; // birth time
130 // perm (namespace permissions)
138 // file (data access)
139 ceph_dir_layout dir_layout
{};
140 file_layout_t layout
;
141 uint64_t size
= 0; // on directory, # dentries
142 uint32_t truncate_seq
= 1;
143 uint64_t truncate_size
= -1;
144 utime_t mtime
; // file data modify time.
145 utime_t atime
; // file data access time.
146 uint32_t time_warp_seq
= 0; // count of (potential) mtime/atime timewarps (i.e., utimes())
147 uint64_t change_attr
= 0;
149 uint64_t max_size
= 0; // max size we can write to
151 // dirfrag, recursive accountin
156 version_t version
= 0; // auth only
157 version_t xattr_version
= 0;
158 utime_t snap_btime
; // snapshot creation (birth) time
159 std::map
<std::string
, std::string
> snap_metadata
;
162 version_t inline_version
= 0;
163 bufferlist inline_data
;
165 std::vector
<uint8_t> fscrypt_auth
;
166 std::vector
<uint8_t> fscrypt_file
;
167 bool is_fscrypt_enabled() {
168 return !!fscrypt_auth
.size();
171 bool is_root() const { return ino
== CEPH_INO_ROOT
; }
172 bool is_symlink() const { return (mode
& S_IFMT
) == S_IFLNK
; }
173 bool is_dir() const { return (mode
& S_IFMT
) == S_IFDIR
; }
174 bool is_file() const { return (mode
& S_IFMT
) == S_IFREG
; }
176 bool has_dir_layout() const {
177 return layout
!= file_layout_t();
180 __u32
hash_dentry_name(const std::string
&dn
) {
181 int which
= dir_layout
.dl_dir_hash
;
183 which
= CEPH_STR_HASH_LINUX
;
184 ceph_assert(ceph_str_hash_valid(which
));
185 return ceph_str_hash(which
, dn
.data(), dn
.length());
192 bool is_complete_and_ordered() {
193 static const unsigned wants
= I_COMPLETE
| I_DIR_ORDERED
;
194 return (flags
& wants
) == wants
;
197 // about the dir (if this is one!)
198 Dir
*dir
= 0; // if i'm a dir.
199 fragtree_t dirfragtree
;
200 uint64_t dir_release_count
= 1;
201 uint64_t dir_ordered_count
= 1;
202 bool dir_hashed
= false;
203 bool dir_replicated
= false;
206 std::map
<mds_rank_t
, Cap
> caps
; // mds -> Cap
208 int64_t cap_dirtier_uid
= -1;
209 int64_t cap_dirtier_gid
= -1;
210 unsigned dirty_caps
= 0;
211 unsigned flushing_caps
= 0;
212 std::map
<ceph_tid_t
, int> flushing_cap_tids
;
216 int snap_cap_refs
= 0;
217 xlist
<Inode
*>::item delay_cap_item
, dirty_cap_item
, flushing_cap_item
;
219 SnapRealm
*snaprealm
= 0;
220 xlist
<Inode
*>::item snaprealm_item
;
221 InodeRef snapdir_parent
; // only if we are a snapdir inode
222 std::map
<snapid_t
,CapSnap
> cap_snaps
; // pending flush to mds
224 //int open_by_mode[CEPH_FILE_MODE_NUM];
225 std::map
<int,int> open_by_mode
;
226 std::map
<int,int> cap_refs
;
228 ObjectCacher::ObjectSet oset
; // ORDER DEPENDENCY: ino
230 uint64_t reported_size
= 0;
231 uint64_t wanted_max_size
= 0;
232 uint64_t requested_max_size
= 0;
234 uint64_t ll_ref
= 0; // separate ref count for ll client
235 xlist
<Dentry
*> dentries
; // if i'm linked to a dentry.
236 std::string symlink
; // symlink content, if it's a symlink
237 std::map
<std::string
,bufferptr
> xattrs
;
238 std::map
<frag_t
,int> fragmap
; // known frag -> mds mappings
239 std::map
<frag_t
, std::vector
<mds_rank_t
>> frag_repmap
; // non-auth mds mappings
241 std::list
<ceph::condition_variable
*> waitfor_caps
;
242 std::list
<ceph::condition_variable
*> waitfor_commit
;
243 std::list
<ceph::condition_variable
*> waitfor_deleg
;
245 Dentry
*get_first_parent() {
246 ceph_assert(!dentries
.empty());
247 return *dentries
.begin();
250 void make_long_path(filepath
& p
);
251 void make_short_path(filepath
& p
);
252 bool make_path_string(std::string
& s
);
253 void make_nosnap_relative_path(filepath
& p
);
255 // The ref count. 1 for each dentry, fh, inode_map,
256 // cwd that links to me.
257 void iget() { get(); }
258 void iput(int n
=1) { ceph_assert(n
>= 0); while (n
--) put(); }
263 void ll_put(uint64_t n
=1) {
264 ceph_assert(ll_ref
>= n
);
269 std::unique_ptr
<ceph_lock_state_t
> fcntl_locks
;
270 std::unique_ptr
<ceph_lock_state_t
> flock_locks
;
272 bool has_any_filelocks() {
274 (fcntl_locks
&& !fcntl_locks
->empty()) ||
275 (flock_locks
&& !flock_locks
->empty());
278 std::list
<Delegation
> delegations
;
280 xlist
<MetaRequest
*> unsafe_ops
;
284 mds_rank_t dir_pin
= MDS_RANK_NONE
;
287 Inode(Client
*c
, vinodeno_t vino
, file_layout_t
*newlayout
)
288 : client(c
), ino(vino
.ino
), snapid(vino
.snapid
), delay_cap_item(this),
289 dirty_cap_item(this), flushing_cap_item(this), snaprealm_item(this),
290 oset((void *)this, newlayout
->pool_id
, this->ino
) {}
293 vinodeno_t
vino() const { return vinodeno_t(ino
, snapid
); }
296 bool operator() (Inode
* const & left
, Inode
* const & right
) {
297 if (left
->ino
.val
< right
->ino
.val
) {
298 return (left
->snapid
.val
< right
->snapid
.val
);
304 bool check_mode(const UserPerm
& perms
, unsigned want
);
307 void get_open_ref(int mode
);
308 bool put_open_ref(int mode
);
310 void get_cap_ref(int cap
);
311 int put_cap_ref(int cap
);
313 bool cap_is_valid(const Cap
&cap
) const;
314 int caps_issued(int *implemented
= 0) const;
315 void try_touch_cap(mds_rank_t mds
);
316 bool caps_issued_mask(unsigned mask
, bool allow_impl
=false);
318 int caps_file_wanted();
320 int caps_mds_wanted();
322 const UserPerm
*get_best_perms();
324 bool have_valid_size();
327 void add_fh(Fh
*f
) {fhs
.insert(f
);}
328 void rm_fh(Fh
*f
) {fhs
.erase(f
);}
329 void set_async_err(int r
);
330 void dump(Formatter
*f
) const;
332 void break_all_delegs() { break_deleg(false); };
334 void recall_deleg(bool skip_read
);
335 bool has_recalled_deleg();
336 int set_deleg(Fh
*fh
, unsigned type
, ceph_deleg_cb_t cb
, void *priv
);
337 void unset_deleg(Fh
*fh
);
339 void mark_caps_dirty(int caps
);
340 void mark_caps_clean();
342 // how many opens for write on this Inode?
343 long open_count_for_write()
345 return (long)(open_by_mode
[CEPH_FILE_MODE_RDWR
] +
346 open_by_mode
[CEPH_FILE_MODE_WR
]);
349 // how many opens of any sort on this inode?
352 return (long) std::accumulate(open_by_mode
.begin(), open_by_mode
.end(), 0,
353 [] (int value
, const std::map
<int, int>::value_type
& p
)
354 { return value
+ p
.second
; });
357 void break_deleg(bool skip_read
);
358 bool delegations_broken(bool skip_read
);
362 std::ostream
& operator<<(std::ostream
&out
, const Inode
&in
);