Skip to content

Commit

Permalink
Revert "PWX-18756 fix race in restart and new req processing (#190) (#…
Browse files Browse the repository at this point in the history
…193)"

This reverts commit 525a5ee.
  • Loading branch information
prabirpaul committed Mar 12, 2021
1 parent af5b6d7 commit 879a7c9
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 34 deletions.
32 changes: 14 additions & 18 deletions dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,7 @@ static void fuse_put_unique(struct fuse_conn *fc, u64 uid)
{
struct fuse_per_cpu_ids *my_ids;
int num_free;
int cpu;

if (uid == 0) {
return;
}

cpu = get_cpu();
int cpu = get_cpu();

my_ids = per_cpu_ptr(fc->per_cpu_ids, cpu);

Expand All @@ -198,12 +192,6 @@ static void fuse_put_unique(struct fuse_conn *fc, u64 uid)

static void queue_request(struct fuse_conn *fc, struct fuse_req *req)
{
req->in.h.len = sizeof(struct fuse_in_header) +
len_args(req->in.numargs, (struct fuse_arg *)req->in.args);

req->in.h.unique = fuse_get_unique(fc);
fc->request_map[req->in.h.unique & (FUSE_MAX_REQUEST_IDS - 1)] = req;

list_add_tail(&req->list, &fc->pending);
}

Expand Down Expand Up @@ -251,15 +239,23 @@ static void fuse_request_send_nowait_locked(struct fuse_conn *fc,

void fuse_request_send_nowait(struct fuse_conn *fc, struct fuse_req *req)
{
req->in.h.len = sizeof(struct fuse_in_header) +
len_args(req->in.numargs, (struct fuse_arg *)req->in.args);

req->in.h.unique = fuse_get_unique(fc);
fc->request_map[req->in.h.unique & (FUSE_MAX_REQUEST_IDS - 1)] = req;

/*
* Ensures checking the value of allow_disconnected and adding request to
* queue is done atomically.
*/
rcu_read_lock();

// 'allow_disconnected' check subsumes 'connected' as well
if (READ_ONCE(fc->allow_disconnected)) {
if (fc->connected || fc->allow_disconnected) {
spin_lock(&fc->lock);
fuse_request_send_nowait_locked(fc, req);
spin_unlock(&fc->lock);

rcu_read_unlock();

fuse_conn_wakeup(fc);
Expand Down Expand Up @@ -1189,8 +1185,8 @@ struct fuse_conn *fuse_conn_get(struct fuse_conn *fc)
void fuse_abort_conn(struct fuse_conn *fc)
{
spin_lock(&fc->lock);
if (READ_ONCE(fc->connected)) {
WRITE_ONCE(fc->connected, 0);
if (fc->connected) {
fc->connected = 0;
fuse_end_queued_requests(fc);
wake_up_all(&fc->waitq);
kill_fasync(&fc->fasync, SIGIO, POLL_IN);
Expand All @@ -1203,7 +1199,7 @@ int fuse_dev_release(struct inode *inode, struct file *file)
struct fuse_conn *fc = fuse_get_conn(file);
if (fc) {
spin_lock(&fc->lock);
WRITE_ONCE(fc->connected, 0);
fc->connected = 0;
fuse_end_queued_requests(fc);
spin_unlock(&fc->lock);
fuse_conn_put(fc);
Expand Down
31 changes: 15 additions & 16 deletions pxd.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ static int pxd_open(struct block_device *bdev, fmode_t mode)
int err = 0;

spin_lock(&fc->lock);
if (!READ_ONCE(fc->connected)) {
if (!fc->connected) {
err = -ENXIO;
} else {
spin_lock(&pxd_dev->lock);
Expand Down Expand Up @@ -606,7 +606,6 @@ static void pxd_rq_fn(struct request_queue *q)
{
struct pxd_device *pxd_dev = q->queuedata;
struct fuse_req *req;
struct fuse_conn *fc = &pxd_dev->ctx->fc;

for (;;) {
struct request *rq;
Expand All @@ -617,7 +616,7 @@ static void pxd_rq_fn(struct request_queue *q)
break;

/* Filter out block requests we don't understand. */
if (BLK_RQ_IS_PASSTHROUGH(rq) || !READ_ONCE(fc->allow_disconnected)) {
if (BLK_RQ_IS_PASSTHROUGH(rq)) {
__blk_end_request_all(rq, 0);
continue;
}
Expand Down Expand Up @@ -654,7 +653,7 @@ static void pxd_rq_fn(struct request_queue *q)

req->rq = rq;
req->queue = q;
fuse_request_send_nowait(fc, req);
fuse_request_send_nowait(&pxd_dev->ctx->fc, req);
spin_lock_irq(&pxd_dev->qlock);
}
}
Expand All @@ -668,7 +667,7 @@ static blk_status_t pxd_queue_rq(struct blk_mq_hw_ctx *hctx,
struct fuse_req *req = blk_mq_rq_to_pdu(rq);
struct fuse_conn *fc = &pxd_dev->ctx->fc;

if (BLK_RQ_IS_PASSTHROUGH(rq) || !READ_ONCE(fc->allow_disconnected))
if (BLK_RQ_IS_PASSTHROUGH(rq))
return BLK_STS_IOERR;

if (!fc->connected && !fc->allow_disconnected)
Expand All @@ -695,7 +694,7 @@ static blk_status_t pxd_queue_rq(struct blk_mq_hw_ctx *hctx,
req->pxd_rdwr_in.chksum = 0;
req->pxd_rdwr_in.pad = 0;
req->rq = rq;
fuse_request_send_nowait(fc, req);
fuse_request_send_nowait(&pxd_dev->ctx->fc, req);

return BLK_STS_OK;
}
Expand Down Expand Up @@ -1230,12 +1229,12 @@ ssize_t pxd_timeout_store(struct device *dev, struct device_attribute *attr,
return -EINVAL;
}

if (!READ_ONCE(ctx->fc.connected)) {
if (!ctx->fc.connected) {
cancel_delayed_work_sync(&ctx->abort_work);
}
spin_lock(&ctx->lock);
pxd_timeout_secs = new_timeout_secs;
if (!READ_ONCE(ctx->fc.connected)) {
if (!ctx->fc.connected) {
schedule_delayed_work(&ctx->abort_work, pxd_timeout_secs * HZ);
}
spin_unlock(&ctx->lock);
Expand Down Expand Up @@ -1591,7 +1590,7 @@ static int pxd_control_open(struct inode *inode, struct file *file)
}

fc = &ctx->fc;
if (READ_ONCE(fc->connected) == 1) {
if (fc->connected == 1) {
printk(KERN_ERR "%s: pxd-control-%d(%lld) already open\n", __func__,
ctx->id, ctx->open_seq);
return -EINVAL;
Expand All @@ -1600,10 +1599,10 @@ static int pxd_control_open(struct inode *inode, struct file *file)
cancel_delayed_work_sync(&ctx->abort_work);
spin_lock(&ctx->lock);
pxd_timeout_secs = PXD_TIMER_SECS_DEFAULT;
WRITE_ONCE(fc->connected, 1);
fc->connected = 1;
spin_unlock(&ctx->lock);

WRITE_ONCE(fc->allow_disconnected, 1);
fc->allow_disconnected = 1;
file->private_data = fc;

pxdctx_set_connected(ctx, true);
Expand All @@ -1627,10 +1626,10 @@ static int pxd_control_release(struct inode *inode, struct file *file)
}

spin_lock(&ctx->lock);
if (READ_ONCE(ctx->fc.connected) == 0) {
if (ctx->fc.connected == 0) {
pxd_printk("%s: not opened\n", __func__);
} else {
WRITE_ONCE(ctx->fc.connected, 0);
ctx->fc.connected = 0;
}

schedule_delayed_work(&ctx->abort_work, pxd_timeout_secs * HZ);
Expand Down Expand Up @@ -1658,12 +1657,12 @@ static void pxd_abort_context(struct work_struct *work)
abort_work);
struct fuse_conn *fc = &ctx->fc;

BUG_ON(READ_ONCE(fc->connected));
BUG_ON(fc->connected);

printk(KERN_ERR "PXD_TIMEOUT (%s:%u): Aborting all requests...",
ctx->name, ctx->id);

WRITE_ONCE(fc->allow_disconnected, 0);
fc->allow_disconnected = 0;

/* Let other threads see the value of allow_disconnected. */
synchronize_rcu();
Expand Down Expand Up @@ -1805,7 +1804,7 @@ void pxd_exit(void)

for (i = 0; i < pxd_num_contexts; ++i) {
/* force cleanup @@@ */
WRITE_ONCE(pxd_contexts[i].fc.connected, 1);
pxd_contexts[i].fc.connected = true;
pxd_context_destroy(&pxd_contexts[i]);
}

Expand Down

0 comments on commit 879a7c9

Please sign in to comment.