On 6/10/2024 4:13 PM, John Garry wrote: > +static bool nvme_valid_atomic_write(struct request *req) > +{ > + struct request_queue *q = req->q; > + u32 boundary_bytes = queue_atomic_write_boundary_bytes(q); > + > + if (blk_rq_bytes(req) > queue_atomic_write_unit_max_bytes(q)) > + return false; > + > + if (boundary_bytes) { > + u64 mask = boundary_bytes - 1, imask = ~mask; > + u64 start = blk_rq_pos(req) << SECTOR_SHIFT; > + u64 end = start + blk_rq_bytes(req) - 1; > + > + /* If greater then must be crossing a boundary */ > + if (blk_rq_bytes(req) > boundary_bytes) > + return false; Nit: I'd cache blk_rq_bytes(req), since that is repeating and this function is called for each atomic IO. > + > + if ((start & imask) != (end & imask)) > + return false; > + } > + > + return true; > +} > + > static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns, > struct request *req, struct nvme_command *cmnd, > enum nvme_opcode op) > @@ -941,6 +965,12 @@ static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns, > > if (req->cmd_flags & REQ_RAHEAD) > dsmgmt |= NVME_RW_DSM_FREQ_PREFETCH; > + /* > + * Ensure that nothing has been sent which cannot be executed > + * atomically. > + */ > + if (req->cmd_flags & REQ_ATOMIC && !nvme_valid_atomic_write(req)) > + return BLK_STS_INVAL; > Is this validity check specific to NVMe or should this be moved up to block layer as it also knows the limits?