Browse Source

Port filesystem changes from jor1k

454784a  Count links in directory
43cf658  Finish fixing (c|a|m)time updating in MergeFile
copy 6 years ago
parent
commit
5eb5389e52
2 changed files with 28 additions and 13 deletions
  1. 3 4
      lib/9p.js
  2. 25 9
      lib/filesystem.js

+ 3 - 4
lib/9p.js

@@ -106,7 +106,7 @@ 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() {
@@ -146,7 +146,7 @@ Virtio9p.prototype.ReceiveRequest = function (index, GetByte) {
             var req = [];
             req[0] = 0x01021997;
             req[1] = this.BLOCKSIZE; // optimal transfer block size
-            req[2] = Math.floor(space/req[1]); // free blocks, let's say 1GB
+            req[2] = Math.floor(space/req[1]); // free blocks
             req[3] = req[2] - Math.floor(size/req[1]); // free blocks in fs
             req[4] = req[2] - Math.floor(size/req[1]); // free blocks avail to non-superuser
             req[5] = this.fs.inodes.length; // total number of inodes
@@ -328,7 +328,7 @@ Virtio9p.prototype.ReceiveRequest = function (index, GetByte) {
             req[3] = inode.uid; // user id
             req[4] = inode.gid; // group id
             
-            req[5] = 0x1; // number of hard links
+            req[5] = inode.nlinks; // number of hard links
             req[6] = (inode.major<<8) | (inode.minor); // device id low
             req[7] = inode.size; // size low
             req[8] = this.BLOCKSIZE;
@@ -639,4 +639,3 @@ Virtio9p.prototype.ReceiveRequest = function (index, GetByte) {
     //consistency checks if there are problems with the filesystem
     //this.fs.Check();
 }
-

+ 25 - 9
lib/filesystem.js

@@ -168,6 +168,7 @@ FS.prototype.LoadRecursive = function(data, parentid)
     inode.gid = data[JSONFS_IDX_GID];
 
     inode.parentid = parentid;
+    this.inodes[inode.parentid].nlinks++;
 
     var ifmt = inode.mode & S_IFMT;
 
@@ -198,6 +199,7 @@ FS.prototype.LoadRecursive = function(data, parentid)
 FS.prototype.LoadDir = function(inode, children)
 {
     inode.updatedir = true;
+    inode.nlinks = 2; // . and ..
 
     var p = this.inodes.length;
     this.PushInode(inode);
@@ -294,11 +296,12 @@ function Inode(qidnumber)
     this.minor = 0x0;
     //data = new Uint8Array(0);
     this.symlink = "";
+    this.nlinks = 1;
     this.mode = 0x01ED;
     this.qid = {
-        type: 0, 
-        version: 0, 
-        path: qidnumber
+        type: 0,
+        version: 0,
+        path: qidnumber,
     };
     this.caps = undefined;
 
@@ -319,10 +322,12 @@ FS.prototype.CreateDirectory = function(name, parentid) {
     x.parentid = parentid;
     x.mode = 0x01FF | S_IFDIR;
     x.updatedir = true;
+    x.nlinks = 2; // . and ..
     if (parentid >= 0) {
         x.uid = this.inodes[parentid].uid;
         x.gid = this.inodes[parentid].gid;
         x.mode = (this.inodes[parentid].mode & 0x1FF) | S_IFDIR;
+        this.inodes[parentid].nlinks++;
     }
     x.qid.type = S_IFDIR >> 8;
     this.PushInode(x);
@@ -336,6 +341,7 @@ FS.prototype.CreateFile = function(filename, parentid) {
     x.parentid = parentid;
     x.uid = this.inodes[parentid].uid;
     x.gid = this.inodes[parentid].gid;
+    this.inodes[parentid].nlinks++;
     x.qid.type = S_IFREG >> 8;
     x.mode = (this.inodes[parentid].mode & 0x1B6) | S_IFREG;
     this.PushInode(x);
@@ -352,6 +358,7 @@ FS.prototype.CreateNode = function(filename, parentid, major, minor) {
     x.minor = minor;
     x.uid = this.inodes[parentid].uid;
     x.gid = this.inodes[parentid].gid;
+    this.inodes[parentid].nlinks++;
     x.qid.type = S_IFSOCK >> 8;
     x.mode = (this.inodes[parentid].mode & 0x1B6);
     this.PushInode(x);
@@ -364,6 +371,7 @@ FS.prototype.CreateSymlink = function(filename, parentid, symlink) {
     x.parentid = parentid;
     x.uid = this.inodes[parentid].uid;
     x.gid = this.inodes[parentid].gid;
+    this.inodes[parentid].nlinks++;
     x.qid.type = S_IFLNK >> 8;
     x.symlink = symlink;
     x.mode = S_IFLNK;
@@ -467,6 +475,8 @@ FS.prototype.Rename = function(olddirid, oldname, newdirid, newname) {
 
     this.inodes[olddirid].updatedir = true;
     this.inodes[newdirid].updatedir = true;
+    this.inodes[olddirid].nlinks--;
+    this.inodes[newdirid].nlinks++;
 
     this.NotifyListeners(idx, "rename", {oldpath: oldpath});
     
@@ -561,10 +571,12 @@ FS.prototype.Unlink = function(idx) {
     }
     // don't delete the content. The file is still accessible
     this.inodes[inode.parentid].updatedir = true;
+    this.inodes[inode.parentid].nlinks--;
     inode.status = STATUS_UNLINKED;
     inode.nextid = -1;
     inode.firstid = -1;
     inode.parentid = -1;
+    inode.nlinks--;
     return true;
 }
 
@@ -640,6 +652,10 @@ FS.prototype.MergeFile = function(file) {
     }
     this.inodes[ids.id].data = file.data;
     this.inodes[ids.id].size = file.data.length;
+    // Don't forget to update the timestamps !
+    this.inodes[ids.id].mtime = Math.floor((new Date()).getTime()/1000);
+    this.inodes[ids.id].atime = this.inodes[ids.id].mtime;
+    this.inodes[ids.id].ctime = this.inodes[ids.id].mtime;
 }
 
 
@@ -717,10 +733,8 @@ FS.prototype.Check = function() {
             } 
         }
     }
-
 }
 
-
 FS.prototype.FillDirectory = function(dirid) {
     var inode = this.GetInode(dirid);
     if (!inode.updatedir) return;
@@ -762,10 +776,12 @@ FS.prototype.FillDirectory = function(dirid) {
     while(id != -1) {
         offset += marshall.Marshall(
         ["Q", "d", "b", "s"],
-        [this.inodes[id].qid,
-        offset+13+8+1+2+UTF8.UTF8Length(this.inodes[id].name),
-        this.inodes[id].mode >> 12,
-        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);
         id = this.inodes[id].nextid;
     }