static int sb_logzero(uuid_t *uuidp) { int cycle = XLOG_INIT_CYCLE; int error; if (!sb_logcheck()) return 0; /* * The log must always move forward on v5 superblocks. Bump it to the * next cycle. */ if (xfs_sb_version_hascrc(&mp->m_sb)) cycle = mp->m_log->l_curr_cycle + 1; dbprintf(_("Clearing log and setting UUID\n")); error = libxfs_log_clear(mp->m_logdev_targp, NULL, XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), uuidp, xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, mp->m_sb.sb_logsunit, XLOG_FMT, cycle); if (error) { dbprintf(_("ERROR: cannot clear the log\n")); return 0; } return 1; }
static void zero_log(xfs_mount_t *mp, libxfs_init_t *args) { int logdev = (mp->m_sb.sb_logstart == 0) ? args->logdev : args->ddev; libxfs_log_clear(logdev, XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), &mp->m_sb.sb_uuid, XLOG_FMT); }
static void zero_log(xfs_mount_t *mp) { int error; xlog_t log; xfs_daddr_t head_blk, tail_blk; dev_t logdev = (mp->m_sb.sb_logstart == 0) ? x.logdev : x.ddev; memset(&log, 0, sizeof(log)); if (!x.logdev) x.logdev = x.ddev; x.logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); x.logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart); log.l_dev = logdev; log.l_logsize = BBTOB(x.logBBsize); log.l_logBBsize = x.logBBsize; log.l_logBBstart = x.logBBstart; log.l_mp = mp; if (xfs_sb_version_hassector(&mp->m_sb)) { log.l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT; ASSERT(log.l_sectbb_log <= mp->m_sectbb_log); /* for larger sector sizes, must have v2 or external log */ ASSERT(log.l_sectbb_log == 0 || log.l_logBBstart == 0 || xfs_sb_version_haslogv2(&mp->m_sb)); ASSERT(mp->m_sb.sb_logsectlog >= BBSHIFT); } log.l_sectbb_mask = (1 << log.l_sectbb_log) - 1; if ((error = xlog_find_tail(&log, &head_blk, &tail_blk))) { do_warn(_("zero_log: cannot find log head/tail " "(xlog_find_tail=%d), zeroing it anyway\n"), error); } else { if (verbose) { do_warn(_("zero_log: head block %lld tail block %lld\n"), head_blk, tail_blk); } if (head_blk != tail_blk) { if (zap_log) { do_warn(_( "ALERT: The filesystem has valuable metadata changes in a log which is being\n" "destroyed because the -L option was used.\n")); } else { do_warn(_( "ERROR: The filesystem has valuable metadata changes in a log which needs to\n" "be replayed. Mount the filesystem to replay the log, and unmount it before\n" "re-running xfs_repair. If you are unable to mount the filesystem, then use\n" "the -L option to destroy the log and attempt a repair.\n" "Note that destroying the log may cause corruption -- please attempt a mount\n" "of the filesystem before doing this.\n")); exit(2); } } } libxfs_log_clear(logdev, XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), &mp->m_sb.sb_uuid, xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, mp->m_sb.sb_logsunit, XLOG_FMT); }
static void zero_log( struct xfs_mount *mp) { int error; xfs_daddr_t head_blk; xfs_daddr_t tail_blk; struct xlog *log = mp->m_log; memset(log, 0, sizeof(struct xlog)); x.logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); x.logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart); x.lbsize = BBSIZE; if (xfs_sb_version_hassector(&mp->m_sb)) x.lbsize <<= (mp->m_sb.sb_logsectlog - BBSHIFT); log->l_dev = mp->m_logdev_targp; log->l_logBBsize = x.logBBsize; log->l_logBBstart = x.logBBstart; log->l_sectBBsize = BTOBB(x.lbsize); log->l_mp = mp; if (xfs_sb_version_hassector(&mp->m_sb)) { log->l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT; ASSERT(log->l_sectbb_log <= mp->m_sectbb_log); /* for larger sector sizes, must have v2 or external log */ ASSERT(log->l_sectbb_log == 0 || log->l_logBBstart == 0 || xfs_sb_version_haslogv2(&mp->m_sb)); ASSERT(mp->m_sb.sb_logsectlog >= BBSHIFT); } log->l_sectbb_mask = (1 << log->l_sectbb_log) - 1; /* * Find the log head and tail and alert the user to the situation if the * log appears corrupted or contains data. In either case, we do not * proceed past this point unless the user explicitly requests to zap * the log. */ error = xlog_find_tail(log, &head_blk, &tail_blk); if (error) { do_warn( _("zero_log: cannot find log head/tail (xlog_find_tail=%d)\n"), error); if (!no_modify && !zap_log) do_error(_( "ERROR: The log head and/or tail cannot be discovered. Attempt to mount the\n" "filesystem to replay the log or use the -L option to destroy the log and\n" "attempt a repair.\n")); } else { if (verbose) { do_warn( _("zero_log: head block %" PRId64 " tail block %" PRId64 "\n"), head_blk, tail_blk); } if (!no_modify && head_blk != tail_blk) { if (zap_log) { do_warn(_( "ALERT: The filesystem has valuable metadata changes in a log which is being\n" "destroyed because the -L option was used.\n")); } else { do_warn(_( "ERROR: The filesystem has valuable metadata changes in a log which needs to\n" "be replayed. Mount the filesystem to replay the log, and unmount it before\n" "re-running xfs_repair. If you are unable to mount the filesystem, then use\n" "the -L option to destroy the log and attempt a repair.\n" "Note that destroying the log may cause corruption -- please attempt a mount\n" "of the filesystem before doing this.\n")); exit(2); } } } /* * Only clear the log when explicitly requested. Doing so is unnecessary * unless something is wrong. Further, this resets the current LSN of * the filesystem and creates more work for repair of v5 superblock * filesystems. */ if (!no_modify && zap_log) { libxfs_log_clear(log->l_dev, NULL, XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), &mp->m_sb.sb_uuid, xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, mp->m_sb.sb_logsunit, XLOG_FMT, XLOG_INIT_CYCLE, true); /* update the log data structure with new state */ error = xlog_find_tail(log, &head_blk, &tail_blk); if (error || head_blk != tail_blk) do_error(_("failed to clear log")); } /* * Finally, seed the max LSN from the current state of the log if this * is a v5 filesystem. */ if (xfs_sb_version_hascrc(&mp->m_sb)) libxfs_max_lsn = log->l_last_sync_lsn; }
static int uuid_f( int argc, char **argv) { char bp[40]; xfs_agnumber_t agno; uuid_t uu; uuid_t *uup=NULL; if (argc != 1 && argc != 2) { dbprintf("invalid parameters\n"); return 0; } if (argc==2) { /* write uuid */ if (flag_readonly || !flag_expert_mode) { dbprintf("%s not started in read-write expert mode, writing disabled\n", progname); return 0; } if (!strcasecmp(argv[1], "generate")) { uuid_generate(uu); } else if (!strcasecmp(argv[1], "nil")) { uuid_clear(uu); } else if (!strcasecmp(argv[1], "rewrite")) { uup=do_uuid(0, NULL); if (!uup) { dbprintf("failed to read UUID from AG 0\n"); return 0; } memcpy(&uu, *uup, sizeof(uuid_t)); uuid_unparse(uu, bp); dbprintf("old uuid = %s\n", bp); } else { if (uuid_parse(argv[1], uu)) { dbprintf("invalid uuid\n"); return 0; } } if (mp->m_sb.sb_logstart) { if (xfsargs.logdev) { dbprintf("external log specified for FS with internal log - aborting \n"); return 0; } } else { if (!xfsargs.logdev) { dbprintf("no external log specified for FS with external log - aborting\n"); return 0; } } dbprintf("clearing log and setting uuid\n"); /* clear log (setting uuid) */ if (libxfs_log_clear( (mp->m_sb.sb_logstart)?xfsargs.ddev:xfsargs.logdev, XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), &uu, XLOG_FMT)) { dbprintf("error clearing log\n"); return 0; } dbprintf("writing all SBs\n"); for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) if (!do_uuid(agno, &uu)) { dbprintf("failed to set uuid in AG %d\n", agno); break; } uuid_unparse(uu, bp); dbprintf("new uuid = %s\n", bp); return 0; } else { /* get (check) uuid */ for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { uup=do_uuid(agno, NULL); if (!uup) { dbprintf("failed to read UUID from AG %d\n", agno); return 0; } if (agno) { if (memcmp(&uu, uup, sizeof(uuid_t))) { dbprintf("warning: uuid copies differ\n"); break; } } else { memcpy(uu, uup, sizeof(uuid_t)); } } if (mp->m_sb.sb_logstart) { if (xfsargs.logdev) dbprintf("warning: external log specified for FS with internal log\n"); } else { if (!xfsargs.logdev) { dbprintf("warning: no external log specified for FS with external log\n"); } } uuid_unparse(uu, bp); dbprintf("uuid = %s\n", bp); } return 0; }