xref: /linux/fs/xfs/libxfs/xfs_inode_util.c (revision e9d2b35bb9d3ff372fad27998fc3969ced3f563d)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000-2006 Silicon Graphics, Inc.
4  * All Rights Reserved.
5  */
6 #include <linux/iversion.h>
7 #include "xfs.h"
8 #include "xfs_fs.h"
9 #include "xfs_shared.h"
10 #include "xfs_format.h"
11 #include "xfs_log_format.h"
12 #include "xfs_trans_resv.h"
13 #include "xfs_sb.h"
14 #include "xfs_mount.h"
15 #include "xfs_inode.h"
16 #include "xfs_inode_util.h"
17 #include "xfs_trans.h"
18 #include "xfs_ialloc.h"
19 #include "xfs_health.h"
20 #include "xfs_bmap.h"
21 
22 uint16_t
23 xfs_flags2diflags(
24 	struct xfs_inode	*ip,
25 	unsigned int		xflags)
26 {
27 	/* can't set PREALLOC this way, just preserve it */
28 	uint16_t		di_flags =
29 		(ip->i_diflags & XFS_DIFLAG_PREALLOC);
30 
31 	if (xflags & FS_XFLAG_IMMUTABLE)
32 		di_flags |= XFS_DIFLAG_IMMUTABLE;
33 	if (xflags & FS_XFLAG_APPEND)
34 		di_flags |= XFS_DIFLAG_APPEND;
35 	if (xflags & FS_XFLAG_SYNC)
36 		di_flags |= XFS_DIFLAG_SYNC;
37 	if (xflags & FS_XFLAG_NOATIME)
38 		di_flags |= XFS_DIFLAG_NOATIME;
39 	if (xflags & FS_XFLAG_NODUMP)
40 		di_flags |= XFS_DIFLAG_NODUMP;
41 	if (xflags & FS_XFLAG_NODEFRAG)
42 		di_flags |= XFS_DIFLAG_NODEFRAG;
43 	if (xflags & FS_XFLAG_FILESTREAM)
44 		di_flags |= XFS_DIFLAG_FILESTREAM;
45 	if (S_ISDIR(VFS_I(ip)->i_mode)) {
46 		if (xflags & FS_XFLAG_RTINHERIT)
47 			di_flags |= XFS_DIFLAG_RTINHERIT;
48 		if (xflags & FS_XFLAG_NOSYMLINKS)
49 			di_flags |= XFS_DIFLAG_NOSYMLINKS;
50 		if (xflags & FS_XFLAG_EXTSZINHERIT)
51 			di_flags |= XFS_DIFLAG_EXTSZINHERIT;
52 		if (xflags & FS_XFLAG_PROJINHERIT)
53 			di_flags |= XFS_DIFLAG_PROJINHERIT;
54 	} else if (S_ISREG(VFS_I(ip)->i_mode)) {
55 		if (xflags & FS_XFLAG_REALTIME)
56 			di_flags |= XFS_DIFLAG_REALTIME;
57 		if (xflags & FS_XFLAG_EXTSIZE)
58 			di_flags |= XFS_DIFLAG_EXTSIZE;
59 	}
60 
61 	return di_flags;
62 }
63 
64 uint64_t
65 xfs_flags2diflags2(
66 	struct xfs_inode	*ip,
67 	unsigned int		xflags)
68 {
69 	uint64_t		di_flags2 =
70 		(ip->i_diflags2 & (XFS_DIFLAG2_REFLINK |
71 				   XFS_DIFLAG2_BIGTIME |
72 				   XFS_DIFLAG2_NREXT64));
73 
74 	if (xflags & FS_XFLAG_DAX)
75 		di_flags2 |= XFS_DIFLAG2_DAX;
76 	if (xflags & FS_XFLAG_COWEXTSIZE)
77 		di_flags2 |= XFS_DIFLAG2_COWEXTSIZE;
78 
79 	return di_flags2;
80 }
81 
82 uint32_t
83 xfs_ip2xflags(
84 	struct xfs_inode	*ip)
85 {
86 	uint32_t		flags = 0;
87 
88 	if (ip->i_diflags & XFS_DIFLAG_ANY) {
89 		if (ip->i_diflags & XFS_DIFLAG_REALTIME)
90 			flags |= FS_XFLAG_REALTIME;
91 		if (ip->i_diflags & XFS_DIFLAG_PREALLOC)
92 			flags |= FS_XFLAG_PREALLOC;
93 		if (ip->i_diflags & XFS_DIFLAG_IMMUTABLE)
94 			flags |= FS_XFLAG_IMMUTABLE;
95 		if (ip->i_diflags & XFS_DIFLAG_APPEND)
96 			flags |= FS_XFLAG_APPEND;
97 		if (ip->i_diflags & XFS_DIFLAG_SYNC)
98 			flags |= FS_XFLAG_SYNC;
99 		if (ip->i_diflags & XFS_DIFLAG_NOATIME)
100 			flags |= FS_XFLAG_NOATIME;
101 		if (ip->i_diflags & XFS_DIFLAG_NODUMP)
102 			flags |= FS_XFLAG_NODUMP;
103 		if (ip->i_diflags & XFS_DIFLAG_RTINHERIT)
104 			flags |= FS_XFLAG_RTINHERIT;
105 		if (ip->i_diflags & XFS_DIFLAG_PROJINHERIT)
106 			flags |= FS_XFLAG_PROJINHERIT;
107 		if (ip->i_diflags & XFS_DIFLAG_NOSYMLINKS)
108 			flags |= FS_XFLAG_NOSYMLINKS;
109 		if (ip->i_diflags & XFS_DIFLAG_EXTSIZE)
110 			flags |= FS_XFLAG_EXTSIZE;
111 		if (ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT)
112 			flags |= FS_XFLAG_EXTSZINHERIT;
113 		if (ip->i_diflags & XFS_DIFLAG_NODEFRAG)
114 			flags |= FS_XFLAG_NODEFRAG;
115 		if (ip->i_diflags & XFS_DIFLAG_FILESTREAM)
116 			flags |= FS_XFLAG_FILESTREAM;
117 	}
118 
119 	if (ip->i_diflags2 & XFS_DIFLAG2_ANY) {
120 		if (ip->i_diflags2 & XFS_DIFLAG2_DAX)
121 			flags |= FS_XFLAG_DAX;
122 		if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE)
123 			flags |= FS_XFLAG_COWEXTSIZE;
124 	}
125 
126 	if (xfs_inode_has_attr_fork(ip))
127 		flags |= FS_XFLAG_HASATTR;
128 	return flags;
129 }
130 
131 prid_t
132 xfs_get_initial_prid(struct xfs_inode *dp)
133 {
134 	if (dp->i_diflags & XFS_DIFLAG_PROJINHERIT)
135 		return dp->i_projid;
136 
137 	/* Assign to the root project by default. */
138 	return 0;
139 }
140 
141 /* Propagate di_flags from a parent inode to a child inode. */
142 static inline void
143 xfs_inode_inherit_flags(
144 	struct xfs_inode	*ip,
145 	const struct xfs_inode	*pip)
146 {
147 	unsigned int		di_flags = 0;
148 	xfs_failaddr_t		failaddr;
149 	umode_t			mode = VFS_I(ip)->i_mode;
150 
151 	if (S_ISDIR(mode)) {
152 		if (pip->i_diflags & XFS_DIFLAG_RTINHERIT)
153 			di_flags |= XFS_DIFLAG_RTINHERIT;
154 		if (pip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) {
155 			di_flags |= XFS_DIFLAG_EXTSZINHERIT;
156 			ip->i_extsize = pip->i_extsize;
157 		}
158 		if (pip->i_diflags & XFS_DIFLAG_PROJINHERIT)
159 			di_flags |= XFS_DIFLAG_PROJINHERIT;
160 	} else if (S_ISREG(mode)) {
161 		if ((pip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
162 		    xfs_has_realtime(ip->i_mount))
163 			di_flags |= XFS_DIFLAG_REALTIME;
164 		if (pip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) {
165 			di_flags |= XFS_DIFLAG_EXTSIZE;
166 			ip->i_extsize = pip->i_extsize;
167 		}
168 	}
169 	if ((pip->i_diflags & XFS_DIFLAG_NOATIME) &&
170 	    xfs_inherit_noatime)
171 		di_flags |= XFS_DIFLAG_NOATIME;
172 	if ((pip->i_diflags & XFS_DIFLAG_NODUMP) &&
173 	    xfs_inherit_nodump)
174 		di_flags |= XFS_DIFLAG_NODUMP;
175 	if ((pip->i_diflags & XFS_DIFLAG_SYNC) &&
176 	    xfs_inherit_sync)
177 		di_flags |= XFS_DIFLAG_SYNC;
178 	if ((pip->i_diflags & XFS_DIFLAG_NOSYMLINKS) &&
179 	    xfs_inherit_nosymlinks)
180 		di_flags |= XFS_DIFLAG_NOSYMLINKS;
181 	if ((pip->i_diflags & XFS_DIFLAG_NODEFRAG) &&
182 	    xfs_inherit_nodefrag)
183 		di_flags |= XFS_DIFLAG_NODEFRAG;
184 	if (pip->i_diflags & XFS_DIFLAG_FILESTREAM)
185 		di_flags |= XFS_DIFLAG_FILESTREAM;
186 
187 	ip->i_diflags |= di_flags;
188 
189 	/*
190 	 * Inode verifiers on older kernels only check that the extent size
191 	 * hint is an integer multiple of the rt extent size on realtime files.
192 	 * They did not check the hint alignment on a directory with both
193 	 * rtinherit and extszinherit flags set.  If the misaligned hint is
194 	 * propagated from a directory into a new realtime file, new file
195 	 * allocations will fail due to math errors in the rt allocator and/or
196 	 * trip the verifiers.  Validate the hint settings in the new file so
197 	 * that we don't let broken hints propagate.
198 	 */
199 	failaddr = xfs_inode_validate_extsize(ip->i_mount, ip->i_extsize,
200 			VFS_I(ip)->i_mode, ip->i_diflags);
201 	if (failaddr) {
202 		ip->i_diflags &= ~(XFS_DIFLAG_EXTSIZE |
203 				   XFS_DIFLAG_EXTSZINHERIT);
204 		ip->i_extsize = 0;
205 	}
206 }
207 
208 /* Propagate di_flags2 from a parent inode to a child inode. */
209 static inline void
210 xfs_inode_inherit_flags2(
211 	struct xfs_inode	*ip,
212 	const struct xfs_inode	*pip)
213 {
214 	xfs_failaddr_t		failaddr;
215 
216 	if (pip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE) {
217 		ip->i_diflags2 |= XFS_DIFLAG2_COWEXTSIZE;
218 		ip->i_cowextsize = pip->i_cowextsize;
219 	}
220 	if (pip->i_diflags2 & XFS_DIFLAG2_DAX)
221 		ip->i_diflags2 |= XFS_DIFLAG2_DAX;
222 
223 	/* Don't let invalid cowextsize hints propagate. */
224 	failaddr = xfs_inode_validate_cowextsize(ip->i_mount, ip->i_cowextsize,
225 			VFS_I(ip)->i_mode, ip->i_diflags, ip->i_diflags2);
226 	if (failaddr) {
227 		ip->i_diflags2 &= ~XFS_DIFLAG2_COWEXTSIZE;
228 		ip->i_cowextsize = 0;
229 	}
230 }
231 
232 /* Initialise an inode's attributes. */
233 void
234 xfs_inode_init(
235 	struct xfs_trans	*tp,
236 	const struct xfs_icreate_args *args,
237 	struct xfs_inode	*ip)
238 {
239 	struct xfs_inode	*pip = args->pip;
240 	struct inode		*dir = pip ? VFS_I(pip) : NULL;
241 	struct xfs_mount	*mp = tp->t_mountp;
242 	struct inode		*inode = VFS_I(ip);
243 	unsigned int		flags;
244 	int			times = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG |
245 					XFS_ICHGTIME_ACCESS;
246 
247 	if (args->flags & XFS_ICREATE_TMPFILE)
248 		set_nlink(inode, 0);
249 	else if (S_ISDIR(args->mode))
250 		set_nlink(inode, 2);
251 	else
252 		set_nlink(inode, 1);
253 	inode->i_rdev = args->rdev;
254 
255 	if (!args->idmap || pip == NULL) {
256 		/* creating a tree root, sb rooted, or detached file */
257 		inode->i_uid = GLOBAL_ROOT_UID;
258 		inode->i_gid = GLOBAL_ROOT_GID;
259 		ip->i_projid = 0;
260 		inode->i_mode = args->mode;
261 	} else {
262 		/* creating a child in the directory tree */
263 		if (dir && !(dir->i_mode & S_ISGID) && xfs_has_grpid(mp)) {
264 			inode_fsuid_set(inode, args->idmap);
265 			inode->i_gid = dir->i_gid;
266 			inode->i_mode = args->mode;
267 		} else {
268 			inode_init_owner(args->idmap, inode, dir, args->mode);
269 		}
270 
271 		/*
272 		 * If the group ID of the new file does not match the effective
273 		 * group ID or one of the supplementary group IDs, the S_ISGID
274 		 * bit is cleared (and only if the irix_sgid_inherit
275 		 * compatibility variable is set).
276 		 */
277 		if (irix_sgid_inherit && (inode->i_mode & S_ISGID) &&
278 		    !vfsgid_in_group_p(i_gid_into_vfsgid(args->idmap, inode)))
279 			inode->i_mode &= ~S_ISGID;
280 
281 		ip->i_projid = pip ? xfs_get_initial_prid(pip) : 0;
282 	}
283 
284 	ip->i_disk_size = 0;
285 	ip->i_df.if_nextents = 0;
286 	ASSERT(ip->i_nblocks == 0);
287 
288 	ip->i_extsize = 0;
289 	ip->i_diflags = 0;
290 
291 	if (xfs_has_v3inodes(mp)) {
292 		inode_set_iversion(inode, 1);
293 		ip->i_cowextsize = 0;
294 		times |= XFS_ICHGTIME_CREATE;
295 	}
296 
297 	xfs_trans_ichgtime(tp, ip, times);
298 
299 	flags = XFS_ILOG_CORE;
300 	switch (args->mode & S_IFMT) {
301 	case S_IFIFO:
302 	case S_IFCHR:
303 	case S_IFBLK:
304 	case S_IFSOCK:
305 		ip->i_df.if_format = XFS_DINODE_FMT_DEV;
306 		flags |= XFS_ILOG_DEV;
307 		break;
308 	case S_IFREG:
309 	case S_IFDIR:
310 		if (pip && (pip->i_diflags & XFS_DIFLAG_ANY))
311 			xfs_inode_inherit_flags(ip, pip);
312 		if (pip && (pip->i_diflags2 & XFS_DIFLAG2_ANY))
313 			xfs_inode_inherit_flags2(ip, pip);
314 		fallthrough;
315 	case S_IFLNK:
316 		ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
317 		ip->i_df.if_bytes = 0;
318 		ip->i_df.if_data = NULL;
319 		break;
320 	default:
321 		ASSERT(0);
322 	}
323 
324 	/*
325 	 * If we need to create attributes immediately after allocating the
326 	 * inode, initialise an empty attribute fork right now. We use the
327 	 * default fork offset for attributes here as we don't know exactly what
328 	 * size or how many attributes we might be adding. We can do this
329 	 * safely here because we know the data fork is completely empty and
330 	 * this saves us from needing to run a separate transaction to set the
331 	 * fork offset in the immediate future.
332 	 */
333 	if (args->flags & XFS_ICREATE_INIT_XATTRS) {
334 		ip->i_forkoff = xfs_default_attroffset(ip) >> 3;
335 		xfs_ifork_init_attr(ip, XFS_DINODE_FMT_EXTENTS, 0);
336 
337 		if (!xfs_has_attr(mp)) {
338 			spin_lock(&mp->m_sb_lock);
339 			xfs_add_attr(mp);
340 			spin_unlock(&mp->m_sb_lock);
341 			xfs_log_sb(tp);
342 		}
343 	}
344 
345 	xfs_trans_log_inode(tp, ip, flags);
346 }
347