|
@@ -230,29 +230,40 @@ static int nbd_send_req(struct nbd_device *nbd, struct request *req)
|
|
|
int result, flags;
|
|
int result, flags;
|
|
|
struct nbd_request request;
|
|
struct nbd_request request;
|
|
|
unsigned long size = blk_rq_bytes(req);
|
|
unsigned long size = blk_rq_bytes(req);
|
|
|
|
|
+ u32 type;
|
|
|
|
|
+
|
|
|
|
|
+ if (req->cmd_type == REQ_TYPE_DRV_PRIV)
|
|
|
|
|
+ type = NBD_CMD_DISC;
|
|
|
|
|
+ else if (req->cmd_flags & REQ_DISCARD)
|
|
|
|
|
+ type = NBD_CMD_TRIM;
|
|
|
|
|
+ else if (req->cmd_flags & REQ_FLUSH)
|
|
|
|
|
+ type = NBD_CMD_FLUSH;
|
|
|
|
|
+ else if (rq_data_dir(req) == WRITE)
|
|
|
|
|
+ type = NBD_CMD_WRITE;
|
|
|
|
|
+ else
|
|
|
|
|
+ type = NBD_CMD_READ;
|
|
|
|
|
|
|
|
memset(&request, 0, sizeof(request));
|
|
memset(&request, 0, sizeof(request));
|
|
|
request.magic = htonl(NBD_REQUEST_MAGIC);
|
|
request.magic = htonl(NBD_REQUEST_MAGIC);
|
|
|
- request.type = htonl(nbd_cmd(req));
|
|
|
|
|
-
|
|
|
|
|
- if (nbd_cmd(req) != NBD_CMD_FLUSH && nbd_cmd(req) != NBD_CMD_DISC) {
|
|
|
|
|
|
|
+ request.type = htonl(type);
|
|
|
|
|
+ if (type != NBD_CMD_FLUSH && type != NBD_CMD_DISC) {
|
|
|
request.from = cpu_to_be64((u64)blk_rq_pos(req) << 9);
|
|
request.from = cpu_to_be64((u64)blk_rq_pos(req) << 9);
|
|
|
request.len = htonl(size);
|
|
request.len = htonl(size);
|
|
|
}
|
|
}
|
|
|
memcpy(request.handle, &req, sizeof(req));
|
|
memcpy(request.handle, &req, sizeof(req));
|
|
|
|
|
|
|
|
dev_dbg(nbd_to_dev(nbd), "request %p: sending control (%s@%llu,%uB)\n",
|
|
dev_dbg(nbd_to_dev(nbd), "request %p: sending control (%s@%llu,%uB)\n",
|
|
|
- req, nbdcmd_to_ascii(nbd_cmd(req)),
|
|
|
|
|
|
|
+ req, nbdcmd_to_ascii(type),
|
|
|
(unsigned long long)blk_rq_pos(req) << 9, blk_rq_bytes(req));
|
|
(unsigned long long)blk_rq_pos(req) << 9, blk_rq_bytes(req));
|
|
|
result = sock_xmit(nbd, 1, &request, sizeof(request),
|
|
result = sock_xmit(nbd, 1, &request, sizeof(request),
|
|
|
- (nbd_cmd(req) == NBD_CMD_WRITE) ? MSG_MORE : 0);
|
|
|
|
|
|
|
+ (type == NBD_CMD_WRITE) ? MSG_MORE : 0);
|
|
|
if (result <= 0) {
|
|
if (result <= 0) {
|
|
|
dev_err(disk_to_dev(nbd->disk),
|
|
dev_err(disk_to_dev(nbd->disk),
|
|
|
"Send control failed (result %d)\n", result);
|
|
"Send control failed (result %d)\n", result);
|
|
|
return -EIO;
|
|
return -EIO;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (nbd_cmd(req) == NBD_CMD_WRITE) {
|
|
|
|
|
|
|
+ if (type == NBD_CMD_WRITE) {
|
|
|
struct req_iterator iter;
|
|
struct req_iterator iter;
|
|
|
struct bio_vec bvec;
|
|
struct bio_vec bvec;
|
|
|
/*
|
|
/*
|
|
@@ -352,7 +363,7 @@ static struct request *nbd_read_stat(struct nbd_device *nbd)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
dev_dbg(nbd_to_dev(nbd), "request %p: got reply\n", req);
|
|
dev_dbg(nbd_to_dev(nbd), "request %p: got reply\n", req);
|
|
|
- if (nbd_cmd(req) == NBD_CMD_READ) {
|
|
|
|
|
|
|
+ if (rq_data_dir(req) != WRITE) {
|
|
|
struct req_iterator iter;
|
|
struct req_iterator iter;
|
|
|
struct bio_vec bvec;
|
|
struct bio_vec bvec;
|
|
|
|
|
|
|
@@ -452,23 +463,11 @@ static void nbd_handle_req(struct nbd_device *nbd, struct request *req)
|
|
|
if (req->cmd_type != REQ_TYPE_FS)
|
|
if (req->cmd_type != REQ_TYPE_FS)
|
|
|
goto error_out;
|
|
goto error_out;
|
|
|
|
|
|
|
|
- nbd_cmd(req) = NBD_CMD_READ;
|
|
|
|
|
- if (rq_data_dir(req) == WRITE) {
|
|
|
|
|
- if ((req->cmd_flags & REQ_DISCARD)) {
|
|
|
|
|
- WARN_ON(!(nbd->flags & NBD_FLAG_SEND_TRIM));
|
|
|
|
|
- nbd_cmd(req) = NBD_CMD_TRIM;
|
|
|
|
|
- } else
|
|
|
|
|
- nbd_cmd(req) = NBD_CMD_WRITE;
|
|
|
|
|
- if (nbd->flags & NBD_FLAG_READ_ONLY) {
|
|
|
|
|
- dev_err(disk_to_dev(nbd->disk),
|
|
|
|
|
- "Write on read-only\n");
|
|
|
|
|
- goto error_out;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (req->cmd_flags & REQ_FLUSH) {
|
|
|
|
|
- BUG_ON(unlikely(blk_rq_sectors(req)));
|
|
|
|
|
- nbd_cmd(req) = NBD_CMD_FLUSH;
|
|
|
|
|
|
|
+ if (rq_data_dir(req) == WRITE &&
|
|
|
|
|
+ (nbd->flags & NBD_FLAG_READ_ONLY)) {
|
|
|
|
|
+ dev_err(disk_to_dev(nbd->disk),
|
|
|
|
|
+ "Write on read-only\n");
|
|
|
|
|
+ goto error_out;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
req->errors = 0;
|
|
req->errors = 0;
|
|
@@ -593,7 +592,6 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
|
|
|
mutex_lock(&nbd->tx_lock);
|
|
mutex_lock(&nbd->tx_lock);
|
|
|
blk_rq_init(NULL, &sreq);
|
|
blk_rq_init(NULL, &sreq);
|
|
|
sreq.cmd_type = REQ_TYPE_DRV_PRIV;
|
|
sreq.cmd_type = REQ_TYPE_DRV_PRIV;
|
|
|
- nbd_cmd(&sreq) = NBD_CMD_DISC;
|
|
|
|
|
|
|
|
|
|
/* Check again after getting mutex back. */
|
|
/* Check again after getting mutex back. */
|
|
|
if (!nbd->sock)
|
|
if (!nbd->sock)
|