diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 39b790bb1623ea977c674a7b148220d565693dd5..4caeb2b91b83fc59fdcc5dc93a54f60196b4469c 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -6070,6 +6070,7 @@ const struct file_operations binder_fops = { .open = binder_open, .flush = binder_flush, .release = binder_release, + .may_pollfree = true, }; static int __init init_binder_device(const char *name) diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 3cb3c82061d7e25bb748f990705b01e2b2ff1c5a..9131bc002349de1a15ba68d8e1868f0c0af581db 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -485,11 +485,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); } /* @@ -575,7 +587,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); @@ -626,7 +637,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 06aceb45df46aa168b7e9f5475facdb1b503d272..9663752b886453bdb2caf8978571af67500ae4a7 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -5182,6 +5182,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 5724f099cf701bf5245a53bd5ff59fac078aa3f6..aea4950984c7ebee30c3927b673de9641634006c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1859,6 +1859,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 {