From: Ahmet Eray Karadag Date: Wed, 3 Dec 2025 03:34:25 +0000 (+0300) Subject: ocfs2: add ocfs2_emergency_state helper and apply to setattr X-Git-Tag: v6.19-rc1~8^2~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=752ba0976b25d69cfac55137573298bd5dd88aa2;p=thirdparty%2Flinux.git ocfs2: add ocfs2_emergency_state helper and apply to setattr Patch series "ocfs2: Refactor read-only checks to use ocfs2_emergency_state", v4. Following the fix for the `make_bad_inode` validation failure (syzbot ID: b93b65ee321c97861072), this separate series introduces a new helper function, `ocfs2_emergency_state()`, to improve and centralize read-only and error state checking. This is modeled after the `ext4_emergency_state()` pattern, providing a single, unified location for checking all filesystem-level emergency conditions. This makes the code cleaner and ensures that any future checks (e.g., for fatal error states) can be added in one place. This series is structured as follows: 1. The first patch introduces the `ocfs2_emergency_state()` helper (currently checking for -EROFS) and applies it to `ocfs2_setattr` to provide a "fail-fast" mechanism, as suggested by Albin Babu Varghese. 2. The second patch completes the refactoring by converting all remaining read-only checks throughout OCFS2 to use this new helper. This patch (of 2): To centralize error checking, follow the pattern of other filesystems like ext4 (which uses `ext4_emergency_state()`), and prepare for future enhancements, this patch introduces a new helper function: `ocfs2_emergency_state()`. The purpose of this helper is to provide a single, unified location for checking all filesystem-level emergency conditions. In this initial implementation, the function only checks for the existing hard and soft read-only modes, returning -EROFS if either is set. This provides a foundation where future checks (e.g., for fatal error states returning -EIO, or shutdown states) can be easily added in one place. This patch also adds this new check to the beginning of `ocfs2_setattr()`. This ensures that operations like `ftruncate` (which triggered the original BUG) fail-fast with -EROFS when the filesystem is already in a read-only state. Link: https://lkml.kernel.org/r/cover.1764728893.git.eraykrdg1@gmail.com Link: https://lkml.kernel.org/r/e9e975bcaaff8dbc155b70fbc1b2798a2e36e96f.1764728893.git.eraykrdg1@gmail.com Co-developed-by: Albin Babu Varghese Signed-off-by: Albin Babu Varghese Signed-off-by: Ahmet Eray Karadag Suggested-by: Heming Zhao Reviewed-by: Heming Zhao Reviewed-by: Joseph Qi Cc: Mark Fasheh Cc: Joel Becker Cc: Junxiao Bi Cc: Changwei Ge Cc: Jun Piao Cc: David Hunter Signed-off-by: Andrew Morton --- diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 21d797ccccd0..ddca292944d7 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -1136,6 +1136,12 @@ int ocfs2_setattr(struct mnt_idmap *idmap, struct dentry *dentry, attr->ia_valid & ATTR_GID ? from_kgid(&init_user_ns, attr->ia_gid) : 0); + status = ocfs2_emergency_state(osb); + if (unlikely(status)) { + mlog_errno(status); + goto bail; + } + /* ensuring we don't even attempt to truncate a symlink */ if (S_ISLNK(inode->i_mode)) attr->ia_valid &= ~ATTR_SIZE; diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 6aaa94c554c1..7b50e03dfa66 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h @@ -680,6 +680,24 @@ static inline int ocfs2_is_soft_readonly(struct ocfs2_super *osb) return ret; } +static inline int ocfs2_is_readonly(struct ocfs2_super *osb) +{ + int ret; + spin_lock(&osb->osb_lock); + ret = osb->osb_flags & (OCFS2_OSB_SOFT_RO | OCFS2_OSB_HARD_RO); + spin_unlock(&osb->osb_lock); + + return ret; +} + +static inline int ocfs2_emergency_state(struct ocfs2_super *osb) +{ + if (ocfs2_is_readonly(osb)) + return -EROFS; + + return 0; +} + static inline int ocfs2_clusterinfo_valid(struct ocfs2_super *osb) { return (osb->s_feature_incompat &