]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/logformat.c
xfs_scrub: adapt phase5 to deferred descriptions
[thirdparty/xfsprogs-dev.git] / db / logformat.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2015 Red Hat, Inc.
4 * All Rights Reserved.
5 */
6
7 #include "libxfs.h"
8 #include "command.h"
9 #include "init.h"
10 #include "output.h"
11 #include "libxlog.h"
12 #include "logformat.h"
13
14 #define MAX_LSUNIT 256 * 1024 /* max log buf. size */
15
16 static int
17 logformat_f(int argc, char **argv)
18 {
19 xfs_daddr_t head_blk;
20 xfs_daddr_t tail_blk;
21 int logversion;
22 int lsunit = -1;
23 int cycle = -1;
24 int error;
25 int c;
26
27 logversion = xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1;
28
29 while ((c = getopt(argc, argv, "c:s:")) != EOF) {
30 switch (c) {
31 case 'c':
32 cycle = strtol(optarg, NULL, 0);
33 if (cycle == 0) {
34 dbprintf("invalid cycle\n");
35 return -1;
36 }
37 break;
38 case 's':
39 lsunit = strtol(optarg, NULL, 0);
40 /*
41 * The log stripe unit must be block aligned and no
42 * larger than 256k.
43 */
44 if (lsunit > 1 &&
45 (lsunit % mp->m_sb.sb_blocksize ||
46 (logversion == 2 && lsunit > MAX_LSUNIT))) {
47 dbprintf("invalid log stripe unit\n");
48 return -1;
49 }
50 break;
51 default:
52 dbprintf("invalid option\n");
53 return -1;
54 }
55 }
56
57 /*
58 * Check whether the log is dirty. This also determines the current log
59 * cycle if we have to use it by default below.
60 */
61 memset(mp->m_log, 0, sizeof(struct xlog));
62 mp->m_log->l_mp = mp;
63 mp->m_log->l_dev = mp->m_logdev_targp;
64 mp->m_log->l_logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
65 mp->m_log->l_logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart);
66 mp->m_log->l_sectBBsize = BBSIZE;
67 if (xfs_sb_version_hassector(&mp->m_sb))
68 mp->m_log->l_sectBBsize <<= (mp->m_sb.sb_logsectlog - BBSHIFT);
69 mp->m_log->l_sectBBsize = BTOBB(mp->m_log->l_sectBBsize);
70
71 error = xlog_find_tail(mp->m_log, &head_blk, &tail_blk);
72 if (error) {
73 dbprintf("could not find log head/tail\n");
74 return -1;
75 }
76 if (head_blk != tail_blk) {
77 dbprintf(_(
78 "The log is dirty. Please mount to replay the log.\n"));
79 return -1;
80 }
81
82 /*
83 * Use the current cycle and/or log stripe unit if either is not
84 * provided by the user.
85 */
86 if (cycle < 0)
87 cycle = mp->m_log->l_curr_cycle;
88 if (lsunit < 0)
89 lsunit = mp->m_sb.sb_logsunit;
90
91 dbprintf("Formatting the log to cycle %d, stripe unit %d bytes.\n",
92 cycle, lsunit);
93 error = -libxfs_log_clear(mp->m_logdev_targp, NULL,
94 mp->m_log->l_logBBstart,
95 mp->m_log->l_logBBsize,
96 &mp->m_sb.sb_uuid, logversion, lsunit,
97 XLOG_FMT, cycle, false);
98 if (error) {
99 dbprintf("error formatting log - %d\n", error);
100 return error;
101 }
102
103 return 0;
104 }
105
106 static void
107 logformat_help(void)
108 {
109 dbprintf(_(
110 "\n"
111 " The 'logformat' command reformats (clears) the log to the specified log\n"
112 " cycle and log stripe unit. If the log cycle is not specified, the log is\n"
113 " reformatted to the current cycle. If the log stripe unit is not specified,\n"
114 " the stripe unit from the filesystem superblock is used.\n"
115 "\n"
116 ));
117 }
118
119 static const struct cmdinfo logformat_cmd = {
120 .name = "logformat",
121 .altname = NULL,
122 .cfunc = logformat_f,
123 .argmin = 0,
124 .argmax = 4,
125 .canpush = 0,
126 .args = N_("[-c cycle] [-s sunit]"),
127 .oneline = N_("reformat the log"),
128 .help = logformat_help,
129 };
130
131 void
132 logformat_init(void)
133 {
134 if (!expert_mode)
135 return;
136
137 add_command(&logformat_cmd);
138 }
139
140 static void
141 print_logres(
142 int i,
143 struct xfs_trans_res *res)
144 {
145 dbprintf(_("type %d logres %u logcount %d flags 0x%x\n"),
146 i, res->tr_logres, res->tr_logcount, res->tr_logflags);
147 }
148
149 static int
150 logres_f(
151 int argc,
152 char **argv)
153 {
154 struct xfs_trans_res resv;
155 struct xfs_trans_res *res;
156 struct xfs_trans_res *end_res;
157 int i;
158
159 res = (struct xfs_trans_res *)M_RES(mp);
160 end_res = (struct xfs_trans_res *)(M_RES(mp) + 1);
161 for (i = 0; res < end_res; i++, res++)
162 print_logres(i, res);
163 libxfs_log_get_max_trans_res(mp, &resv);
164 print_logres(-1, &resv);
165
166 return 0;
167 }
168
169 static void
170 logres_help(void)
171 {
172 dbprintf(_(
173 "\n"
174 " The 'logres' command prints information about all log reservation types.\n"
175 " This includes the reservation space, the intended transaction roll count,\n"
176 " and the reservation flags, if any.\n"
177 "\n"
178 ));
179 }
180
181 static const struct cmdinfo logres_cmd = {
182 .name = "logres",
183 .altname = NULL,
184 .cfunc = logres_f,
185 .argmin = 0,
186 .argmax = 0,
187 .canpush = 0,
188 .args = NULL,
189 .oneline = N_("dump log reservations"),
190 .help = logres_help,
191 };
192
193 void
194 logres_init(void)
195 {
196 add_command(&logres_cmd);
197 }