]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - db/crc.c
libxfs/linux.c: Replace use of ustat by stat
[thirdparty/xfsprogs-dev.git] / db / crc.c
CommitLineData
b64af2c4
ES
1/*
2 * Copyright (c) 2016 Red Hat, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation.
16 */
17
18#include "libxfs.h"
19#include "addr.h"
20#include "command.h"
21#include "type.h"
22#include "faddr.h"
23#include "fprint.h"
24#include "field.h"
25#include "flist.h"
26#include "io.h"
27#include "init.h"
28#include "output.h"
29#include "bit.h"
30#include "print.h"
31
32static int crc_f(int argc, char **argv);
33static void crc_help(void);
34
35static const cmdinfo_t crc_cmd =
36 { "crc", NULL, crc_f, 0, 1, 0, "[-i|-r|-v]",
37 N_("manipulate crc values for V5 filesystem structures"), crc_help };
38
39void
40crc_init(void)
41{
42 if (xfs_sb_version_hascrc(&mp->m_sb))
43 add_command(&crc_cmd);
44}
45
46static void
47crc_help(void)
48{
49 dbprintf(_(
50"\n"
51" 'crc' validates, invalidates, or recalculates the crc value for\n"
52" the current on-disk metadata structures in Version 5 filesystems.\n"
53"\n"
54" Usage: \"crc [-i|-r|-v]\"\n"
55"\n"
56));
57
58}
59
60static int
61crc_f(
62 int argc,
63 char **argv)
64{
65 const struct xfs_buf_ops *stashed_ops = NULL;
66 extern char *progname;
67 const field_t *fields;
68 const ftattr_t *fa;
69 flist_t *fl;
70 int invalidate = 0;
71 int recalculate = 0;
72 int validate = 0;
73 int c;
74
75 if (cur_typ == NULL) {
76 dbprintf(_("no current type\n"));
77 return 0;
78 }
79
80 if (cur_typ->fields == NULL) {
81 dbprintf(_("current type (%s) is not a structure\n"),
82 cur_typ->name);
83 return 0;
84 }
85
86 if (argc) while ((c = getopt(argc, argv, "irv")) != EOF) {
87 switch (c) {
88 case 'i':
89 invalidate = 1;
90 break;
91 case 'r':
92 recalculate = 1;
93 break;
94 case 'v':
95 validate = 1;
96 break;
97 default:
98 dbprintf(_("bad option for crc command\n"));
99 return 0;
100 }
101 } else
102 validate = 1;
103
104 if (invalidate + recalculate + validate > 1) {
105 dbprintf(_("crc command accepts only one option\n"));
106 return 0;
107 }
108
109 if ((invalidate || recalculate) &&
110 ((x.isreadonly & LIBXFS_ISREADONLY) || !expert_mode)) {
111 dbprintf(_("%s not in expert mode, writing disabled\n"),
112 progname);
113 return 0;
114 }
115
116 fields = cur_typ->fields;
117
118 /* if we're a root field type, go down 1 layer to get field list */
119 if (fields->name[0] == '\0') {
120 fa = &ftattrtab[fields->ftyp];
121 ASSERT(fa->ftyp == fields->ftyp);
122 fields = fa->subfld;
123 }
124
125 /* Search for a CRC field */
126 fl = flist_find_ftyp(fields, FLDT_CRC);
127 if (!fl) {
128 dbprintf(_("No CRC field found for type %s\n"), cur_typ->name);
129 return 0;
130 }
131
132 /* run down the field list and set offsets into the data */
133 if (!flist_parse(fields, fl, iocur_top->data, 0)) {
134 flist_free(fl);
135 dbprintf(_("parsing error\n"));
136 return 0;
137 }
138
139 if (invalidate) {
140 struct xfs_buf_ops nowrite_ops;
141 flist_t *sfl;
142 int bit_length;
143 int parentoffset;
144 int crc;
145
146 sfl = fl;
147 parentoffset = 0;
148 while (sfl->child) {
149 parentoffset = sfl->offset;
150 sfl = sfl->child;
151 }
152 ASSERT(sfl->fld->ftyp == FLDT_CRC);
153
154 bit_length = fsize(sfl->fld, iocur_top->data, parentoffset, 0);
155 bit_length *= fcount(sfl->fld, iocur_top->data, parentoffset);
156 crc = getbitval(iocur_top->data, sfl->offset, bit_length,
157 BVUNSIGNED);
158 /* Off by one.. */
159 crc = cpu_to_be32(crc + 1);
160 setbitval(iocur_top->data, sfl->offset, bit_length, &crc);
161
162 /* Temporarily remove write verifier to write a bad CRC */
163 stashed_ops = iocur_top->bp->b_ops;
164 nowrite_ops.verify_read = stashed_ops->verify_read;
165 nowrite_ops.verify_write = xfs_dummy_verify;
166 iocur_top->bp->b_ops = &nowrite_ops;
167 }
168
169 if (invalidate || recalculate) {
170 if (invalidate)
171 dbprintf(_("Invalidating CRC:\n"));
172 else
173 dbprintf(_("Recalculating CRC:\n"));
174
175 write_cur();
176 if (stashed_ops)
177 iocur_top->bp->b_ops = stashed_ops;
178 /* re-verify to get proper b_error state */
179 iocur_top->bp->b_ops->verify_read(iocur_top->bp);
180 } else
181 dbprintf(_("Verifying CRC:\n"));
182
183 /* And show us what we've got! */
184 flist_print(fl);
185 print_flist(fl);
186 flist_free(fl);
187 return 0;
188}