]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - include/xfs_inode.h
61d4d285a106130a3bfcb6fa6b59a1356328098f
[thirdparty/xfsprogs-dev.git] / include / xfs_inode.h
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
5 */
6
7 #ifndef __XFS_INODE_H__
8 #define __XFS_INODE_H__
9
10 /*
11 * Borrow the kernel's uid/gid types. These are used by xfs_inode_util.h, so
12 * they must come first in the header file.
13 */
14
15 typedef struct {
16 uid_t val;
17 } kuid_t;
18
19 typedef struct {
20 gid_t val;
21 } kgid_t;
22
23 static inline kuid_t make_kuid(uid_t uid)
24 {
25 kuid_t v = { .val = uid };
26 return v;
27 }
28
29 static inline kgid_t make_kgid(gid_t gid)
30 {
31 kgid_t v = { .val = gid };
32 return v;
33 }
34
35 #define KUIDT_INIT(value) (kuid_t){ value }
36 #define KGIDT_INIT(value) (kgid_t){ value }
37 #define GLOBAL_ROOT_UID KUIDT_INIT(0)
38 #define GLOBAL_ROOT_GID KGIDT_INIT(0)
39
40 /* These match kernel side includes */
41 #include "xfs_inode_buf.h"
42 #include "xfs_inode_fork.h"
43 #include "xfs_inode_util.h"
44
45 struct xfs_trans;
46 struct xfs_mount;
47 struct xfs_inode_log_item;
48 struct inode;
49
50 /*
51 * These are not actually used, they are only for userspace build
52 * compatibility in code that looks at i_state
53 */
54 #define I_DIRTY_TIME 0
55 #define I_DIRTY_TIME_EXPIRED 0
56
57 static inline bool IS_I_VERSION(const struct inode *inode) { return false; }
58 #define inode_maybe_inc_iversion(inode,flags) (0)
59
60 /*
61 * Inode interface. This fakes up a "VFS inode" to make the xfs_inode appear
62 * similar to the kernel which now is used tohold certain parts of the on-disk
63 * metadata.
64 */
65 struct inode {
66 mode_t i_mode;
67 kuid_t i_uid;
68 kgid_t i_gid;
69 uint32_t i_nlink;
70 xfs_dev_t i_rdev; /* This actually holds xfs_dev_t */
71 unsigned int i_count;
72 unsigned long i_state; /* Not actually used in userspace */
73 uint32_t i_generation;
74 uint64_t i_version;
75 struct timespec64 __i_atime;
76 struct timespec64 __i_mtime;
77 struct timespec64 __i_ctime; /* use inode_*_ctime accessors! */
78 spinlock_t i_lock;
79 };
80
81 static inline void
82 inode_set_iversion(struct inode *inode, uint64_t version)
83 {
84 inode->i_version = version;
85 }
86
87 static inline uint32_t i_uid_read(struct inode *inode)
88 {
89 return inode->i_uid.val;
90 }
91 static inline uint32_t i_gid_read(struct inode *inode)
92 {
93 return inode->i_gid.val;
94 }
95 static inline void i_uid_write(struct inode *inode, uid_t uid)
96 {
97 inode->i_uid.val = uid;
98 }
99 static inline void i_gid_write(struct inode *inode, gid_t gid)
100 {
101 inode->i_gid.val = gid;
102 }
103
104 static inline void inode_fsuid_set(struct inode *inode,
105 struct mnt_idmap *idmap)
106 {
107 inode->i_uid = make_kuid(0);
108 }
109
110 static inline void inode_fsgid_set(struct inode *inode,
111 struct mnt_idmap *idmap)
112 {
113 inode->i_gid = make_kgid(0);
114 }
115
116 static inline void ihold(struct inode *inode)
117 {
118 inode->i_count++;
119 }
120
121 static inline time64_t inode_get_atime_sec(const struct inode *inode)
122 {
123 return inode->__i_atime.tv_sec;
124 }
125
126 static inline long inode_get_atime_nsec(const struct inode *inode)
127 {
128 return inode->__i_atime.tv_nsec;
129 }
130
131 static inline struct timespec64 inode_get_atime(const struct inode *inode)
132 {
133 return inode->__i_atime;
134 }
135
136 static inline struct timespec64 inode_set_atime_to_ts(struct inode *inode,
137 struct timespec64 ts)
138 {
139 inode->__i_atime = ts;
140 return ts;
141 }
142
143 static inline struct timespec64 inode_set_atime(struct inode *inode,
144 time64_t sec, long nsec)
145 {
146 struct timespec64 ts = { .tv_sec = sec,
147 .tv_nsec = nsec };
148 return inode_set_atime_to_ts(inode, ts);
149 }
150
151 static inline time64_t inode_get_mtime_sec(const struct inode *inode)
152 {
153 return inode->__i_mtime.tv_sec;
154 }
155
156 static inline long inode_get_mtime_nsec(const struct inode *inode)
157 {
158 return inode->__i_mtime.tv_nsec;
159 }
160
161 static inline struct timespec64 inode_get_mtime(const struct inode *inode)
162 {
163 return inode->__i_mtime;
164 }
165
166 static inline struct timespec64 inode_set_mtime_to_ts(struct inode *inode,
167 struct timespec64 ts)
168 {
169 inode->__i_mtime = ts;
170 return ts;
171 }
172
173 static inline struct timespec64 inode_set_mtime(struct inode *inode,
174 time64_t sec, long nsec)
175 {
176 struct timespec64 ts = { .tv_sec = sec,
177 .tv_nsec = nsec };
178 return inode_set_mtime_to_ts(inode, ts);
179 }
180
181 static inline time64_t inode_get_ctime_sec(const struct inode *inode)
182 {
183 return inode->__i_ctime.tv_sec;
184 }
185
186 static inline long inode_get_ctime_nsec(const struct inode *inode)
187 {
188 return inode->__i_ctime.tv_nsec;
189 }
190
191 static inline struct timespec64 inode_get_ctime(const struct inode *inode)
192 {
193 return inode->__i_ctime;
194 }
195
196 static inline struct timespec64 inode_set_ctime_to_ts(struct inode *inode,
197 struct timespec64 ts)
198 {
199 inode->__i_ctime = ts;
200 return ts;
201 }
202
203 extern struct timespec64 current_time(struct inode *inode);
204
205 static inline struct timespec64 inode_set_ctime_current(struct inode *inode)
206 {
207 struct timespec64 now = current_time(inode);
208
209 inode_set_ctime_to_ts(inode, now);
210 return now;
211 }
212
213 static inline bool inode_wrong_type(const struct inode *inode, umode_t mode)
214 {
215 return (inode->i_mode ^ mode) & S_IFMT;
216 }
217
218 typedef struct xfs_inode {
219 struct cache_node i_node;
220 struct xfs_mount *i_mount; /* fs mount struct ptr */
221 xfs_ino_t i_ino; /* inode number (agno/agino) */
222 struct xfs_imap i_imap; /* location for xfs_imap() */
223 struct xfs_ifork *i_cowfp; /* copy on write extents */
224 struct xfs_ifork i_df; /* data fork */
225 struct xfs_ifork i_af; /* attribute fork */
226 struct xfs_inode_log_item *i_itemp; /* logging information */
227 uint64_t i_delayed_blks; /* count of delay alloc blks */
228 /* Space that has been set aside to root a btree in this file. */
229 uint64_t i_meta_resv_asked;
230
231 xfs_fsize_t i_disk_size; /* number of bytes in file */
232 xfs_rfsblock_t i_nblocks; /* # of direct & btree blocks */
233 prid_t i_projid; /* owner's project id */
234 xfs_extlen_t i_extsize; /* basic/minimum extent size */
235 /*
236 * i_used_blocks is used for zoned rtrmap inodes,
237 * i_cowextsize is used for other v3 inodes,
238 * i_flushiter for v1/2 inodes
239 */
240 union {
241 uint32_t i_used_blocks; /* used blocks in RTG */
242 xfs_extlen_t i_cowextsize; /* basic cow extent size */
243 uint16_t i_flushiter; /* incremented on flush */
244 };
245 uint8_t i_forkoff; /* attr fork offset >> 3 */
246 enum xfs_metafile_type i_metatype; /* XFS_METAFILE_* */
247 uint16_t i_diflags; /* XFS_DIFLAG_... */
248 uint64_t i_diflags2; /* XFS_DIFLAG2_... */
249 struct timespec64 i_crtime; /* time created */
250
251 /* unlinked list pointers */
252 xfs_agino_t i_next_unlinked;
253 xfs_agino_t i_prev_unlinked;
254
255 xfs_fsize_t i_size; /* in-memory size */
256 struct inode i_vnode;
257 } xfs_inode_t;
258
259 static inline bool xfs_inode_has_attr_fork(const struct xfs_inode *ip)
260 {
261 return ip->i_forkoff > 0;
262 }
263
264 static inline struct xfs_ifork *
265 xfs_ifork_ptr(
266 struct xfs_inode *ip,
267 int whichfork)
268 {
269 switch (whichfork) {
270 case XFS_DATA_FORK:
271 return &ip->i_df;
272 case XFS_ATTR_FORK:
273 if (!xfs_inode_has_attr_fork(ip))
274 return NULL;
275 return &ip->i_af;
276 case XFS_COW_FORK:
277 return ip->i_cowfp;
278 default:
279 ASSERT(0);
280 return NULL;
281 }
282 }
283
284 static inline unsigned int xfs_inode_fork_boff(struct xfs_inode *ip)
285 {
286 return ip->i_forkoff << 3;
287 }
288
289 static inline unsigned int xfs_inode_data_fork_size(struct xfs_inode *ip)
290 {
291 if (xfs_inode_has_attr_fork(ip))
292 return xfs_inode_fork_boff(ip);
293
294 return XFS_LITINO(ip->i_mount);
295 }
296
297 static inline unsigned int xfs_inode_attr_fork_size(struct xfs_inode *ip)
298 {
299 if (xfs_inode_has_attr_fork(ip))
300 return XFS_LITINO(ip->i_mount) - xfs_inode_fork_boff(ip);
301 return 0;
302 }
303
304 static inline unsigned int
305 xfs_inode_fork_size(
306 struct xfs_inode *ip,
307 int whichfork)
308 {
309 switch (whichfork) {
310 case XFS_DATA_FORK:
311 return xfs_inode_data_fork_size(ip);
312 case XFS_ATTR_FORK:
313 return xfs_inode_attr_fork_size(ip);
314 default:
315 return 0;
316 }
317 }
318
319 /* Convert from vfs inode to xfs inode */
320 static inline struct xfs_inode *XFS_I(struct inode *inode)
321 {
322 return container_of(inode, struct xfs_inode, i_vnode);
323 }
324
325 /* convert from xfs inode to vfs inode */
326 static inline struct inode *VFS_I(struct xfs_inode *ip)
327 {
328 return &ip->i_vnode;
329 }
330
331 /* convert from const xfs inode to const vfs inode */
332 static inline const struct inode *VFS_IC(const struct xfs_inode *ip)
333 {
334 return &ip->i_vnode;
335 }
336
337 /* We only have i_size in the xfs inode in userspace */
338 static inline loff_t i_size_read(struct inode *inode)
339 {
340 return XFS_I(inode)->i_size;
341 }
342
343 /*
344 * wrappers around the mode checks to simplify code
345 */
346 static inline bool XFS_ISREG(struct xfs_inode *ip)
347 {
348 return S_ISREG(VFS_I(ip)->i_mode);
349 }
350
351 static inline bool XFS_ISDIR(struct xfs_inode *ip)
352 {
353 return S_ISDIR(VFS_I(ip)->i_mode);
354 }
355
356 /*
357 * For regular files we only update the on-disk filesize when actually
358 * writing data back to disk. Until then only the copy in the VFS inode
359 * is uptodate.
360 */
361 static inline xfs_fsize_t XFS_ISIZE(struct xfs_inode *ip)
362 {
363 if (XFS_ISREG(ip))
364 return ip->i_size;
365 return ip->i_disk_size;
366 }
367 #define XFS_IS_REALTIME_INODE(ip) ((ip)->i_diflags & XFS_DIFLAG_REALTIME)
368
369 static inline bool xfs_is_zoned_inode(struct xfs_inode *ip)
370 {
371 return xfs_has_zoned(ip->i_mount) && XFS_IS_REALTIME_INODE(ip);
372 }
373
374 /* inode link counts */
375 static inline void set_nlink(struct inode *inode, uint32_t nlink)
376 {
377 inode->i_nlink = nlink;
378 }
379 static inline void inc_nlink(struct inode *inode)
380 {
381 inode->i_nlink++;
382 }
383 static inline void drop_nlink(struct inode *inode)
384 {
385 inode->i_nlink--;
386 }
387
388 static inline bool xfs_is_reflink_inode(const struct xfs_inode *ip)
389 {
390 return ip->i_diflags2 & XFS_DIFLAG2_REFLINK;
391 }
392
393 static inline bool xfs_inode_has_bigtime(const struct xfs_inode *ip)
394 {
395 return ip->i_diflags2 & XFS_DIFLAG2_BIGTIME;
396 }
397
398 static inline bool xfs_inode_has_large_extent_counts(const struct xfs_inode *ip)
399 {
400 return ip->i_diflags2 & XFS_DIFLAG2_NREXT64;
401 }
402
403
404 /*
405 * Decide if this file is a realtime file whose data allocation unit is larger
406 * than a single filesystem block.
407 */
408 static inline bool xfs_inode_has_bigrtalloc(const struct xfs_inode *ip)
409 {
410 return XFS_IS_REALTIME_INODE(ip) && ip->i_mount->m_sb.sb_rextsize > 1;
411 }
412
413 static inline bool xfs_is_always_cow_inode(const struct xfs_inode *ip)
414 {
415 return false;
416 }
417
418 static inline bool xfs_is_metadir_inode(const struct xfs_inode *ip)
419 {
420 return ip->i_diflags2 & XFS_DIFLAG2_METADATA;
421 }
422
423 extern void libxfs_trans_inode_alloc_buf (struct xfs_trans *,
424 struct xfs_buf *);
425
426 extern void libxfs_trans_ichgtime(struct xfs_trans *,
427 struct xfs_inode *, int);
428 extern int libxfs_iflush_int (struct xfs_inode *, struct xfs_buf *);
429
430 int libxfs_icreate(struct xfs_trans *tp, xfs_ino_t ino,
431 const struct xfs_icreate_args *args, struct xfs_inode **ipp);
432
433 /* Inode Cache Interfaces */
434 extern int libxfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
435 uint, struct xfs_inode **);
436 extern void libxfs_irele(struct xfs_inode *ip);
437
438 #define XFS_DEFAULT_COWEXTSZ_HINT 32
439
440 #define XFS_INHERIT_GID(pip) (VFS_I(pip)->i_mode & S_ISGID)
441
442 #define xfs_inherit_noatime (false)
443 #define xfs_inherit_nodump (false)
444 #define xfs_inherit_sync (false)
445 #define xfs_inherit_nosymlinks (false)
446 #define xfs_inherit_nodefrag (false)
447
448 #endif /* __XFS_INODE_H__ */