summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2019-03-25 16:30:28 +0800
committerJeremy Kerr <jk@ozlabs.org>2019-03-27 00:54:38 +0000
commitbcc6cc5bcadb20005ae03c8c4a4eb87006f0d222 (patch)
tree98771ea84b7ab588ae5220eab72137870f18c5f1
parentd5b9857609401e3cf9c53b111134a6aab8e4573c (diff)
downloadjsnbd-master.tar.gz
jsnbd-master.zip
js: Allow serving files > 4GB in sizeHEADmaster
Currently, the javascript NBD server only handles files of sizes that are representable in 32 bits. Although we can't do full 64-bit offsets with Javascript's number representation, we should be able to handle up to Number.MAX_SAFE_INTEGER. This change adds support for using the top-32 bit field in file sizes and read request offsets. Reported-by: Lei YU <mine260309@gmail.com> Signed-off-by: Jeremy Kerr <jk@ozlabs.org> Change-Id: I41dee58c3913cba49c5cd73ebdd5d6fb56786d25
-rw-r--r--web/js/nbd.js23
1 files changed, 15 insertions, 8 deletions
diff --git a/web/js/nbd.js b/web/js/nbd.js
index 1de4d3b..b58d9aa 100644
--- a/web/js/nbd.js
+++ b/web/js/nbd.js
@@ -195,9 +195,10 @@ function NBDServer(endpoint, file)
n += 124;
var resp = new ArrayBuffer(n);
var view = new DataView(resp, 0, 10);
- /* export size. todo: 64 bits? */
- view.setUint32(0, 0);
- view.setUint32(4, this.file.size & 0xffffffff);
+ /* export size. */
+ var size = this.file.size;
+ view.setUint32(0, Math.floor(size / (2**32)));
+ view.setUint32(4, size & 0xffffffff);
/* transmission flags: read-only */
view.setUint16(8, NBD_FLAG_HAS_FLAGS | NBD_FLAG_READ_ONLY);
this.ws.send(resp);
@@ -305,17 +306,23 @@ function NBDServer(endpoint, file)
this._handle_cmd_read = function(req)
{
- if (req.offset_msB)
+ var offset;
+
+ offset = (req.offset_msB * 2**32) + req.offset_lsB;
+
+ if (offset > Number.MAX_SAFE_INTEGER)
+ return ENOSPC;
+
+ if (offset + req.length > Number.MAX_SAFE_INTEGER)
return ENOSPC;
- if (req.offset_lsB + req.length > file.size)
+ if (offset + req.length > file.size)
return ENOSPC;
this._log("read: 0x" + req.length.toString(16) +
- " bytes, offset 0x" + req.offset_lsB.toString(16));
+ " bytes, offset 0x" + offset.toString(16));
- var blob = this.file.slice(req.offset_lsB,
- req.offset_lsB + req.length);
+ var blob = this.file.slice(offset, offset + req.length);
var reader = new FileReader();
reader.onload = (function(ev) {
OpenPOWER on IntegriCloud