Commit 839c4f59 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'mm-hotfixes-stable-2024-09-19-00-31' of...

Merge tag 'mm-hotfixes-stable-2024-09-19-00-31' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Pull misc hotfixes from Andrew Morton:
 "12 hotfixes, 11 of which are cc:stable.

  Four fixes for longstanding ocfs2 issues and the remainder address
  random MM things"

* tag 'mm-hotfixes-stable-2024-09-19-00-31' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm:
  mm/madvise: process_madvise() drop capability check if same mm
  mm/huge_memory: ensure huge_zero_folio won't have large_rmappable flag set
  mm/hugetlb.c: fix UAF of vma in hugetlb fault pathway
  mm: change vmf_anon_prepare() to __vmf_anon_prepare()
  resource: fix region_intersects() vs add_memory_driver_managed()
  zsmalloc: use unique zsmalloc caches names
  mm/damon/vaddr: protect vma traversal in __damon_va_thre_regions() with rcu read lock
  mm: vmscan.c: fix OOM on swap stress test
  ocfs2: cancel dqi_sync_work before freeing oinfo
  ocfs2: fix possible null-ptr-deref in ocfs2_set_buffer_uptodate
  ocfs2: remove unreasonable unlock in ocfs2_read_blocks
  ocfs2: fix null-ptr-deref when journal load failed.
parents a1d1eb2f 22af8caf
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -235,7 +235,6 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
		if (bhs[i] == NULL) {
			bhs[i] = sb_getblk(sb, block++);
			if (bhs[i] == NULL) {
				ocfs2_metadata_cache_io_unlock(ci);
				status = -ENOMEM;
				mlog_errno(status);
				/* Don't forget to put previous bh! */
@@ -389,6 +388,7 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
		/* Always set the buffer in the cache, even if it was
		 * a forced read, or read-ahead which hasn't yet
		 * completed. */
		if (bh)
			ocfs2_set_buffer_uptodate(ci, bh);
	}
	ocfs2_metadata_cache_io_unlock(ci);
+4 −3
Original line number Diff line number Diff line
@@ -1055,7 +1055,7 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb)
	if (!igrab(inode))
		BUG();

	num_running_trans = atomic_read(&(osb->journal->j_num_trans));
	num_running_trans = atomic_read(&(journal->j_num_trans));
	trace_ocfs2_journal_shutdown(num_running_trans);

	/* Do a commit_cache here. It will flush our journal, *and*
@@ -1074,9 +1074,10 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb)
		osb->commit_task = NULL;
	}

	BUG_ON(atomic_read(&(osb->journal->j_num_trans)) != 0);
	BUG_ON(atomic_read(&(journal->j_num_trans)) != 0);

	if (ocfs2_mount_local(osb)) {
	if (ocfs2_mount_local(osb) &&
	    (journal->j_journal->j_flags & JBD2_LOADED)) {
		jbd2_journal_lock_updates(journal->j_journal);
		status = jbd2_journal_flush(journal->j_journal, 0);
		jbd2_journal_unlock_updates(journal->j_journal);
+6 −2
Original line number Diff line number Diff line
@@ -692,7 +692,7 @@ static int ocfs2_local_read_info(struct super_block *sb, int type)
	int status;
	struct buffer_head *bh = NULL;
	struct ocfs2_quota_recovery *rec;
	int locked = 0;
	int locked = 0, global_read = 0;

	info->dqi_max_spc_limit = 0x7fffffffffffffffLL;
	info->dqi_max_ino_limit = 0x7fffffffffffffffLL;
@@ -700,6 +700,7 @@ static int ocfs2_local_read_info(struct super_block *sb, int type)
	if (!oinfo) {
		mlog(ML_ERROR, "failed to allocate memory for ocfs2 quota"
			       " info.");
		status = -ENOMEM;
		goto out_err;
	}
	info->dqi_priv = oinfo;
@@ -712,6 +713,7 @@ static int ocfs2_local_read_info(struct super_block *sb, int type)
	status = ocfs2_global_read_info(sb, type);
	if (status < 0)
		goto out_err;
	global_read = 1;

	status = ocfs2_inode_lock(lqinode, &oinfo->dqi_lqi_bh, 1);
	if (status < 0) {
@@ -782,10 +784,12 @@ static int ocfs2_local_read_info(struct super_block *sb, int type)
		if (locked)
			ocfs2_inode_unlock(lqinode, 1);
		ocfs2_release_local_quota_bitmaps(&oinfo->dqi_chunk);
		if (global_read)
			cancel_delayed_work_sync(&oinfo->dqi_sync_work);
		kfree(oinfo);
	}
	brelse(bh);
	return -1;
	return status;
}

/* Write local info to quota file */
+50 −8
Original line number Diff line number Diff line
@@ -540,20 +540,62 @@ static int __region_intersects(struct resource *parent, resource_size_t start,
			       size_t size, unsigned long flags,
			       unsigned long desc)
{
	struct resource res;
	resource_size_t ostart, oend;
	int type = 0; int other = 0;
	struct resource *p;
	struct resource *p, *dp;
	bool is_type, covered;
	struct resource res;

	res.start = start;
	res.end = start + size - 1;

	for (p = parent->child; p ; p = p->sibling) {
		bool is_type = (((p->flags & flags) == flags) &&
				((desc == IORES_DESC_NONE) ||
				 (desc == p->desc)));

		if (resource_overlaps(p, &res))
			is_type ? type++ : other++;
		if (!resource_overlaps(p, &res))
			continue;
		is_type = (p->flags & flags) == flags &&
			(desc == IORES_DESC_NONE || desc == p->desc);
		if (is_type) {
			type++;
			continue;
		}
		/*
		 * Continue to search in descendant resources as if the
		 * matched descendant resources cover some ranges of 'p'.
		 *
		 * |------------- "CXL Window 0" ------------|
		 * |-- "System RAM" --|
		 *
		 * will behave similar as the following fake resource
		 * tree when searching "System RAM".
		 *
		 * |-- "System RAM" --||-- "CXL Window 0a" --|
		 */
		covered = false;
		ostart = max(res.start, p->start);
		oend = min(res.end, p->end);
		for_each_resource(p, dp, false) {
			if (!resource_overlaps(dp, &res))
				continue;
			is_type = (dp->flags & flags) == flags &&
				(desc == IORES_DESC_NONE || desc == dp->desc);
			if (is_type) {
				type++;
				/*
				 * Range from 'ostart' to 'dp->start'
				 * isn't covered by matched resource.
				 */
				if (dp->start > ostart)
					break;
				if (dp->end >= oend) {
					covered = true;
					break;
				}
				/* Remove covered range */
				ostart = max(ostart, dp->end + 1);
			}
		}
		if (!covered)
			other++;
	}

	if (type == 0)
+2 −0
Original line number Diff line number Diff line
@@ -126,6 +126,7 @@ static int __damon_va_three_regions(struct mm_struct *mm,
	 * If this is too slow, it can be optimised to examine the maple
	 * tree gaps.
	 */
	rcu_read_lock();
	for_each_vma(vmi, vma) {
		unsigned long gap;

@@ -146,6 +147,7 @@ static int __damon_va_three_regions(struct mm_struct *mm,
next:
		prev = vma;
	}
	rcu_read_unlock();

	if (!sz_range(&second_gap) || !sz_range(&first_gap))
		return -EINVAL;
Loading