Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.dk/linux-block
Browse files Browse the repository at this point in the history
Pull block fixes from Jens Axboe:
 "A small collection of fixes that should go into this cycle.

   - a pull request from Christoph for NVMe, which ended up being
     manually applied to avoid pulling in newer bits in master. Mostly
     fibre channel fixes from James, but also a few fixes from Jon and
     Vijay

   - a pull request from Konrad, with just a single fix for xen-blkback
     from Gustavo.

   - a fuseblk bdi fix from Jan, fixing a regression in this series with
     the dynamic backing devices.

   - a blktrace fix from Shaohua, replacing sscanf() with kstrtoull().

   - a request leak fix for drbd from Lars, fixing a regression in the
     last series with the kref changes. This will go to stable as well"

* 'for-linus' of git://git.kernel.dk/linux-block:
  nvmet: release the sq ref on rdma read errors
  nvmet-fc: remove target cpu scheduling flag
  nvme-fc: stop queues on error detection
  nvme-fc: require target or discovery role for fc-nvme targets
  nvme-fc: correct port role bits
  nvme: unmap CMB and remove sysfs file in reset path
  blktrace: fix integer parse
  fuseblk: Fix warning in super_setup_bdi_name()
  block: xen-blkback: add null check to avoid null pointer dereference
  drbd: fix request leak introduced by locking/atomic, kref: Kill kref_sub()
  • Loading branch information
torvalds committed May 20, 2017
2 parents ef82f1a + 549f01a commit 894e216
Show file tree
Hide file tree
Showing 13 changed files with 59 additions and 36 deletions.
27 changes: 15 additions & 12 deletions drivers/block/drbd/drbd_req.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,24 +315,32 @@ void drbd_req_complete(struct drbd_request *req, struct bio_and_error *m)
}

/* still holds resource->req_lock */
static int drbd_req_put_completion_ref(struct drbd_request *req, struct bio_and_error *m, int put)
static void drbd_req_put_completion_ref(struct drbd_request *req, struct bio_and_error *m, int put)
{
struct drbd_device *device = req->device;
D_ASSERT(device, m || (req->rq_state & RQ_POSTPONED));

if (!put)
return;

if (!atomic_sub_and_test(put, &req->completion_ref))
return 0;
return;

drbd_req_complete(req, m);

/* local completion may still come in later,
* we need to keep the req object around. */
if (req->rq_state & RQ_LOCAL_ABORTED)
return;

if (req->rq_state & RQ_POSTPONED) {
/* don't destroy the req object just yet,
* but queue it for retry */
drbd_restart_request(req);
return 0;
return;
}

return 1;
kref_put(&req->kref, drbd_req_destroy);
}

static void set_if_null_req_next(struct drbd_peer_device *peer_device, struct drbd_request *req)
Expand Down Expand Up @@ -519,12 +527,8 @@ static void mod_rq_state(struct drbd_request *req, struct bio_and_error *m,
if (req->i.waiting)
wake_up(&device->misc_wait);

if (c_put) {
if (drbd_req_put_completion_ref(req, m, c_put))
kref_put(&req->kref, drbd_req_destroy);
} else {
kref_put(&req->kref, drbd_req_destroy);
}
drbd_req_put_completion_ref(req, m, c_put);
kref_put(&req->kref, drbd_req_destroy);
}

static void drbd_report_io_error(struct drbd_device *device, struct drbd_request *req)
Expand Down Expand Up @@ -1366,8 +1370,7 @@ static void drbd_send_and_submit(struct drbd_device *device, struct drbd_request
}

out:
if (drbd_req_put_completion_ref(req, &m, 1))
kref_put(&req->kref, drbd_req_destroy);
drbd_req_put_completion_ref(req, &m, 1);
spin_unlock_irq(&resource->req_lock);

/* Even though above is a kref_put(), this is safe.
Expand Down
8 changes: 5 additions & 3 deletions drivers/block/xen-blkback/xenbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,11 +504,13 @@ static int xen_blkbk_remove(struct xenbus_device *dev)

dev_set_drvdata(&dev->dev, NULL);

if (be->blkif)
if (be->blkif) {
xen_blkif_disconnect(be->blkif);

/* Put the reference we set in xen_blkif_alloc(). */
xen_blkif_put(be->blkif);
/* Put the reference we set in xen_blkif_alloc(). */
xen_blkif_put(be->blkif);
}

