Re: [PATCH v2] fs, USB gadget: Rework kiocb cancellation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2/8/24 14:14, Jens Axboe wrote:
On 2/8/24 2:55 PM, Bart Van Assche wrote:
-static int ffs_aio_cancel(struct kiocb *kiocb)
+static void ffs_epfile_cancel_kiocb(struct kiocb *kiocb)
  {
  	struct ffs_io_data *io_data = kiocb->private;
  	struct ffs_epfile *epfile = kiocb->ki_filp->private_data;
  	unsigned long flags;
-	int value;
spin_lock_irqsave(&epfile->ffs->eps_lock, flags);
-
  	if (io_data && io_data->ep && io_data->req)
-		value = usb_ep_dequeue(io_data->ep, io_data->req);
-	else
-		value = -EINVAL;
-
+		usb_ep_dequeue(io_data->ep, io_data->req);
  	spin_unlock_irqrestore(&epfile->ffs->eps_lock, flags);
-
-	return value;
  }

I'm assuming the NULL checks can go because it's just the async parts
now?

Probably. I will look into this.

+static void aio_cancel_and_del(struct aio_kiocb *req);
+

Just move the function higher up? It doesn't have any dependencies.

aio_cancel_and_del() calls aio_poll_cancel(). aio_poll_cancel() calls
poll_iocb_lock_wq(). poll_iocb_lock_wq() is defined below the first call of
aio_cancel_and_del(). It's probably possible to get rid of that function
declaration but a nontrivial amount of code would have to be moved.

@@ -1552,6 +1538,24 @@ static ssize_t aio_setup_rw(int rw, const struct iocb *iocb,
  	return __import_iovec(rw, buf, len, UIO_FASTIOV, iovec, iter, compat);
  }
+static void aio_add_rw_to_active_reqs(struct kiocb *req)
+{
+	struct aio_kiocb *aio = container_of(req, struct aio_kiocb, rw);
+	struct kioctx *ctx = aio->ki_ctx;
+	unsigned long flags;
+
+	/*
+	 * If the .cancel_kiocb() callback has been set, add the request
+	 * to the list of active requests.
+	 */
+	if (!req->ki_filp->f_op->cancel_kiocb)
+		return;
+
+	spin_lock_irqsave(&ctx->ctx_lock, flags);
+	list_add_tail(&aio->ki_list, &ctx->active_reqs);
+	spin_unlock_irqrestore(&ctx->ctx_lock, flags);
+}

This can use spin_lock_irq(), always called from process context.

I will make this change.

+{
+	void (*cancel_kiocb)(struct kiocb *) =
+		req->rw.ki_filp->f_op->cancel_kiocb;
+	struct kioctx *ctx = req->ki_ctx;
+
+	lockdep_assert_held(&ctx->ctx_lock);
+
+	switch (req->ki_opcode) {
+	case IOCB_CMD_PREAD:
+	case IOCB_CMD_PWRITE:
+	case IOCB_CMD_PREADV:
+	case IOCB_CMD_PWRITEV:
+		if (cancel_kiocb)
+			cancel_kiocb(&req->rw);
+		break;
+	case IOCB_CMD_FSYNC:
+	case IOCB_CMD_FDSYNC:
+		break;
+	case IOCB_CMD_POLL:
+		aio_poll_cancel(req);
+		break;
+	default:
+		WARN_ONCE(true, "invalid aio operation %d\n", req->ki_opcode);
+	}
+
+	list_del_init(&req->ki_list);
+}

Why don't you just keep ki_cancel() and just change it to a void return
that takes an aio_kiocb? Then you don't need this odd switch, or adding
an opcode field just for this. That seems cleaner.

Keeping .ki_cancel() means that it must be set before I/O starts and only
if the I/O is submitted by libaio. That would require an approach to
recognize whether or not a struct kiocb is embedded in struct aio_kiocb,
e.g. the patch that you posted as a reply on version one of this patch.
Does anyone else want to comment on this?

Thanks,

Bart.




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux