diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 60dba1f2eb16dc589a35b67aafcceeabc3cf1183..e310641c78eba2b7ea124b42534d5eccd3f1b271 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -6190,6 +6190,7 @@ const struct file_operations binder_fops = { .open = binder_open, .flush = binder_flush, .release = binder_release, + .may_pollfree = true, }; #ifdef CONFIG_BINDER_TRANSACTION_PROC_BRIEF diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index d25f341a0cecf5369f512809d21471bc1ce41dc6..ec3a8d582a0f40138debf29541b22f91be5e4930 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -544,11 +544,23 @@ static inline void nvme_fault_inject_fini(struct nvme_fault_inject *fault_inj) static inline void nvme_should_fail(struct request *req) {} #endif +bool nvme_wait_reset(struct nvme_ctrl *ctrl); +int nvme_try_sched_reset(struct nvme_ctrl *ctrl); + static inline int nvme_reset_subsystem(struct nvme_ctrl *ctrl) { + int ret; + if (!ctrl->subsystem) return -ENOTTY; - return ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65); + if (!nvme_wait_reset(ctrl)) + return -EBUSY; + + ret = ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65); + if (ret) + return ret; + + return nvme_try_sched_reset(ctrl); } /* @@ -635,7 +647,6 @@ void nvme_cancel_tagset(struct nvme_ctrl *ctrl); void nvme_cancel_admin_tagset(struct nvme_ctrl *ctrl); bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, enum nvme_ctrl_state new_state); -bool nvme_wait_reset(struct nvme_ctrl *ctrl); int nvme_disable_ctrl(struct nvme_ctrl *ctrl); int nvme_enable_ctrl(struct nvme_ctrl *ctrl); int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl); @@ -690,7 +701,6 @@ int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count); void nvme_stop_keep_alive(struct nvme_ctrl *ctrl); int nvme_reset_ctrl(struct nvme_ctrl *ctrl); int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl); -int nvme_try_sched_reset(struct nvme_ctrl *ctrl); int nvme_delete_ctrl(struct nvme_ctrl *ctrl); int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp, u8 csi, diff --git a/fs/io_uring.c b/fs/io_uring.c index 0d24fc4390650f5ad602d1b6257c3b24a6149c5e..2b02aedeab9b4d59aecf379dd6836b70141da347 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -5186,6 +5186,11 @@ static __poll_t __io_arm_poll_handler(struct io_kiocb *req, struct io_ring_ctx *ctx = req->ctx; bool cancel = false; + if (req->file->f_op->may_pollfree) { + spin_lock_irq(&ctx->completion_lock); + return -EOPNOTSUPP; + } + INIT_HLIST_NODE(&req->hash_node); io_init_poll_iocb(poll, mask, wake_func); poll->file = req->file; diff --git a/fs/signalfd.c b/fs/signalfd.c index b94fb5f81797a6ab74914da7e95597d3ee343e46..41dc597b78cc6392294d4b1afe5683e150da93e1 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c @@ -248,6 +248,7 @@ static const struct file_operations signalfd_fops = { .poll = signalfd_poll, .read = signalfd_read, .llseek = noop_llseek, + .may_pollfree = true, }; static int do_signalfd4(int ufd, sigset_t *mask, int flags) diff --git a/include/linux/fs.h b/include/linux/fs.h index b7f42d3dce26c3091640df309d15b819d6adb7be..3e548c0d3e07c914f6870f692ad75273283ea756 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1860,6 +1860,7 @@ struct file_operations { struct file *file_out, loff_t pos_out, loff_t len, unsigned int remap_flags); int (*fadvise)(struct file *, loff_t, loff_t, int); + bool may_pollfree; } __randomize_layout; struct inode_operations {