Backport filesystem and 9p changes from jor1k. Thanks @s-macke
This commit is contained in:
parent
9404fb29d5
commit
b1d6fab094
230
lib/9p.js
230
lib/9p.js
|
@ -59,7 +59,7 @@ function Virtio9p(filesystem, bus) {
|
|||
/** @const @type {BusConnector} */
|
||||
this.bus = bus;
|
||||
|
||||
this.SendReply = function(x) {};
|
||||
this.SendReply = function(x, y) {};
|
||||
this.deviceid = 0x9; // 9p filesystem
|
||||
this.hostfeature = 0x1; // mountpoint
|
||||
//this.configspace = [0x0, 0x4, 0x68, 0x6F, 0x73, 0x74]; // length of string and "host" string
|
||||
|
@ -106,17 +106,18 @@ Virtio9p.prototype.set_state = function(state)
|
|||
};
|
||||
|
||||
Virtio9p.prototype.Createfid = function(inode, type, uid) {
|
||||
return {inodeid: inode, type: type, uid: uid};
|
||||
return {inodeid: inode, type: type, uid: uid};
|
||||
}
|
||||
|
||||
Virtio9p.prototype.Reset = function() {
|
||||
this.fids = [];
|
||||
}
|
||||
|
||||
|
||||
Virtio9p.prototype.BuildReply = function(id, tag, payloadsize) {
|
||||
Marshall(["w", "b", "h"], [payloadsize+7, id+1, tag], this.replybuffer, 0);
|
||||
marshall.Marshall(["w", "b", "h"], [payloadsize+7, id+1, tag], this.replybuffer, 0);
|
||||
if ((payloadsize+7) >= this.replybuffer.length) {
|
||||
DebugMessage("Error in 9p: payloadsize exceeds maximum length");
|
||||
message.Debug("Error in 9p: payloadsize exceeds maximum length");
|
||||
}
|
||||
//for(var i=0; i<payload.length; i++)
|
||||
// this.replybuffer[7+i] = payload[i];
|
||||
|
@ -125,22 +126,22 @@ Virtio9p.prototype.BuildReply = function(id, tag, payloadsize) {
|
|||
}
|
||||
|
||||
Virtio9p.prototype.SendError = function (tag, errormsg, errorcode) {
|
||||
//var size = Marshall(["s", "w"], [errormsg, errorcode], this.replybuffer, 7);
|
||||
var size = Marshall(["w"], [errorcode], this.replybuffer, 7);
|
||||
//var size = marshall.Marshall(["s", "w"], [errormsg, errorcode], this.replybuffer, 7);
|
||||
var size = marshall.Marshall(["w"], [errorcode], this.replybuffer, 7);
|
||||
this.BuildReply(6, tag, size);
|
||||
}
|
||||
|
||||
Virtio9p.prototype.ReceiveRequest = function (index, GetByte) {
|
||||
var header = Unmarshall2(["w", "b", "h"], GetByte);
|
||||
//var size = header[0];
|
||||
var header = marshall.Unmarshall2(["w", "b", "h"], GetByte);
|
||||
var size = header[0];
|
||||
var id = header[1];
|
||||
var tag = header[2];
|
||||
//DebugMessage("size:" + size + " id:" + id + " tag:" + tag);
|
||||
//message.Debug("size:" + size + " id:" + id + " tag:" + tag);
|
||||
|
||||
switch(id)
|
||||
{
|
||||
case 8: // statfs
|
||||
var size = this.fs.GetTotalSize(); // size used by all files
|
||||
size = this.fs.GetTotalSize(); // size used by all files
|
||||
var space = this.fs.GetSpace();
|
||||
var req = [];
|
||||
req[0] = 0x01021997;
|
||||
|
@ -153,43 +154,41 @@ Virtio9p.prototype.ReceiveRequest = function (index, GetByte) {
|
|||
req[7] = 0; // file system id?
|
||||
req[8] = 256; // maximum length of filenames
|
||||
|
||||
size = Marshall(["w", "w", "d", "d", "d", "d", "d", "d", "w"], req, this.replybuffer, 7);
|
||||
size = marshall.Marshall(["w", "w", "d", "d", "d", "d", "d", "d", "w"], req, this.replybuffer, 7);
|
||||
this.BuildReply(id, tag, size);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
case 112: // topen
|
||||
case 12: // tlopen
|
||||
var req = Unmarshall2(["w", "w"], GetByte);
|
||||
var req = marshall.Unmarshall2(["w", "w"], GetByte);
|
||||
var fid = req[0];
|
||||
var mode = req[1];
|
||||
DebugMessage("[open] fid=" + fid + ", mode=" + mode);
|
||||
var inode = this.fs.GetInode(this.fids[fid].inodeid);
|
||||
req[0] = inode.qid;
|
||||
req[1] = this.msize - 24;
|
||||
Marshall(["Q", "w"], req, this.replybuffer, 7);
|
||||
this.BuildReply(id, tag, 13+4);
|
||||
DebugMessage("file open " + inode.name);
|
||||
message.Debug("[open] fid=" + fid + ", mode=" + mode);
|
||||
var idx = this.fids[fid].inodeid;
|
||||
var inode = this.fs.GetInode(idx);
|
||||
message.Debug("file open " + inode.name);
|
||||
//if (inode.status == STATUS_LOADING) return;
|
||||
var ret = this.fs.OpenInode(this.fids[fid].inodeid, mode);
|
||||
var ret = this.fs.OpenInode(idx, mode);
|
||||
|
||||
this.fs.AddEvent(this.fids[fid].inodeid,
|
||||
function() {
|
||||
DebugMessage("file opened " + inode.name + " tag:"+tag);
|
||||
message.Debug("file opened " + inode.name + " tag:"+tag);
|
||||
req[0] = inode.qid;
|
||||
req[1] = this.msize - 24;
|
||||
Marshall(["Q", "w"], req, this.replybuffer, 7);
|
||||
marshall.Marshall(["Q", "w"], req, this.replybuffer, 7);
|
||||
this.BuildReply(id, tag, 13+4);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
}.bind(this)
|
||||
);
|
||||
break;
|
||||
|
||||
case 70: // link (just copying)
|
||||
var req = Unmarshall2(["w", "w", "s"], GetByte);
|
||||
var req = marshall.Unmarshall2(["w", "w", "s"], GetByte);
|
||||
var dfid = req[0];
|
||||
var fid = req[1];
|
||||
var name = req[2];
|
||||
DebugMessage("[link] dfid=" + dfid + ", name=" + name);
|
||||
message.Debug("[link] dfid=" + dfid + ", name=" + name);
|
||||
var inode = this.fs.CreateInode();
|
||||
var inodetarget = this.fs.GetInode(this.fids[fid].inodeid);
|
||||
var targetdata = this.fs.inodedata[this.fids[fid].inodeid];
|
||||
|
@ -198,7 +197,6 @@ Virtio9p.prototype.ReceiveRequest = function (index, GetByte) {
|
|||
inode.size = inodetarget.size;
|
||||
inode.symlink = inodetarget.symlink;
|
||||
var data = this.fs.inodedata[this.fs.inodes.length] = new Uint8Array(inode.size);
|
||||
//inode.waswritten = true;
|
||||
for(var i=0; i<inode.size; i++) {
|
||||
data[i] = targetdata[i];
|
||||
}
|
||||
|
@ -210,81 +208,81 @@ Virtio9p.prototype.ReceiveRequest = function (index, GetByte) {
|
|||
//inode.gid = inodetarget.gid;
|
||||
//inode.mode = inodetarget.mode | S_IFLNK;
|
||||
this.BuildReply(id, tag, 0);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
case 16: // symlink
|
||||
var req = Unmarshall2(["w", "s", "s", "w"], GetByte);
|
||||
var req = marshall.Unmarshall2(["w", "s", "s", "w"], GetByte);
|
||||
var fid = req[0];
|
||||
var name = req[1];
|
||||
var symgt = req[2];
|
||||
var gid = req[3];
|
||||
DebugMessage("[symlink] fid=" + fid + ", name=" + name + ", symgt=" + symgt + ", gid=" + gid);
|
||||
message.Debug("[symlink] fid=" + fid + ", name=" + name + ", symgt=" + symgt + ", gid=" + gid);
|
||||
var idx = this.fs.CreateSymlink(name, this.fids[fid].inodeid, symgt);
|
||||
var inode = this.fs.GetInode(idx);
|
||||
inode.uid = this.fids[fid].uid;
|
||||
inode.gid = gid;
|
||||
Marshall(["Q"], [inode.qid], this.replybuffer, 7);
|
||||
marshall.Marshall(["Q"], [inode.qid], this.replybuffer, 7);
|
||||
this.BuildReply(id, tag, 13);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
case 18: // mknod
|
||||
var req = Unmarshall2(["w", "s", "w", "w", "w", "w"], GetByte);
|
||||
var req = marshall.Unmarshall2(["w", "s", "w", "w", "w", "w"], GetByte);
|
||||
var fid = req[0];
|
||||
var name = req[1];
|
||||
var mode = req[2];
|
||||
var major = req[3];
|
||||
var minor = req[4];
|
||||
var gid = req[5];
|
||||
DebugMessage("[mknod] fid=" + fid + ", name=" + name + ", major=" + major + ", minor=" + minor+ "");
|
||||
message.Debug("[mknod] fid=" + fid + ", name=" + name + ", major=" + major + ", minor=" + minor+ "");
|
||||
var idx = this.fs.CreateNode(name, this.fids[fid].inodeid, major, minor);
|
||||
var inode = this.fs.GetInode(idx);
|
||||
inode.mode = mode;
|
||||
inode.uid = this.fids[fid].uid;
|
||||
inode.gid = gid;
|
||||
Marshall(["Q"], [inode.qid], this.replybuffer, 7);
|
||||
marshall.Marshall(["Q"], [inode.qid], this.replybuffer, 7);
|
||||
this.BuildReply(id, tag, 13);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
|
||||
case 22: // TREADLINK
|
||||
var req = Unmarshall2(["w"], GetByte);
|
||||
var req = marshall.Unmarshall2(["w"], GetByte);
|
||||
var fid = req[0];
|
||||
DebugMessage("[readlink] fid=" + fid);
|
||||
message.Debug("[readlink] fid=" + fid);
|
||||
var inode = this.fs.GetInode(this.fids[fid].inodeid);
|
||||
var size = Marshall(["s"], [inode.symlink], this.replybuffer, 7);
|
||||
size = marshall.Marshall(["s"], [inode.symlink], this.replybuffer, 7);
|
||||
this.BuildReply(id, tag, size);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
|
||||
case 72: // tmkdir
|
||||
var req = Unmarshall2(["w", "s", "w", "w"], GetByte);
|
||||
var req = marshall.Unmarshall2(["w", "s", "w", "w"], GetByte);
|
||||
var fid = req[0];
|
||||
var name = req[1];
|
||||
var mode = req[2];
|
||||
var gid = req[3];
|
||||
DebugMessage("[mkdir] fid=" + fid + ", name=" + name + ", mode=" + mode + ", gid=" + gid);
|
||||
message.Debug("[mkdir] fid=" + fid + ", name=" + name + ", mode=" + mode + ", gid=" + gid);
|
||||
var idx = this.fs.CreateDirectory(name, this.fids[fid].inodeid);
|
||||
var inode = this.fs.GetInode(idx);
|
||||
inode.mode = mode | S_IFDIR;
|
||||
inode.uid = this.fids[fid].uid;
|
||||
inode.gid = gid;
|
||||
Marshall(["Q"], [inode.qid], this.replybuffer, 7);
|
||||
marshall.Marshall(["Q"], [inode.qid], this.replybuffer, 7);
|
||||
this.BuildReply(id, tag, 13);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
case 14: // tlcreate
|
||||
var req = Unmarshall2(["w", "s", "w", "w", "w"], GetByte);
|
||||
var req = marshall.Unmarshall2(["w", "s", "w", "w", "w"], GetByte);
|
||||
var fid = req[0];
|
||||
var name = req[1];
|
||||
var flags = req[2];
|
||||
var mode = req[3];
|
||||
var gid = req[4];
|
||||
DebugMessage("[create] fid=" + fid + ", name=" + name + ", flags=" + flags + ", mode=" + mode + ", gid=" + gid);
|
||||
message.Debug("[create] fid=" + fid + ", name=" + name + ", flags=" + flags + ", mode=" + mode + ", gid=" + gid);
|
||||
var idx = this.fs.CreateFile(name, this.fids[fid].inodeid);
|
||||
this.fids[fid].inodeid = idx;
|
||||
this.fids[fid].type = FID_INODE;
|
||||
|
@ -292,16 +290,16 @@ Virtio9p.prototype.ReceiveRequest = function (index, GetByte) {
|
|||
inode.uid = this.fids[fid].uid;
|
||||
inode.gid = gid;
|
||||
inode.mode = mode;
|
||||
Marshall(["Q", "w"], [inode.qid, this.msize - 24], this.replybuffer, 7);
|
||||
marshall.Marshall(["Q", "w"], [inode.qid, this.msize - 24], this.replybuffer, 7);
|
||||
this.BuildReply(id, tag, 13+4);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
case 52: // lock always suceed
|
||||
DebugMessage("lock file\n");
|
||||
Marshall(["w"], [0], this.replybuffer, 7);
|
||||
message.Debug("lock file\n");
|
||||
marshall.Marshall(["w"], [0], this.replybuffer, 7);
|
||||
this.BuildReply(id, tag, 1);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
/*
|
||||
|
@ -310,10 +308,10 @@ Virtio9p.prototype.ReceiveRequest = function (index, GetByte) {
|
|||
*/
|
||||
|
||||
case 24: // getattr
|
||||
var req = Unmarshall2(["w", "d"], GetByte);
|
||||
var req = marshall.Unmarshall2(["w", "d"], GetByte);
|
||||
var fid = req[0];
|
||||
var inode = this.fs.GetInode(this.fids[fid].inodeid);
|
||||
DebugMessage("[getattr]: fid=" + fid + " name=" + inode.name + " request mask=" + req[1]);
|
||||
message.Debug("[getattr]: fid=" + fid + " name=" + inode.name + " request mask=" + req[1]);
|
||||
req[0] |= 0x1000; // P9_STATS_GEN
|
||||
|
||||
req[0] = req[1]; // request mask
|
||||
|
@ -338,7 +336,7 @@ Virtio9p.prototype.ReceiveRequest = function (index, GetByte) {
|
|||
req[17] = 0x0;
|
||||
req[18] = 0x0; // st_gen
|
||||
req[19] = 0x0; // data_version
|
||||
Marshall([
|
||||
marshall.Marshall([
|
||||
"d", "Q",
|
||||
"w",
|
||||
"w", "w",
|
||||
|
@ -351,11 +349,11 @@ Virtio9p.prototype.ReceiveRequest = function (index, GetByte) {
|
|||
"d", "d",
|
||||
], req, this.replybuffer, 7);
|
||||
this.BuildReply(id, tag, 8 + 13 + 4 + 4+ 4 + 8*15);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
case 26: // setattr
|
||||
var req = Unmarshall2(["w", "w",
|
||||
var req = marshall.Unmarshall2(["w", "w",
|
||||
"w", // mode
|
||||
"w", "w", // uid, gid
|
||||
"d", // size
|
||||
|
@ -364,7 +362,7 @@ Virtio9p.prototype.ReceiveRequest = function (index, GetByte) {
|
|||
, GetByte);
|
||||
var fid = req[0];
|
||||
var inode = this.fs.GetInode(this.fids[fid].inodeid);
|
||||
DebugMessage("[setattr]: fid=" + fid + " request mask=" + req[1] + " name=" +inode.name);
|
||||
message.Debug("[setattr]: fid=" + fid + " request mask=" + req[1] + " name=" +inode.name);
|
||||
if (req[1] & P9_SETATTR_MODE) {
|
||||
inode.mode = req[2];
|
||||
}
|
||||
|
@ -393,38 +391,38 @@ Virtio9p.prototype.ReceiveRequest = function (index, GetByte) {
|
|||
this.fs.ChangeSize(this.fids[fid].inodeid, req[5]);
|
||||
}
|
||||
this.BuildReply(id, tag, 0);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
case 50: // fsync
|
||||
var req = Unmarshall2(["w", "d"], GetByte);
|
||||
var req = marshall.Unmarshall2(["w", "d"], GetByte);
|
||||
var fid = req[0];
|
||||
this.BuildReply(id, tag, 0);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
case 40: // TREADDIR
|
||||
case 116: // read
|
||||
var req = Unmarshall2(["w", "d", "w"], GetByte);
|
||||
var req = marshall.Unmarshall2(["w", "d", "w"], GetByte);
|
||||
var fid = req[0];
|
||||
var offset = req[1];
|
||||
var count = req[2];
|
||||
var inode = this.fs.GetInode(this.fids[fid].inodeid);
|
||||
if (id == 40) DebugMessage("[treaddir]: fid=" + fid + " offset=" + offset + " count=" + count);
|
||||
if (id == 116) DebugMessage("[read]: fid=" + fid + " (" + inode.name + ") offset=" + offset + " count=" + count + " fidtype=" + this.fids[fid].type);
|
||||
if (id == 40) message.Debug("[treaddir]: fid=" + fid + " offset=" + offset + " count=" + count);
|
||||
if (id == 116) message.Debug("[read]: fid=" + fid + " (" + inode.name + ") offset=" + offset + " count=" + count + " fidtype=" + this.fids[fid].type);
|
||||
if (this.fids[fid].type == FID_XATTR) {
|
||||
if (inode.caps.length < offset+count) count = inode.caps.length - offset;
|
||||
for(var i=0; i<count; i++)
|
||||
this.replybuffer[7+4+i] = inode.caps[offset+i];
|
||||
Marshall(["w"], [count], this.replybuffer, 7);
|
||||
marshall.Marshall(["w"], [count], this.replybuffer, 7);
|
||||
this.BuildReply(id, tag, 4 + count);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
} else {
|
||||
var file = this.fs.inodes[this.fids[fid].inodeid];
|
||||
this.bus.send("9p-read-start");
|
||||
|
||||
this.fs.OpenInode(this.fids[fid].inodeid, undefined);
|
||||
this.fs.AddEvent(this.fids[fid].inodeid,
|
||||
this.fs.AddEvent(this.fids[fid].inodeid,
|
||||
function() {
|
||||
this.bus.send("9p-read-end", [file.name, count]);
|
||||
|
||||
|
@ -434,167 +432,167 @@ Virtio9p.prototype.ReceiveRequest = function (index, GetByte) {
|
|||
for(var i=0; i<count; i++)
|
||||
this.replybuffer[7+4+i] = data[offset+i];
|
||||
}
|
||||
Marshall(["w"], [count], this.replybuffer, 7);
|
||||
marshall.Marshall(["w"], [count], this.replybuffer, 7);
|
||||
this.BuildReply(id, tag, 4 + count);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 118: // write
|
||||
var req = Unmarshall2(["w", "d", "w"], GetByte);
|
||||
var req = marshall.Unmarshall2(["w", "d", "w"], GetByte);
|
||||
var fid = req[0];
|
||||
var offset = req[1];
|
||||
var count = req[2];
|
||||
DebugMessage("[write]: fid=" + fid + " (" + this.fs.inodes[this.fids[fid].inodeid].name + ") offset=" + offset + " count=" + count);
|
||||
message.Debug("[write]: fid=" + fid + " (" + this.fs.inodes[this.fids[fid].inodeid].name + ") offset=" + offset + " count=" + count);
|
||||
this.fs.Write(this.fids[fid].inodeid, offset, count, GetByte);
|
||||
|
||||
var file = this.fs.inodes[this.fids[fid].inodeid];
|
||||
this.bus.send("9p-write-end", [file.name, count]);
|
||||
|
||||
Marshall(["w"], [count], this.replybuffer, 7);
|
||||
marshall.Marshall(["w"], [count], this.replybuffer, 7);
|
||||
this.BuildReply(id, tag, 4);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
case 74: // RENAMEAT
|
||||
var req = Unmarshall2(["w", "s", "w", "s"], GetByte);
|
||||
var req = marshall.Unmarshall2(["w", "s", "w", "s"], GetByte);
|
||||
var olddirfid = req[0];
|
||||
var oldname = req[1];
|
||||
var newdirfid = req[2];
|
||||
var newname = req[3];
|
||||
DebugMessage("[renameat]: oldname=" + oldname + " newname=" + newname);
|
||||
message.Debug("[renameat]: oldname=" + oldname + " newname=" + newname);
|
||||
var ret = this.fs.Rename(this.fids[olddirfid].inodeid, oldname, this.fids[newdirfid].inodeid, newname);
|
||||
if (ret == false) {
|
||||
this.SendError(tag, "No such file or directory", ENOENT);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
}
|
||||
this.BuildReply(id, tag, 0);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
case 76: // TUNLINKAT
|
||||
var req = Unmarshall2(["w", "s", "w"], GetByte);
|
||||
var req = marshall.Unmarshall2(["w", "s", "w"], GetByte);
|
||||
var dirfd = req[0];
|
||||
var name = req[1];
|
||||
var flags = req[2];
|
||||
DebugMessage("[unlink]: dirfd=" + dirfd + " name=" + name + " flags=" + flags);
|
||||
message.Debug("[unlink]: dirfd=" + dirfd + " name=" + name + " flags=" + flags);
|
||||
var fid = this.fs.Search(this.fids[dirfd].inodeid, name);
|
||||
if (fid == -1) {
|
||||
this.SendError(tag, "No such file or directory", ENOENT);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
}
|
||||
var ret = this.fs.Unlink(fid);
|
||||
if (!ret) {
|
||||
this.SendError(tag, "Directory not empty", ENOTEMPTY);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
}
|
||||
this.BuildReply(fid, tag, 0);
|
||||
this.SendReply(index);
|
||||
this.BuildReply(id, tag, 0);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
case 100: // version
|
||||
var version = Unmarshall2(["w", "s"], GetByte);
|
||||
DebugMessage("[version]: msize=" + version[0] + " version=" + version[1]);
|
||||
var version = marshall.Unmarshall2(["w", "s"], GetByte);
|
||||
message.Debug("[version]: msize=" + version[0] + " version=" + version[1]);
|
||||
this.msize = version[0];
|
||||
var size = Marshall(["w", "s"], [this.msize, this.VERSION], this.replybuffer, 7);
|
||||
size = marshall.Marshall(["w", "s"], [this.msize, this.VERSION], this.replybuffer, 7);
|
||||
this.BuildReply(id, tag, size);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
case 104: // attach
|
||||
// return root directorie's QID
|
||||
var req = Unmarshall2(["w", "w", "s", "s", "w"], GetByte);
|
||||
var req = marshall.Unmarshall2(["w", "w", "s", "s", "w"], GetByte);
|
||||
var fid = req[0];
|
||||
var uid = req[4];
|
||||
DebugMessage("[attach]: fid=" + fid + " afid=" + hex8(req[1]) + " uname=" + req[2] + " aname=" + req[3]);
|
||||
message.Debug("[attach]: fid=" + fid + " afid=" + hex8(req[1]) + " uname=" + req[2] + " aname=" + req[3]);
|
||||
this.fids[fid] = this.Createfid(0, FID_INODE, uid);
|
||||
var inode = this.fs.GetInode(this.fids[fid].inodeid);
|
||||
Marshall(["Q"], [inode.qid], this.replybuffer, 7);
|
||||
marshall.Marshall(["Q"], [inode.qid], this.replybuffer, 7);
|
||||
this.BuildReply(id, tag, 13);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
case 108: // tflush
|
||||
var req = Unmarshall2(["h"], GetByte);
|
||||
var req = marshall.Unmarshall2(["h"], GetByte);
|
||||
var oldtag = req[0];
|
||||
DebugMessage("[flush] " + tag);
|
||||
//Marshall(["Q"], [inode.qid], this.replybuffer, 7);
|
||||
message.Debug("[flush] " + tag);
|
||||
//marshall.Marshall(["Q"], [inode.qid], this.replybuffer, 7);
|
||||
this.BuildReply(id, tag, 0);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
|
||||
case 110: // walk
|
||||
var req = Unmarshall2(["w", "w", "h"], GetByte);
|
||||
var req = marshall.Unmarshall2(["w", "w", "h"], GetByte);
|
||||
var fid = req[0];
|
||||
var nwfid = req[1];
|
||||
var nwname = req[2];
|
||||
DebugMessage("[walk]: fid=" + req[0] + " nwfid=" + req[1] + " nwname=" + nwname);
|
||||
message.Debug("[walk]: fid=" + req[0] + " nwfid=" + req[1] + " nwname=" + nwname);
|
||||
if (nwname == 0) {
|
||||
this.fids[nwfid] = this.Createfid(this.fids[fid].inodeid, FID_INODE, this.fids[fid].uid);
|
||||
//this.fids[nwfid].inodeid = this.fids[fid].inodeid;
|
||||
Marshall(["h"], [0], this.replybuffer, 7);
|
||||
marshall.Marshall(["h"], [0], this.replybuffer, 7);
|
||||
this.BuildReply(id, tag, 2);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
}
|
||||
var wnames = [];
|
||||
for(var i=0; i<nwname; i++) {
|
||||
wnames.push("s");
|
||||
}
|
||||
var walk = Unmarshall2(wnames, GetByte);
|
||||
var walk = marshall.Unmarshall2(wnames, GetByte);
|
||||
var idx = this.fids[fid].inodeid;
|
||||
var offset = 7+2;
|
||||
var nwidx = 0;
|
||||
//console.log(idx, this.fs.inodes[idx]);
|
||||
DebugMessage("walk in dir " + this.fs.inodes[idx].name + " to: " + walk.toString());
|
||||
message.Debug("walk in dir " + this.fs.inodes[idx].name + " to: " + walk.toString());
|
||||
for(var i=0; i<nwname; i++) {
|
||||
idx = this.fs.Search(idx, walk[i]);
|
||||
|
||||
if (idx == -1) {
|
||||
DebugMessage("Could not find: " + walk[i]);
|
||||
message.Debug("Could not find: " + walk[i]);
|
||||
break;
|
||||
}
|
||||
offset += Marshall(["Q"], [this.fs.inodes[idx].qid], this.replybuffer, offset);
|
||||
offset += marshall.Marshall(["Q"], [this.fs.inodes[idx].qid], this.replybuffer, offset);
|
||||
nwidx++;
|
||||
//DebugMessage(this.fids[nwfid].inodeid);
|
||||
//message.Debug(this.fids[nwfid].inodeid);
|
||||
//this.fids[nwfid].inodeid = idx;
|
||||
//this.fids[nwfid].type = FID_INODE;
|
||||
this.fids[nwfid] = this.Createfid(idx, FID_INODE, this.fids[fid].uid);
|
||||
}
|
||||
Marshall(["h"], [nwidx], this.replybuffer, 7);
|
||||
marshall.Marshall(["h"], [nwidx], this.replybuffer, 7);
|
||||
this.BuildReply(id, tag, offset-7);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
case 120: // clunk
|
||||
var req = Unmarshall2(["w"], GetByte);
|
||||
DebugMessage("[clunk]: fid=" + req[0]);
|
||||
var req = marshall.Unmarshall2(["w"], GetByte);
|
||||
message.Debug("[clunk]: fid=" + req[0]);
|
||||
if (this.fids[req[0]] && this.fids[req[0]].inodeid >= 0) {
|
||||
this.fs.CloseInode(this.fids[req[0]].inodeid);
|
||||
this.fids[req[0]].inodeid = -1;
|
||||
this.fids[req[0]].type = FID_NONE;
|
||||
}
|
||||
this.BuildReply(id, tag, 0);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
this.SendError(tag, "Operation i not supported", ENOTSUPP);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
case 30: // xattrwalk
|
||||
var req = Unmarshall2(["w", "w", "s"], GetByte);
|
||||
var req = marshall.Unmarshall2(["w", "w", "s"], GetByte);
|
||||
var fid = req[0];
|
||||
var newfid = req[1];
|
||||
var name = req[2];
|
||||
DebugMessage("[xattrwalk]: fid=" + req[0] + " newfid=" + req[1] + " name=" + req[2]);
|
||||
message.Debug("[xattrwalk]: fid=" + req[0] + " newfid=" + req[1] + " name=" + req[2]);
|
||||
this.fids[newfid] = this.Createfid(this.fids[fid].inodeid, FID_NONE, this.fids[fid].uid);
|
||||
//this.fids[newfid].inodeid = this.fids[fid].inodeid;
|
||||
//this.fids[newfid].type = FID_NONE;
|
||||
|
@ -603,16 +601,16 @@ Virtio9p.prototype.ReceiveRequest = function (index, GetByte) {
|
|||
length = this.fs.PrepareCAPs(this.fids[fid].inodeid);
|
||||
this.fids[newfid].type = FID_XATTR;
|
||||
}
|
||||
Marshall(["d"], [length], this.replybuffer, 7);
|
||||
marshall.Marshall(["d"], [length], this.replybuffer, 7);
|
||||
this.BuildReply(id, tag, 8);
|
||||
this.SendReply(index);
|
||||
this.SendReply(0, index);
|
||||
break;
|
||||
|
||||
default:
|
||||
DebugMessage("Error in Virtio9p: Unknown id " + id + " received");
|
||||
abort();
|
||||
message.Debug("Error in Virtio9p: Unknown id " + id + " received");
|
||||
message.Abort();
|
||||
//this.SendError(tag, "Operation i not supported", ENOTSUPP);
|
||||
//this.SendReply(index);
|
||||
//this.SendReply(0, index);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,25 +84,30 @@ function FS(baseurl) {
|
|||
// -----------------------------------------------------
|
||||
|
||||
FS.prototype.AddEvent = function(id, OnEvent) {
|
||||
var inode = this.inodes[id];
|
||||
var inode = this.GetInode(id);
|
||||
if (inode.status == STATUS_OK) {
|
||||
OnEvent();
|
||||
return;
|
||||
}
|
||||
this.events.push({id: id, OnEvent: OnEvent});
|
||||
this.events.push({id: id, OnEvent: OnEvent});
|
||||
}
|
||||
|
||||
FS.prototype.HandleEvent = function(id) {
|
||||
|
||||
if (this.filesinloadingqueue == 0) {
|
||||
this.OnLoaded();
|
||||
this.OnLoaded = function() {};
|
||||
this.OnLoaded = function() {}
|
||||
}
|
||||
//DebugMessage("number of events: " + this.events.length);
|
||||
for(var i = this.events.length - 1; i >= 0; i--) {
|
||||
if (this.events[i].id != id) continue;
|
||||
this.events[i].OnEvent();
|
||||
this.events.splice(i, 1);
|
||||
//message.Debug("number of events: " + this.events.length);
|
||||
var newevents = [];
|
||||
for(var i=0; i<this.events.length; i++) {
|
||||
if (this.events[i].id == id) {
|
||||
this.events[i].OnEvent();
|
||||
} else {
|
||||
newevents.push(this.events[i]);
|
||||
}
|
||||
}
|
||||
this.events = newevents;
|
||||
}
|
||||
|
||||
FS.prototype.OnJSONLoaded = function(fs)
|
||||
|
@ -254,7 +259,6 @@ FS.prototype.PushInode = function(inode) {
|
|||
if (inode.parentid != -1) {
|
||||
this.inodes.push(inode);
|
||||
inode.fid = this.inodes.length - 1;
|
||||
|
||||
var parent_node = this.inodes[inode.parentid];
|
||||
parent_node.updatedir = true;
|
||||
inode.nextid = parent_node.firstid;
|
||||
|
@ -267,8 +271,9 @@ FS.prototype.PushInode = function(inode) {
|
|||
}
|
||||
}
|
||||
|
||||
DebugMessage("Error in Filesystem: Pushed inode with name = "+ inode.name + " has no parent");
|
||||
abort();
|
||||
message.Debug("Error in Filesystem: Pushed inode with name = "+ inode.name + " has no parent");
|
||||
message.Abort();
|
||||
|
||||
}
|
||||
|
||||
/** @constructor */
|
||||
|
@ -302,8 +307,6 @@ function Inode(qidnumber)
|
|||
//this.qid_type = 0;
|
||||
//this.qid_version = 0;
|
||||
//this.qid_path = qidnumber;
|
||||
|
||||
//this.waswritten = false;
|
||||
}
|
||||
|
||||
FS.prototype.CreateInode = function() {
|
||||
|
@ -317,6 +320,7 @@ FS.prototype.CreateDirectory = function(name, parentid) {
|
|||
x.name = name;
|
||||
x.parentid = parentid;
|
||||
x.mode = 0x01FF | S_IFDIR;
|
||||
x.updatedir = true;
|
||||
if (parentid >= 0) {
|
||||
x.uid = this.inodes[parentid].uid;
|
||||
x.gid = this.inodes[parentid].gid;
|
||||
|
@ -324,6 +328,7 @@ FS.prototype.CreateDirectory = function(name, parentid) {
|
|||
}
|
||||
x.qid.type = S_IFDIR >> 8;
|
||||
this.PushInode(x);
|
||||
this.NotifyListeners(this.inodes.length-1, 'newdir');
|
||||
return this.inodes.length-1;
|
||||
}
|
||||
|
||||
|
@ -336,6 +341,7 @@ FS.prototype.CreateFile = function(filename, parentid) {
|
|||
x.qid.type = S_IFREG >> 8;
|
||||
x.mode = (this.inodes[parentid].mode & 0x1B6) | S_IFREG;
|
||||
this.PushInode(x);
|
||||
this.NotifyListeners(this.inodes.length-1, 'newfile');
|
||||
return this.inodes.length-1;
|
||||
}
|
||||
|
||||
|
@ -371,7 +377,6 @@ FS.prototype.CreateTextFile = function(filename, parentid, str) {
|
|||
var id = this.CreateFile(filename, parentid);
|
||||
var x = this.inodes[id];
|
||||
var data = this.inodedata[id] = new Uint8Array(str.length);
|
||||
//x.waswritten = true;
|
||||
x.size = str.length;
|
||||
for (var j = 0; j < str.length; j++) {
|
||||
data[j] = str.charCodeAt(j);
|
||||
|
@ -387,7 +392,6 @@ FS.prototype.CreateBinaryFile = function(filename, parentid, buffer) {
|
|||
var x = this.inodes[id];
|
||||
var data = this.inodedata[id] = new Uint8Array(buffer.length);
|
||||
data.set(buffer);
|
||||
//x.waswritten = true;
|
||||
x.size = buffer.length;
|
||||
return id;
|
||||
}
|
||||
|
@ -407,7 +411,7 @@ FS.prototype.OpenInode = function(id, mode) {
|
|||
case S_IFCHR: type = "Character Device"; break;
|
||||
}
|
||||
*/
|
||||
//DebugMessage("open:" + this.GetFullPath(id) + " status:" + inode.status);
|
||||
//message.Debug("open:" + this.GetFullPath(id) + " type: " + inode.mode + " status:" + inode.status);
|
||||
if (inode.status == STATUS_ON_SERVER) {
|
||||
this.LoadFile(id);
|
||||
return false;
|
||||
|
@ -416,23 +420,23 @@ FS.prototype.OpenInode = function(id, mode) {
|
|||
}
|
||||
|
||||
FS.prototype.CloseInode = function(id) {
|
||||
//DebugMessage("close: " + this.GetFullPath(id));
|
||||
//message.Debug("close: " + this.GetFullPath(id));
|
||||
var inode = this.GetInode(id);
|
||||
if (inode.status == STATUS_UNLINKED) {
|
||||
//DebugMessage("Filesystem: Delete unlinked file");
|
||||
//message.Debug("Filesystem: Delete unlinked file");
|
||||
inode.status == STATUS_INVALID;
|
||||
delete this.inodedata[id];
|
||||
//inode.waswritten = true;
|
||||
inode.size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
FS.prototype.Rename = function(olddirid, oldname, newdirid, newname) {
|
||||
//DebugMessage("Rename " + oldname + " to " + newname);
|
||||
// message.Debug("Rename " + oldname + " to " + newname);
|
||||
if ((olddirid == newdirid) && (oldname == newname)) {
|
||||
return true;
|
||||
}
|
||||
var oldid = this.Search(olddirid, oldname);
|
||||
var oldpath = this.GetFullPath(oldid);
|
||||
if (oldid == -1) {
|
||||
return false;
|
||||
}
|
||||
|
@ -450,8 +454,8 @@ FS.prototype.Rename = function(olddirid, oldname, newdirid, newname) {
|
|||
} else {
|
||||
var id = this.FindPreviousID(idx);
|
||||
if (id == -1) {
|
||||
//DebugMessage("Error in Filesystem: Cannot find previous id of inode");
|
||||
abort();
|
||||
message.Debug("Error in Filesystem: Cannot find previous id of inode");
|
||||
message.Abort();
|
||||
}
|
||||
this.inodes[id].nextid = inode.nextid;
|
||||
}
|
||||
|
@ -465,13 +469,16 @@ FS.prototype.Rename = function(olddirid, oldname, newdirid, newname) {
|
|||
|
||||
this.inodes[olddirid].updatedir = true;
|
||||
this.inodes[newdirid].updatedir = true;
|
||||
|
||||
this.NotifyListeners(idx, "rename", {oldpath: oldpath});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FS.prototype.Write = function(id, offset, count, GetByte) {
|
||||
this.NotifyListeners(id, 'write');
|
||||
var inode = this.inodes[id];
|
||||
var data = this.inodedata[id];
|
||||
//inode.waswritten = true;
|
||||
|
||||
if (!data || data.length < (offset+count)) {
|
||||
this.ChangeSize(id, Math.floor(((offset+count)*3)/2) );
|
||||
|
@ -489,7 +496,7 @@ FS.prototype.Search = function(parentid, name) {
|
|||
var id = this.inodes[parentid].firstid;
|
||||
while(id != -1) {
|
||||
if (this.inodes[id].parentid != parentid) { // consistency check
|
||||
DebugMessage("Error in Filesystem: Found inode with wrong parent id");
|
||||
message.Debug("Error in Filesystem: Found inode with wrong parent id");
|
||||
}
|
||||
if (this.inodes[id].name == name) return id;
|
||||
id = this.inodes[id].nextid;
|
||||
|
@ -533,9 +540,10 @@ FS.prototype.FindPreviousID = function(idx) {
|
|||
}
|
||||
|
||||
FS.prototype.Unlink = function(idx) {
|
||||
this.NotifyListeners(idx, 'delete');
|
||||
if (idx == 0) return false; // root node cannot be deleted
|
||||
var inode = this.GetInode(idx);
|
||||
//DebugMessage("Unlink " + inode.name);
|
||||
//message.Debug("Unlink " + inode.name);
|
||||
|
||||
// check if directory is not empty
|
||||
if ((inode.mode&S_IFMT) == S_IFDIR) {
|
||||
|
@ -548,8 +556,8 @@ FS.prototype.Unlink = function(idx) {
|
|||
} else {
|
||||
var id = this.FindPreviousID(idx);
|
||||
if (id == -1) {
|
||||
DebugMessage("Error in Filesystem: Cannot find previous id of inode");
|
||||
abort();
|
||||
message.Debug("Error in Filesystem: Cannot find previous id of inode");
|
||||
message.Abort();
|
||||
}
|
||||
this.inodes[id].nextid = inode.nextid;
|
||||
}
|
||||
|
@ -565,12 +573,12 @@ FS.prototype.Unlink = function(idx) {
|
|||
FS.prototype.GetInode = function(idx)
|
||||
{
|
||||
if (isNaN(idx)) {
|
||||
DebugMessage("Error in filesystem: id is not a number ");
|
||||
message.Debug("Error in filesystem: id is not a number ");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((idx < 0) || (idx > this.inodes.length)) {
|
||||
DebugMessage("Error in filesystem: Attempt to get inode with id " + idx);
|
||||
message.Debug("Error in filesystem: Attempt to get inode with id " + idx);
|
||||
return 0;
|
||||
}
|
||||
return this.inodes[idx];
|
||||
|
@ -580,11 +588,10 @@ FS.prototype.ChangeSize = function(idx, newsize)
|
|||
{
|
||||
var inode = this.GetInode(idx);
|
||||
var temp = this.inodedata[idx];
|
||||
//DebugMessage("change size to: " + newsize);
|
||||
//message.Debug("change size to: " + newsize);
|
||||
if (newsize == inode.size) return;
|
||||
var data = this.inodedata[idx] = new Uint8Array(newsize);
|
||||
inode.size = newsize;
|
||||
//inode.waswritten = true;
|
||||
if(!temp) return;
|
||||
var size = Math.min(temp.length, inode.size);
|
||||
for(var i=0; i<size; i++) {
|
||||
|
@ -627,15 +634,63 @@ FS.prototype.GetRecursiveList = function(dirid, list) {
|
|||
}
|
||||
|
||||
FS.prototype.MergeFile = function(file) {
|
||||
throw "unimplemented";
|
||||
//DebugMessage("Merge path:" + file.name);
|
||||
//var ids = this.SearchPath(file.name);
|
||||
//if (ids.parentid == -1) return; // not even the path seems to exist
|
||||
//if (ids.id == -1) {
|
||||
// ids.id = this.CreateFile(ids.name, ids.parentid);
|
||||
message.Debug("Merge path:" + file.name);
|
||||
var ids = this.SearchPath(file.name);
|
||||
if (ids.parentid == -1) return; // not even the path seems to exist
|
||||
if (ids.id == -1) {
|
||||
ids.id = this.CreateFile(ids.name, ids.parentid);
|
||||
}
|
||||
this.inodes[ids.id].data = file.data;
|
||||
this.inodes[ids.id].size = file.data.length;
|
||||
}
|
||||
|
||||
|
||||
FS.prototype.RecursiveDelete = function(path) {
|
||||
var toDelete = []
|
||||
var ids = this.SearchPath(path);
|
||||
if (ids.parentid == -1 || ids.id == -1) return;
|
||||
|
||||
this.GetRecursiveList(ids.id, toDelete);
|
||||
|
||||
for(var i=toDelete.length-1; i>=0; i--)
|
||||
this.Unlink(toDelete[i]);
|
||||
|
||||
}
|
||||
|
||||
FS.prototype.DeleteNode = function(path) {
|
||||
var ids = this.SearchPath(path);
|
||||
if (ids.parentid == -1 || ids.id == -1) return;
|
||||
|
||||
if ((this.inodes[ids.id].mode&S_IFMT) == S_IFREG){
|
||||
this.Unlink(ids.id);
|
||||
return;
|
||||
}
|
||||
if ((this.inodes[ids.id].mode&S_IFMT) == S_IFDIR){
|
||||
var toDelete = []
|
||||
this.GetRecursiveList(ids.id, toDelete);
|
||||
for(var i=toDelete.length-1; i>=0; i--)
|
||||
this.Unlink(toDelete[i]);
|
||||
this.Unlink(ids.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/** @param {*=} info */
|
||||
FS.prototype.NotifyListeners = function(id, action, info) {
|
||||
//if(info==undefined)
|
||||
// info = {};
|
||||
|
||||
//var path = this.GetFullPath(id);
|
||||
//if (this.watchFiles[path] == true && action=='write') {
|
||||
// message.Send("WatchFileEvent", path);
|
||||
//}
|
||||
//for (var directory in this.watchDirectories) {
|
||||
// if (this.watchDirectories.hasOwnProperty(directory)) {
|
||||
// var indexOf = path.indexOf(directory)
|
||||
// if(indexOf == 0 || indexOf == 1)
|
||||
// message.Send("WatchDirectoryEvent", {path: path, event: action, info: info});
|
||||
// }
|
||||
//}
|
||||
//this.inodes[ids.id].data = file.data;
|
||||
//this.inodes[ids.id].size = file.data.length;
|
||||
}
|
||||
|
||||
|
||||
|
@ -644,23 +699,23 @@ FS.prototype.Check = function() {
|
|||
{
|
||||
if (this.inodes[i].status == STATUS_INVALID) continue;
|
||||
if (this.inodes[i].nextid == i) {
|
||||
DebugMessage("Error in filesystem: file points to itself");
|
||||
abort();
|
||||
message.Debug("Error in filesystem: file points to itself");
|
||||
message.Abort();
|
||||
}
|
||||
|
||||
var inode = this.GetInode(i);
|
||||
if (inode.parentid < 0) {
|
||||
DebugMessage("Error in filesystem: negative parent id " + i);
|
||||
message.Debug("Error in filesystem: negative parent id " + i);
|
||||
}
|
||||
var n = inode.name.length;
|
||||
if (n == 0) {
|
||||
DebugMessage("Error in filesystem: inode with no name and id " + i);
|
||||
message.Debug("Error in filesystem: inode with no name and id " + i);
|
||||
}
|
||||
|
||||
for (var j in inode.name) {
|
||||
var c = inode.name.charCodeAt(j);
|
||||
if (c < 32) {
|
||||
DebugMessage("Error in filesystem: Unallowed char in filename");
|
||||
message.Debug("Error in filesystem: Unallowed char in filename");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -678,29 +733,28 @@ FS.prototype.FillDirectory = function(dirid) {
|
|||
var size = 0;
|
||||
var id = this.inodes[dirid].firstid;
|
||||
while(id != -1) {
|
||||
size += 13 + 8 + 1 + 2 + UTF8Length(this.inodes[id].name);
|
||||
size += 13 + 8 + 1 + 2 + UTF8.UTF8Length(this.inodes[id].name);
|
||||
id = this.inodes[id].nextid;
|
||||
}
|
||||
|
||||
size += 13 + 8 + 1 + 2 + 1; // "." entry
|
||||
size += 13 + 8 + 1 + 2 + 2; // ".." entry
|
||||
//DebugMessage("size of dir entry: " + size);
|
||||
//message.Debug("size of dir entry: " + size);
|
||||
var data = this.inodedata[dirid] = new Uint8Array(size);
|
||||
//inode.waswritten = true;
|
||||
inode.size = size;
|
||||
|
||||
var offset = 0x0;
|
||||
offset += Marshall(
|
||||
offset += marshall.Marshall(
|
||||
["Q", "d", "b", "s"],
|
||||
[this.MakeQid(this.inodes[dirid]),
|
||||
[this.inodes[dirid].qid,
|
||||
offset+13+8+1+2+1,
|
||||
this.inodes[dirid].mode >> 12,
|
||||
"."],
|
||||
data, offset);
|
||||
|
||||
offset += Marshall(
|
||||
offset += marshall.Marshall(
|
||||
["Q", "d", "b", "s"],
|
||||
[this.MakeQid(this.inodes[parentid]),
|
||||
[this.inodes[parentid].qid,
|
||||
offset+13+8+1+2+2,
|
||||
this.inodes[parentid].mode >> 12,
|
||||
".."],
|
||||
|
@ -708,10 +762,10 @@ FS.prototype.FillDirectory = function(dirid) {
|
|||
|
||||
id = this.inodes[dirid].firstid;
|
||||
while(id != -1) {
|
||||
offset += Marshall(
|
||||
offset += marshall.Marshall(
|
||||
["Q", "d", "b", "s"],
|
||||
[this.MakeQid(this.inodes[id]),
|
||||
offset+13+8+1+2+UTF8Length(this.inodes[id].name),
|
||||
[this.inodes[id].qid,
|
||||
offset+13+8+1+2+UTF8.UTF8Length(this.inodes[id].name),
|
||||
this.inodes[id].mode >> 12,
|
||||
this.inodes[id].name],
|
||||
data, offset);
|
||||
|
@ -756,23 +810,3 @@ FS.prototype.PrepareCAPs = function(id) {
|
|||
return inode.caps.length;
|
||||
}
|
||||
|
||||
//FS.prototype.ClearCache = function()
|
||||
//{
|
||||
// for(var id in this.inodedata)
|
||||
// {
|
||||
// if(!this.inodes[id].waswritten)
|
||||
// {
|
||||
// delete this.inodedata[id];
|
||||
// }
|
||||
// }
|
||||
//};
|
||||
|
||||
FS.prototype.MakeQid = function(inode)
|
||||
{
|
||||
return inode.qid;
|
||||
//return {
|
||||
// type: inode.qid_type,
|
||||
// version: inode.qid_version,
|
||||
// path: inode.qid_path,
|
||||
//};
|
||||
};
|
||||
|
|
130
lib/jor1k.js
130
lib/jor1k.js
|
@ -29,17 +29,20 @@ var VRING_DESC_F_WRITE = 2; /* This marks a buffer as write-only (otherwise
|
|||
var VRING_DESC_F_INDIRECT = 4; /* This means the buffer contains a list of buffer descriptors. */
|
||||
|
||||
|
||||
function Swap16(x)
|
||||
{
|
||||
// OR1K is big endian, therefore no conversion needed for us
|
||||
return x;
|
||||
}
|
||||
function Swap32(x)
|
||||
{
|
||||
return x;
|
||||
function hex8(n)
|
||||
{
|
||||
return h(n);
|
||||
}
|
||||
|
||||
function abort()
|
||||
var message = {};
|
||||
|
||||
/** @param {...string} log */
|
||||
message.Debug = function(log)
|
||||
{
|
||||
dbg_log([].slice.apply(arguments).join(" "), LOG_9P);
|
||||
}
|
||||
|
||||
message.Abort = function()
|
||||
{
|
||||
if(DEBUG)
|
||||
{
|
||||
|
@ -47,63 +50,58 @@ function abort()
|
|||
}
|
||||
}
|
||||
|
||||
function hex8(n)
|
||||
|
||||
// XXX: Should go through emulator interface
|
||||
var LoadBinaryResource;
|
||||
|
||||
if(typeof XMLHttpRequest !== "undefined")
|
||||
{
|
||||
return h(n);
|
||||
}
|
||||
|
||||
/** @param {...string} log */
|
||||
function DebugMessage(log)
|
||||
{
|
||||
dbg_log([].slice.apply(arguments).join(" "), LOG_9P);
|
||||
}
|
||||
|
||||
function LoadXMLResource(url, OnSuccess, OnError) {
|
||||
var req = new XMLHttpRequest();
|
||||
req.open('GET', url, true);
|
||||
//req.overrideMimeType('text/xml');
|
||||
req.onreadystatechange = function () {
|
||||
if (req.readyState != 4) {
|
||||
return;
|
||||
}
|
||||
if ((req.status != 200) && (req.status != 0)) {
|
||||
OnError("Error: Could not load XML file " + url);
|
||||
return;
|
||||
}
|
||||
OnSuccess(req.responseText);
|
||||
};
|
||||
req.send(null);
|
||||
}
|
||||
|
||||
|
||||
function LoadBinaryResource(url, OnSuccess, OnError) {
|
||||
var req = new XMLHttpRequest();
|
||||
req.open('GET', url, true);
|
||||
req.responseType = "arraybuffer";
|
||||
req.onreadystatechange = function () {
|
||||
if (req.readyState != 4) {
|
||||
return;
|
||||
}
|
||||
if ((req.status != 200) && (req.status != 0)) {
|
||||
OnError("Error: Could not load file " + url);
|
||||
return;
|
||||
}
|
||||
var arrayBuffer = req.response;
|
||||
if (arrayBuffer) {
|
||||
OnSuccess(arrayBuffer);
|
||||
} else {
|
||||
OnError("Error: No data received from: " + url);
|
||||
}
|
||||
};
|
||||
/*
|
||||
req.onload = function(e)
|
||||
{
|
||||
var arrayBuffer = req.response;
|
||||
if (arrayBuffer) {
|
||||
OnLoadFunction(arrayBuffer);
|
||||
}
|
||||
LoadBinaryResource = function(url, OnSuccess, OnError) {
|
||||
var req = new XMLHttpRequest();
|
||||
req.open('GET', url, true);
|
||||
req.responseType = "arraybuffer";
|
||||
req.onreadystatechange = function () {
|
||||
if (req.readyState != 4) {
|
||||
return;
|
||||
}
|
||||
if ((req.status != 200) && (req.status != 0)) {
|
||||
OnError("Error: Could not load file " + url);
|
||||
return;
|
||||
}
|
||||
var arrayBuffer = req.response;
|
||||
if (arrayBuffer) {
|
||||
OnSuccess(arrayBuffer);
|
||||
} else {
|
||||
OnError("Error: No data received from: " + url);
|
||||
}
|
||||
};
|
||||
*/
|
||||
req.send(null);
|
||||
/*
|
||||
req.onload = function(e)
|
||||
{
|
||||
var arrayBuffer = req.response;
|
||||
if (arrayBuffer) {
|
||||
OnLoadFunction(arrayBuffer);
|
||||
}
|
||||
};
|
||||
*/
|
||||
req.send(null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadBinaryResource = function(url, OnSuccess, OnError)
|
||||
{
|
||||
//console.log(url);
|
||||
require("fs")["readFile"](url, function(err, data)
|
||||
{
|
||||
if(err)
|
||||
{
|
||||
OnError(err);
|
||||
}
|
||||
else
|
||||
{
|
||||
OnSuccess(new Uint8Array(data).buffer);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
// -------------------------------------------------
|
||||
// helper functions for virtio and 9p.
|
||||
|
||||
var marshall = {};
|
||||
|
||||
|
||||
// Inserts data from an array to a byte aligned struct in memory
|
||||
function Marshall(typelist, input, struct, offset) {
|
||||
marshall.Marshall = function(typelist, input, struct, offset) {
|
||||
var item;
|
||||
var size = 0;
|
||||
for (var i=0; i < typelist.length; i++) {
|
||||
|
@ -56,12 +58,12 @@ function Marshall(typelist, input, struct, offset) {
|
|||
struct[lengthoffset+1] = (length >> 8) & 0xFF;
|
||||
break;
|
||||
case "Q":
|
||||
Marshall(["b", "w", "d"], [item.type, item.version, item.path], struct, offset)
|
||||
marshall.Marshall(["b", "w", "d"], [item.type, item.version, item.path], struct, offset)
|
||||
offset += 13;
|
||||
size += 13;
|
||||
break;
|
||||
default:
|
||||
DebugMessage("Marshall: Unknown type=" + typelist[i]);
|
||||
message.Debug("Marshall: Unknown type=" + typelist[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +72,7 @@ function Marshall(typelist, input, struct, offset) {
|
|||
|
||||
|
||||
// Extracts data from a byte aligned struct in memory to an array
|
||||
function Unmarshall(typelist, struct, offset) {
|
||||
marshall.Unmarshall = function(typelist, struct, offset) {
|
||||
var output = [];
|
||||
for (var i=0; i < typelist.length; i++) {
|
||||
switch (typelist[i]) {
|
||||
|
@ -109,7 +111,7 @@ function Unmarshall(typelist, struct, offset) {
|
|||
output.push(str);
|
||||
break;
|
||||
default:
|
||||
DebugMessage("Error in Unmarshall: Unknown type=" + typelist[i]);
|
||||
message.Debug("Error in Unmarshall: Unknown type=" + typelist[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +120,7 @@ function Unmarshall(typelist, struct, offset) {
|
|||
|
||||
|
||||
// Extracts data from a byte aligned struct in memory to an array
|
||||
function Unmarshall2(typelist, GetByte) {
|
||||
marshall.Unmarshall2 = function(typelist, GetByte) {
|
||||
var output = [];
|
||||
for (var i=0; i < typelist.length; i++) {
|
||||
switch (typelist[i]) {
|
||||
|
@ -157,7 +159,7 @@ function Unmarshall2(typelist, GetByte) {
|
|||
output.push(str);
|
||||
break;
|
||||
default:
|
||||
DebugMessage("Error in Unmarshall2: Unknown type=" + typelist[i]);
|
||||
message.Debug("Error in Unmarshall2: Unknown type=" + typelist[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
var UTF8 = {}
|
||||
|
||||
/** @constructor */
|
||||
function UTF8StreamToUnicode() {
|
||||
|
||||
|
@ -50,7 +52,7 @@ function UnicodeToUTF8Stream(key)
|
|||
if (key < 0x800) return [0xC0|((key>>6)&0x1F), 0x80|(key&0x3F)];
|
||||
}
|
||||
|
||||
function UTF8Length(s)
|
||||
UTF8.UTF8Length = function(s)
|
||||
{
|
||||
var length = 0;
|
||||
for(var i=0; i<s.length; i++) {
|
||||
|
|
|
@ -32,6 +32,7 @@ function VirtIO(cpu, bus, filesystem)
|
|||
io.register_read(0xA800, this, undefined, undefined, function()
|
||||
{
|
||||
// device features
|
||||
dbg_log("Read device features", LOG_VIRTIO);
|
||||
return 1;
|
||||
});
|
||||
|
||||
|
@ -81,12 +82,31 @@ function VirtIO(cpu, bus, filesystem)
|
|||
io.register_write(0xA812, this, function(data)
|
||||
{
|
||||
dbg_log("Write device status: " + h(data, 2), LOG_VIRTIO);
|
||||
|
||||
if(data === 0)
|
||||
{
|
||||
dbg_log("Reset", LOG_VIRTIO);
|
||||
this.reset();
|
||||
}
|
||||
else if(data & 0x80)
|
||||
{
|
||||
dbg_log("Warning: Device status failed", LOG_VIRTIO);
|
||||
}
|
||||
else
|
||||
{
|
||||
dbg_log(((data & 1) ? "ACKNOWLEDGE " : "") +
|
||||
((data & 2) ? "DRIVER " : "") +
|
||||
((data & 4) ? "DRIVER_OK" : ""),
|
||||
LOG_VIRTIO);
|
||||
|
||||
}
|
||||
|
||||
this.device_status = data;
|
||||
});
|
||||
|
||||
io.register_read(0xA812, this, function()
|
||||
{
|
||||
dbg_log("Read device status", LOG_VIRTIO);
|
||||
dbg_log("Read device status: " + h(this.device_status), LOG_VIRTIO);
|
||||
return this.device_status;
|
||||
});
|
||||
|
||||
|
@ -297,7 +317,7 @@ VirtIO.prototype.handle_descriptor = function(idx)
|
|||
}.bind(this));
|
||||
};
|
||||
|
||||
VirtIO.prototype.device_reply = function(infos)
|
||||
VirtIO.prototype.device_reply = function(queueidx, infos)
|
||||
{
|
||||
if(infos.next === -1)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue