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

Merge tag 'block-6.10-20240614' of git://git.kernel.dk/linux

Pull block fixes from Jens Axboe:

 - NVMe pull request via Keith:
     - Discard double free on error conditions (Chunguang)
     - Target Fixes (Daniel)
     - Namespace detachment regression fix (Keith)

 - Fix for an issue with flush requests and queuelist reuse (Chengming)

 - nbd sparse annotation fixes (Christoph)

 - unmap and free bio mapped data via submitter (Anuj)

 - loop discard/fallocate unsupported fix (Cyril)

 - Fix for the zoned write plugging added in this release (Damien)

 - sed-opal wrong address fix (Su)

* tag 'block-6.10-20240614' of git://git.kernel.dk/linux:
  loop: Disable fallocate() zero and discard if not supported
  nvme: fix namespace removal list
  nbd: Remove __force casts
  nvmet: always initialize cqe.result
  nvmet-passthru: propagate status from id override functions
  nvme: avoid double free special payload
  block: unmap and free user mapped integrity via submitter
  block: fix request.queuelist usage in flush
  block: Optimize disk zone resource cleanup
  block: sed-opal: avoid possible wrong address reference in read_sed_opal_key()
parents ac3cb72a 5f75e081
Loading
Loading
Loading
Loading
+24 −2
Original line number Diff line number Diff line
@@ -144,16 +144,38 @@ void bio_integrity_free(struct bio *bio)
	struct bio_integrity_payload *bip = bio_integrity(bio);
	struct bio_set *bs = bio->bi_pool;

	if (bip->bip_flags & BIP_INTEGRITY_USER)
		return;
	if (bip->bip_flags & BIP_BLOCK_INTEGRITY)
		kfree(bvec_virt(bip->bip_vec));
	else if (bip->bip_flags & BIP_INTEGRITY_USER)
		bio_integrity_unmap_user(bip);

	__bio_integrity_free(bs, bip);
	bio->bi_integrity = NULL;
	bio->bi_opf &= ~REQ_INTEGRITY;
}

/**
 * bio_integrity_unmap_free_user - Unmap and free bio user integrity payload
 * @bio:	bio containing bip to be unmapped and freed
 *
 * Description: Used to unmap and free the user mapped integrity portion of a
 * bio. Submitter attaching the user integrity buffer is responsible for
 * unmapping and freeing it during completion.
 */
void bio_integrity_unmap_free_user(struct bio *bio)
{
	struct bio_integrity_payload *bip = bio_integrity(bio);
	struct bio_set *bs = bio->bi_pool;

	if (WARN_ON_ONCE(!(bip->bip_flags & BIP_INTEGRITY_USER)))
		return;
	bio_integrity_unmap_user(bip);
	__bio_integrity_free(bs, bip);
	bio->bi_integrity = NULL;
	bio->bi_opf &= ~REQ_INTEGRITY;
}
EXPORT_SYMBOL(bio_integrity_unmap_free_user);

/**
 * bio_integrity_add_page - Attach integrity metadata
 * @bio:	bio to update
+2 −1
Original line number Diff line number Diff line
@@ -185,7 +185,7 @@ static void blk_flush_complete_seq(struct request *rq,
		/* queue for flush */
		if (list_empty(pending))
			fq->flush_pending_since = jiffies;
		list_move_tail(&rq->queuelist, pending);
		list_add_tail(&rq->queuelist, pending);
		break;

	case REQ_FSEQ_DATA:
@@ -263,6 +263,7 @@ static enum rq_end_io_ret flush_end_io(struct request *flush_rq,
		unsigned int seq = blk_flush_cur_seq(rq);

		BUG_ON(seq != REQ_FSEQ_PREFLUSH && seq != REQ_FSEQ_POSTFLUSH);
		list_del_init(&rq->queuelist);
		blk_flush_complete_seq(rq, fq, seq, error);
	}

+3 −0
Original line number Diff line number Diff line
@@ -1552,6 +1552,9 @@ static void disk_destroy_zone_wplugs_hash_table(struct gendisk *disk)

void disk_free_zone_resources(struct gendisk *disk)
{
	if (!disk->zone_wplugs_pool)
		return;

	cancel_work_sync(&disk->zone_wplugs_work);

	if (disk->zone_wplugs_wq) {
+1 −1
Original line number Diff line number Diff line
@@ -314,7 +314,7 @@ static int read_sed_opal_key(const char *key_name, u_char *buffer, int buflen)
			      &key_type_user, key_name, true);

	if (IS_ERR(kref))
		ret = PTR_ERR(kref);
		return PTR_ERR(kref);

	key = key_ref_to_ptr(kref);
	down_read(&key->sem);
+23 −0
Original line number Diff line number Diff line
@@ -302,6 +302,21 @@ static int lo_read_simple(struct loop_device *lo, struct request *rq,
	return 0;
}

static void loop_clear_limits(struct loop_device *lo, int mode)
{
	struct queue_limits lim = queue_limits_start_update(lo->lo_queue);

	if (mode & FALLOC_FL_ZERO_RANGE)
		lim.max_write_zeroes_sectors = 0;

	if (mode & FALLOC_FL_PUNCH_HOLE) {
		lim.max_hw_discard_sectors = 0;
		lim.discard_granularity = 0;
	}

	queue_limits_commit_update(lo->lo_queue, &lim);
}

static int lo_fallocate(struct loop_device *lo, struct request *rq, loff_t pos,
			int mode)
{
@@ -320,6 +335,14 @@ static int lo_fallocate(struct loop_device *lo, struct request *rq, loff_t pos,
	ret = file->f_op->fallocate(file, mode, pos, blk_rq_bytes(rq));
	if (unlikely(ret && ret != -EINVAL && ret != -EOPNOTSUPP))
		return -EIO;

	/*
	 * We initially configure the limits in a hope that fallocate is
	 * supported and clear them here if that turns out not to be true.
	 */
	if (unlikely(ret == -EOPNOTSUPP))
		loop_clear_limits(lo, mode);

	return ret;
}

Loading