xref: /linux/fs/xfs/scrub/symlink_repair.c (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2018-2024 Oracle.  All Rights Reserved.
4  * Author: Darrick J. Wong <djwong@kernel.org>
5  */
6 #include "xfs.h"
7 #include "xfs_fs.h"
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "xfs_trans_resv.h"
11 #include "xfs_mount.h"
12 #include "xfs_defer.h"
13 #include "xfs_btree.h"
14 #include "xfs_bit.h"
15 #include "xfs_log_format.h"
16 #include "xfs_trans.h"
17 #include "xfs_sb.h"
18 #include "xfs_inode.h"
19 #include "xfs_inode_fork.h"
20 #include "xfs_symlink.h"
21 #include "xfs_bmap.h"
22 #include "xfs_quota.h"
23 #include "xfs_da_format.h"
24 #include "xfs_da_btree.h"
25 #include "xfs_bmap_btree.h"
26 #include "xfs_trans_space.h"
27 #include "xfs_symlink_remote.h"
28 #include "xfs_exchmaps.h"
29 #include "xfs_exchrange.h"
30 #include "xfs_health.h"
31 #include "scrub/xfs_scrub.h"
32 #include "scrub/scrub.h"
33 #include "scrub/common.h"
34 #include "scrub/trace.h"
35 #include "scrub/repair.h"
36 #include "scrub/tempfile.h"
37 #include "scrub/tempexch.h"
38 #include "scrub/reap.h"
39 
40 /*
41  * Symbolic Link Repair
42  * ====================
43  *
44  * We repair symbolic links by reading whatever target data we can find, up to
45  * the first NULL byte.  If the recovered target strlen matches i_size, then
46  * we rewrite the target.  In all other cases, we replace the target with an
47  * overly long string that cannot possibly resolve.  The new target is written
48  * into a private hidden temporary file, and then a file contents exchange
49  * commits the new symlink target to the file being repaired.
50  */
51 
52 /* Set us up to repair the symlink file. */
53 int
54 xrep_setup_symlink(
55 	struct xfs_scrub	*sc,
56 	unsigned int		*resblks)
57 {
58 	struct xfs_mount	*mp = sc->mp;
59 	unsigned long long	blocks;
60 	int			error;
61 
62 	error = xrep_tempfile_create(sc, S_IFLNK);
63 	if (error)
64 		return error;
65 
66 	/*
67 	 * If we're doing a repair, we reserve enough blocks to write out a
68 	 * completely new symlink file, plus twice as many blocks as we would
69 	 * need if we can only allocate one block per data fork mapping.  This
70 	 * should cover the preallocation of the temporary file and exchanging
71 	 * the extent mappings.
72 	 *
73 	 * We cannot use xfs_exchmaps_estimate because we have not yet
74 	 * constructed the replacement symlink and therefore do not know how
75 	 * many extents it will use.  By the time we do, we will have a dirty
76 	 * transaction (which we cannot drop because we cannot drop the
77 	 * symlink ILOCK) and cannot ask for more reservation.
78 	 */
79 	blocks = xfs_symlink_blocks(sc->mp, XFS_SYMLINK_MAXLEN);
80 	blocks += xfs_bmbt_calc_size(mp, blocks) * 2;
81 	if (blocks > UINT_MAX)
82 		return -EOPNOTSUPP;
83 
84 	*resblks += blocks;
85 	return 0;
86 }
87 
88 /*
89  * Try to salvage the pathname from remote blocks.  Returns the number of bytes
90  * salvaged or a negative errno.
91  */
92 STATIC ssize_t
93 xrep_symlink_salvage_remote(
94 	struct xfs_scrub	*sc)
95 {
96 	struct xfs_bmbt_irec	mval[XFS_SYMLINK_MAPS];
97 	struct xfs_inode	*ip = sc->ip;
98 	struct xfs_buf		*bp;
99 	char			*target_buf = sc->buf;
100 	xfs_failaddr_t		fa;
101 	xfs_filblks_t		fsblocks;
102 	xfs_daddr_t		d;
103 	loff_t			len;
104 	loff_t			offset = 0;
105 	unsigned int		byte_cnt;
106 	bool			magic_ok;
107 	bool			hdr_ok;
108 	int			n;
109 	int			nmaps = XFS_SYMLINK_MAPS;
110 	int			error;
111 
112 	/* We'll only read until the buffer is full. */
113 	len = min_t(loff_t, ip->i_disk_size, XFS_SYMLINK_MAXLEN);
114 	fsblocks = xfs_symlink_blocks(sc->mp, len);
115 	error = xfs_bmapi_read(ip, 0, fsblocks, mval, &nmaps, 0);
116 	if (error)
117 		return error;
118 
119 	for (n = 0; n < nmaps; n++) {
120 		struct xfs_dsymlink_hdr	*dsl;
121 
122 		d = XFS_FSB_TO_DADDR(sc->mp, mval[n].br_startblock);
123 
124 		/* Read the rmt block.  We'll run the verifiers manually. */
125 		error = xfs_trans_read_buf(sc->mp, sc->tp, sc->mp->m_ddev_targp,
126 				d, XFS_FSB_TO_BB(sc->mp, mval[n].br_blockcount),
127 				0, &bp, NULL);
128 		if (error)
129 			return error;
130 		bp->b_ops = &xfs_symlink_buf_ops;
131 
132 		/* How many bytes do we expect to get out of this buffer? */
133 		byte_cnt = XFS_FSB_TO_B(sc->mp, mval[n].br_blockcount);
134 		byte_cnt = XFS_SYMLINK_BUF_SPACE(sc->mp, byte_cnt);
135 		byte_cnt = min_t(unsigned int, byte_cnt, len);
136 
137 		/*
138 		 * See if the verifiers accept this block.  We're willing to
139 		 * salvage if the if the offset/byte/ino are ok and either the
140 		 * verifier passed or the magic is ok.  Anything else and we
141 		 * stop dead in our tracks.
142 		 */
143 		fa = bp->b_ops->verify_struct(bp);
144 		dsl = bp->b_addr;
145 		magic_ok = dsl->sl_magic == cpu_to_be32(XFS_SYMLINK_MAGIC);
146 		hdr_ok = xfs_symlink_hdr_ok(ip->i_ino, offset, byte_cnt, bp);
147 		if (!hdr_ok || (fa != NULL && !magic_ok))
148 			break;
149 
150 		memcpy(target_buf + offset, dsl + 1, byte_cnt);
151 
152 		len -= byte_cnt;
153 		offset += byte_cnt;
154 	}
155 	return offset;
156 }
157 
158 /*
159  * Try to salvage an inline symlink's contents.  Returns the number of bytes
160  * salvaged or a negative errno.
161  */
162 STATIC ssize_t
163 xrep_symlink_salvage_inline(
164 	struct xfs_scrub	*sc)
165 {
166 	struct xfs_inode	*ip = sc->ip;
167 	char			*target_buf = sc->buf;
168 	char			*old_target;
169 	struct xfs_ifork	*ifp;
170 	unsigned int		nr;
171 
172 	ifp = xfs_ifork_ptr(ip, XFS_DATA_FORK);
173 	if (!ifp->if_data)
174 		return 0;
175 
176 	/*
177 	 * If inode repair zapped the link target, pretend that we didn't find
178 	 * any bytes at all so that we can replace the (now totally lost) link
179 	 * target with a warning message.
180 	 */
181 	old_target = ifp->if_data;
182 	if (xfs_inode_has_sickness(sc->ip, XFS_SICK_INO_SYMLINK_ZAPPED) &&
183 	    sc->ip->i_disk_size == 1 && old_target[0] == '?')
184 		return 0;
185 
186 	nr = min(XFS_SYMLINK_MAXLEN, xfs_inode_data_fork_size(ip));
187 	strncpy(target_buf, ifp->if_data, nr);
188 	return nr;
189 }
190 
191 #define DUMMY_TARGET \
192 	"The target of this symbolic link could not be recovered at all and " \
193 	"has been replaced with this explanatory message.  To avoid " \
194 	"accidentally pointing to an existing file path, this message is " \
195 	"longer than the maximum supported file name length.  That is an " \
196 	"acceptable length for a symlink target on XFS but will produce " \
197 	"File Name Too Long errors if resolved."
198 
199 /* Salvage whatever we can of the target. */
200 STATIC int
201 xrep_symlink_salvage(
202 	struct xfs_scrub	*sc)
203 {
204 	char			*target_buf = sc->buf;
205 	ssize_t			buflen = 0;
206 
207 	BUILD_BUG_ON(sizeof(DUMMY_TARGET) - 1 <= NAME_MAX);
208 
209 	/*
210 	 * Salvage the target if there weren't any corruption problems observed
211 	 * while scanning it.
212 	 */
213 	if (!(sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) {
214 		if (sc->ip->i_df.if_format == XFS_DINODE_FMT_LOCAL)
215 			buflen = xrep_symlink_salvage_inline(sc);
216 		else
217 			buflen = xrep_symlink_salvage_remote(sc);
218 		if (buflen < 0)
219 			return buflen;
220 
221 		/*
222 		 * NULL-terminate the buffer because the ondisk target does not
223 		 * do that for us.  If salvage didn't find the exact amount of
224 		 * data that we expected to find, don't salvage anything.
225 		 */
226 		target_buf[buflen] = 0;
227 		if (strlen(target_buf) != sc->ip->i_disk_size)
228 			buflen = 0;
229 	}
230 
231 	/*
232 	 * Change an empty target into a dummy target and clear the symlink
233 	 * target zapped flag.
234 	 */
235 	if (buflen == 0) {
236 		sc->sick_mask |= XFS_SICK_INO_SYMLINK_ZAPPED;
237 		sprintf(target_buf, DUMMY_TARGET);
238 	}
239 
240 	trace_xrep_symlink_salvage_target(sc->ip, target_buf,
241 			strlen(target_buf));
242 	return 0;
243 }
244 
245 STATIC void
246 xrep_symlink_local_to_remote(
247 	struct xfs_trans	*tp,
248 	struct xfs_buf		*bp,
249 	struct xfs_inode	*ip,
250 	struct xfs_ifork	*ifp,
251 	void			*priv)
252 {
253 	struct xfs_scrub	*sc = priv;
254 	struct xfs_dsymlink_hdr	*dsl = bp->b_addr;
255 
256 	xfs_symlink_local_to_remote(tp, bp, ip, ifp, NULL);
257 
258 	if (!xfs_has_crc(sc->mp))
259 		return;
260 
261 	dsl->sl_owner = cpu_to_be64(sc->ip->i_ino);
262 	xfs_trans_log_buf(tp, bp, 0,
263 			  sizeof(struct xfs_dsymlink_hdr) + ifp->if_bytes - 1);
264 }
265 
266 /*
267  * Prepare both links' data forks for an exchange.  Promote the tempfile from
268  * local format to extents format, and if the file being repaired has a short
269  * format data fork, turn it into an empty extent list.
270  */
271 STATIC int
272 xrep_symlink_swap_prep(
273 	struct xfs_scrub	*sc,
274 	bool			temp_local,
275 	bool			ip_local)
276 {
277 	int			error;
278 
279 	/*
280 	 * If the temp link is in shortform format, convert that to a remote
281 	 * target so that we can use the atomic mapping exchange.
282 	 */
283 	if (temp_local) {
284 		int		logflags = XFS_ILOG_CORE;
285 
286 		error = xfs_bmap_local_to_extents(sc->tp, sc->tempip, 1,
287 				&logflags, XFS_DATA_FORK,
288 				xrep_symlink_local_to_remote,
289 				sc);
290 		if (error)
291 			return error;
292 
293 		xfs_trans_log_inode(sc->tp, sc->ip, 0);
294 
295 		error = xfs_defer_finish(&sc->tp);
296 		if (error)
297 			return error;
298 	}
299 
300 	/*
301 	 * If the file being repaired had a shortform data fork, convert that
302 	 * to an empty extent list in preparation for the atomic mapping
303 	 * exchange.
304 	 */
305 	if (ip_local) {
306 		struct xfs_ifork	*ifp;
307 
308 		ifp = xfs_ifork_ptr(sc->ip, XFS_DATA_FORK);
309 		xfs_idestroy_fork(ifp);
310 		ifp->if_format = XFS_DINODE_FMT_EXTENTS;
311 		ifp->if_nextents = 0;
312 		ifp->if_bytes = 0;
313 		ifp->if_data = NULL;
314 		ifp->if_height = 0;
315 
316 		xfs_trans_log_inode(sc->tp, sc->ip,
317 				XFS_ILOG_CORE | XFS_ILOG_DDATA);
318 	}
319 
320 	return 0;
321 }
322 
323 /* Exchange the temporary symlink's data fork with the one being repaired. */
324 STATIC int
325 xrep_symlink_swap(
326 	struct xfs_scrub	*sc)
327 {
328 	struct xrep_tempexch	*tx = sc->buf;
329 	bool			ip_local, temp_local;
330 	int			error;
331 
332 	ip_local = sc->ip->i_df.if_format == XFS_DINODE_FMT_LOCAL;
333 	temp_local = sc->tempip->i_df.if_format == XFS_DINODE_FMT_LOCAL;
334 
335 	/*
336 	 * If the both links have a local format data fork and the rebuilt
337 	 * remote data would fit in the repaired file's data fork, copy the
338 	 * contents from the tempfile and declare ourselves done.
339 	 */
340 	if (ip_local && temp_local &&
341 	    sc->tempip->i_disk_size <= xfs_inode_data_fork_size(sc->ip)) {
342 		xrep_tempfile_copyout_local(sc, XFS_DATA_FORK);
343 		return 0;
344 	}
345 
346 	/* Otherwise, make sure both data forks are in block-mapping mode. */
347 	error = xrep_symlink_swap_prep(sc, temp_local, ip_local);
348 	if (error)
349 		return error;
350 
351 	return xrep_tempexch_contents(sc, tx);
352 }
353 
354 /*
355  * Free all the remote blocks and reset the data fork.  The caller must join
356  * the inode to the transaction.  This function returns with the inode joined
357  * to a clean scrub transaction.
358  */
359 STATIC int
360 xrep_symlink_reset_fork(
361 	struct xfs_scrub	*sc)
362 {
363 	struct xfs_ifork	*ifp = xfs_ifork_ptr(sc->tempip, XFS_DATA_FORK);
364 	int			error;
365 
366 	/* Unmap all the remote target buffers. */
367 	if (xfs_ifork_has_extents(ifp)) {
368 		error = xrep_reap_ifork(sc, sc->tempip, XFS_DATA_FORK);
369 		if (error)
370 			return error;
371 	}
372 
373 	trace_xrep_symlink_reset_fork(sc->tempip);
374 
375 	/* Reset the temp symlink target to dummy content. */
376 	xfs_idestroy_fork(ifp);
377 	return xfs_symlink_write_target(sc->tp, sc->tempip, sc->tempip->i_ino,
378 			"?", 1, 0, 0);
379 }
380 
381 /*
382  * Reinitialize a link target.  Caller must ensure the inode is joined to
383  * the transaction.
384  */
385 STATIC int
386 xrep_symlink_rebuild(
387 	struct xfs_scrub	*sc)
388 {
389 	struct xrep_tempexch	*tx;
390 	char			*target_buf = sc->buf;
391 	xfs_fsblock_t		fs_blocks;
392 	unsigned int		target_len;
393 	unsigned int		resblks;
394 	int			error;
395 
396 	/* How many blocks do we need? */
397 	target_len = strlen(target_buf);
398 	ASSERT(target_len != 0);
399 	if (target_len == 0 || target_len > XFS_SYMLINK_MAXLEN)
400 		return -EFSCORRUPTED;
401 
402 	trace_xrep_symlink_rebuild(sc->ip);
403 
404 	/*
405 	 * In preparation to write the new symlink target to the temporary
406 	 * file, drop the ILOCK of the file being repaired (it shouldn't be
407 	 * joined) and take the ILOCK of the temporary file.
408 	 *
409 	 * The VFS does not take the IOLOCK while reading a symlink (and new
410 	 * symlinks are hidden with INEW until they've been written) so it's
411 	 * possible that a readlink() could see the old corrupted contents
412 	 * while we're doing this.
413 	 */
414 	xchk_iunlock(sc, XFS_ILOCK_EXCL);
415 	xrep_tempfile_ilock(sc);
416 	xfs_trans_ijoin(sc->tp, sc->tempip, 0);
417 
418 	/*
419 	 * Reserve resources to reinitialize the target.  We're allowed to
420 	 * exceed file quota to repair inconsistent metadata, though this is
421 	 * unlikely.
422 	 */
423 	fs_blocks = xfs_symlink_blocks(sc->mp, target_len);
424 	resblks = xfs_symlink_space_res(sc->mp, target_len, fs_blocks);
425 	error = xfs_trans_reserve_quota_nblks(sc->tp, sc->tempip, resblks, 0,
426 			true);
427 	if (error)
428 		return error;
429 
430 	/* Erase the dummy target set up by the tempfile initialization. */
431 	xfs_idestroy_fork(&sc->tempip->i_df);
432 	sc->tempip->i_df.if_bytes = 0;
433 	sc->tempip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
434 
435 	/* Write the salvaged target to the temporary link. */
436 	error = xfs_symlink_write_target(sc->tp, sc->tempip, sc->ip->i_ino,
437 			target_buf, target_len, fs_blocks, resblks);
438 	if (error)
439 		return error;
440 
441 	/*
442 	 * Commit the repair transaction so that we can use the atomic mapping
443 	 * exchange functions to compute the correct block reservations and
444 	 * re-lock the inodes.
445 	 */
446 	target_buf = NULL;
447 	error = xrep_trans_commit(sc);
448 	if (error)
449 		return error;
450 
451 	/* Last chance to abort before we start committing fixes. */
452 	if (xchk_should_terminate(sc, &error))
453 		return error;
454 
455 	xrep_tempfile_iunlock(sc);
456 
457 	/*
458 	 * We're done with the temporary buffer, so we can reuse it for the
459 	 * tempfile contents exchange information.
460 	 */
461 	tx = sc->buf;
462 	error = xrep_tempexch_trans_alloc(sc, XFS_DATA_FORK, tx);
463 	if (error)
464 		return error;
465 
466 	/*
467 	 * Exchange the temp link's data fork with the file being repaired.
468 	 * This recreates the transaction and takes the ILOCKs of the file
469 	 * being repaired and the temporary file.
470 	 */
471 	error = xrep_symlink_swap(sc);
472 	if (error)
473 		return error;
474 
475 	/*
476 	 * Release the old symlink blocks and reset the data fork of the temp
477 	 * link to an empty shortform link.  This is the last repair action we
478 	 * perform on the symlink, so we don't need to clean the transaction.
479 	 */
480 	return xrep_symlink_reset_fork(sc);
481 }
482 
483 /* Repair a symbolic link. */
484 int
485 xrep_symlink(
486 	struct xfs_scrub	*sc)
487 {
488 	int			error;
489 
490 	/* The rmapbt is required to reap the old data fork. */
491 	if (!xfs_has_rmapbt(sc->mp))
492 		return -EOPNOTSUPP;
493 	/* We require atomic file exchange range to rebuild anything. */
494 	if (!xfs_has_exchange_range(sc->mp))
495 		return -EOPNOTSUPP;
496 
497 	ASSERT(sc->ilock_flags & XFS_ILOCK_EXCL);
498 
499 	error = xrep_symlink_salvage(sc);
500 	if (error)
501 		return error;
502 
503 	/* Now reset the target. */
504 	error = xrep_symlink_rebuild(sc);
505 	if (error)
506 		return error;
507 
508 	return xrep_trans_commit(sc);
509 }
510