aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/nbd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/nbd.c')
-rw-r--r--drivers/block/nbd.c50
1 files changed, 24 insertions, 26 deletions
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 39e5f7fae3ef..83a7ba4a3eec 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -230,29 +230,40 @@ static int nbd_send_req(struct nbd_device *nbd, struct request *req)
230 int result, flags; 230 int result, flags;
231 struct nbd_request request; 231 struct nbd_request request;
232 unsigned long size = blk_rq_bytes(req); 232 unsigned long size = blk_rq_bytes(req);
233 u32 type;
234
235 if (req->cmd_type == REQ_TYPE_DRV_PRIV)
236 type = NBD_CMD_DISC;
237 else if (req->cmd_flags & REQ_DISCARD)
238 type = NBD_CMD_TRIM;
239 else if (req->cmd_flags & REQ_FLUSH)
240 type = NBD_CMD_FLUSH;
241 else if (rq_data_dir(req) == WRITE)
242 type = NBD_CMD_WRITE;
243 else
244 type = NBD_CMD_READ;
233 245
234 memset(&request, 0, sizeof(request)); 246 memset(&request, 0, sizeof(request));
235 request.magic = htonl(NBD_REQUEST_MAGIC); 247 request.magic = htonl(NBD_REQUEST_MAGIC);
236 request.type = htonl(nbd_cmd(req)); 248 request.type = htonl(type);
237 249 if (type != NBD_CMD_FLUSH && type != NBD_CMD_DISC) {
238 if (nbd_cmd(req) != NBD_CMD_FLUSH && nbd_cmd(req) != NBD_CMD_DISC) {
239 request.from = cpu_to_be64((u64)blk_rq_pos(req) << 9); 250 request.from = cpu_to_be64((u64)blk_rq_pos(req) << 9);
240 request.len = htonl(size); 251 request.len = htonl(size);
241 } 252 }
242 memcpy(request.handle, &req, sizeof(req)); 253 memcpy(request.handle, &req, sizeof(req));
243 254
244 dev_dbg(nbd_to_dev(nbd), "request %p: sending control (%s@%llu,%uB)\n", 255 dev_dbg(nbd_to_dev(nbd), "request %p: sending control (%s@%llu,%uB)\n",
245 req, nbdcmd_to_ascii(nbd_cmd(req)), 256 req, nbdcmd_to_ascii(type),
246 (unsigned long long)blk_rq_pos(req) << 9, blk_rq_bytes(req)); 257 (unsigned long long)blk_rq_pos(req) << 9, blk_rq_bytes(req));
247 result = sock_xmit(nbd, 1, &request, sizeof(request), 258 result = sock_xmit(nbd, 1, &request, sizeof(request),
248 (nbd_cmd(req) == NBD_CMD_WRITE) ? MSG_MORE : 0); 259 (type == NBD_CMD_WRITE) ? MSG_MORE : 0);
249 if (result <= 0) { 260 if (result <= 0) {
250 dev_err(disk_to_dev(nbd->disk), 261 dev_err(disk_to_dev(nbd->disk),
251 "Send control failed (result %d)\n", result); 262 "Send control failed (result %d)\n", result);
252 return -EIO; 263 return -EIO;
253 } 264 }
254 265
255 if (nbd_cmd(req) == NBD_CMD_WRITE) { 266 if (type == NBD_CMD_WRITE) {
256 struct req_iterator iter; 267 struct req_iterator iter;
257 struct bio_vec bvec; 268 struct bio_vec bvec;
258 /* 269 /*
@@ -352,7 +363,7 @@ static struct request *nbd_read_stat(struct nbd_device *nbd)
352 } 363 }
353 364
354 dev_dbg(nbd_to_dev(nbd), "request %p: got reply\n", req); 365 dev_dbg(nbd_to_dev(nbd), "request %p: got reply\n", req);
355 if (nbd_cmd(req) == NBD_CMD_READ) { 366 if (rq_data_dir(req) != WRITE) {
356 struct req_iterator iter; 367 struct req_iterator iter;
357 struct bio_vec bvec; 368 struct bio_vec bvec;
358 369
@@ -452,23 +463,11 @@ static void nbd_handle_req(struct nbd_device *nbd, struct request *req)
452 if (req->cmd_type != REQ_TYPE_FS) 463 if (req->cmd_type != REQ_TYPE_FS)
453 goto error_out; 464 goto error_out;
454 465
455 nbd_cmd(req) = NBD_CMD_READ; 466 if (rq_data_dir(req) == WRITE &&
456 if (rq_data_dir(req) == WRITE) { 467 (nbd->flags & NBD_FLAG_READ_ONLY)) {
457 if ((req->cmd_flags & REQ_DISCARD)) { 468 dev_err(disk_to_dev(nbd->disk),
458 WARN_ON(!(nbd->flags & NBD_FLAG_SEND_TRIM)); 469 "Write on read-only\n");
459 nbd_cmd(req) = NBD_CMD_TRIM; 470 goto error_out;
460 } else
461 nbd_cmd(req) = NBD_CMD_WRITE;
462 if (nbd->flags & NBD_FLAG_READ_ONLY) {
463 dev_err(disk_to_dev(nbd->disk),
464 "Write on read-only\n");
465 goto error_out;
466 }
467 }
468
469 if (req->cmd_flags & REQ_FLUSH) {
470 BUG_ON(unlikely(blk_rq_sectors(req)));
471 nbd_cmd(req) = NBD_CMD_FLUSH;
472 } 471 }
473 472
474 req->errors = 0; 473 req->errors = 0;
@@ -592,8 +591,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
592 fsync_bdev(bdev); 591 fsync_bdev(bdev);
593 mutex_lock(&nbd->tx_lock); 592 mutex_lock(&nbd->tx_lock);
594 blk_rq_init(NULL, &sreq); 593 blk_rq_init(NULL, &sreq);
595 sreq.cmd_type = REQ_TYPE_SPECIAL; 594 sreq.cmd_type = REQ_TYPE_DRV_PRIV;
596 nbd_cmd(&sreq) = NBD_CMD_DISC;
597 595
598 /* Check again after getting mutex back. */ 596 /* Check again after getting mutex back. */
599 if (!nbd->sock) 597 if (!nbd->sock)