diff options
-rw-r--r-- | fs/xfs/libxfs/xfs_fs.h | 6 | ||||
-rw-r--r-- | fs/xfs/scrub/common.h | 3 | ||||
-rw-r--r-- | fs/xfs/scrub/scrub.c | 5 | ||||
-rw-r--r-- | fs/xfs/xfs_ioctl.c | 3 |
4 files changed, 14 insertions, 3 deletions
diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h index 7ac2b0a99aae..5911508d8f38 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -791,9 +791,13 @@ struct xfs_scrub_metadata { /* i: Don't mark inodes DONTCACHE at the end. */ #define XFS_SCRUB_IFLAG_RETAIN_INODES (1 << 9) +/* i: Rebuild the data structure. */ +#define XFS_SCRUB_IFLAG_FORCE_REBUILD (1 << 10) + #define XFS_SCRUB_FLAGS_IN (XFS_SCRUB_IFLAG_REPAIR | \ XFS_SCRUB_IFLAG_FREEZE_OK | \ - XFS_SCRUB_IFLAG_RETAIN_INODES) + XFS_SCRUB_IFLAG_RETAIN_INODES | \ + XFS_SCRUB_IFLAG_FORCE_REBUILD) #define XFS_SCRUB_FLAGS_OUT (XFS_SCRUB_OFLAG_CORRUPT | \ XFS_SCRUB_OFLAG_PREEN | \ XFS_SCRUB_OFLAG_XFAIL | \ diff --git a/fs/xfs/scrub/common.h b/fs/xfs/scrub/common.h index 70a42897cd22..dc7b2f41c1d2 100644 --- a/fs/xfs/scrub/common.h +++ b/fs/xfs/scrub/common.h @@ -194,7 +194,8 @@ static inline bool xfs_scrub_needs_repair(struct xfs_scrub_metadata *sm) { return sm->sm_flags & (XFS_SCRUB_OFLAG_CORRUPT | XFS_SCRUB_OFLAG_XCORRUPT | - XFS_SCRUB_OFLAG_PREEN); + XFS_SCRUB_OFLAG_PREEN | + XFS_SCRUB_IFLAG_FORCE_REBUILD); } int xchk_iwalk_find_next(struct xfs_mount *mp, struct xfs_trans *tp, diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c index d3944a1d0146..3a43fe95dfc8 100644 --- a/fs/xfs/scrub/scrub.c +++ b/fs/xfs/scrub/scrub.c @@ -476,6 +476,11 @@ xchk_validate_inputs( goto out; } + /* No rebuild without repair. */ + if ((sm->sm_flags & XFS_SCRUB_IFLAG_FORCE_REBUILD) && + !(sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR)) + return -EINVAL; + /* * We only want to repair read-write v5+ filesystems. Defer the check * for ops->repair until after our scrub confirms that we need to diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 8913c27ddd11..525eba22c2a2 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -1810,7 +1810,8 @@ xfs_ioc_scrub_metadata( if (copy_from_user(&scrub, arg, sizeof(scrub))) return -EFAULT; - if ((scrub.sm_flags & XFS_SCRUB_IFLAG_FREEZE_OK) && + if ((scrub.sm_flags & (XFS_SCRUB_IFLAG_FREEZE_OK | + XFS_SCRUB_IFLAG_FORCE_REBUILD)) && !capable(CAP_SYS_ADMIN)) return -EPERM; |