Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * Copyright (c) 2000-2006 Silicon Graphics, Inc.
4 : * All Rights Reserved.
5 : */
6 : #include "xfs.h"
7 : #include "xfs_fs.h"
8 : #include "xfs_shared.h"
9 : #include "xfs_format.h"
10 : #include "xfs_log_format.h"
11 : #include "xfs_trans_resv.h"
12 : #include "xfs_mount.h"
13 : #include "xfs_ag.h"
14 : #include "xfs_inode.h"
15 : #include "xfs_errortag.h"
16 : #include "xfs_error.h"
17 : #include "xfs_icache.h"
18 : #include "xfs_trans.h"
19 : #include "xfs_ialloc.h"
20 : #include "xfs_dir2.h"
21 : #include "xfs_health.h"
22 :
23 : #include <linux/iversion.h>
24 :
25 : /*
26 : * If we are doing readahead on an inode buffer, we might be in log recovery
27 : * reading an inode allocation buffer that hasn't yet been replayed, and hence
28 : * has not had the inode cores stamped into it. Hence for readahead, the buffer
29 : * may be potentially invalid.
30 : *
31 : * If the readahead buffer is invalid, we need to mark it with an error and
32 : * clear the DONE status of the buffer so that a followup read will re-read it
33 : * from disk. We don't report the error otherwise to avoid warnings during log
34 : * recovery and we don't get unnecessary panics on debug kernels. We use EIO here
35 : * because all we want to do is say readahead failed; there is no-one to report
36 : * the error to, so this will distinguish it from a non-ra verifier failure.
37 : * Changes to this readahead error behaviour also need to be reflected in
38 : * xfs_dquot_buf_readahead_verify().
39 : */
40 : static void
41 70739166 : xfs_inode_buf_verify(
42 : struct xfs_buf *bp,
43 : bool readahead)
44 : {
45 70739166 : struct xfs_mount *mp = bp->b_mount;
46 70739166 : int i;
47 70739166 : int ni;
48 :
49 : /*
50 : * Validate the magic number and version of every inode in the buffer
51 : */
52 70739166 : ni = XFS_BB_TO_FSB(mp, bp->b_length) * mp->m_sb.sb_inopblock;
53 2334235949 : for (i = 0; i < ni; i++) {
54 2263501944 : struct xfs_dinode *dip;
55 2263501944 : xfs_agino_t unlinked_ino;
56 2263501944 : int di_ok;
57 :
58 2263501944 : dip = xfs_buf_offset(bp, (i << mp->m_sb.sb_inodelog));
59 2263501977 : unlinked_ino = be32_to_cpu(dip->di_next_unlinked);
60 4527000300 : di_ok = xfs_verify_magic16(bp, dip->di_magic) &&
61 2263501944 : xfs_dinode_good_version(mp, dip->di_version) &&
62 2263498158 : xfs_verify_agino_or_null(bp->b_pag, unlinked_ino);
63 2263501944 : if (unlikely(XFS_TEST_ERROR(!di_ok, mp,
64 : XFS_ERRTAG_ITOBP_INOTOBP))) {
65 5161 : if (readahead) {
66 3177 : bp->b_flags &= ~XBF_DONE;
67 3177 : xfs_buf_ioerror(bp, -EIO);
68 3177 : return;
69 : }
70 :
71 : #ifdef DEBUG
72 1984 : xfs_alert(mp,
73 : "bad inode magic/vsn daddr %lld #%d (magic=%x)",
74 : (unsigned long long)xfs_buf_daddr(bp), i,
75 : be16_to_cpu(dip->di_magic));
76 : #endif
77 1984 : xfs_buf_verifier_error(bp, -EFSCORRUPTED,
78 : __func__, dip, sizeof(*dip),
79 : NULL);
80 1984 : return;
81 : }
82 : }
83 : }
84 :
85 :
86 : static void
87 11330981 : xfs_inode_buf_read_verify(
88 : struct xfs_buf *bp)
89 : {
90 11330981 : xfs_inode_buf_verify(bp, false);
91 11330981 : }
92 :
93 : static void
94 279217 : xfs_inode_buf_readahead_verify(
95 : struct xfs_buf *bp)
96 : {
97 279217 : xfs_inode_buf_verify(bp, true);
98 279217 : }
99 :
100 : static void
101 59128970 : xfs_inode_buf_write_verify(
102 : struct xfs_buf *bp)
103 : {
104 59128970 : xfs_inode_buf_verify(bp, false);
105 59128970 : }
106 :
107 : const struct xfs_buf_ops xfs_inode_buf_ops = {
108 : .name = "xfs_inode",
109 : .magic16 = { cpu_to_be16(XFS_DINODE_MAGIC),
110 : cpu_to_be16(XFS_DINODE_MAGIC) },
111 : .verify_read = xfs_inode_buf_read_verify,
112 : .verify_write = xfs_inode_buf_write_verify,
113 : };
114 :
115 : const struct xfs_buf_ops xfs_inode_buf_ra_ops = {
116 : .name = "xfs_inode_ra",
117 : .magic16 = { cpu_to_be16(XFS_DINODE_MAGIC),
118 : cpu_to_be16(XFS_DINODE_MAGIC) },
119 : .verify_read = xfs_inode_buf_readahead_verify,
120 : .verify_write = xfs_inode_buf_write_verify,
121 : };
122 :
123 :
124 : /*
125 : * This routine is called to map an inode to the buffer containing the on-disk
126 : * version of the inode. It returns a pointer to the buffer containing the
127 : * on-disk inode in the bpp parameter.
128 : */
129 : int
130 912950802 : xfs_imap_to_bp(
131 : struct xfs_mount *mp,
132 : struct xfs_trans *tp,
133 : struct xfs_imap *imap,
134 : struct xfs_buf **bpp)
135 : {
136 912950802 : int error;
137 :
138 912950802 : error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno,
139 912950802 : imap->im_len, XBF_UNMAPPED, bpp, &xfs_inode_buf_ops);
140 913150823 : if (xfs_metadata_is_sick(error))
141 1930 : xfs_agno_mark_sick(mp, xfs_daddr_to_agno(mp, imap->im_blkno),
142 : XFS_SICK_AG_INODES);
143 913150823 : return error;
144 : }
145 :
146 : static inline struct timespec64 xfs_inode_decode_bigtime(uint64_t ts)
147 : {
148 2048309474 : struct timespec64 tv;
149 2048309474 : uint32_t n;
150 :
151 2048309474 : tv.tv_sec = xfs_bigtime_to_unix(div_u64_rem(ts, NSEC_PER_SEC, &n));
152 2048309474 : tv.tv_nsec = n;
153 :
154 2048309474 : return tv;
155 : }
156 :
157 : /* Convert an ondisk timestamp to an incore timestamp. */
158 : struct timespec64
159 2048895318 : xfs_inode_from_disk_ts(
160 : struct xfs_dinode *dip,
161 : const xfs_timestamp_t ts)
162 : {
163 2048895318 : struct timespec64 tv;
164 2048895318 : struct xfs_legacy_timestamp *lts;
165 :
166 4097790636 : if (xfs_dinode_has_bigtime(dip))
167 2048309474 : return xfs_inode_decode_bigtime(be64_to_cpu(ts));
168 :
169 585844 : lts = (struct xfs_legacy_timestamp *)&ts;
170 585844 : tv.tv_sec = (int)be32_to_cpu(lts->t_sec);
171 585844 : tv.tv_nsec = (int)be32_to_cpu(lts->t_nsec);
172 :
173 585844 : return tv;
174 : }
175 :
176 : int
177 376224831 : xfs_inode_from_disk(
178 : struct xfs_inode *ip,
179 : struct xfs_dinode *from)
180 : {
181 376224831 : struct inode *inode = VFS_I(ip);
182 376224831 : int error;
183 376224831 : xfs_failaddr_t fa;
184 :
185 376224831 : ASSERT(ip->i_cowfp == NULL);
186 :
187 376224831 : fa = xfs_dinode_verify(ip->i_mount, ip->i_ino, from);
188 376204776 : if (fa) {
189 1082 : xfs_inode_verifier_error(ip, -EFSCORRUPTED, "dinode", from,
190 : sizeof(*from), fa);
191 1082 : return -EFSCORRUPTED;
192 : }
193 :
194 : /*
195 : * First get the permanent information that is needed to allocate an
196 : * inode. If the inode is unused, mode is zero and we shouldn't mess
197 : * with the uninitialized part of it.
198 : */
199 376203694 : if (!xfs_has_v3inodes(ip->i_mount))
200 2262 : ip->i_flushiter = be16_to_cpu(from->di_flushiter);
201 376203694 : inode->i_generation = be32_to_cpu(from->di_gen);
202 376203694 : inode->i_mode = be16_to_cpu(from->di_mode);
203 376203694 : if (!inode->i_mode)
204 : return 0;
205 :
206 : /*
207 : * Convert v1 inodes immediately to v2 inode format as this is the
208 : * minimum inode version format we support in the rest of the code.
209 : * They will also be unconditionally written back to disk as v2 inodes.
210 : */
211 376202270 : if (unlikely(from->di_version == 1)) {
212 0 : set_nlink(inode, be16_to_cpu(from->di_onlink));
213 0 : ip->i_projid = 0;
214 : } else {
215 376202270 : set_nlink(inode, be32_to_cpu(from->di_nlink));
216 376184492 : ip->i_projid = (prid_t)be16_to_cpu(from->di_projid_hi) << 16 |
217 376184492 : be16_to_cpu(from->di_projid_lo);
218 : }
219 :
220 376184492 : i_uid_write(inode, be32_to_cpu(from->di_uid));
221 376199798 : i_gid_write(inode, be32_to_cpu(from->di_gid));
222 :
223 : /*
224 : * Time is signed, so need to convert to signed 32 bit before
225 : * storing in inode timestamp which may be 64 bit. Otherwise
226 : * a time before epoch is converted to a time long after epoch
227 : * on 64 bit systems.
228 : */
229 376225331 : inode->i_atime = xfs_inode_from_disk_ts(from, from->di_atime);
230 376225331 : inode->i_mtime = xfs_inode_from_disk_ts(from, from->di_mtime);
231 376225331 : inode->i_ctime = xfs_inode_from_disk_ts(from, from->di_ctime);
232 :
233 376225331 : ip->i_disk_size = be64_to_cpu(from->di_size);
234 376225331 : ip->i_nblocks = be64_to_cpu(from->di_nblocks);
235 376225331 : ip->i_extsize = be32_to_cpu(from->di_extsize);
236 376225331 : ip->i_forkoff = from->di_forkoff;
237 376225331 : ip->i_diflags = be16_to_cpu(from->di_flags);
238 376225331 : ip->i_next_unlinked = be32_to_cpu(from->di_next_unlinked);
239 :
240 376225331 : if (from->di_dmevmask || from->di_dmstate)
241 5 : xfs_iflags_set(ip, XFS_IPRESERVE_DM_FIELDS);
242 :
243 376228026 : if (xfs_has_v3inodes(ip->i_mount)) {
244 376227188 : inode_set_iversion_queried(inode,
245 376227188 : be64_to_cpu(from->di_changecount));
246 376227188 : ip->i_crtime = xfs_inode_from_disk_ts(from, from->di_crtime);
247 376227188 : ip->i_diflags2 = be64_to_cpu(from->di_flags2);
248 376227188 : ip->i_cowextsize = be32_to_cpu(from->di_cowextsize);
249 : }
250 :
251 376228026 : error = xfs_iformat_data_fork(ip, from);
252 376230365 : if (error)
253 : return error;
254 376230343 : if (from->di_forkoff) {
255 373449767 : error = xfs_iformat_attr_fork(ip, from);
256 373434987 : if (error)
257 0 : goto out_destroy_data_fork;
258 : }
259 376215563 : if (xfs_is_reflink_inode(ip))
260 90879702 : xfs_ifork_init_cow(ip);
261 : return 0;
262 :
263 : out_destroy_data_fork:
264 0 : xfs_idestroy_fork(&ip->i_df);
265 0 : return error;
266 : }
267 :
268 : /* Convert an incore timestamp to an ondisk timestamp. */
269 : static inline xfs_timestamp_t
270 1997575862 : xfs_inode_to_disk_ts(
271 : struct xfs_inode *ip,
272 : const struct timespec64 tv)
273 : {
274 1997575862 : struct xfs_legacy_timestamp *lts;
275 1997575862 : xfs_timestamp_t ts;
276 :
277 1997575862 : if (xfs_inode_has_bigtime(ip))
278 1997024251 : return cpu_to_be64(xfs_inode_encode_bigtime(tv));
279 :
280 551611 : lts = (struct xfs_legacy_timestamp *)&ts;
281 551611 : lts->t_sec = cpu_to_be32(tv.tv_sec);
282 551611 : lts->t_nsec = cpu_to_be32(tv.tv_nsec);
283 :
284 551611 : return ts;
285 : }
286 :
287 : static inline void
288 499671055 : xfs_inode_to_disk_iext_counters(
289 : struct xfs_inode *ip,
290 : struct xfs_dinode *to)
291 : {
292 499671055 : if (xfs_inode_has_large_extent_counts(ip)) {
293 499669373 : to->di_big_nextents = cpu_to_be64(xfs_ifork_nextents(&ip->i_df));
294 499669373 : to->di_big_anextents = cpu_to_be32(xfs_ifork_nextents(&ip->i_af));
295 : /*
296 : * We might be upgrading the inode to use larger extent counters
297 : * than was previously used. Hence zero the unused field.
298 : */
299 499669373 : to->di_nrext64_pad = cpu_to_be16(0);
300 : } else {
301 1682 : to->di_nextents = cpu_to_be32(xfs_ifork_nextents(&ip->i_df));
302 3364 : to->di_anextents = cpu_to_be16(xfs_ifork_nextents(&ip->i_af));
303 : }
304 499671055 : }
305 :
306 : void
307 500055463 : xfs_inode_to_disk(
308 : struct xfs_inode *ip,
309 : struct xfs_dinode *to,
310 : xfs_lsn_t lsn)
311 : {
312 500055463 : struct inode *inode = VFS_I(ip);
313 :
314 500055463 : to->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
315 500055463 : to->di_onlink = 0;
316 :
317 500055463 : to->di_format = xfs_ifork_format(&ip->i_df);
318 500055463 : to->di_uid = cpu_to_be32(i_uid_read(inode));
319 499628405 : to->di_gid = cpu_to_be32(i_gid_read(inode));
320 500085483 : to->di_projid_lo = cpu_to_be16(ip->i_projid & 0xffff);
321 500085483 : to->di_projid_hi = cpu_to_be16(ip->i_projid >> 16);
322 :
323 500085483 : to->di_atime = xfs_inode_to_disk_ts(ip, inode->i_atime);
324 500085483 : to->di_mtime = xfs_inode_to_disk_ts(ip, inode->i_mtime);
325 500085483 : to->di_ctime = xfs_inode_to_disk_ts(ip, inode->i_ctime);
326 500085483 : to->di_nlink = cpu_to_be32(inode->i_nlink);
327 500085483 : to->di_gen = cpu_to_be32(inode->i_generation);
328 500085483 : to->di_mode = cpu_to_be16(inode->i_mode);
329 :
330 500085483 : to->di_size = cpu_to_be64(ip->i_disk_size);
331 500085483 : to->di_nblocks = cpu_to_be64(ip->i_nblocks);
332 500085483 : to->di_extsize = cpu_to_be32(ip->i_extsize);
333 500085483 : to->di_forkoff = ip->i_forkoff;
334 500085483 : to->di_aformat = xfs_ifork_format(&ip->i_af);
335 500085483 : to->di_flags = cpu_to_be16(ip->i_diflags);
336 :
337 500085483 : if (xfs_has_v3inodes(ip->i_mount)) {
338 500084070 : to->di_version = 3;
339 500084070 : to->di_changecount = cpu_to_be64(inode_peek_iversion(inode));
340 500084070 : to->di_crtime = xfs_inode_to_disk_ts(ip, ip->i_crtime);
341 500084070 : to->di_flags2 = cpu_to_be64(ip->i_diflags2);
342 500084070 : to->di_cowextsize = cpu_to_be32(ip->i_cowextsize);
343 500084070 : to->di_ino = cpu_to_be64(ip->i_ino);
344 500084070 : to->di_lsn = cpu_to_be64(lsn);
345 500084070 : memset(to->di_pad2, 0, sizeof(to->di_pad2));
346 500084070 : uuid_copy(&to->di_uuid, &ip->i_mount->m_sb.sb_meta_uuid);
347 499514156 : to->di_v3_pad = 0;
348 : } else {
349 1413 : to->di_version = 2;
350 1413 : to->di_flushiter = cpu_to_be16(ip->i_flushiter);
351 2826 : memset(to->di_v2_pad, 0, sizeof(to->di_v2_pad));
352 : }
353 :
354 499515569 : xfs_inode_to_disk_iext_counters(ip, to);
355 499632393 : }
356 :
357 : static xfs_failaddr_t
358 624636538 : xfs_dinode_verify_fork(
359 : struct xfs_dinode *dip,
360 : struct xfs_mount *mp,
361 : int whichfork)
362 : {
363 624636538 : xfs_extnum_t di_nextents;
364 624636538 : xfs_extnum_t max_extents;
365 624636538 : mode_t mode = be16_to_cpu(dip->di_mode);
366 624637387 : uint32_t fork_size = XFS_DFORK_SIZE(dip, mp, whichfork);
367 624636538 : uint32_t fork_format = XFS_DFORK_FORMAT(dip, whichfork);
368 :
369 624636538 : di_nextents = xfs_dfork_nextents(dip, whichfork);
370 :
371 : /*
372 : * For fork types that can contain local data, check that the fork
373 : * format matches the size of local data contained within the fork.
374 : *
375 : * For all types, check that when the size says the should be in extent
376 : * or btree format, the inode isn't claiming it is in local format.
377 : */
378 624633763 : if (whichfork == XFS_DATA_FORK) {
379 251215718 : if (S_ISDIR(mode) || S_ISLNK(mode)) {
380 80257718 : if (be64_to_cpu(dip->di_size) <= fork_size &&
381 : fork_format != XFS_DINODE_FMT_LOCAL)
382 33 : return __this_address;
383 : }
384 :
385 251215685 : if (be64_to_cpu(dip->di_size) > fork_size &&
386 : fork_format == XFS_DINODE_FMT_LOCAL)
387 0 : return __this_address;
388 : }
389 :
390 624633730 : switch (fork_format) {
391 433789337 : case XFS_DINODE_FMT_LOCAL:
392 : /*
393 : * No local regular files yet.
394 : */
395 433789337 : if (S_ISREG(mode) && whichfork == XFS_DATA_FORK)
396 22 : return __this_address;
397 433789315 : if (di_nextents)
398 0 : return __this_address;
399 : break;
400 177659922 : case XFS_DINODE_FMT_EXTENTS:
401 177660513 : if (di_nextents > XFS_DFORK_MAXEXT(dip, mp, whichfork))
402 0 : return __this_address;
403 : break;
404 : case XFS_DINODE_FMT_BTREE:
405 25979430 : max_extents = xfs_iext_max_nextents(
406 : xfs_dinode_has_large_extent_counts(dip),
407 : whichfork);
408 12989712 : if (di_nextents > max_extents)
409 0 : return __this_address;
410 : break;
411 97411 : case XFS_DINODE_FMT_RMAP:
412 97411 : if (!xfs_has_rtrmapbt(mp))
413 0 : return __this_address;
414 97411 : if (!(dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_METADIR)))
415 0 : return __this_address;
416 : break;
417 97301 : case XFS_DINODE_FMT_REFCOUNT:
418 97301 : if (!xfs_has_rtreflink(mp))
419 0 : return __this_address;
420 97301 : if (!(dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_METADIR)))
421 0 : return __this_address;
422 : break;
423 : default:
424 44 : return __this_address;
425 : }
426 : return NULL;
427 : }
428 :
429 : static xfs_failaddr_t
430 376212253 : xfs_dinode_verify_forkoff(
431 : struct xfs_dinode *dip,
432 : struct xfs_mount *mp)
433 : {
434 376212253 : if (!dip->di_forkoff)
435 : return NULL;
436 :
437 373429718 : switch (dip->di_format) {
438 124923483 : case XFS_DINODE_FMT_DEV:
439 124923483 : if (dip->di_forkoff != (roundup(sizeof(xfs_dev_t), 8) >> 3))
440 0 : return __this_address;
441 : break;
442 : case XFS_DINODE_FMT_RMAP:
443 : case XFS_DINODE_FMT_REFCOUNT:
444 193202 : if (!(xfs_has_metadir(mp) && xfs_has_parent(mp)))
445 0 : return __this_address;
446 248506235 : fallthrough;
447 : case XFS_DINODE_FMT_LOCAL: /* fall through ... */
448 : case XFS_DINODE_FMT_EXTENTS: /* fall through ... */
449 : case XFS_DINODE_FMT_BTREE:
450 248506246 : if (dip->di_forkoff >= (XFS_LITINO(mp) >> 3))
451 0 : return __this_address;
452 : break;
453 : default:
454 0 : return __this_address;
455 : }
456 : return NULL;
457 : }
458 :
459 : static xfs_failaddr_t
460 376211799 : xfs_dinode_verify_nrext64(
461 : struct xfs_mount *mp,
462 : struct xfs_dinode *dip)
463 : {
464 752423598 : if (xfs_dinode_has_large_extent_counts(dip)) {
465 376209478 : if (!xfs_has_large_extent_counts(mp))
466 0 : return __this_address;
467 376209478 : if (dip->di_nrext64_pad != 0)
468 0 : return __this_address;
469 2321 : } else if (dip->di_version >= 3) {
470 48 : if (dip->di_v3_pad != 0)
471 0 : return __this_address;
472 : }
473 :
474 : return NULL;
475 : }
476 :
477 : /*
478 : * Validate all the picky requirements we have for a file that claims to be
479 : * filesystem metadata.
480 : */
481 : xfs_failaddr_t
482 606702 : xfs_dinode_verify_metadir(
483 : struct xfs_mount *mp,
484 : struct xfs_dinode *dip,
485 : uint16_t mode,
486 : uint16_t flags,
487 : uint64_t flags2)
488 : {
489 606702 : if (!xfs_has_metadir(mp))
490 0 : return __this_address;
491 :
492 : /* V5 filesystem only */
493 606702 : if (dip->di_version < 3)
494 0 : return __this_address;
495 :
496 : /* V3 inode fields that are always zero */
497 606702 : if (dip->di_onlink)
498 0 : return __this_address;
499 606702 : if ((flags2 & XFS_DIFLAG2_NREXT64) && dip->di_nrext64_pad)
500 0 : return __this_address;
501 606702 : if (!(flags2 & XFS_DIFLAG2_NREXT64) && dip->di_flushiter)
502 0 : return __this_address;
503 :
504 : /* Metadata files can only be directories or regular files */
505 606702 : if (!S_ISDIR(mode) && !S_ISREG(mode))
506 0 : return __this_address;
507 :
508 : /* They must have zero access permissions */
509 606702 : if (mode & 0777)
510 0 : return __this_address;
511 :
512 : /* DMAPI event and state masks are zero */
513 606702 : if (dip->di_dmevmask || dip->di_dmstate)
514 0 : return __this_address;
515 :
516 : /* User, group, and project IDs must be zero */
517 606702 : if (dip->di_uid || dip->di_gid ||
518 606702 : dip->di_projid_lo || dip->di_projid_hi)
519 0 : return __this_address;
520 :
521 : /* Immutable, sync, noatime, nodump, and nodefrag flags must be set */
522 606702 : if (!(flags & XFS_DIFLAG_IMMUTABLE))
523 0 : return __this_address;
524 606702 : if (!(flags & XFS_DIFLAG_SYNC))
525 0 : return __this_address;
526 606702 : if (!(flags & XFS_DIFLAG_NOATIME))
527 0 : return __this_address;
528 606702 : if (!(flags & XFS_DIFLAG_NODUMP))
529 0 : return __this_address;
530 606702 : if (!(flags & XFS_DIFLAG_NODEFRAG))
531 0 : return __this_address;
532 :
533 : /* Directories must have nosymlinks flags set */
534 606702 : if (S_ISDIR(mode) && !(flags & XFS_DIFLAG_NOSYMLINKS))
535 0 : return __this_address;
536 :
537 : /* dax flags2 must not be set */
538 606702 : if (flags2 & XFS_DIFLAG2_DAX)
539 0 : return __this_address;
540 :
541 : return NULL;
542 : }
543 :
544 : xfs_failaddr_t
545 376243075 : xfs_dinode_verify(
546 : struct xfs_mount *mp,
547 : xfs_ino_t ino,
548 : struct xfs_dinode *dip)
549 : {
550 376243075 : xfs_failaddr_t fa;
551 376243075 : uint16_t mode;
552 376243075 : uint16_t flags;
553 376243075 : uint64_t flags2;
554 376243075 : uint64_t di_size;
555 376243075 : xfs_extnum_t nextents;
556 376243075 : xfs_extnum_t naextents;
557 376243075 : xfs_filblks_t nblocks;
558 :
559 376243075 : if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))
560 0 : return __this_address;
561 :
562 : /* Verify v3 integrity information first */
563 376243075 : if (dip->di_version >= 3) {
564 376232664 : if (!xfs_has_v3inodes(mp))
565 0 : return __this_address;
566 376232664 : if (!xfs_verify_cksum((char *)dip, mp->m_sb.sb_inodesize,
567 : XFS_DINODE_CRC_OFF))
568 26 : return __this_address;
569 376229054 : if (be64_to_cpu(dip->di_ino) != ino)
570 0 : return __this_address;
571 376229054 : if (!uuid_equal(&dip->di_uuid, &mp->m_sb.sb_meta_uuid))
572 0 : return __this_address;
573 : }
574 :
575 376218907 : if (dip->di_version > 1) {
576 376218907 : if (dip->di_onlink)
577 0 : return __this_address;
578 : } else {
579 0 : if (dip->di_nlink)
580 0 : return __this_address;
581 : }
582 :
583 : /* don't allow invalid i_size */
584 376218907 : di_size = be64_to_cpu(dip->di_size);
585 376218907 : if (di_size & (1ULL << 63))
586 0 : return __this_address;
587 :
588 376218907 : mode = be16_to_cpu(dip->di_mode);
589 376218907 : if (mode && xfs_mode_to_ftype(mode) == XFS_DIR3_FT_UNKNOWN)
590 693 : return __this_address;
591 :
592 : /* No zero-length symlinks/dirs. */
593 376215462 : if ((S_ISLNK(mode) || S_ISDIR(mode)) && di_size == 0)
594 88 : return __this_address;
595 :
596 376215374 : fa = xfs_dinode_verify_nrext64(mp, dip);
597 376208817 : if (fa)
598 : return fa;
599 :
600 376212456 : nextents = xfs_dfork_data_extents(dip);
601 376212456 : naextents = xfs_dfork_attr_extents(dip);
602 376212456 : nblocks = be64_to_cpu(dip->di_nblocks);
603 :
604 : /* Fork checks carried over from xfs_iformat_fork */
605 376212456 : if (mode && nextents + naextents > nblocks)
606 0 : return __this_address;
607 :
608 376212456 : if (S_ISDIR(mode) && nextents > mp->m_dir_geo->max_extents)
609 0 : return __this_address;
610 :
611 376212456 : if (mode && XFS_DFORK_BOFF(dip) > mp->m_sb.sb_inodesize)
612 0 : return __this_address;
613 :
614 376212456 : flags = be16_to_cpu(dip->di_flags);
615 :
616 376212456 : if (mode && (flags & XFS_DIFLAG_REALTIME) && !mp->m_rtdev_targp)
617 0 : return __this_address;
618 :
619 : /* check for illegal values of forkoff */
620 376212456 : fa = xfs_dinode_verify_forkoff(dip, mp);
621 376196239 : if (fa)
622 : return fa;
623 :
624 : /* Do we have appropriate data fork formats for the mode? */
625 376213834 : switch (mode & S_IFMT) {
626 124993751 : case S_IFIFO:
627 : case S_IFCHR:
628 : case S_IFBLK:
629 : case S_IFSOCK:
630 124993751 : if (dip->di_format != XFS_DINODE_FMT_DEV)
631 176 : return __this_address;
632 : break;
633 251219159 : case S_IFREG:
634 : case S_IFLNK:
635 : case S_IFDIR:
636 251219159 : fa = xfs_dinode_verify_fork(dip, mp, XFS_DATA_FORK);
637 251212618 : if (fa)
638 : return fa;
639 : break;
640 : case 0:
641 : /* Uninitialized inode ok. */
642 : break;
643 : default:
644 0 : return __this_address;
645 : }
646 :
647 376207329 : if (dip->di_forkoff) {
648 373424939 : fa = xfs_dinode_verify_fork(dip, mp, XFS_ATTR_FORK);
649 373424142 : if (fa)
650 : return fa;
651 : } else {
652 : /*
653 : * If there is no fork offset, this may be a freshly-made inode
654 : * in a new disk cluster, in which case di_aformat is zeroed.
655 : * Otherwise, such an inode must be in EXTENTS format; this goes
656 : * for freed inodes as well.
657 : */
658 2782390 : switch (dip->di_aformat) {
659 : case 0:
660 : case XFS_DINODE_FMT_EXTENTS:
661 2782390 : break;
662 : default:
663 0 : return __this_address;
664 : }
665 2782390 : if (naextents)
666 0 : return __this_address;
667 : }
668 :
669 : /* extent size hint validation */
670 376206861 : fa = xfs_inode_validate_extsize(mp, be32_to_cpu(dip->di_extsize),
671 : mode, flags);
672 376191487 : if (fa)
673 : return fa;
674 :
675 : /* only version 3 or greater inodes are extensively verified here */
676 376192902 : if (dip->di_version < 3)
677 : return NULL;
678 :
679 376190640 : flags2 = be64_to_cpu(dip->di_flags2);
680 :
681 : /* don't allow reflink/cowextsize if we don't have reflink */
682 376190640 : if ((flags2 & (XFS_DIFLAG2_REFLINK | XFS_DIFLAG2_COWEXTSIZE)) &&
683 : !xfs_has_reflink(mp))
684 0 : return __this_address;
685 :
686 : /* only regular files get reflink */
687 376190640 : if ((flags2 & XFS_DIFLAG2_REFLINK) && (mode & S_IFMT) != S_IFREG)
688 0 : return __this_address;
689 :
690 : /* don't let reflink and realtime mix */
691 376190640 : if ((flags2 & XFS_DIFLAG2_REFLINK) && (flags & XFS_DIFLAG_REALTIME) &&
692 87381 : !xfs_has_rtreflink(mp))
693 0 : return __this_address;
694 :
695 : /* COW extent size hint validation */
696 376190640 : fa = xfs_inode_validate_cowextsize(mp, be32_to_cpu(dip->di_cowextsize),
697 : mode, flags, flags2);
698 376186452 : if (fa)
699 : return fa;
700 :
701 : /* bigtime iflag can only happen on bigtime filesystems */
702 752372206 : if (xfs_dinode_has_bigtime(dip) &&
703 : !xfs_has_bigtime(mp))
704 0 : return __this_address;
705 :
706 376186103 : if (flags2 & XFS_DIFLAG2_METADIR) {
707 606702 : fa = xfs_dinode_verify_metadir(mp, dip, mode, flags, flags2);
708 606702 : if (fa)
709 0 : return fa;
710 : }
711 :
712 : return NULL;
713 : }
714 :
715 : void
716 503227287 : xfs_dinode_calc_crc(
717 : struct xfs_mount *mp,
718 : struct xfs_dinode *dip)
719 : {
720 503227287 : uint32_t crc;
721 :
722 503227287 : if (dip->di_version < 3)
723 : return;
724 :
725 503225962 : ASSERT(xfs_has_crc(mp));
726 503225962 : crc = xfs_start_cksum_update((char *)dip, mp->m_sb.sb_inodesize,
727 : XFS_DINODE_CRC_OFF);
728 503164316 : dip->di_crc = xfs_end_cksum(crc);
729 : }
730 :
731 : /*
732 : * Validate di_extsize hint.
733 : *
734 : * 1. Extent size hint is only valid for directories and regular files.
735 : * 2. FS_XFLAG_EXTSIZE is only valid for regular files.
736 : * 3. FS_XFLAG_EXTSZINHERIT is only valid for directories.
737 : * 4. Hint cannot be larger than MAXTEXTLEN.
738 : * 5. Can be changed on directories at any time.
739 : * 6. Hint value of 0 turns off hints, clears inode flags.
740 : * 7. Extent size must be a multiple of the appropriate block size.
741 : * For realtime files, this is the rt extent size.
742 : * 8. For non-realtime files, the extent size hint must be limited
743 : * to half the AG size to avoid alignment extending the extent beyond the
744 : * limits of the AG.
745 : */
746 : xfs_failaddr_t
747 547804894 : xfs_inode_validate_extsize(
748 : struct xfs_mount *mp,
749 : uint32_t extsize,
750 : uint16_t mode,
751 : uint16_t flags)
752 : {
753 547804894 : bool rt_flag;
754 547804894 : bool hint_flag;
755 547804894 : bool inherit_flag;
756 547804894 : uint32_t alloc_unit = 1;
757 :
758 547804894 : rt_flag = (flags & XFS_DIFLAG_REALTIME);
759 547804894 : hint_flag = (flags & XFS_DIFLAG_EXTSIZE);
760 547804894 : inherit_flag = (flags & XFS_DIFLAG_EXTSZINHERIT);
761 :
762 : /*
763 : * This comment describes a historic gap in this verifier function.
764 : *
765 : * For a directory with both RTINHERIT and EXTSZINHERIT flags set, this
766 : * function has never checked that the extent size hint is an integer
767 : * multiple of the realtime extent size. Since we allow users to set
768 : * this combination on non-rt filesystems /and/ to change the rt
769 : * extent size when adding a rt device to a filesystem, the net effect
770 : * is that users can configure a filesystem anticipating one rt
771 : * geometry and change their minds later. Directories do not use the
772 : * extent size hint, so this is harmless for them.
773 : *
774 : * If a directory with a misaligned extent size hint is allowed to
775 : * propagate that hint into a new regular realtime file, the result
776 : * is that the inode cluster buffer verifier will trigger a corruption
777 : * shutdown the next time it is run, because the verifier has always
778 : * enforced the alignment rule for regular files.
779 : *
780 : * Because we allow administrators to set a new rt extent size when
781 : * adding a rt section, we cannot add a check to this verifier because
782 : * that will result a new source of directory corruption errors when
783 : * reading an existing filesystem. Instead, we rely on callers to
784 : * decide when alignment checks are appropriate, and fix things up as
785 : * needed.
786 : */
787 :
788 547804894 : if (rt_flag)
789 73825484 : alloc_unit = mp->m_sb.sb_rextsize;
790 :
791 547804894 : if ((hint_flag || inherit_flag) && !(S_ISDIR(mode) || S_ISREG(mode)))
792 0 : return __this_address;
793 :
794 547804894 : if (hint_flag && !S_ISREG(mode))
795 0 : return __this_address;
796 :
797 547804894 : if (inherit_flag && !S_ISDIR(mode))
798 0 : return __this_address;
799 :
800 547804894 : if ((hint_flag || inherit_flag) && extsize == 0)
801 0 : return __this_address;
802 :
803 : /* free inodes get flags set to zero but extsize remains */
804 547804894 : if (mode && !(hint_flag || inherit_flag) && extsize != 0)
805 0 : return __this_address;
806 :
807 547804894 : if (extsize % alloc_unit)
808 2 : return __this_address;
809 :
810 547804892 : if (extsize > XFS_MAX_BMBT_EXTLEN)
811 0 : return __this_address;
812 :
813 547804892 : if (!rt_flag && extsize > mp->m_sb.sb_agblocks / 2)
814 0 : return __this_address;
815 :
816 : return NULL;
817 : }
818 :
819 : /*
820 : * Validate di_cowextsize hint.
821 : *
822 : * 1. CoW extent size hint can only be set if reflink is enabled on the fs.
823 : * The inode does not have to have any shared blocks, but it must be a v3.
824 : * 2. FS_XFLAG_COWEXTSIZE is only valid for directories and regular files;
825 : * for a directory, the hint is propagated to new files.
826 : * 3. Can be changed on files & directories at any time.
827 : * 4. Hint value of 0 turns off hints, clears inode flags.
828 : * 5. Extent size must be a multiple of the appropriate block size.
829 : * 6. The extent size hint must be limited to half the AG size to avoid
830 : * alignment extending the extent beyond the limits of the AG.
831 : */
832 : xfs_failaddr_t
833 588957229 : xfs_inode_validate_cowextsize(
834 : struct xfs_mount *mp,
835 : uint32_t cowextsize,
836 : uint16_t mode,
837 : uint16_t flags,
838 : uint64_t flags2)
839 : {
840 588957229 : bool rt_flag;
841 588957229 : bool hint_flag;
842 588957229 : uint32_t alloc_unit = 1;
843 :
844 588957229 : rt_flag = (flags & XFS_DIFLAG_REALTIME);
845 588957229 : hint_flag = (flags2 & XFS_DIFLAG2_COWEXTSIZE);
846 :
847 : /*
848 : * Similar to extent size hints, a directory can be configured to
849 : * propagate realtime status and a CoW extent size hint to newly
850 : * created files even if there is no realtime device, and the hints on
851 : * disk can become misaligned if the sysadmin changes the rt extent
852 : * size while adding the realtime device.
853 : *
854 : * Therefore, we can only enforce the rextsize alignment check against
855 : * regular realtime files, and rely on callers to decide when alignment
856 : * checks are appropriate, and fix things up as needed.
857 : */
858 :
859 588957229 : if (rt_flag)
860 73603483 : alloc_unit = mp->m_sb.sb_rextsize;
861 :
862 588957229 : if (hint_flag && !xfs_has_reflink(mp))
863 0 : return __this_address;
864 :
865 588957229 : if (hint_flag && !(S_ISDIR(mode) || S_ISREG(mode)))
866 0 : return __this_address;
867 :
868 588957229 : if (hint_flag && cowextsize == 0)
869 0 : return __this_address;
870 :
871 : /* free inodes get flags set to zero but cowextsize remains */
872 588957229 : if (mode && !hint_flag && cowextsize != 0)
873 0 : return __this_address;
874 :
875 588957229 : if (cowextsize % alloc_unit)
876 0 : return __this_address;
877 :
878 588957229 : if (cowextsize > XFS_MAX_BMBT_EXTLEN)
879 0 : return __this_address;
880 :
881 588957229 : if (!rt_flag && cowextsize > mp->m_sb.sb_agblocks / 2)
882 0 : return __this_address;
883 :
884 : return NULL;
885 : }
|