Skip to content

Commit 768f4dc

Browse files
committed
Merge patch series "fserror: bug fixes"
This contains two fixes for the new fserror infrastructure. * patches from https://patch.msgid.link/177148129514.716249.10889194125495783768.stgit@frogsfrogsfrogs: fserror: fix lockdep complaint when igrabbing inode fsnotify: drop unused helper Link: https://patch.msgid.link/177148129514.716249.10889194125495783768.stgit@frogsfrogsfrogs Signed-off-by: Christian Brauner <brauner@kernel.org>
2 parents 6c4b224 + 294f54f commit 768f4dc

File tree

2 files changed

+46
-13
lines changed

2 files changed

+46
-13
lines changed

fs/iomap/ioend.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,57 @@ static u32 iomap_finish_ioend_buffered(struct iomap_ioend *ioend)
6969
return folio_count;
7070
}
7171

72+
static DEFINE_SPINLOCK(failed_ioend_lock);
73+
static LIST_HEAD(failed_ioend_list);
74+
75+
static void
76+
iomap_fail_ioends(
77+
struct work_struct *work)
78+
{
79+
struct iomap_ioend *ioend;
80+
struct list_head tmp;
81+
unsigned long flags;
82+
83+
spin_lock_irqsave(&failed_ioend_lock, flags);
84+
list_replace_init(&failed_ioend_list, &tmp);
85+
spin_unlock_irqrestore(&failed_ioend_lock, flags);
86+
87+
while ((ioend = list_first_entry_or_null(&tmp, struct iomap_ioend,
88+
io_list))) {
89+
list_del_init(&ioend->io_list);
90+
iomap_finish_ioend_buffered(ioend);
91+
cond_resched();
92+
}
93+
}
94+
95+
static DECLARE_WORK(failed_ioend_work, iomap_fail_ioends);
96+
97+
static void iomap_fail_ioend_buffered(struct iomap_ioend *ioend)
98+
{
99+
unsigned long flags;
100+
101+
/*
102+
* Bounce I/O errors to a workqueue to avoid nested i_lock acquisitions
103+
* in the fserror code. The caller no longer owns the ioend reference
104+
* after the spinlock drops.
105+
*/
106+
spin_lock_irqsave(&failed_ioend_lock, flags);
107+
if (list_empty(&failed_ioend_list))
108+
WARN_ON_ONCE(!schedule_work(&failed_ioend_work));
109+
list_add_tail(&ioend->io_list, &failed_ioend_list);
110+
spin_unlock_irqrestore(&failed_ioend_lock, flags);
111+
}
112+
72113
static void ioend_writeback_end_bio(struct bio *bio)
73114
{
74115
struct iomap_ioend *ioend = iomap_ioend_from_bio(bio);
75116

76117
ioend->io_error = blk_status_to_errno(bio->bi_status);
118+
if (ioend->io_error) {
119+
iomap_fail_ioend_buffered(ioend);
120+
return;
121+
}
122+
77123
iomap_finish_ioend_buffered(ioend);
78124
}
79125

include/linux/fsnotify.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -495,19 +495,6 @@ static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid)
495495
fsnotify_dentry(dentry, mask);
496496
}
497497

498-
static inline int fsnotify_sb_error(struct super_block *sb, struct inode *inode,
499-
int error)
500-
{
501-
struct fs_error_report report = {
502-
.error = error,
503-
.inode = inode,
504-
.sb = sb,
505-
};
506-
507-
return fsnotify(FS_ERROR, &report, FSNOTIFY_EVENT_ERROR,
508-
NULL, NULL, NULL, 0);
509-
}
510-
511498
static inline void fsnotify_mnt_attach(struct mnt_namespace *ns, struct vfsmount *mnt)
512499
{
513500
fsnotify_mnt(FS_MNT_ATTACH, ns, mnt);

0 commit comments

Comments
 (0)