From: sashiko-bot@kernel.org
To: "Christian Brauner" <brauner@kernel.org>, "Jan Kara" <jack@suse.com>
Cc: "Al Viro" <viro@zeniv.linux.org.uk>,
linux-ext4@vger.kernel.org, linux-mm@kvack.org,
linux-efi@vger.kernel.org, linux-mtd@lists.infradead.org,
dsterba@suse.cz, tytso@mit.edu, "Mark Fasheh" <mark@fasheh.com>,
"Joel Becker" <jlbec@evilplan.org>,
"Joseph Qi" <joseph.qi@linux.alibaba.com>
Subject: Re: [PATCH v2 28/34] ubifs: don't set SB_RDONLY after errors
Date: Fri, 30 Oct 2026 16:10:12 +0000 [thread overview]
Message-ID: <sashiko-outbox-191247@kernel.org> (raw)
In-Reply-To: <20261029-work-fs-sb_rdonly-v2-28-2f44f64f0b66@kernel.org>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] ubifs: writeback and ubifs_remount_ro() run inconsistently after ro_error
- [Medium] ubifs: unguarded assert in ubifs_reconfigure() when remounting after ro_error
- [Medium] ubifs: setting SB_RDONLY before SB_BORN in ubifs_ro_mode() desyncs ro state
--
commit 3140481bddfcfa10cd4b3bde25d5a8913266c1e3
Author: Christian Brauner <brauner@kernel.org>
ubifs: don't set SB_RDONLY after errors
This commit stops setting SB_RDONLY in ubifs_ro_mode() once SB_BORN is set on
the superblock, calling sb_set_emergency_ro() instead. It also allows
read-only remounts to proceed through ubifs_remount_ro() after an error and
checks c->ro_error in the xattr setters.
> diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c
> index 6c6d682427793..7a59aa1ea5ce9 100644
> --- a/fs/ubifs/io.c
> +++ b/fs/ubifs/io.c
> @@ -72,7 +72,14 @@ void ubifs_ro_mode(struct ubifs_info *c, int err)
> if (!c->ro_error) {
> c->ro_error = 1;
> c->no_chk_data_crc = 0;
> - c->vfs_sb->s_flags |= SB_RDONLY;
> + /*
> + * Before SB_BORN the mounter holds s_umount, later see
> + * sb_set_emergency_ro().
> + */
> + if (!(c->vfs_sb->s_flags & SB_BORN))
> + c->vfs_sb->s_flags |= SB_RDONLY;
> + else
> + sb_set_emergency_ro(c->vfs_sb);
[Severity: Medium]
Can setting SB_RDONLY instead of calling sb_set_emergency_ro() before SB_BORN
is set race on sb->s_flags and leave c->ro_mount and SB_STATE_EMERGENCY_RO out
of sync with sb->s_flags?
In mount_ubifs(), c->ro_mount is latched once at entry and the background
thread c->bgt is started before vfs_get_tree() sets SB_BORN:
fs/ubifs/super.c:mount_ubifs() {
c->ro_mount = !!sb_rdonly(c->vfs_sb);
...
if (!c->ro_mount) {
/* Create background thread */
c->bgt = kthread_run(ubifs_bg_thread, c, "%s", c->bgt_name);
}
Before vfs_get_tree() sets SB_BORN, ubifs_ro_mode() can be called without
failing the mount if an assertion fails under the default ASSACT_RO action in
ubifs_assert_failed() during mount_ubifs() or ubifs_iget(sb, UBIFS_ROOT_INO),
or if ubifs_bg_thread() wakes up after ubifs_fill_super() unlocks
c->umount_mutex and hits an error in ubifs_bg_wbufs_sync() or run_bg_commit().
If c->bgt calls ubifs_ro_mode() before SB_BORN is set, modifying
c->vfs_sb->s_flags |= SB_RDONLY happens without holding s_umount while the
mounter thread is modifying sb->s_flags in vfs_get_tree().
In addition, the mount finishes with SB_RDONLY set on sb->s_flags,
c->ro_error == 1, c->ro_mount == 0, and SB_STATE_EMERGENCY_RO clear:
fs/ubifs/super.c:ubifs_reconfigure() {
if (c->ro_mount && !(fc->sb_flags & SB_RDONLY)) {
if (c->ro_error) {
ubifs_msg(c, "cannot re-mount R/W due to prior errors");
return -EROFS;
}
...
} else if (!c->ro_mount && (fc->sb_flags & SB_RDONLY)) {
/* After an error ubifs_remount_ro() can't write but still works. */
ubifs_remount_ro(c);
}
}
Because sb_emergency_ro(sb) is false and c->ro_mount is 0, a subsequent
remount to read-write passes both reconfigure_super() and ubifs_reconfigure()
and clears SB_RDONLY, while a remount to read-only sees sb_rdonly(sb) as true
in reconfigure_super() and skips sb_prepare_remount_readonly() and
sb_start_ro_state_change() before calling ubifs_remount_ro().
Should ubifs_ro_mode() call sb_set_emergency_ro(c->vfs_sb) unconditionally?
[ ... ]
> diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
> index 38972786817e7..ef39da4e780b7 100644
> --- a/fs/ubifs/super.c
> +++ b/fs/ubifs/super.c
> @@ -1977,10 +1977,7 @@ static int ubifs_reconfigure(struct fs_context *fc)
> if (err)
> return err;
> } else if (!c->ro_mount && (fc->sb_flags & SB_RDONLY)) {
> - if (c->ro_error) {
> - ubifs_msg(c, "cannot re-mount R/O due to prior errors");
> - return -EROFS;
> - }
> + /* After an error ubifs_remount_ro() can't write but still works. */
[Severity: High]
Does allowing ubifs_remount_ro() to run after c->ro_error is set cause a NULL
pointer dereference on c->write_reserve_buf or trigger assertions in
reserve_space() and ubifs_wbuf_sync_nolock()?
Previously, ubifs_ro_mode() set SB_RDONLY on sb->s_flags (causing
sync_filesystem() to return early via sb_rdonly(sb)), and ubifs_reconfigure()
refused to call ubifs_remount_ro(c) when c->ro_error was set.
With SB_RDONLY no longer set on error, writeback still runs
ubifs_writepages() -> ubifs_writepage(). When a dirty folio extends past
ui->synced_i_size, ubifs_writepage() calls ubifs_write_inode():
fs/ubifs/file.c:ubifs_writepage() {
if (folio_pos(folio) + len > synced_i_size) {
err = inode->i_sb->s_op->write_inode(inode, NULL);
if (err)
goto out_redirty;
}
return do_writepage(folio, len);
}
In ubifs_write_inode(), ubifs_jnl_write_inode() fails with -EROFS when
c->ro_error is set without updating ui->synced_i_size, but ubifs_write_inode()
still clears ui->dirty = 0:
fs/ubifs/super.c:ubifs_write_inode() {
if (inode->i_nlink) {
err = ubifs_jnl_write_inode(c, inode);
if (err)
ubifs_err(c, "can't write inode %llu, error %d",
inode->i_ino, err);
else
err = dbg_check_inode_size(c, inode, ui->ui_size);
}
ui->dirty = 0;
mutex_unlock(&ui->ui_mutex);
ubifs_release_dirty_inode_budget(c, ui);
return err;
}
ubifs_writepage() then jumps to out_redirty and calls
folio_redirty_for_writepage(), which re-marks the folio PAGECACHE_TAG_DIRTY
and marks the inode I_DIRTY_PAGES without calling ubifs_dirty_inode(), leaving
ui->dirty == 0 while requeue_inode() puts the inode back onto wb->b_dirty.
If sync_inodes_sb() during ubifs_reconfigure() is the first writeback pass to
hit c->ro_error on that inode (for example, if writeback_inodes_sb() stopped
earlier after exhausting work->nr_pages or its time slice in
writeback_sb_inodes(), or skipped the inode while I_SYNC was set),
sync_filesystem() finishes with the redirtied folio still on wb->b_dirty and
ui->dirty == 0.
ubifs_reconfigure() ignores the return value of sync_filesystem() and calls
ubifs_remount_ro(), which frees c->write_reserve_buf and sets c->ro_mount = 1:
fs/ubifs/super.c:ubifs_remount_ro() {
kfree(c->write_reserve_buf);
c->write_reserve_buf = NULL;
vfree(c->ileb_buf);
c->ileb_buf = NULL;
ubifs_lpt_free(c, 1);
c->ro_mount = 1;
}
When background writeback (wb_workfn) subsequently flushes wb->b_dirty,
ubifs_writepage() calls ubifs_write_inode() again. Because ui->dirty is 0,
ubifs_write_inode() returns 0 immediately, and ubifs_writepage() proceeds into
do_writepage() -> ubifs_jnl_write_data():
fs/ubifs/journal.c:ubifs_jnl_write_data() {
data = kmalloc(dlen + auth_len, GFP_NOFS | __GFP_NOWARN);
if (!data) {
allocated = 0;
mutex_lock(&c->write_reserve_mutex);
data = c->write_reserve_buf;
}
data->ch.node_type = UBIFS_DATA_NODE;
}
If kmalloc() fails under memory pressure, data = c->write_reserve_buf is NULL
and data->ch.node_type dereferences NULL. Even if kmalloc() succeeds,
make_reservation() -> reserve_space() hits
ubifs_assert(c, !c->ro_media && !c->ro_mount) before checking c->ro_error:
fs/ubifs/journal.c:reserve_space() {
ubifs_assert(c, !c->ro_media && !c->ro_mount);
squeeze = (jhead == BASEHD);
again:
mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead);
if (c->ro_error) {
err = -EROFS;
goto out_unlock;
}
}
Furthermore, unlike ubifs_put_super() (which guards ubifs_wbuf_sync() with
if (!c->ro_error)), ubifs_remount_ro() and ubifs_sync_fs() call
ubifs_wbuf_sync() -> ubifs_wbuf_sync_nolock(), which evaluates wbuf geometry
assertions before checking c->ro_error:
fs/ubifs/io.c:ubifs_wbuf_sync_nolock() {
ubifs_assert(c, !(wbuf->avail & 7));
ubifs_assert(c, wbuf->offs + wbuf->size <= c->leb_size);
ubifs_assert(c, wbuf->size >= c->min_io_size);
ubifs_assert(c, wbuf->size <= c->max_write_size);
ubifs_assert(c, wbuf->size % c->min_io_size == 0);
ubifs_assert(c, !c->ro_media && !c->ro_mount);
if (c->leb_size - wbuf->offs >= c->max_write_size)
ubifs_assert(c, !((wbuf->offs + wbuf->size) % c->max_write_size));
if (c->ro_error)
return -EROFS;
}
If c->ro_error was triggered by a mid-write failure in
ubifs_wbuf_write_nolock() after advancing wbuf->offs while wbuf->used > 0 and
before updating wbuf->size, those assertions can fire during
ubifs_remount_ro() or ubifs_sync_fs().
> ubifs_remount_ro(c);
[Severity: Medium]
Can remounting read-only after a garbage collection error trigger the
c->lst.taken_empty_lebs > 0 assertion at the end of ubifs_reconfigure()?
At the end of ubifs_reconfigure(), the code checks:
fs/ubifs/super.c:ubifs_reconfigure() {
if (!c->need_recovery)
ubifs_assert(c, c->lst.taken_empty_lebs > 0);
}
When c->lst.taken_empty_lebs is 1 (holding only the reserved GC LEB
c->gc_lnum), ubifs_garbage_collect() -> ubifs_garbage_collect_leb() ->
move_nodes() -> switch_gc_head() consumes c->gc_lnum and sets c->gc_lnum = -1.
Once the first node is written to the GC write-buffer, bud_wbuf_callback() ->
ubifs_update_one_lp() -> ubifs_change_lp() decrements c->lst.taken_empty_lebs
to 0.
If an error then occurs in move_nodes() or gc_sync_wbufs() before a new
c->gc_lnum is retained, ubifs_garbage_collect() switches to read-only error
mode with c->ro_error == 1, c->gc_lnum == -1, and
c->lst.taken_empty_lebs == 0:
fs/ubifs/gc.c:ubifs_garbage_collect() {
out:
ubifs_assert(c, ret < 0);
ubifs_assert(c, ret != -ENOSPC && ret != -EAGAIN);
ubifs_wbuf_sync_nolock(wbuf);
ubifs_ro_mode(c, ret);
mutex_unlock(&wbuf->io_mutex);
if (lp.lnum != -1)
ubifs_return_leb(c, lp.lnum);
return ret;
}
Now that ubifs_reconfigure() no longer returns -EROFS on a read-only remount
when c->ro_error is set, should the assertion at the end of
ubifs_reconfigure() also be guarded by !c->ro_error, similar to
ubifs_put_super()?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261029-work-fs-sb_rdonly-v2-0-2f44f64f0b66@kernel.org?part=28
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
WARNING: multiple messages have this Message-ID (diff)
From: sashiko-bot@kernel.org
To: "Christian Brauner" <brauner@kernel.org>, "Jan Kara" <jack@suse.com>
Cc: "Al Viro" <viro@zeniv.linux.org.uk>,
linux-ext4@vger.kernel.org, linux-mm@kvack.org,
linux-efi@vger.kernel.org, linux-mtd@lists.infradead.org,
dsterba@suse.cz, tytso@mit.edu, "Mark Fasheh" <mark@fasheh.com>,
"Joel Becker" <jlbec@evilplan.org>,
"Joseph Qi" <joseph.qi@linux.alibaba.com>
Subject: Re: [PATCH v2 28/34] ubifs: don't set SB_RDONLY after errors
Date: Fri, 30 Oct 2026 16:10:12 +0000 [thread overview]
Message-ID: <sashiko-outbox-191247@kernel.org> (raw)
In-Reply-To: <20261029-work-fs-sb_rdonly-v2-28-2f44f64f0b66@kernel.org>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] ubifs: writeback and ubifs_remount_ro() run inconsistently after ro_error
- [Medium] ubifs: unguarded assert in ubifs_reconfigure() when remounting after ro_error
- [Medium] ubifs: setting SB_RDONLY before SB_BORN in ubifs_ro_mode() desyncs ro state
--
commit 3140481bddfcfa10cd4b3bde25d5a8913266c1e3
Author: Christian Brauner <brauner@kernel.org>
ubifs: don't set SB_RDONLY after errors
This commit stops setting SB_RDONLY in ubifs_ro_mode() once SB_BORN is set on
the superblock, calling sb_set_emergency_ro() instead. It also allows
read-only remounts to proceed through ubifs_remount_ro() after an error and
checks c->ro_error in the xattr setters.
> diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c
> index 6c6d682427793..7a59aa1ea5ce9 100644
> --- a/fs/ubifs/io.c
> +++ b/fs/ubifs/io.c
> @@ -72,7 +72,14 @@ void ubifs_ro_mode(struct ubifs_info *c, int err)
> if (!c->ro_error) {
> c->ro_error = 1;
> c->no_chk_data_crc = 0;
> - c->vfs_sb->s_flags |= SB_RDONLY;
> + /*
> + * Before SB_BORN the mounter holds s_umount, later see
> + * sb_set_emergency_ro().
> + */
> + if (!(c->vfs_sb->s_flags & SB_BORN))
> + c->vfs_sb->s_flags |= SB_RDONLY;
> + else
> + sb_set_emergency_ro(c->vfs_sb);
[Severity: Medium]
Can setting SB_RDONLY instead of calling sb_set_emergency_ro() before SB_BORN
is set race on sb->s_flags and leave c->ro_mount and SB_STATE_EMERGENCY_RO out
of sync with sb->s_flags?
In mount_ubifs(), c->ro_mount is latched once at entry and the background
thread c->bgt is started before vfs_get_tree() sets SB_BORN:
fs/ubifs/super.c:mount_ubifs() {
c->ro_mount = !!sb_rdonly(c->vfs_sb);
...
if (!c->ro_mount) {
/* Create background thread */
c->bgt = kthread_run(ubifs_bg_thread, c, "%s", c->bgt_name);
}
Before vfs_get_tree() sets SB_BORN, ubifs_ro_mode() can be called without
failing the mount if an assertion fails under the default ASSACT_RO action in
ubifs_assert_failed() during mount_ubifs() or ubifs_iget(sb, UBIFS_ROOT_INO),
or if ubifs_bg_thread() wakes up after ubifs_fill_super() unlocks
c->umount_mutex and hits an error in ubifs_bg_wbufs_sync() or run_bg_commit().
If c->bgt calls ubifs_ro_mode() before SB_BORN is set, modifying
c->vfs_sb->s_flags |= SB_RDONLY happens without holding s_umount while the
mounter thread is modifying sb->s_flags in vfs_get_tree().
In addition, the mount finishes with SB_RDONLY set on sb->s_flags,
c->ro_error == 1, c->ro_mount == 0, and SB_STATE_EMERGENCY_RO clear:
fs/ubifs/super.c:ubifs_reconfigure() {
if (c->ro_mount && !(fc->sb_flags & SB_RDONLY)) {
if (c->ro_error) {
ubifs_msg(c, "cannot re-mount R/W due to prior errors");
return -EROFS;
}
...
} else if (!c->ro_mount && (fc->sb_flags & SB_RDONLY)) {
/* After an error ubifs_remount_ro() can't write but still works. */
ubifs_remount_ro(c);
}
}
Because sb_emergency_ro(sb) is false and c->ro_mount is 0, a subsequent
remount to read-write passes both reconfigure_super() and ubifs_reconfigure()
and clears SB_RDONLY, while a remount to read-only sees sb_rdonly(sb) as true
in reconfigure_super() and skips sb_prepare_remount_readonly() and
sb_start_ro_state_change() before calling ubifs_remount_ro().
Should ubifs_ro_mode() call sb_set_emergency_ro(c->vfs_sb) unconditionally?
[ ... ]
> diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
> index 38972786817e7..ef39da4e780b7 100644
> --- a/fs/ubifs/super.c
> +++ b/fs/ubifs/super.c
> @@ -1977,10 +1977,7 @@ static int ubifs_reconfigure(struct fs_context *fc)
> if (err)
> return err;
> } else if (!c->ro_mount && (fc->sb_flags & SB_RDONLY)) {
> - if (c->ro_error) {
> - ubifs_msg(c, "cannot re-mount R/O due to prior errors");
> - return -EROFS;
> - }
> + /* After an error ubifs_remount_ro() can't write but still works. */
[Severity: High]
Does allowing ubifs_remount_ro() to run after c->ro_error is set cause a NULL
pointer dereference on c->write_reserve_buf or trigger assertions in
reserve_space() and ubifs_wbuf_sync_nolock()?
Previously, ubifs_ro_mode() set SB_RDONLY on sb->s_flags (causing
sync_filesystem() to return early via sb_rdonly(sb)), and ubifs_reconfigure()
refused to call ubifs_remount_ro(c) when c->ro_error was set.
With SB_RDONLY no longer set on error, writeback still runs
ubifs_writepages() -> ubifs_writepage(). When a dirty folio extends past
ui->synced_i_size, ubifs_writepage() calls ubifs_write_inode():
fs/ubifs/file.c:ubifs_writepage() {
if (folio_pos(folio) + len > synced_i_size) {
err = inode->i_sb->s_op->write_inode(inode, NULL);
if (err)
goto out_redirty;
}
return do_writepage(folio, len);
}
In ubifs_write_inode(), ubifs_jnl_write_inode() fails with -EROFS when
c->ro_error is set without updating ui->synced_i_size, but ubifs_write_inode()
still clears ui->dirty = 0:
fs/ubifs/super.c:ubifs_write_inode() {
if (inode->i_nlink) {
err = ubifs_jnl_write_inode(c, inode);
if (err)
ubifs_err(c, "can't write inode %llu, error %d",
inode->i_ino, err);
else
err = dbg_check_inode_size(c, inode, ui->ui_size);
}
ui->dirty = 0;
mutex_unlock(&ui->ui_mutex);
ubifs_release_dirty_inode_budget(c, ui);
return err;
}
ubifs_writepage() then jumps to out_redirty and calls
folio_redirty_for_writepage(), which re-marks the folio PAGECACHE_TAG_DIRTY
and marks the inode I_DIRTY_PAGES without calling ubifs_dirty_inode(), leaving
ui->dirty == 0 while requeue_inode() puts the inode back onto wb->b_dirty.
If sync_inodes_sb() during ubifs_reconfigure() is the first writeback pass to
hit c->ro_error on that inode (for example, if writeback_inodes_sb() stopped
earlier after exhausting work->nr_pages or its time slice in
writeback_sb_inodes(), or skipped the inode while I_SYNC was set),
sync_filesystem() finishes with the redirtied folio still on wb->b_dirty and
ui->dirty == 0.
ubifs_reconfigure() ignores the return value of sync_filesystem() and calls
ubifs_remount_ro(), which frees c->write_reserve_buf and sets c->ro_mount = 1:
fs/ubifs/super.c:ubifs_remount_ro() {
kfree(c->write_reserve_buf);
c->write_reserve_buf = NULL;
vfree(c->ileb_buf);
c->ileb_buf = NULL;
ubifs_lpt_free(c, 1);
c->ro_mount = 1;
}
When background writeback (wb_workfn) subsequently flushes wb->b_dirty,
ubifs_writepage() calls ubifs_write_inode() again. Because ui->dirty is 0,
ubifs_write_inode() returns 0 immediately, and ubifs_writepage() proceeds into
do_writepage() -> ubifs_jnl_write_data():
fs/ubifs/journal.c:ubifs_jnl_write_data() {
data = kmalloc(dlen + auth_len, GFP_NOFS | __GFP_NOWARN);
if (!data) {
allocated = 0;
mutex_lock(&c->write_reserve_mutex);
data = c->write_reserve_buf;
}
data->ch.node_type = UBIFS_DATA_NODE;
}
If kmalloc() fails under memory pressure, data = c->write_reserve_buf is NULL
and data->ch.node_type dereferences NULL. Even if kmalloc() succeeds,
make_reservation() -> reserve_space() hits
ubifs_assert(c, !c->ro_media && !c->ro_mount) before checking c->ro_error:
fs/ubifs/journal.c:reserve_space() {
ubifs_assert(c, !c->ro_media && !c->ro_mount);
squeeze = (jhead == BASEHD);
again:
mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead);
if (c->ro_error) {
err = -EROFS;
goto out_unlock;
}
}
Furthermore, unlike ubifs_put_super() (which guards ubifs_wbuf_sync() with
if (!c->ro_error)), ubifs_remount_ro() and ubifs_sync_fs() call
ubifs_wbuf_sync() -> ubifs_wbuf_sync_nolock(), which evaluates wbuf geometry
assertions before checking c->ro_error:
fs/ubifs/io.c:ubifs_wbuf_sync_nolock() {
ubifs_assert(c, !(wbuf->avail & 7));
ubifs_assert(c, wbuf->offs + wbuf->size <= c->leb_size);
ubifs_assert(c, wbuf->size >= c->min_io_size);
ubifs_assert(c, wbuf->size <= c->max_write_size);
ubifs_assert(c, wbuf->size % c->min_io_size == 0);
ubifs_assert(c, !c->ro_media && !c->ro_mount);
if (c->leb_size - wbuf->offs >= c->max_write_size)
ubifs_assert(c, !((wbuf->offs + wbuf->size) % c->max_write_size));
if (c->ro_error)
return -EROFS;
}
If c->ro_error was triggered by a mid-write failure in
ubifs_wbuf_write_nolock() after advancing wbuf->offs while wbuf->used > 0 and
before updating wbuf->size, those assertions can fire during
ubifs_remount_ro() or ubifs_sync_fs().
> ubifs_remount_ro(c);
[Severity: Medium]
Can remounting read-only after a garbage collection error trigger the
c->lst.taken_empty_lebs > 0 assertion at the end of ubifs_reconfigure()?
At the end of ubifs_reconfigure(), the code checks:
fs/ubifs/super.c:ubifs_reconfigure() {
if (!c->need_recovery)
ubifs_assert(c, c->lst.taken_empty_lebs > 0);
}
When c->lst.taken_empty_lebs is 1 (holding only the reserved GC LEB
c->gc_lnum), ubifs_garbage_collect() -> ubifs_garbage_collect_leb() ->
move_nodes() -> switch_gc_head() consumes c->gc_lnum and sets c->gc_lnum = -1.
Once the first node is written to the GC write-buffer, bud_wbuf_callback() ->
ubifs_update_one_lp() -> ubifs_change_lp() decrements c->lst.taken_empty_lebs
to 0.
If an error then occurs in move_nodes() or gc_sync_wbufs() before a new
c->gc_lnum is retained, ubifs_garbage_collect() switches to read-only error
mode with c->ro_error == 1, c->gc_lnum == -1, and
c->lst.taken_empty_lebs == 0:
fs/ubifs/gc.c:ubifs_garbage_collect() {
out:
ubifs_assert(c, ret < 0);
ubifs_assert(c, ret != -ENOSPC && ret != -EAGAIN);
ubifs_wbuf_sync_nolock(wbuf);
ubifs_ro_mode(c, ret);
mutex_unlock(&wbuf->io_mutex);
if (lp.lnum != -1)
ubifs_return_leb(c, lp.lnum);
return ret;
}
Now that ubifs_reconfigure() no longer returns -EROFS on a read-only remount
when c->ro_error is set, should the assertion at the end of
ubifs_reconfigure() also be guarded by !c->ro_error, similar to
ubifs_put_super()?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261029-work-fs-sb_rdonly-v2-0-2f44f64f0b66@kernel.org?part=28
next prev parent reply other threads:[~2026-10-30 16:10 UTC|newest]
Thread overview: 121+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-29 16:06 [PATCH v2 00/34] fs: don't set SB_RDONLY after filesystem errors Christian Brauner
2026-10-29 16:06 ` Christian Brauner
2026-10-29 16:06 ` [PATCH v2 01/34] ecryptfs: don't leak the inode when a lookup can't open the lower file Christian Brauner
2026-10-29 16:06 ` Christian Brauner
2026-10-30 16:09 ` sashiko-bot
2026-10-29 16:06 ` [PATCH v2 02/34] ecryptfs: fall back to a read-only " Christian Brauner
2026-10-29 16:06 ` Christian Brauner
2026-10-30 16:09 ` sashiko-bot
2026-10-30 16:09 ` sashiko-bot
2026-10-29 16:06 ` [PATCH v2 03/34] fs: add a generic emergency read-only state Christian Brauner
2026-10-29 16:06 ` Christian Brauner
2026-10-30 16:09 ` sashiko-bot
2026-10-29 16:06 ` [PATCH v2 04/34] ext2: don't set SB_RDONLY after filesystem errors Christian Brauner
2026-10-29 16:06 ` Christian Brauner
2026-10-30 16:09 ` sashiko-bot
2026-10-29 16:06 ` [PATCH v2 05/34] jfs: " Christian Brauner
2026-10-29 16:06 ` Christian Brauner
2026-10-30 16:09 ` sashiko-bot
2026-10-30 16:09 ` sashiko-bot
2026-10-29 16:06 ` [PATCH v2 06/34] nilfs2: " Christian Brauner
2026-10-29 16:06 ` Christian Brauner
2026-10-30 16:09 ` sashiko-bot
2026-10-30 16:09 ` sashiko-bot
2026-10-29 16:06 ` [PATCH v2 07/34] fat: " Christian Brauner
2026-10-29 16:06 ` Christian Brauner
2026-10-30 16:09 ` sashiko-bot
2026-10-30 16:09 ` sashiko-bot
2026-10-29 16:06 ` [PATCH v2 08/34] exfat: keep the current mount options on remount Christian Brauner
2026-10-29 16:06 ` Christian Brauner
2026-10-30 16:09 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 09/34] exfat: don't set SB_RDONLY after filesystem errors Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:09 ` sashiko-bot
2026-10-30 16:09 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 10/34] exfat: use the generic emergency read-only state Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:09 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 11/34] hfs: don't set SB_RDONLY after MDB write errors Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:09 ` sashiko-bot
2026-10-30 16:09 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 12/34] hfs: use the generic emergency read-only state Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:09 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 13/34] hfsplus: don't set SB_RDONLY when creating the attributes tree Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:09 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 14/34] affs: don't set SB_RDONLY after filesystem errors Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 15/34] ufs: " Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 16/34] hpfs: " Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:10 ` sashiko-bot
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 17/34] ntfs: " Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:10 ` sashiko-bot
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 18/34] ntfs: use the generic emergency read-only state Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 19/34] ocfs2: keep the current mount options on remount Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 2:58 ` Joseph Qi
2026-10-30 2:58 ` Joseph Qi
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 20/34] ocfs2: don't set SB_RDONLY after filesystem errors Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 3:01 ` Joseph Qi
2026-10-30 3:01 ` Joseph Qi
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 21/34] zonefs: don't set SB_RDONLY after I/O errors Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 22/34] zonefs: use the generic emergency read-only state Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 23/34] btrfs: check BTRFS_FS_STATE_RO instead of SB_RDONLY at runtime Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 24/34] btrfs: don't set SB_RDONLY after filesystem errors Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 25/34] gfs2: wait for a pending withdraw before remounting read-only Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:10 ` sashiko-bot
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 26/34] gfs2: don't set SB_RDONLY on withdraw Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:10 ` sashiko-bot
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 27/34] efivarfs: stop using SB_RDONLY for read-only efivar ops Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 28/34] ubifs: don't set SB_RDONLY after errors Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 3:42 ` Zhihao Cheng
2026-10-30 3:42 ` Zhihao Cheng
2026-10-30 16:10 ` sashiko-bot [this message]
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 29/34] selftests/filesystems: test filesystem errors while frozen Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 30/34] ext4: allow remounting read-only in the emergency state Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 31/34] ext4: use the generic emergency read-only state Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 32/34] selftests/filesystems: test ext4 remounts in the emergency state Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 33/34] xfs: allow remounting read-only after a shutdown Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:10 ` sashiko-bot
2026-10-29 16:07 ` [PATCH v2 34/34] selftests/filesystems: test xfs remounts " Christian Brauner
2026-10-29 16:07 ` Christian Brauner
2026-10-30 16:10 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-191247@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=brauner@kernel.org \
--cc=dsterba@suse.cz \
--cc=jack@suse.com \
--cc=jlbec@evilplan.org \
--cc=joseph.qi@linux.alibaba.com \
--cc=linux-efi@vger.kernel.org \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-mtd@lists.infradead.org \
--cc=mark@fasheh.com \
--cc=sashiko-reviews@lists.linux.dev \
--cc=tytso@mit.edu \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.