Commit 8feb4732 authored by Darrick J. Wong's avatar Darrick J. Wong

xfs: allow parent directory scans to be interrupted with fatal signals

Allow a fatal signal to interrupt us when we're scanning a directory to
verify a parent pointer.
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
parent 2911edb6
...@@ -32,8 +32,10 @@ xchk_setup_parent( ...@@ -32,8 +32,10 @@ xchk_setup_parent(
struct xchk_parent_ctx { struct xchk_parent_ctx {
struct dir_context dc; struct dir_context dc;
struct xfs_scrub *sc;
xfs_ino_t ino; xfs_ino_t ino;
xfs_nlink_t nlink; xfs_nlink_t nlink;
bool cancelled;
}; };
/* Look for a single entry in a directory pointing to an inode. */ /* Look for a single entry in a directory pointing to an inode. */
...@@ -47,11 +49,21 @@ xchk_parent_actor( ...@@ -47,11 +49,21 @@ xchk_parent_actor(
unsigned type) unsigned type)
{ {
struct xchk_parent_ctx *spc; struct xchk_parent_ctx *spc;
int error = 0;
spc = container_of(dc, struct xchk_parent_ctx, dc); spc = container_of(dc, struct xchk_parent_ctx, dc);
if (spc->ino == ino) if (spc->ino == ino)
spc->nlink++; spc->nlink++;
return 0;
/*
* If we're facing a fatal signal, bail out. Store the cancellation
* status separately because the VFS readdir code squashes error codes
* into short directory reads.
*/
if (xchk_should_terminate(spc->sc, &error))
spc->cancelled = true;
return error;
} }
/* Count the number of dentries in the parent dir that point to this inode. */ /* Count the number of dentries in the parent dir that point to this inode. */
...@@ -62,10 +74,9 @@ xchk_parent_count_parent_dentries( ...@@ -62,10 +74,9 @@ xchk_parent_count_parent_dentries(
xfs_nlink_t *nlink) xfs_nlink_t *nlink)
{ {
struct xchk_parent_ctx spc = { struct xchk_parent_ctx spc = {
.dc.actor = xchk_parent_actor, .dc.actor = xchk_parent_actor,
.dc.pos = 0, .ino = sc->ip->i_ino,
.ino = sc->ip->i_ino, .sc = sc,
.nlink = 0,
}; };
size_t bufsize; size_t bufsize;
loff_t oldpos; loff_t oldpos;
...@@ -97,6 +108,10 @@ xchk_parent_count_parent_dentries( ...@@ -97,6 +108,10 @@ xchk_parent_count_parent_dentries(
error = xfs_readdir(sc->tp, parent, &spc.dc, bufsize); error = xfs_readdir(sc->tp, parent, &spc.dc, bufsize);
if (error) if (error)
goto out; goto out;
if (spc.cancelled) {
error = -EAGAIN;
goto out;
}
if (oldpos == spc.dc.pos) if (oldpos == spc.dc.pos)
break; break;
oldpos = spc.dc.pos; oldpos = spc.dc.pos;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment