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