Unverified Commit 768f4dc4 authored by Christian Brauner's avatar Christian Brauner
Browse files

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: default avatarChristian Brauner <brauner@kernel.org>
parents 6c4b2243 294f54f8
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
@@ -69,11 +69,57 @@ static u32 iomap_finish_ioend_buffered(struct iomap_ioend *ioend)
	return folio_count;
}

static DEFINE_SPINLOCK(failed_ioend_lock);
static LIST_HEAD(failed_ioend_list);

static void
iomap_fail_ioends(
	struct work_struct	*work)
{
	struct iomap_ioend	*ioend;
	struct list_head	tmp;
	unsigned long		flags;

	spin_lock_irqsave(&failed_ioend_lock, flags);
	list_replace_init(&failed_ioend_list, &tmp);
	spin_unlock_irqrestore(&failed_ioend_lock, flags);

	while ((ioend = list_first_entry_or_null(&tmp, struct iomap_ioend,
			io_list))) {
		list_del_init(&ioend->io_list);
		iomap_finish_ioend_buffered(ioend);
		cond_resched();
	}
}

static DECLARE_WORK(failed_ioend_work, iomap_fail_ioends);

static void iomap_fail_ioend_buffered(struct iomap_ioend *ioend)
{
	unsigned long flags;

	/*
	 * Bounce I/O errors to a workqueue to avoid nested i_lock acquisitions
	 * in the fserror code.  The caller no longer owns the ioend reference
	 * after the spinlock drops.
	 */
	spin_lock_irqsave(&failed_ioend_lock, flags);
	if (list_empty(&failed_ioend_list))
		WARN_ON_ONCE(!schedule_work(&failed_ioend_work));
	list_add_tail(&ioend->io_list, &failed_ioend_list);
	spin_unlock_irqrestore(&failed_ioend_lock, flags);
}

static void ioend_writeback_end_bio(struct bio *bio)
{
	struct iomap_ioend *ioend = iomap_ioend_from_bio(bio);

	ioend->io_error = blk_status_to_errno(bio->bi_status);
	if (ioend->io_error) {
		iomap_fail_ioend_buffered(ioend);
		return;
	}

	iomap_finish_ioend_buffered(ioend);
}

+0 −13
Original line number Diff line number Diff line
@@ -495,19 +495,6 @@ static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid)
		fsnotify_dentry(dentry, mask);
}

static inline int fsnotify_sb_error(struct super_block *sb, struct inode *inode,
				    int error)
{
	struct fs_error_report report = {
		.error = error,
		.inode = inode,
		.sb = sb,
	};

	return fsnotify(FS_ERROR, &report, FSNOTIFY_EVENT_ERROR,
			NULL, NULL, NULL, 0);
}

static inline void fsnotify_mnt_attach(struct mnt_namespace *ns, struct vfsmount *mnt)
{
	fsnotify_mnt(FS_MNT_ATTACH, ns, mnt);