]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - include/xfs_inode.h
xfs: convert to ctime accessor functions
[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 /* These match kernel side includes */
11 #include "xfs_inode_buf.h"
12 #include "xfs_inode_fork.h"
13
14 struct xfs_trans;
15 struct xfs_mount;
16 struct xfs_inode_log_item;
17 struct inode;
18
19 /*
20 * These are not actually used, they are only for userspace build
21 * compatibility in code that looks at i_state
22 */
23 #define I_DIRTY_TIME 0
24 #define I_DIRTY_TIME_EXPIRED 0
25
26 static inline bool IS_I_VERSION(const struct inode *inode) { return false; }
27 #define inode_maybe_inc_iversion(inode,flags) (0)
28
29 /*
30 * Inode interface. This fakes up a "VFS inode" to make the xfs_inode appear
31 * similar to the kernel which now is used tohold certain parts of the on-disk
32 * metadata.
33 */
34 struct inode {
35 mode_t i_mode;
36 uint32_t i_uid;
37 uint32_t i_gid;
38 uint32_t i_nlink;
39 xfs_dev_t i_rdev; /* This actually holds xfs_dev_t */
40 unsigned int i_count;
41 unsigned long i_state; /* Not actually used in userspace */
42 uint32_t i_generation;
43 uint64_t i_version;
44 struct timespec64 i_atime;
45 struct timespec64 i_mtime;
46 struct timespec64 __i_ctime; /* use inode_*_ctime accessors! */
47 spinlock_t i_lock;
48 };
49
50 static inline uint32_t i_uid_read(struct inode *inode)
51 {
52 return inode->i_uid;
53 }
54 static inline uint32_t i_gid_read(struct inode *inode)
55 {
56 return inode->i_gid;
57 }
58 static inline void i_uid_write(struct inode *inode, uint32_t uid)
59 {
60 inode->i_uid = uid;
61 }
62 static inline void i_gid_write(struct inode *inode, uint32_t gid)
63 {
64 inode->i_gid = gid;
65 }
66
67 static inline void ihold(struct inode *inode)
68 {
69 inode->i_count++;
70 }
71
72 /* Userspace does not support multigrain timestamps incore. */
73 #define I_CTIME_QUERIED (0)
74
75 static inline struct timespec64 inode_get_ctime(const struct inode *inode)
76 {
77 struct timespec64 ctime;
78
79 ctime.tv_sec = inode->__i_ctime.tv_sec;
80 ctime.tv_nsec = inode->__i_ctime.tv_nsec & ~I_CTIME_QUERIED;
81
82 return ctime;
83 }
84
85 static inline struct timespec64 inode_set_ctime_to_ts(struct inode *inode,
86 struct timespec64 ts)
87 {
88 inode->__i_ctime = ts;
89 return ts;
90 }
91
92 typedef struct xfs_inode {
93 struct cache_node i_node;
94 struct xfs_mount *i_mount; /* fs mount struct ptr */
95 xfs_ino_t i_ino; /* inode number (agno/agino) */
96 struct xfs_imap i_imap; /* location for xfs_imap() */
97 struct xfs_buftarg i_dev; /* dev for this inode */
98 struct xfs_ifork *i_cowfp; /* copy on write extents */
99 struct xfs_ifork i_df; /* data fork */
100 struct xfs_ifork i_af; /* attribute fork */
101 struct xfs_inode_log_item *i_itemp; /* logging information */
102 unsigned int i_delayed_blks; /* count of delay alloc blks */
103 xfs_fsize_t i_disk_size; /* number of bytes in file */
104 xfs_rfsblock_t i_nblocks; /* # of direct & btree blocks */
105 prid_t i_projid; /* owner's project id */
106 xfs_extlen_t i_extsize; /* basic/minimum extent size */
107 /* cowextsize is only used for v3 inodes, flushiter for v1/2 */
108 union {
109 xfs_extlen_t i_cowextsize; /* basic cow extent size */
110 uint16_t i_flushiter; /* incremented on flush */
111 };
112 uint8_t i_forkoff; /* attr fork offset >> 3 */
113 uint16_t i_diflags; /* XFS_DIFLAG_... */
114 uint64_t i_diflags2; /* XFS_DIFLAG2_... */
115 struct timespec64 i_crtime; /* time created */
116
117 /* unlinked list pointers */
118 xfs_agino_t i_next_unlinked;
119
120 xfs_extnum_t i_cnextents; /* # of extents in cow fork */
121 unsigned int i_cformat; /* format of cow fork */
122
123 xfs_fsize_t i_size; /* in-memory size */
124 struct inode i_vnode;
125 } xfs_inode_t;
126
127 static inline bool xfs_inode_has_attr_fork(struct xfs_inode *ip)
128 {
129 return ip->i_forkoff > 0;
130 }
131
132 static inline struct xfs_ifork *
133 xfs_ifork_ptr(
134 struct xfs_inode *ip,
135 int whichfork)
136 {
137 switch (whichfork) {
138 case XFS_DATA_FORK:
139 return &ip->i_df;
140 case XFS_ATTR_FORK:
141 if (!xfs_inode_has_attr_fork(ip))
142 return NULL;
143 return &ip->i_af;
144 case XFS_COW_FORK:
145 return ip->i_cowfp;
146 default:
147 ASSERT(0);
148 return NULL;
149 }
150 }
151
152 static inline unsigned int xfs_inode_fork_boff(struct xfs_inode *ip)
153 {
154 return ip->i_forkoff << 3;
155 }
156
157 static inline unsigned int xfs_inode_data_fork_size(struct xfs_inode *ip)
158 {
159 if (xfs_inode_has_attr_fork(ip))
160 return xfs_inode_fork_boff(ip);
161
162 return XFS_LITINO(ip->i_mount);
163 }
164
165 static inline unsigned int xfs_inode_attr_fork_size(struct xfs_inode *ip)
166 {
167 if (xfs_inode_has_attr_fork(ip))
168 return XFS_LITINO(ip->i_mount) - xfs_inode_fork_boff(ip);
169 return 0;
170 }
171
172 static inline unsigned int
173 xfs_inode_fork_size(
174 struct xfs_inode *ip,
175 int whichfork)
176 {
177 switch (whichfork) {
178 case XFS_DATA_FORK:
179 return xfs_inode_data_fork_size(ip);
180 case XFS_ATTR_FORK:
181 return xfs_inode_attr_fork_size(ip);
182 default:
183 return 0;
184 }
185 }
186
187 /* Convert from vfs inode to xfs inode */
188 static inline struct xfs_inode *XFS_I(struct inode *inode)
189 {
190 return container_of(inode, struct xfs_inode, i_vnode);
191 }
192
193 /* convert from xfs inode to vfs inode */
194 static inline struct inode *VFS_I(struct xfs_inode *ip)
195 {
196 return &ip->i_vnode;
197 }
198
199 /* We only have i_size in the xfs inode in userspace */
200 static inline loff_t i_size_read(struct inode *inode)
201 {
202 return XFS_I(inode)->i_size;
203 }
204
205 /*
206 * wrappers around the mode checks to simplify code
207 */
208 static inline bool XFS_ISREG(struct xfs_inode *ip)
209 {
210 return S_ISREG(VFS_I(ip)->i_mode);
211 }
212
213 static inline bool XFS_ISDIR(struct xfs_inode *ip)
214 {
215 return S_ISDIR(VFS_I(ip)->i_mode);
216 }
217
218 /*
219 * For regular files we only update the on-disk filesize when actually
220 * writing data back to disk. Until then only the copy in the VFS inode
221 * is uptodate.
222 */
223 static inline xfs_fsize_t XFS_ISIZE(struct xfs_inode *ip)
224 {
225 if (XFS_ISREG(ip))
226 return ip->i_size;
227 return ip->i_disk_size;
228 }
229 #define XFS_IS_REALTIME_INODE(ip) ((ip)->i_diflags & XFS_DIFLAG_REALTIME)
230
231 /* inode link counts */
232 static inline void set_nlink(struct inode *inode, uint32_t nlink)
233 {
234 inode->i_nlink = nlink;
235 }
236 static inline void inc_nlink(struct inode *inode)
237 {
238 inode->i_nlink++;
239 }
240
241 static inline bool xfs_is_reflink_inode(struct xfs_inode *ip)
242 {
243 return ip->i_diflags2 & XFS_DIFLAG2_REFLINK;
244 }
245
246 static inline bool xfs_inode_has_bigtime(struct xfs_inode *ip)
247 {
248 return ip->i_diflags2 & XFS_DIFLAG2_BIGTIME;
249 }
250
251 static inline bool xfs_inode_has_large_extent_counts(struct xfs_inode *ip)
252 {
253 return ip->i_diflags2 & XFS_DIFLAG2_NREXT64;
254 }
255
256 /* Always set the child's GID to this value, even if the parent is setgid. */
257 #define CRED_FORCE_GID (1U << 0)
258 struct cred {
259 uid_t cr_uid;
260 gid_t cr_gid;
261 unsigned int cr_flags;
262 };
263
264 extern int libxfs_dir_ialloc (struct xfs_trans **, struct xfs_inode *,
265 mode_t, nlink_t, xfs_dev_t, struct cred *,
266 struct fsxattr *, struct xfs_inode **);
267 extern void libxfs_trans_inode_alloc_buf (struct xfs_trans *,
268 struct xfs_buf *);
269
270 extern void libxfs_trans_ichgtime(struct xfs_trans *,
271 struct xfs_inode *, int);
272 extern int libxfs_iflush_int (struct xfs_inode *, struct xfs_buf *);
273
274 extern struct timespec64 current_time(struct inode *inode);
275
276 /* Inode Cache Interfaces */
277 extern int libxfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
278 uint, struct xfs_inode **);
279 extern void libxfs_irele(struct xfs_inode *ip);
280
281 #endif /* __XFS_INODE_H__ */