]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - include/xfs_inode.h
xfsprogs: Release v6.15.0
[thirdparty/xfsprogs-dev.git] / include / xfs_inode.h
CommitLineData
959ef981 1// SPDX-License-Identifier: GPL-2.0
b626fb59
DC
2/*
3 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
b626fb59
DC
5 */
6
7#ifndef __XFS_INODE_H__
8#define __XFS_INODE_H__
9
04fd1569
DW
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
15typedef struct {
16 uid_t val;
17} kuid_t;
18
19typedef struct {
20 gid_t val;
21} kgid_t;
22
23static inline kuid_t make_kuid(uid_t uid)
24{
25 kuid_t v = { .val = uid };
26 return v;
27}
28
29static 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
b626fb59 40/* These match kernel side includes */
6b803e5a
CH
41#include "xfs_inode_buf.h"
42#include "xfs_inode_fork.h"
fadb819b 43#include "xfs_inode_util.h"
b626fb59
DC
44
45struct xfs_trans;
46struct xfs_mount;
47struct xfs_inode_log_item;
a565e345 48struct inode;
b626fb59 49
b192e77c
ES
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
a565e345 57static inline bool IS_I_VERSION(const struct inode *inode) { return false; }
b192e77c
ES
58#define inode_maybe_inc_iversion(inode,flags) (0)
59
b626fb59 60/*
1bc6cbe3
DC
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.
b626fb59 64 */
1bc6cbe3 65struct inode {
ec24f6fa 66 mode_t i_mode;
04fd1569
DW
67 kuid_t i_uid;
68 kgid_t i_gid;
ec24f6fa
DW
69 uint32_t i_nlink;
70 xfs_dev_t i_rdev; /* This actually holds xfs_dev_t */
50edfee5 71 unsigned int i_count;
ec24f6fa
DW
72 unsigned long i_state; /* Not actually used in userspace */
73 uint32_t i_generation;
74 uint64_t i_version;
bb16db6a
JL
75 struct timespec64 __i_atime;
76 struct timespec64 __i_mtime;
6cfd0b48 77 struct timespec64 __i_ctime; /* use inode_*_ctime accessors! */
686bddf9 78 spinlock_t i_lock;
1bc6cbe3
DC
79};
80
fdf7f987
DW
81static inline void
82inode_set_iversion(struct inode *inode, uint64_t version)
83{
84 inode->i_version = version;
85}
86
100eb9e9
CH
87static inline uint32_t i_uid_read(struct inode *inode)
88{
04fd1569 89 return inode->i_uid.val;
100eb9e9
CH
90}
91static inline uint32_t i_gid_read(struct inode *inode)
92{
04fd1569 93 return inode->i_gid.val;
100eb9e9 94}
04fd1569 95static inline void i_uid_write(struct inode *inode, uid_t uid)
100eb9e9 96{
04fd1569 97 inode->i_uid.val = uid;
100eb9e9 98}
04fd1569 99static inline void i_gid_write(struct inode *inode, gid_t gid)
100eb9e9 100{
04fd1569 101 inode->i_gid.val = gid;
100eb9e9
CH
102}
103
fdf7f987
DW
104static inline void inode_fsuid_set(struct inode *inode,
105 struct mnt_idmap *idmap)
106{
107 inode->i_uid = make_kuid(0);
108}
109
110static inline void inode_fsgid_set(struct inode *inode,
111 struct mnt_idmap *idmap)
112{
113 inode->i_gid = make_kgid(0);
114}
115
50edfee5
DW
116static inline void ihold(struct inode *inode)
117{
118 inode->i_count++;
119}
120
bb16db6a
JL
121static inline time64_t inode_get_atime_sec(const struct inode *inode)
122{
123 return inode->__i_atime.tv_sec;
124}
125
126static inline long inode_get_atime_nsec(const struct inode *inode)
127{
128 return inode->__i_atime.tv_nsec;
129}
130
131static inline struct timespec64 inode_get_atime(const struct inode *inode)
132{
133 return inode->__i_atime;
134}
135
136static 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
143static 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
151static inline time64_t inode_get_mtime_sec(const struct inode *inode)
152{
153 return inode->__i_mtime.tv_sec;
154}
155
156static inline long inode_get_mtime_nsec(const struct inode *inode)
157{
158 return inode->__i_mtime.tv_nsec;
159}
160
161static inline struct timespec64 inode_get_mtime(const struct inode *inode)
162{
163 return inode->__i_mtime;
164}
165
166static 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
173static 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
181static inline time64_t inode_get_ctime_sec(const struct inode *inode)
182{
183 return inode->__i_ctime.tv_sec;
184}
185
186static inline long inode_get_ctime_nsec(const struct inode *inode)
187{
188 return inode->__i_ctime.tv_nsec;
189}
190
6cfd0b48
JL
191static inline struct timespec64 inode_get_ctime(const struct inode *inode)
192{
faea09b8 193 return inode->__i_ctime;
6cfd0b48
JL
194}
195
196static 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
f99988c2
JL
203extern struct timespec64 current_time(struct inode *inode);
204
205static 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
3c2daed2
DW
213static inline bool inode_wrong_type(const struct inode *inode, umode_t mode)
214{
215 return (inode->i_mode ^ mode) & S_IFMT;
216}
217
b626fb59
DC
218typedef 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() */
cb8a004a 223 struct xfs_ifork *i_cowfp; /* copy on write extents */
b626fb59 224 struct xfs_ifork i_df; /* data fork */
7ff5f1ed 225 struct xfs_ifork i_af; /* attribute fork */
b626fb59 226 struct xfs_inode_log_item *i_itemp; /* logging information */
2711590c
DW
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
509dcb4b 231 xfs_fsize_t i_disk_size; /* number of bytes in file */
aa00f286 232 xfs_rfsblock_t i_nblocks; /* # of direct & btree blocks */
0ca7fa97 233 prid_t i_projid; /* owner's project id */
fd2f92c8 234 xfs_extlen_t i_extsize; /* basic/minimum extent size */
611ad47e
CH
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 */
dc1d7a09 240 union {
611ad47e 241 uint32_t i_used_blocks; /* used blocks in RTG */
dc1d7a09
CH
242 xfs_extlen_t i_cowextsize; /* basic cow extent size */
243 uint16_t i_flushiter; /* incremented on flush */
244 };
073f2424 245 uint8_t i_forkoff; /* attr fork offset >> 3 */
65713c2c 246 enum xfs_metafile_type i_metatype; /* XFS_METAFILE_* */
4350eee7 247 uint16_t i_diflags; /* XFS_DIFLAG_... */
defd6446 248 uint64_t i_diflags2; /* XFS_DIFLAG2_... */
a1f6b388 249 struct timespec64 i_crtime; /* time created */
cb8a004a 250
69535dad
DC
251 /* unlinked list pointers */
252 xfs_agino_t i_next_unlinked;
0f1f6742 253 xfs_agino_t i_prev_unlinked;
69535dad 254
b626fb59 255 xfs_fsize_t i_size; /* in-memory size */
1bc6cbe3 256 struct inode i_vnode;
b626fb59
DC
257} xfs_inode_t;
258
b99309ee 259static inline bool xfs_inode_has_attr_fork(const struct xfs_inode *ip)
4f841585
DW
260{
261 return ip->i_forkoff > 0;
262}
263
722e81c1
DW
264static inline struct xfs_ifork *
265xfs_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:
4f841585 273 if (!xfs_inode_has_attr_fork(ip))
7ff5f1ed
DW
274 return NULL;
275 return &ip->i_af;
722e81c1
DW
276 case XFS_COW_FORK:
277 return ip->i_cowfp;
278 default:
279 ASSERT(0);
280 return NULL;
281 }
282}
283
eae3e30d
DW
284static inline unsigned int xfs_inode_fork_boff(struct xfs_inode *ip)
285{
286 return ip->i_forkoff << 3;
287}
288
289static 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
297static 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
304static inline unsigned int
305xfs_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
ca75eb20
BF
319/* Convert from vfs inode to xfs inode */
320static 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 */
1bc6cbe3
DC
326static inline struct inode *VFS_I(struct xfs_inode *ip)
327{
328 return &ip->i_vnode;
329}
330
4bba3a07
AH
331/* convert from const xfs inode to const vfs inode */
332static inline const struct inode *VFS_IC(const struct xfs_inode *ip)
333{
334 return &ip->i_vnode;
335}
336
ca75eb20
BF
337/* We only have i_size in the xfs inode in userspace */
338static inline loff_t i_size_read(struct inode *inode)
339{
340 return XFS_I(inode)->i_size;
341}
342
e37bf53c
DC
343/*
344 * wrappers around the mode checks to simplify code
345 */
346static inline bool XFS_ISREG(struct xfs_inode *ip)
347{
348 return S_ISREG(VFS_I(ip)->i_mode);
349}
350
351static inline bool XFS_ISDIR(struct xfs_inode *ip)
352{
353 return S_ISDIR(VFS_I(ip)->i_mode);
354}
355
b626fb59
DC
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 */
361static inline xfs_fsize_t XFS_ISIZE(struct xfs_inode *ip)
362{
e37bf53c 363 if (XFS_ISREG(ip))
b626fb59 364 return ip->i_size;
509dcb4b 365 return ip->i_disk_size;
b626fb59 366}
4350eee7 367#define XFS_IS_REALTIME_INODE(ip) ((ip)->i_diflags & XFS_DIFLAG_REALTIME)
b626fb59 368
611ad47e
CH
369static 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
bcbe04c1
DC
374/* inode link counts */
375static inline void set_nlink(struct inode *inode, uint32_t nlink)
376{
377 inode->i_nlink = nlink;
378}
379static inline void inc_nlink(struct inode *inode)
380{
381 inode->i_nlink++;
382}
7b3f2025
DW
383static inline void drop_nlink(struct inode *inode)
384{
385 inode->i_nlink--;
386}
bcbe04c1 387
b99309ee 388static inline bool xfs_is_reflink_inode(const struct xfs_inode *ip)
cfe32f0d 389{
defd6446 390 return ip->i_diflags2 & XFS_DIFLAG2_REFLINK;
cfe32f0d
DW
391}
392
b99309ee 393static inline bool xfs_inode_has_bigtime(const struct xfs_inode *ip)
e7e3beb9 394{
defd6446 395 return ip->i_diflags2 & XFS_DIFLAG2_BIGTIME;
e7e3beb9
DW
396}
397
b99309ee 398static inline bool xfs_inode_has_large_extent_counts(const struct xfs_inode *ip)
5a8b4d6a
CB
399{
400 return ip->i_diflags2 & XFS_DIFLAG2_NREXT64;
401}
402
378e94fc
DW
403
404/*
405 * Decide if this file is a realtime file whose data allocation unit is larger
406 * than a single filesystem block.
407 */
b99309ee 408static inline bool xfs_inode_has_bigrtalloc(const struct xfs_inode *ip)
378e94fc
DW
409{
410 return XFS_IS_REALTIME_INODE(ip) && ip->i_mount->m_sb.sb_rextsize > 1;
411}
412
b99309ee 413static inline bool xfs_is_always_cow_inode(const struct xfs_inode *ip)
8a8799bb
DW
414{
415 return false;
416}
417
65713c2c
DW
418static inline bool xfs_is_metadir_inode(const struct xfs_inode *ip)
419{
420 return ip->i_diflags2 & XFS_DIFLAG2_METADATA;
421}
422
b626fb59
DC
423extern void libxfs_trans_inode_alloc_buf (struct xfs_trans *,
424 struct xfs_buf *);
425
426extern void libxfs_trans_ichgtime(struct xfs_trans *,
427 struct xfs_inode *, int);
428extern int libxfs_iflush_int (struct xfs_inode *, struct xfs_buf *);
429
b47055a4
DW
430int libxfs_icreate(struct xfs_trans *tp, xfs_ino_t ino,
431 const struct xfs_icreate_args *args, struct xfs_inode **ipp);
432
b626fb59
DC
433/* Inode Cache Interfaces */
434extern int libxfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
1fecabf9 435 uint, struct xfs_inode **);
31845e4c 436extern void libxfs_irele(struct xfs_inode *ip);
b626fb59 437
8a8799bb
DW
438#define XFS_DEFAULT_COWEXTSZ_HINT 32
439
fdf7f987
DW
440#define XFS_INHERIT_GID(pip) (VFS_I(pip)->i_mode & S_ISGID)
441
fa2f7708
DW
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
b626fb59 448#endif /* __XFS_INODE_H__ */