]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/crc.c
2 * Copyright (c) 2016 Red Hat, Inc.
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.
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.
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.
32 static int crc_f(int argc
, char **argv
);
33 static void crc_help(void);
35 static 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
};
42 if (xfs_sb_version_hascrc(&mp
->m_sb
))
43 add_command(&crc_cmd
);
51 " 'crc' validates, invalidates, or recalculates the crc value for\n"
52 " the current on-disk metadata structures in Version 5 filesystems.\n"
54 " Usage: \"crc [-i|-r|-v]\"\n"
65 const struct xfs_buf_ops
*stashed_ops
= NULL
;
66 extern char *progname
;
67 const field_t
*fields
;
75 if (cur_typ
== NULL
) {
76 dbprintf(_("no current type\n"));
80 if (cur_typ
->fields
== NULL
) {
81 dbprintf(_("current type (%s) is not a structure\n"),
86 if (argc
) while ((c
= getopt(argc
, argv
, "irv")) != EOF
) {
98 dbprintf(_("bad option for crc command\n"));
104 if (invalidate
+ recalculate
+ validate
> 1) {
105 dbprintf(_("crc command accepts only one option\n"));
109 if ((invalidate
|| recalculate
) &&
110 ((x
.isreadonly
& LIBXFS_ISREADONLY
) || !expert_mode
)) {
111 dbprintf(_("%s not in expert mode, writing disabled\n"),
116 fields
= cur_typ
->fields
;
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
);
125 /* Search for a CRC field */
126 fl
= flist_find_ftyp(fields
, FLDT_CRC
);
128 dbprintf(_("No CRC field found for type %s\n"), cur_typ
->name
);
132 /* run down the field list and set offsets into the data */
133 if (!flist_parse(fields
, fl
, iocur_top
->data
, 0)) {
135 dbprintf(_("parsing error\n"));
140 struct xfs_buf_ops nowrite_ops
;
149 parentoffset
= sfl
->offset
;
152 ASSERT(sfl
->fld
->ftyp
== FLDT_CRC
);
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
,
159 crc
= cpu_to_be32(crc
+ 1);
160 setbitval(iocur_top
->data
, sfl
->offset
, bit_length
, &crc
);
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
;
169 if (invalidate
|| recalculate
) {
171 dbprintf(_("Invalidating CRC:\n"));
173 dbprintf(_("Recalculating CRC:\n"));
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
);
181 dbprintf(_("Verifying CRC:\n"));
183 /* And show us what we've got! */