* [PATCH 0/2] ocfs2: Refactor read-only checks to use ocfs2_emergency_state
@ 2025-11-18 0:26 Ahmet Eray Karadag
2025-11-18 0:26 ` [PATCH 1/2] ocfs2: Add ocfs2_emergency_state helper and apply to setattr Ahmet Eray Karadag
2025-11-18 0:26 ` [PATCH 2/2] ocfs2: Convert remaining read-only checks to ocfs2_emergency_state Ahmet Eray Karadag
0 siblings, 2 replies; 7+ messages in thread
From: Ahmet Eray Karadag @ 2025-11-18 0:26 UTC (permalink / raw)
To: mark, jlbec, joseph.qi
Cc: ocfs2-devel, linux-kernel, david.hunter.linux, skhan,
Ahmet Eray Karadag
Hi all,
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.
Ahmet Eray Karadag (2):
ocfs2: Add ocfs2_emergency_state helper and apply to setattr
ocfs2: Convert remaining read-only checks to ocfs2_emergency_state
fs/ocfs2/buffer_head_io.c | 4 ++--
fs/ocfs2/file.c | 23 ++++++++++++++++-------
fs/ocfs2/inode.c | 3 +--
fs/ocfs2/move_extents.c | 5 +++--
fs/ocfs2/ocfs2.h | 8 ++++++++
fs/ocfs2/resize.c | 8 +++++---
fs/ocfs2/super.c | 2 +-
7 files changed, 36 insertions(+), 17 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 1/2] ocfs2: Add ocfs2_emergency_state helper and apply to setattr 2025-11-18 0:26 [PATCH 0/2] ocfs2: Refactor read-only checks to use ocfs2_emergency_state Ahmet Eray Karadag @ 2025-11-18 0:26 ` Ahmet Eray Karadag 2025-11-25 2:58 ` Heming Zhao 2025-11-18 0:26 ` [PATCH 2/2] ocfs2: Convert remaining read-only checks to ocfs2_emergency_state Ahmet Eray Karadag 1 sibling, 1 reply; 7+ messages in thread From: Ahmet Eray Karadag @ 2025-11-18 0:26 UTC (permalink / raw) To: mark, jlbec, joseph.qi Cc: ocfs2-devel, linux-kernel, david.hunter.linux, skhan, Ahmet Eray Karadag, Heming Zhao, Albin Babu Varghese 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. Suggested-by: Heming Zhao <heming.zhao@suse.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> --- fs/ocfs2/file.c | 6 ++++++ fs/ocfs2/ocfs2.h | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 21d797ccccd0..03a98985ac92 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -1137,6 +1137,12 @@ int ocfs2_setattr(struct mnt_idmap *idmap, struct dentry *dentry, from_kgid(&init_user_ns, attr->ia_gid) : 0); /* ensuring we don't even attempt to truncate a symlink */ + status = ocfs2_emergency_state(osb); + if (status < 0) { + mlog_errno(status); + goto bail; + } + 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..2ac16632dd19 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h @@ -680,6 +680,14 @@ static inline int ocfs2_is_soft_readonly(struct ocfs2_super *osb) return ret; } +static inline int ocfs2_emergency_state(struct ocfs2_super *osb) +{ + if (ocfs2_is_soft_readonly(osb) || ocfs2_is_hard_readonly(osb)) { + return -EROFS; + } + return 0; +} + static inline int ocfs2_clusterinfo_valid(struct ocfs2_super *osb) { return (osb->s_feature_incompat & -- 2.43.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] ocfs2: Add ocfs2_emergency_state helper and apply to setattr 2025-11-18 0:26 ` [PATCH 1/2] ocfs2: Add ocfs2_emergency_state helper and apply to setattr Ahmet Eray Karadag @ 2025-11-25 2:58 ` Heming Zhao 2025-11-28 9:06 ` Ahmet Eray Karadag 0 siblings, 1 reply; 7+ messages in thread From: Heming Zhao @ 2025-11-25 2:58 UTC (permalink / raw) To: Ahmet Eray Karadag Cc: mark, jlbec, joseph.qi, ocfs2-devel, linux-kernel, david.hunter.linux, skhan, Albin Babu Varghese On Tue, Nov 18, 2025 at 03:26:44AM +0300, Ahmet Eray Karadag wrote: > 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. > > Suggested-by: Heming Zhao <heming.zhao@suse.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> > --- > fs/ocfs2/file.c | 6 ++++++ > fs/ocfs2/ocfs2.h | 8 ++++++++ > 2 files changed, 14 insertions(+) > > diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c > index 21d797ccccd0..03a98985ac92 100644 > --- a/fs/ocfs2/file.c > +++ b/fs/ocfs2/file.c > @@ -1137,6 +1137,12 @@ int ocfs2_setattr(struct mnt_idmap *idmap, struct dentry *dentry, > from_kgid(&init_user_ns, attr->ia_gid) : 0); > > /* ensuring we don't even attempt to truncate a symlink */ > + status = ocfs2_emergency_state(osb); > + if (status < 0) { > + mlog_errno(status); > + goto bail; > + } > + I prefer the ext4_emerency_state() style, using "if (unlikely(status))" here. > 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..2ac16632dd19 100644 > --- a/fs/ocfs2/ocfs2.h > +++ b/fs/ocfs2/ocfs2.h > @@ -680,6 +680,14 @@ static inline int ocfs2_is_soft_readonly(struct ocfs2_super *osb) > return ret; > } > > +static inline int ocfs2_emergency_state(struct ocfs2_super *osb) > +{ > + if (ocfs2_is_soft_readonly(osb) || ocfs2_is_hard_readonly(osb)) { > + return -EROFS; > + } > + return 0; > +} > + calling ocfs2_is_[soft|hard]_readonly() is a little expensive because it involves acquiring the spinlock osb->osb_lock twice. In my view, we could introduce a new function, such as ocfs2_is_readonly(): ``` 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 } ``` Thanks, Heming > static inline int ocfs2_clusterinfo_valid(struct ocfs2_super *osb) > { > return (osb->s_feature_incompat & > -- > 2.43.0 > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] ocfs2: Add ocfs2_emergency_state helper and apply to setattr 2025-11-25 2:58 ` Heming Zhao @ 2025-11-28 9:06 ` Ahmet Eray Karadag 2025-12-01 7:43 ` Heming Zhao 0 siblings, 1 reply; 7+ messages in thread From: Ahmet Eray Karadag @ 2025-11-28 9:06 UTC (permalink / raw) To: Heming Zhao Cc: mark, jlbec, joseph.qi, ocfs2-devel, linux-kernel, david.hunter.linux, skhan, Albin Babu Varghese On Tue, Nov 25, 2025 at 10:58:32AM +0800, Heming Zhao wrote: > On Tue, Nov 18, 2025 at 03:26:44AM +0300, Ahmet Eray Karadag wrote: > > 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. > > > > Suggested-by: Heming Zhao <heming.zhao@suse.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> > > --- > > fs/ocfs2/file.c | 6 ++++++ > > fs/ocfs2/ocfs2.h | 8 ++++++++ > > 2 files changed, 14 insertions(+) > > > > diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c > > index 21d797ccccd0..03a98985ac92 100644 > > --- a/fs/ocfs2/file.c > > +++ b/fs/ocfs2/file.c > > @@ -1137,6 +1137,12 @@ int ocfs2_setattr(struct mnt_idmap *idmap, struct dentry *dentry, > > from_kgid(&init_user_ns, attr->ia_gid) : 0); > > > > /* ensuring we don't even attempt to truncate a symlink */ > > + status = ocfs2_emergency_state(osb); > > + if (status < 0) { > > + mlog_errno(status); > > + goto bail; > > + } > > + > > I prefer the ext4_emerency_state() style, using "if (unlikely(status))" here. > > > 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..2ac16632dd19 100644 > > --- a/fs/ocfs2/ocfs2.h > > +++ b/fs/ocfs2/ocfs2.h > > @@ -680,6 +680,14 @@ static inline int ocfs2_is_soft_readonly(struct ocfs2_super *osb) > > return ret; > > } > > > > +static inline int ocfs2_emergency_state(struct ocfs2_super *osb) > > +{ > > + if (ocfs2_is_soft_readonly(osb) || ocfs2_is_hard_readonly(osb)) { > > + return -EROFS; > > + } > > + return 0; > > +} > > + > > calling ocfs2_is_[soft|hard]_readonly() is a little expensive because it > involves acquiring the spinlock osb->osb_lock twice. In my view, we could > introduce a new function, such as ocfs2_is_readonly(): In ext4, the helper functions check read-only flags without acquiring a lock. Would it be problematic to do the same in ocfs2? > > ``` > 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 > } > ``` > > Thanks, > Heming > > > static inline int ocfs2_clusterinfo_valid(struct ocfs2_super *osb) > > { > > return (osb->s_feature_incompat & > > -- > > 2.43.0 > > I agree with the other comments. We will send v2. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] ocfs2: Add ocfs2_emergency_state helper and apply to setattr 2025-11-28 9:06 ` Ahmet Eray Karadag @ 2025-12-01 7:43 ` Heming Zhao 0 siblings, 0 replies; 7+ messages in thread From: Heming Zhao @ 2025-12-01 7:43 UTC (permalink / raw) To: Ahmet Eray Karadag Cc: mark, jlbec, joseph.qi, ocfs2-devel, linux-kernel, david.hunter.linux, skhan, Albin Babu Varghese On Fri, Nov 28, 2025 at 12:06:28PM +0300, Ahmet Eray Karadag wrote: > On Tue, Nov 25, 2025 at 10:58:32AM +0800, Heming Zhao wrote: > > On Tue, Nov 18, 2025 at 03:26:44AM +0300, Ahmet Eray Karadag wrote: > > > 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. > > > > > > Suggested-by: Heming Zhao <heming.zhao@suse.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> > > > --- > > > fs/ocfs2/file.c | 6 ++++++ > > > fs/ocfs2/ocfs2.h | 8 ++++++++ > > > 2 files changed, 14 insertions(+) > > > > > > diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c > > > index 21d797ccccd0..03a98985ac92 100644 > > > --- a/fs/ocfs2/file.c > > > +++ b/fs/ocfs2/file.c > > > @@ -1137,6 +1137,12 @@ int ocfs2_setattr(struct mnt_idmap *idmap, struct dentry *dentry, > > > from_kgid(&init_user_ns, attr->ia_gid) : 0); > > > > > > /* ensuring we don't even attempt to truncate a symlink */ > > > + status = ocfs2_emergency_state(osb); > > > + if (status < 0) { > > > + mlog_errno(status); > > > + goto bail; > > > + } > > > + > > > > I prefer the ext4_emerency_state() style, using "if (unlikely(status))" here. > > > > > 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..2ac16632dd19 100644 > > > --- a/fs/ocfs2/ocfs2.h > > > +++ b/fs/ocfs2/ocfs2.h > > > @@ -680,6 +680,14 @@ static inline int ocfs2_is_soft_readonly(struct ocfs2_super *osb) > > > return ret; > > > } > > > > > > +static inline int ocfs2_emergency_state(struct ocfs2_super *osb) > > > +{ > > > + if (ocfs2_is_soft_readonly(osb) || ocfs2_is_hard_readonly(osb)) { > > > + return -EROFS; > > > + } > > > + return 0; > > > +} > > > + > > > > calling ocfs2_is_[soft|hard]_readonly() is a little expensive because it > > involves acquiring the spinlock osb->osb_lock twice. In my view, we could > > introduce a new function, such as ocfs2_is_readonly(): > In ext4, the helper functions check read-only flags without acquiring a lock. > Would it be problematic to do the same in ocfs2? Comparing with the ext4 code, in my view, OCFS2 incorrectly mixes the normal read-only state with the emergency read-only state. For the minimal code change, we must currently acquire the spinlock to access osb->osb_flags. Thanks, Heming > > > > ``` > > 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 > > } > > ``` > > > > Thanks, > > Heming > > > > > static inline int ocfs2_clusterinfo_valid(struct ocfs2_super *osb) > > > { > > > return (osb->s_feature_incompat & > > > -- > > > 2.43.0 > > > > I agree with the other comments. We will send v2. ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/2] ocfs2: Convert remaining read-only checks to ocfs2_emergency_state 2025-11-18 0:26 [PATCH 0/2] ocfs2: Refactor read-only checks to use ocfs2_emergency_state Ahmet Eray Karadag 2025-11-18 0:26 ` [PATCH 1/2] ocfs2: Add ocfs2_emergency_state helper and apply to setattr Ahmet Eray Karadag @ 2025-11-18 0:26 ` Ahmet Eray Karadag 2025-11-25 3:02 ` Heming Zhao 1 sibling, 1 reply; 7+ messages in thread From: Ahmet Eray Karadag @ 2025-11-18 0:26 UTC (permalink / raw) To: mark, jlbec, joseph.qi Cc: ocfs2-devel, linux-kernel, david.hunter.linux, skhan, Ahmet Eray Karadag, Albin Babu Varghese 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. 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> --- fs/ocfs2/buffer_head_io.c | 4 ++-- fs/ocfs2/file.c | 17 ++++++++++------- fs/ocfs2/inode.c | 3 +-- fs/ocfs2/move_extents.c | 5 +++-- fs/ocfs2/resize.c | 8 +++++--- fs/ocfs2/super.c | 2 +- 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/fs/ocfs2/buffer_head_io.c b/fs/ocfs2/buffer_head_io.c index 8f714406528d..c43d4a58aa9a 100644 --- a/fs/ocfs2/buffer_head_io.c +++ b/fs/ocfs2/buffer_head_io.c @@ -434,8 +434,8 @@ int ocfs2_write_super_or_backup(struct ocfs2_super *osb, BUG_ON(buffer_jbd(bh)); ocfs2_check_super_or_backup(osb->sb, bh->b_blocknr); - if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) { - ret = -EROFS; + ret = ocfs2_emergency_state(osb); + if (ret < 0) { mlog_errno(ret); goto out; } diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 03a98985ac92..c299b73cf4ec 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -179,8 +179,9 @@ static int ocfs2_sync_file(struct file *file, loff_t start, loff_t end, file->f_path.dentry->d_name.name, (unsigned long long)datasync); - if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) - return -EROFS; + ret = ocfs2_emergency_state(osb); + if (ret < 0) + return ret; err = file_write_and_wait_range(file, start, end); if (err) @@ -209,7 +210,7 @@ int ocfs2_should_update_atime(struct inode *inode, struct timespec64 now; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); - if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) + if (ocfs2_emergency_state(osb)) return 0; if ((inode->i_flags & S_NOATIME) || @@ -1949,8 +1950,9 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, handle_t *handle; unsigned long long max_off = inode->i_sb->s_maxbytes; - if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) - return -EROFS; + ret = ocfs2_emergency_state(osb); + if (ret < 0) + return ret; inode_lock(inode); @@ -2713,8 +2715,9 @@ static loff_t ocfs2_remap_file_range(struct file *file_in, loff_t pos_in, return -EINVAL; if (!ocfs2_refcount_tree(osb)) return -EOPNOTSUPP; - if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) - return -EROFS; + ret = ocfs2_emergency_state(osb); + if (ret < 0) + return ret; /* Lock both files against IO */ ret = ocfs2_reflink_inodes_lock(inode_in, &in_bh, inode_out, &out_bh); diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 415ad29ec758..dca8db61bc0f 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c @@ -1586,8 +1586,7 @@ static int ocfs2_filecheck_repair_inode_block(struct super_block *sb, trace_ocfs2_filecheck_repair_inode_block( (unsigned long long)bh->b_blocknr); - if (ocfs2_is_hard_readonly(OCFS2_SB(sb)) || - ocfs2_is_soft_readonly(OCFS2_SB(sb))) { + if (ocfs2_emergency_state(OCFS2_SB(sb))) { mlog(ML_ERROR, "Filecheck: cannot repair dinode #%llu " "on readonly filesystem\n", diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c index 86f2631e6360..f586593b3a63 100644 --- a/fs/ocfs2/move_extents.c +++ b/fs/ocfs2/move_extents.c @@ -898,8 +898,9 @@ static int ocfs2_move_extents(struct ocfs2_move_extents_context *context) struct buffer_head *di_bh = NULL; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); - if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) - return -EROFS; + status = ocfs2_emergency_state(osb); + if (status < 0) + return status; inode_lock(inode); diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c index b0733c08ed13..d9f5e1d065b4 100644 --- a/fs/ocfs2/resize.c +++ b/fs/ocfs2/resize.c @@ -276,8 +276,9 @@ int ocfs2_group_extend(struct inode * inode, int new_clusters) u32 first_new_cluster; u64 lgd_blkno; - if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) - return -EROFS; + ret = ocfs2_emergency_state(osb); + if (ret < 0) + return ret; if (new_clusters < 0) return -EINVAL; @@ -466,7 +467,8 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input) u16 cl_bpc; u64 bg_ptr; - if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) + ret = ocfs2_emergency_state(osb); + if (ret < 0) return -EROFS; main_bm_inode = ocfs2_get_system_file_inode(osb, diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 53daa4482406..c6019d260efc 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -2487,7 +2487,7 @@ static int ocfs2_handle_error(struct super_block *sb) rv = -EIO; } else { /* default option */ rv = -EROFS; - if (sb_rdonly(sb) && (ocfs2_is_soft_readonly(osb) || ocfs2_is_hard_readonly(osb))) + if (sb_rdonly(sb) && ocfs2_emergency_state(osb)) return rv; pr_crit("OCFS2: File system is now read-only.\n"); -- 2.43.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] ocfs2: Convert remaining read-only checks to ocfs2_emergency_state 2025-11-18 0:26 ` [PATCH 2/2] ocfs2: Convert remaining read-only checks to ocfs2_emergency_state Ahmet Eray Karadag @ 2025-11-25 3:02 ` Heming Zhao 0 siblings, 0 replies; 7+ messages in thread From: Heming Zhao @ 2025-11-25 3:02 UTC (permalink / raw) To: Ahmet Eray Karadag Cc: mark, jlbec, joseph.qi, ocfs2-devel, linux-kernel, david.hunter.linux, skhan, Albin Babu Varghese On Tue, Nov 18, 2025 at 03:26:46AM +0300, Ahmet Eray Karadag wrote: > 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. > > 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> > --- > fs/ocfs2/buffer_head_io.c | 4 ++-- > fs/ocfs2/file.c | 17 ++++++++++------- > fs/ocfs2/inode.c | 3 +-- > fs/ocfs2/move_extents.c | 5 +++-- > fs/ocfs2/resize.c | 8 +++++--- > fs/ocfs2/super.c | 2 +- > 6 files changed, 22 insertions(+), 17 deletions(-) > > diff --git a/fs/ocfs2/buffer_head_io.c b/fs/ocfs2/buffer_head_io.c > index 8f714406528d..c43d4a58aa9a 100644 > --- a/fs/ocfs2/buffer_head_io.c > +++ b/fs/ocfs2/buffer_head_io.c > @@ -434,8 +434,8 @@ int ocfs2_write_super_or_backup(struct ocfs2_super *osb, > BUG_ON(buffer_jbd(bh)); > ocfs2_check_super_or_backup(osb->sb, bh->b_blocknr); > > - if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) { > - ret = -EROFS; > + ret = ocfs2_emergency_state(osb); > + if (ret < 0) { > mlog_errno(ret); > goto out; > } as comment in patch [1/2], I prefer "if (unlikely(ret))" here. > diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c > index 03a98985ac92..c299b73cf4ec 100644 > --- a/fs/ocfs2/file.c > +++ b/fs/ocfs2/file.c > @@ -179,8 +179,9 @@ static int ocfs2_sync_file(struct file *file, loff_t start, loff_t end, > file->f_path.dentry->d_name.name, > (unsigned long long)datasync); > > - if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) > - return -EROFS; > + ret = ocfs2_emergency_state(osb); > + if (ret < 0) > + return ret; ditto > > err = file_write_and_wait_range(file, start, end); > if (err) > @@ -209,7 +210,7 @@ int ocfs2_should_update_atime(struct inode *inode, > struct timespec64 now; > struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); > > - if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) > + if (ocfs2_emergency_state(osb)) > return 0; ditto > > if ((inode->i_flags & S_NOATIME) || > @@ -1949,8 +1950,9 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, > handle_t *handle; > unsigned long long max_off = inode->i_sb->s_maxbytes; > > - if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) > - return -EROFS; > + ret = ocfs2_emergency_state(osb); > + if (ret < 0) > + return ret; ditto > > inode_lock(inode); > > @@ -2713,8 +2715,9 @@ static loff_t ocfs2_remap_file_range(struct file *file_in, loff_t pos_in, > return -EINVAL; > if (!ocfs2_refcount_tree(osb)) > return -EOPNOTSUPP; > - if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) > - return -EROFS; > + ret = ocfs2_emergency_state(osb); > + if (ret < 0) > + return ret; ditto > > /* Lock both files against IO */ > ret = ocfs2_reflink_inodes_lock(inode_in, &in_bh, inode_out, &out_bh); > diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c > index 415ad29ec758..dca8db61bc0f 100644 > --- a/fs/ocfs2/inode.c > +++ b/fs/ocfs2/inode.c > @@ -1586,8 +1586,7 @@ static int ocfs2_filecheck_repair_inode_block(struct super_block *sb, > trace_ocfs2_filecheck_repair_inode_block( > (unsigned long long)bh->b_blocknr); > > - if (ocfs2_is_hard_readonly(OCFS2_SB(sb)) || > - ocfs2_is_soft_readonly(OCFS2_SB(sb))) { > + if (ocfs2_emergency_state(OCFS2_SB(sb))) { ditto > mlog(ML_ERROR, > "Filecheck: cannot repair dinode #%llu " > "on readonly filesystem\n", > diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c > index 86f2631e6360..f586593b3a63 100644 > --- a/fs/ocfs2/move_extents.c > +++ b/fs/ocfs2/move_extents.c > @@ -898,8 +898,9 @@ static int ocfs2_move_extents(struct ocfs2_move_extents_context *context) > struct buffer_head *di_bh = NULL; > struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); > > - if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) > - return -EROFS; > + status = ocfs2_emergency_state(osb); > + if (status < 0) > + return status; ditto > > inode_lock(inode); > > diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c > index b0733c08ed13..d9f5e1d065b4 100644 > --- a/fs/ocfs2/resize.c > +++ b/fs/ocfs2/resize.c > @@ -276,8 +276,9 @@ int ocfs2_group_extend(struct inode * inode, int new_clusters) > u32 first_new_cluster; > u64 lgd_blkno; > > - if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) > - return -EROFS; > + ret = ocfs2_emergency_state(osb); > + if (ret < 0) > + return ret; ditto > > if (new_clusters < 0) > return -EINVAL; > @@ -466,7 +467,8 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input) > u16 cl_bpc; > u64 bg_ptr; > > - if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) > + ret = ocfs2_emergency_state(osb); > + if (ret < 0) > return -EROFS; ditto Thanks, Heming > > main_bm_inode = ocfs2_get_system_file_inode(osb, > diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c > index 53daa4482406..c6019d260efc 100644 > --- a/fs/ocfs2/super.c > +++ b/fs/ocfs2/super.c > @@ -2487,7 +2487,7 @@ static int ocfs2_handle_error(struct super_block *sb) > rv = -EIO; > } else { /* default option */ > rv = -EROFS; > - if (sb_rdonly(sb) && (ocfs2_is_soft_readonly(osb) || ocfs2_is_hard_readonly(osb))) > + if (sb_rdonly(sb) && ocfs2_emergency_state(osb)) > return rv; > > pr_crit("OCFS2: File system is now read-only.\n"); > -- > 2.43.0 > > ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-12-01 7:44 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-11-18 0:26 [PATCH 0/2] ocfs2: Refactor read-only checks to use ocfs2_emergency_state Ahmet Eray Karadag 2025-11-18 0:26 ` [PATCH 1/2] ocfs2: Add ocfs2_emergency_state helper and apply to setattr Ahmet Eray Karadag 2025-11-25 2:58 ` Heming Zhao 2025-11-28 9:06 ` Ahmet Eray Karadag 2025-12-01 7:43 ` Heming Zhao 2025-11-18 0:26 ` [PATCH 2/2] ocfs2: Convert remaining read-only checks to ocfs2_emergency_state Ahmet Eray Karadag 2025-11-25 3:02 ` Heming Zhao
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox