Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <albinbabuvarghese20@gmail.com>
Signed-off-by: Albin Babu Varghese <albinbabuvarghese20@gmail.com>
Signed-off-by: Ahmet Eray Karadag <eraykrdg1@gmail.com>
Suggested-by: Heming Zhao <heming.zhao@suse.com>
Reviewed-by: Heming Zhao <heming.zhao@suse.com>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Cc: David Hunter <david.hunter.linux@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Ahmet Eray Karadag and committed by
Andrew Morton
752ba097 01da5216

+24
+6
fs/ocfs2/file.c
··· 1136 1136 attr->ia_valid & ATTR_GID ? 1137 1137 from_kgid(&init_user_ns, attr->ia_gid) : 0); 1138 1138 1139 + status = ocfs2_emergency_state(osb); 1140 + if (unlikely(status)) { 1141 + mlog_errno(status); 1142 + goto bail; 1143 + } 1144 + 1139 1145 /* ensuring we don't even attempt to truncate a symlink */ 1140 1146 if (S_ISLNK(inode->i_mode)) 1141 1147 attr->ia_valid &= ~ATTR_SIZE;
+18
fs/ocfs2/ocfs2.h
··· 680 680 return ret; 681 681 } 682 682 683 + static inline int ocfs2_is_readonly(struct ocfs2_super *osb) 684 + { 685 + int ret; 686 + spin_lock(&osb->osb_lock); 687 + ret = osb->osb_flags & (OCFS2_OSB_SOFT_RO | OCFS2_OSB_HARD_RO); 688 + spin_unlock(&osb->osb_lock); 689 + 690 + return ret; 691 + } 692 + 693 + static inline int ocfs2_emergency_state(struct ocfs2_super *osb) 694 + { 695 + if (ocfs2_is_readonly(osb)) 696 + return -EROFS; 697 + 698 + return 0; 699 + } 700 + 683 701 static inline int ocfs2_clusterinfo_valid(struct ocfs2_super *osb) 684 702 { 685 703 return (osb->s_feature_incompat &