/* Set us up to repair the symlink file. */ int
xrep_setup_symlink( struct xfs_scrub *sc, unsignedint *resblks)
{ struct xfs_mount *mp = sc->mp; unsignedlonglong blocks; int error;
error = xrep_tempfile_create(sc, S_IFLNK); if (error) return error;
/* We'll only read until the buffer is full. */
len = min_t(loff_t, ip->i_disk_size, XFS_SYMLINK_MAXLEN);
fsblocks = xfs_symlink_blocks(sc->mp, len);
error = xfs_bmapi_read(ip, 0, fsblocks, mval, &nmaps, 0); if (error) return error;
for (n = 0; n < nmaps; n++) { struct xfs_dsymlink_hdr *dsl;
d = XFS_FSB_TO_DADDR(sc->mp, mval[n].br_startblock);
/* Read the rmt block. We'll run the verifiers manually. */
error = xfs_trans_read_buf(sc->mp, sc->tp, sc->mp->m_ddev_targp,
d, XFS_FSB_TO_BB(sc->mp, mval[n].br_blockcount), 0, &bp, NULL); if (error) return error;
bp->b_ops = &xfs_symlink_buf_ops;
/* How many bytes do we expect to get out of this buffer? */
byte_cnt = XFS_FSB_TO_B(sc->mp, mval[n].br_blockcount);
byte_cnt = XFS_SYMLINK_BUF_SPACE(sc->mp, byte_cnt);
byte_cnt = min_t(unsignedint, byte_cnt, len);
nr = min(XFS_SYMLINK_MAXLEN, xfs_inode_data_fork_size(ip));
strncpy(target_buf, ifp->if_data, nr); return nr;
}
#define DUMMY_TARGET \ "The target of this symbolic link could not be recovered at all and " \ "has been replaced with this explanatory message. To avoid " \ "accidentally pointing to an existing file path, this message is " \ "longer than the maximum supported file name length. That is an " \ "acceptable length for a symlink target on XFS but will produce " \ "File Name Too Long errors if resolved."
/* Salvage whatever we can of the target. */ STATICint
xrep_symlink_salvage( struct xfs_scrub *sc)
{ char *target_buf = sc->buf;
ssize_t buflen = 0;
/* Exchange the temporary symlink's data fork with the one being repaired. */ STATICint
xrep_symlink_swap( struct xfs_scrub *sc)
{ struct xrep_tempexch *tx = sc->buf; bool ip_local, temp_local; int error;
/* Otherwise, make sure both data forks are in block-mapping mode. */
error = xrep_symlink_swap_prep(sc, temp_local, ip_local); if (error) return error;
/* How many blocks do we need? */
target_len = strlen(target_buf);
ASSERT(target_len != 0); if (target_len == 0 || target_len > XFS_SYMLINK_MAXLEN) return -EFSCORRUPTED;
/* Erase the dummy target set up by the tempfile initialization. */
xfs_idestroy_fork(&sc->tempip->i_df);
sc->tempip->i_df.if_bytes = 0;
sc->tempip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
/* Write the salvaged target to the temporary link. */
error = xfs_symlink_write_target(sc->tp, sc->tempip, sc->ip->i_ino,
target_buf, target_len, fs_blocks, resblks); if (error) return error;
/* Repair a symbolic link. */ int
xrep_symlink( struct xfs_scrub *sc)
{ int error;
/* The rmapbt is required to reap the old data fork. */ if (!xfs_has_rmapbt(sc->mp)) return -EOPNOTSUPP; /* We require atomic file exchange range to rebuild anything. */ if (!xfs_has_exchange_range(sc->mp)) return -EOPNOTSUPP;
ASSERT(sc->ilock_flags & XFS_ILOCK_EXCL);
error = xrep_symlink_salvage(sc); if (error) return error;
/* Now reset the target. */
error = xrep_symlink_rebuild(sc); if (error) return error;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.