Skip to content

Commit dcb660f

Browse files
committed
xfs: probe the scrub ioctl
Create a probe scrubber with id 0. This will be used by xfs_scrub to probe the kernel's abilities to scrub (and repair) the metadata. We do this by validating the ioctl inputs from userspace, preparing the filesystem for a scrub (or a repair) operation, and immediately returning to userspace. Userspace can use the returned errno and structure state to decide (in broad terms) if scrub/repair are supported by the running kernel. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Dave Chinner <dchinner@redhat.com>
1 parent a563718 commit dcb660f

File tree

7 files changed

+150
-1
lines changed

7 files changed

+150
-1
lines changed

fs/xfs/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ ifeq ($(CONFIG_XFS_ONLINE_SCRUB),y)
143143

144144
xfs-y += $(addprefix scrub/, \
145145
trace.o \
146+
common.o \
146147
scrub.o \
147148
)
148149
endif

fs/xfs/libxfs/xfs_fs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,9 +483,10 @@ struct xfs_scrub_metadata {
483483
*/
484484

485485
/* Scrub subcommands. */
486+
#define XFS_SCRUB_TYPE_PROBE 0 /* presence test ioctl */
486487

487488
/* Number of scrub subcommands. */
488-
#define XFS_SCRUB_TYPE_NR 0
489+
#define XFS_SCRUB_TYPE_NR 1
489490

490491
/* i: Repair this metadata. */
491492
#define XFS_SCRUB_IFLAG_REPAIR (1 << 0)

fs/xfs/scrub/common.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (C) 2017 Oracle. All Rights Reserved.
3+
*
4+
* Author: Darrick J. Wong <darrick.wong@oracle.com>
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU General Public License
8+
* as published by the Free Software Foundation; either version 2
9+
* of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it would be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program; if not, write the Free Software Foundation,
18+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
#include "xfs.h"
21+
#include "xfs_fs.h"
22+
#include "xfs_shared.h"
23+
#include "xfs_format.h"
24+
#include "xfs_trans_resv.h"
25+
#include "xfs_mount.h"
26+
#include "xfs_defer.h"
27+
#include "xfs_btree.h"
28+
#include "xfs_bit.h"
29+
#include "xfs_log_format.h"
30+
#include "xfs_trans.h"
31+
#include "xfs_sb.h"
32+
#include "xfs_inode.h"
33+
#include "xfs_alloc.h"
34+
#include "xfs_alloc_btree.h"
35+
#include "xfs_bmap.h"
36+
#include "xfs_bmap_btree.h"
37+
#include "xfs_ialloc.h"
38+
#include "xfs_ialloc_btree.h"
39+
#include "xfs_refcount.h"
40+
#include "xfs_refcount_btree.h"
41+
#include "xfs_rmap.h"
42+
#include "xfs_rmap_btree.h"
43+
#include "scrub/xfs_scrub.h"
44+
#include "scrub/scrub.h"
45+
#include "scrub/common.h"
46+
#include "scrub/trace.h"
47+
48+
/* Common code for the metadata scrubbers. */
49+
50+
/* Per-scrubber setup functions */
51+
52+
/* Set us up with a transaction and an empty context. */
53+
int
54+
xfs_scrub_setup_fs(
55+
struct xfs_scrub_context *sc,
56+
struct xfs_inode *ip)
57+
{
58+
return xfs_scrub_trans_alloc(sc->sm, sc->mp, &sc->tp);
59+
}

fs/xfs/scrub/common.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (C) 2017 Oracle. All Rights Reserved.
3+
*
4+
* Author: Darrick J. Wong <darrick.wong@oracle.com>
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU General Public License
8+
* as published by the Free Software Foundation; either version 2
9+
* of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it would be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program; if not, write the Free Software Foundation,
18+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
#ifndef __XFS_SCRUB_COMMON_H__
21+
#define __XFS_SCRUB_COMMON_H__
22+
23+
/*
24+
* We /could/ terminate a scrub/repair operation early. If we're not
25+
* in a good place to continue (fatal signal, etc.) then bail out.
26+
* Note that we're careful not to make any judgements about *error.
27+
*/
28+
static inline bool
29+
xfs_scrub_should_terminate(
30+
struct xfs_scrub_context *sc,
31+
int *error)
32+
{
33+
if (fatal_signal_pending(current)) {
34+
if (*error == 0)
35+
*error = -EAGAIN;
36+
return true;
37+
}
38+
return false;
39+
}
40+
41+
/*
42+
* Grab an empty transaction so that we can re-grab locked buffers if
43+
* one of our btrees turns out to be cyclic.
44+
*/
45+
static inline int
46+
xfs_scrub_trans_alloc(
47+
struct xfs_scrub_metadata *sm,
48+
struct xfs_mount *mp,
49+
struct xfs_trans **tpp)
50+
{
51+
return xfs_trans_alloc_empty(mp, tpp);
52+
}
53+
54+
/* Setup functions */
55+
int xfs_scrub_setup_fs(struct xfs_scrub_context *sc, struct xfs_inode *ip);
56+
57+
#endif /* __XFS_SCRUB_COMMON_H__ */

fs/xfs/scrub/scrub.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "xfs_rmap_btree.h"
4343
#include "scrub/xfs_scrub.h"
4444
#include "scrub/scrub.h"
45+
#include "scrub/common.h"
4546
#include "scrub/trace.h"
4647

4748
/*
@@ -108,6 +109,30 @@
108109
* will be set.
109110
*/
110111

112+
/*
113+
* Scrub probe -- userspace uses this to probe if we're willing to scrub
114+
* or repair a given mountpoint. This will be used by xfs_scrub to
115+
* probe the kernel's abilities to scrub (and repair) the metadata. We
116+
* do this by validating the ioctl inputs from userspace, preparing the
117+
* filesystem for a scrub (or a repair) operation, and immediately
118+
* returning to userspace. Userspace can use the returned errno and
119+
* structure state to decide (in broad terms) if scrub/repair are
120+
* supported by the running kernel.
121+
*/
122+
int
123+
xfs_scrub_probe(
124+
struct xfs_scrub_context *sc)
125+
{
126+
int error = 0;
127+
128+
if (sc->sm->sm_ino || sc->sm->sm_agno)
129+
return -EINVAL;
130+
if (xfs_scrub_should_terminate(sc, &error))
131+
return error;
132+
133+
return 0;
134+
}
135+
111136
/* Scrub setup and teardown */
112137

113138
/* Free all the resources and finish the transactions. */
@@ -126,6 +151,10 @@ xfs_scrub_teardown(
126151
/* Scrubbing dispatch. */
127152

128153
static const struct xfs_scrub_meta_ops meta_scrub_ops[] = {
154+
{ /* ioctl presence test */
155+
.setup = xfs_scrub_setup_fs,
156+
.scrub = xfs_scrub_probe,
157+
},
129158
};
130159

131160
/* This isn't a stable feature, warn once per day. */

fs/xfs/scrub/scrub.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,6 @@ struct xfs_scrub_context {
4545
};
4646

4747
/* Metadata scrubbers */
48+
int xfs_scrub_tester(struct xfs_scrub_context *sc);
4849

4950
#endif /* __XFS_SCRUB_SCRUB_H__ */

fs/xfs/scrub/trace.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "xfs_trans.h"
3333
#include "scrub/xfs_scrub.h"
3434
#include "scrub/scrub.h"
35+
#include "scrub/common.h"
3536

3637
/*
3738
* We include this last to have the helpers above available for the trace

0 commit comments

Comments
 (0)