summaryrefslogtreecommitdiff
path: root/fs/xfs/libxfs/xfs_rtgroup.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/libxfs/xfs_rtgroup.c')
-rw-r--r--fs/xfs/libxfs/xfs_rtgroup.c38
1 files changed, 33 insertions, 5 deletions
diff --git a/fs/xfs/libxfs/xfs_rtgroup.c b/fs/xfs/libxfs/xfs_rtgroup.c
index 470260c911c8..790a0b8c137f 100644
--- a/fs/xfs/libxfs/xfs_rtgroup.c
+++ b/fs/xfs/libxfs/xfs_rtgroup.c
@@ -271,6 +271,8 @@ struct xfs_rtginode_ops {
enum xfs_metafile_type metafile_type;
+ unsigned int sick; /* rtgroup sickness flag */
+
/* Does the fs have this feature? */
bool (*enabled)(struct xfs_mount *mp);
@@ -285,11 +287,13 @@ static const struct xfs_rtginode_ops xfs_rtginode_ops[XFS_RTGI_MAX] = {
[XFS_RTGI_BITMAP] = {
.name = "bitmap",
.metafile_type = XFS_METAFILE_RTBITMAP,
+ .sick = XFS_SICK_RG_BITMAP,
.create = xfs_rtbitmap_create,
},
[XFS_RTGI_SUMMARY] = {
.name = "summary",
.metafile_type = XFS_METAFILE_RTSUMMARY,
+ .sick = XFS_SICK_RG_SUMMARY,
.create = xfs_rtsummary_create,
},
};
@@ -323,6 +327,17 @@ xfs_rtginode_enabled(
return ops->enabled(rtg_mount(rtg));
}
+/* Mark an rtgroup inode sick */
+void
+xfs_rtginode_mark_sick(
+ struct xfs_rtgroup *rtg,
+ enum xfs_rtg_inodes type)
+{
+ const struct xfs_rtginode_ops *ops = &xfs_rtginode_ops[type];
+
+ xfs_group_mark_sick(rtg_group(rtg), ops->sick);
+}
+
/* Load and existing rtgroup inode into the rtgroup structure. */
int
xfs_rtginode_load(
@@ -358,8 +373,10 @@ xfs_rtginode_load(
} else {
const char *path;
- if (!mp->m_rtdirip)
+ if (!mp->m_rtdirip) {
+ xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
return -EFSCORRUPTED;
+ }
path = xfs_rtginode_path(rtg_rgno(rtg), type);
if (!path)
@@ -369,17 +386,22 @@ xfs_rtginode_load(
kfree(path);
}
- if (error)
+ if (error) {
+ if (xfs_metadata_is_sick(error))
+ xfs_rtginode_mark_sick(rtg, type);
return error;
+ }
if (XFS_IS_CORRUPT(mp, ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS &&
ip->i_df.if_format != XFS_DINODE_FMT_BTREE)) {
xfs_irele(ip);
+ xfs_rtginode_mark_sick(rtg, type);
return -EFSCORRUPTED;
}
if (XFS_IS_CORRUPT(mp, ip->i_projid != rtg_rgno(rtg))) {
xfs_irele(ip);
+ xfs_rtginode_mark_sick(rtg, type);
return -EFSCORRUPTED;
}
@@ -416,8 +438,10 @@ xfs_rtginode_create(
if (!xfs_rtginode_enabled(rtg, type))
return 0;
- if (!mp->m_rtdirip)
+ if (!mp->m_rtdirip) {
+ xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
return -EFSCORRUPTED;
+ }
upd.path = xfs_rtginode_path(rtg_rgno(rtg), type);
if (!upd.path)
@@ -464,8 +488,10 @@ int
xfs_rtginode_mkdir_parent(
struct xfs_mount *mp)
{
- if (!mp->m_metadirip)
+ if (!mp->m_metadirip) {
+ xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
return -EFSCORRUPTED;
+ }
return xfs_metadir_mkdir(mp->m_metadirip, "rtgroups", &mp->m_rtdirip);
}
@@ -477,8 +503,10 @@ xfs_rtginode_load_parent(
{
struct xfs_mount *mp = tp->t_mountp;
- if (!mp->m_metadirip)
+ if (!mp->m_metadirip) {
+ xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
return -EFSCORRUPTED;
+ }
return xfs_metadir_load(tp, mp->m_metadirip, "rtgroups",
XFS_METAFILE_DIR, &mp->m_rtdirip);