Commit bc88aa51 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'ubifs-for-linus-6.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs

Pull UBI fixes from Richard Weinberger:

 - Fix failure to attach when vid_hdr offset equals the (sub)page size

 - Fix for a deadlock in UBI's worker thread

* tag 'ubifs-for-linus-6.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs:
  ubi: Fix failure attaching when vid_hdr offset equals to (sub)page size
  ubi: Fix deadlock caused by recursively holding work_sem
parents a7a55e27 1e020e1b
Loading
Loading
Loading
Loading
+15 −6
Original line number Diff line number Diff line
@@ -666,12 +666,6 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024)
	ubi->ec_hdr_alsize = ALIGN(UBI_EC_HDR_SIZE, ubi->hdrs_min_io_size);
	ubi->vid_hdr_alsize = ALIGN(UBI_VID_HDR_SIZE, ubi->hdrs_min_io_size);

	if (ubi->vid_hdr_offset && ((ubi->vid_hdr_offset + UBI_VID_HDR_SIZE) >
	    ubi->vid_hdr_alsize)) {
		ubi_err(ubi, "VID header offset %d too large.", ubi->vid_hdr_offset);
		return -EINVAL;
	}

	dbg_gen("min_io_size      %d", ubi->min_io_size);
	dbg_gen("max_write_size   %d", ubi->max_write_size);
	dbg_gen("hdrs_min_io_size %d", ubi->hdrs_min_io_size);
@@ -689,6 +683,21 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024)
						ubi->vid_hdr_aloffset;
	}

	/*
	 * Memory allocation for VID header is ubi->vid_hdr_alsize
	 * which is described in comments in io.c.
	 * Make sure VID header shift + UBI_VID_HDR_SIZE not exceeds
	 * ubi->vid_hdr_alsize, so that all vid header operations
	 * won't access memory out of bounds.
	 */
	if ((ubi->vid_hdr_shift + UBI_VID_HDR_SIZE) > ubi->vid_hdr_alsize) {
		ubi_err(ubi, "Invalid VID header offset %d, VID header shift(%d)"
			" + VID header size(%zu) > VID header aligned size(%d).",
			ubi->vid_hdr_offset, ubi->vid_hdr_shift,
			UBI_VID_HDR_SIZE, ubi->vid_hdr_alsize);
		return -EINVAL;
	}

	/* Similar for the data offset */
	ubi->leb_start = ubi->vid_hdr_offset + UBI_VID_HDR_SIZE;
	ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size);
+2 −2
Original line number Diff line number Diff line
@@ -575,7 +575,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
 * @vol_id: the volume ID that last used this PEB
 * @lnum: the last used logical eraseblock number for the PEB
 * @torture: if the physical eraseblock has to be tortured
 * @nested: denotes whether the work_sem is already held in read mode
 * @nested: denotes whether the work_sem is already held
 *
 * This function returns zero in case of success and a %-ENOMEM in case of
 * failure.
@@ -1131,7 +1131,7 @@ static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk)
		int err1;

		/* Re-schedule the LEB for erasure */
		err1 = schedule_erase(ubi, e, vol_id, lnum, 0, false);
		err1 = schedule_erase(ubi, e, vol_id, lnum, 0, true);
		if (err1) {
			spin_lock(&ubi->wl_lock);
			wl_entry_destroy(ubi, e);