kfree(be->mode);
kfree(be);
return 0;
Expand Down
10 changes: 10 additions & 0 deletions drivers/nvme/host/fc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1754,6 +1754,10 @@ nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg)
dev_info(ctrl->ctrl.device,
"NVME-FC{%d}: resetting controller\n", ctrl->cnum);

/* stop the queues on error, cleanup is in reset thread */
if (ctrl->queue_count > 1)
nvme_stop_queues(&ctrl->ctrl);

if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RECONNECTING)) {
dev_err(ctrl->ctrl.device,
"NVME-FC{%d}: error_recovery: Couldn't change state "
Expand Down Expand Up @@ -2720,6 +2724,12 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
unsigned long flags;
int ret, idx;

if (!(rport->remoteport.port_role &
(FC_PORT_ROLE_NVME_DISCOVERY | FC_PORT_ROLE_NVME_TARGET))) {
ret = -EBADR;
goto out_fail;
}

ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
if (!ctrl) {
ret = -ENOMEM;
Expand Down
7 changes: 6 additions & 1 deletion drivers/nvme/host/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1506,6 +1506,11 @@ static inline void nvme_release_cmb(struct nvme_dev *dev)
if (dev->cmb) {
iounmap(dev->cmb);
dev->cmb = NULL;
if (dev->cmbsz) {
sysfs_remove_file_from_group(&dev->ctrl.device->kobj,
&dev_attr_cmb.attr, NULL);
dev->cmbsz = 0;
}
}
}

Expand Down Expand Up @@ -1779,6 +1784,7 @@ static void nvme_pci_disable(struct nvme_dev *dev)
{
struct pci_dev *pdev = to_pci_dev(dev->dev);

nvme_release_cmb(dev);
pci_free_irq_vectors(pdev);

if (pci_is_enabled(pdev)) {
Expand Down Expand Up @@ -2184,7 +2190,6 @@ static void nvme_remove(struct pci_dev *pdev)
nvme_dev_disable(dev, true);
nvme_dev_remove_admin(dev);
nvme_free_queues(dev, 0);
nvme_release_cmb(dev);
nvme_release_prp_pools(dev);
nvme_dev_unmap(dev);
nvme_put_ctrl(&dev->ctrl);
Expand Down
6 changes: 6 additions & 0 deletions drivers/nvme/target/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,12 @@ bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq,
}
EXPORT_SYMBOL_GPL(nvmet_req_init);

void nvmet_req_uninit(struct nvmet_req *req)
{
percpu_ref_put(&req->sq->ref);
}
EXPORT_SYMBOL_GPL(nvmet_req_uninit);

static inline bool nvmet_cc_en(u32 cc)
{
return cc & 0x1;
Expand Down
4 changes: 1 addition & 3 deletions drivers/nvme/target/fc.c
Original file line number Diff line number Diff line change
Expand Up @@ -517,9 +517,7 @@ nvmet_fc_queue_to_cpu(struct nvmet_fc_tgtport *tgtport, int qid)
{
int cpu, idx, cnt;

if (!(tgtport->ops->target_features &
NVMET_FCTGTFEAT_NEEDS_CMD_CPUSCHED) ||
tgtport->ops->max_hw_queues == 1)
if (tgtport->ops->max_hw_queues == 1)
return WORK_CPU_UNBOUND;

/* Simple cpu selection based on qid modulo active cpu count */
Expand Down
1 change: 0 additions & 1 deletion drivers/nvme/target/fcloop.c
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,6 @@ static struct nvmet_fc_target_template tgttemplate = {
.dma_boundary = FCLOOP_DMABOUND_4G,
/* optional features */
.target_features = NVMET_FCTGTFEAT_CMD_IN_ISR |
NVMET_FCTGTFEAT_NEEDS_CMD_CPUSCHED |
NVMET_FCTGTFEAT_OPDONE_IN_ISR,
/* sizes of additional private data for data structures */
.target_priv_sz = sizeof(struct fcloop_tport),
Expand Down
1 change: 1 addition & 0 deletions drivers/nvme/target/nvmet.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ u16 nvmet_parse_fabrics_cmd(struct nvmet_req *req);

bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq,
struct nvmet_sq *sq, struct nvmet_fabrics_ops *ops);
void nvmet_req_uninit(struct nvmet_req *req);
void nvmet_req_complete(struct nvmet_req *req, u16 status);

void nvmet_cq_setup(struct nvmet_ctrl *ctrl, struct nvmet_cq *cq, u16 qid,
Expand Down
1 change: 1 addition & 0 deletions drivers/nvme/target/rdma.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,7 @@ static void nvmet_rdma_read_data_done(struct ib_cq *cq, struct ib_wc *wc)
rsp->n_rdma = 0;

if (unlikely(wc->status != IB_WC_SUCCESS)) {
nvmet_req_uninit(&rsp->req);
nvmet_rdma_release_rsp(rsp);
if (wc->status != IB_WC_WR_FLUSH_ERR) {
pr_info("RDMA READ for CQE 0x%p failed with status %s (%d).\n",
Expand Down
1 change: 0 additions & 1 deletion drivers/scsi/lpfc/lpfc_nvmet.c
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,6 @@ lpfc_nvmet_create_targetport(struct lpfc_hba *phba)
lpfc_tgttemplate.max_sgl_segments = phba->cfg_nvme_seg_cnt + 1;
lpfc_tgttemplate.max_hw_queues = phba->cfg_nvme_io_channel;
lpfc_tgttemplate.target_features = NVMET_FCTGTFEAT_READDATA_RSP |
NVMET_FCTGTFEAT_NEEDS_CMD_CPUSCHED |
NVMET_FCTGTFEAT_CMD_IN_ISR |
NVMET_FCTGTFEAT_OPDONE_IN_ISR;

Expand Down
9 changes: 8 additions & 1 deletion fs/fuse/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -975,8 +975,15 @@ static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb)
int err;
char *suffix = "";

if (sb->s_bdev)
if (sb->s_bdev) {
suffix = "-fuseblk";
/*
* sb->s_bdi points to blkdev's bdi however we want to redirect
* it to our private bdi...
*/
bdi_put(sb->s_bdi);
sb->s_bdi = &noop_backing_dev_info;
}
err = super_setup_bdi_name(sb, "%u:%u%s", MAJOR(fc->dev),
MINOR(fc->dev), suffix);
if (err)
Expand Down
16 changes: 4 additions & 12 deletions include/linux/nvme-fc-driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@

/* FC Port role bitmask - can merge with FC Port Roles in fc transport */
#define FC_PORT_ROLE_NVME_INITIATOR 0x10
#define FC_PORT_ROLE_NVME_TARGET 0x11
#define FC_PORT_ROLE_NVME_DISCOVERY 0x12
#define FC_PORT_ROLE_NVME_TARGET 0x20
#define FC_PORT_ROLE_NVME_DISCOVERY 0x40


/**
Expand Down Expand Up @@ -642,23 +642,15 @@ enum {
* sequence in one LLDD operation. Errors during Data
* sequence transmit must not allow RSP sequence to be sent.
*/
NVMET_FCTGTFEAT_NEEDS_CMD_CPUSCHED = (1 << 1),
/* Bit 1: When 0, the LLDD will deliver FCP CMD
* on the CPU it should be affinitized to. Thus work will
* be scheduled on the cpu received on. When 1, the LLDD
* may not deliver the CMD on the CPU it should be worked
* on. The transport should pick a cpu to schedule the work
* on.
*/
NVMET_FCTGTFEAT_CMD_IN_ISR = (1 << 2),
NVMET_FCTGTFEAT_CMD_IN_ISR = (1 << 1),
/* Bit 2: When 0, the LLDD is calling the cmd rcv handler
* in a non-isr context, allowing the transport to finish
* op completion in the calling context. When 1, the LLDD
* is calling the cmd rcv handler in an ISR context,
* requiring the transport to transition to a workqueue
* for op completion.
*/
NVMET_FCTGTFEAT_OPDONE_IN_ISR = (1 << 3),
NVMET_FCTGTFEAT_OPDONE_IN_ISR = (1 << 2),
/* Bit 3: When 0, the LLDD is calling the op done handler
* in a non-isr context, allowing the transport to finish
* op completion in the calling context. When 1, the LLDD
Expand Down
4 changes: 2 additions & 2 deletions kernel/trace/blktrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1662,14 +1662,14 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
goto out;

if (attr == &dev_attr_act_mask) {
if (sscanf(buf, "%llx", &value) != 1) {
if (kstrtoull(buf, 0, &value)) {
/* Assume it is a list of trace category names */
ret = blk_trace_str2mask(buf);
if (ret < 0)
goto out;
value = ret;
}
} else if (sscanf(buf, "%llu", &value) != 1)
} else if (kstrtoull(buf, 0, &value))
goto out;

ret = -ENXIO;
Expand Down

0 comments on commit 894e216

Please sign in to comment.