All basic operations now working in Linux 9P mounted fs

This commit is contained in:
David Humphrey 2018-05-22 14:16:20 -04:00
parent 2e627cfe5b
commit 93633da622
4 changed files with 80 additions and 20 deletions

View File

@ -48,10 +48,12 @@ var Buffer = require('../buffer.js');
*/
function update_node_times(context, path, node, times, callback) {
var update = false;
// If updating the P9 info only, don't send change events (honour flags).
var queueChangeEvent = false;
if(times.ctime || times.mtime) {
// Update the qid's version field, since node has changed.
// TODO: this might more than I need to do...
// TODO: this might be more than I need to do...
node.p9.qid.version = times.ctime || times.mtime;
update = true;
}
@ -70,24 +72,27 @@ function update_node_times(context, path, node, times, callback) {
// We don't do atime tracking for perf reasons, but do mirror ctime
node.atime = times.ctime;
update = true;
queueChangeEvent = true;
}
if(times.atime) {
// The only time we explicitly pass atime is when utimes(), futimes() is called.
// Override ctime mirror here if so
node.atime = times.atime;
update = true;
queueChangeEvent = true;
}
if(times.mtime) {
node.mtime = times.mtime;
// Also update the qid's version filed, since file has changed.
node.p9.qid.version = times.mtime;
update = true;
queueChangeEvent = true;
}
function complete(error) {
// Queue this change so we can send watch events.
// Unlike node.js, we send the full path vs. basename/dirname only.
context.changes.push({ event: 'change', path: path });
if(queueChangeEvent) {
context.changes.push({ event: 'change', path: path });
}
callback(error);
}
@ -908,6 +913,7 @@ function link_node(context, oldpath, newpath, callback) {
newpath = normalize(newpath);
var newname = basename(newpath);
var newParentPath = dirname(newpath);
var ctime = Date.now();
var oldDirectoryNode;
var oldDirectoryData;
@ -919,7 +925,7 @@ function link_node(context, oldpath, newpath, callback) {
if(error) {
callback(error);
} else {
update_node_times(context, newpath, fileNode, { ctime: Date.now() }, callback);
update_node_times(context, newpath, fileNode, { ctime: ctime }, callback);
}
}
@ -927,8 +933,9 @@ function link_node(context, oldpath, newpath, callback) {
if(error) {
callback(error);
} else {
fileNode = result;
fileNode = Node.fromObject(result);
fileNode.nlinks += 1;
fileNode.updatePathInfo(newpath, ctime);
context.putObject(fileNode.id, fileNode, update_time);
}
}
@ -2018,12 +2025,26 @@ function rename(fs, context, oldpath, newpath, callback) {
var newName = Path.basename(newpath);
var oldParentDirectory, oldParentData;
var newParentDirectory, newParentData;
var ctime = Date.now();
var fileNode;
function update_times(error, newNode) {
function update_times(error) {
if(error) {
callback(error);
} else {
update_node_times(context, newpath, newNode, { ctime: Date.now() }, callback);
update_node_times(context, newpath, fileNode, { ctime: ctime }, callback);
}
}
function update_file_node(error, result) {
if(error) {
callback(error);
} else {
fileNode = Node.fromObject(result);
// Don't think I need this here...
// fileNode.nlinks += 1;
fileNode.updatePathInfo(newpath, ctime);
context.putObject(fileNode.id, fileNode, update_times);
}
}
@ -2031,7 +2052,7 @@ function rename(fs, context, oldpath, newpath, callback) {
if(error) {
callback(error);
} else {
context.getObject(newParentData[newName].id, update_times);
context.getObject(newParentData[newName].id, update_file_node);
}
}

View File

@ -75,29 +75,37 @@ function Node(options) {
* should be different. The version is a version number for a file; typically,
* it is incremented every time the file is modified."
*/
options.p9 = options.p9 || {qid: {}};
this.p9 = {
qid: {
type: getQType(this.mode) || P9_QTFILE,
type: options.p9.qid.type || (getQType(this.mode) || P9_QTFILE),
// use mtime for version info, since we already keep that updated
version: now,
version: options.p9.qid.now || now,
// files have a unique `path` number, which takes into account files with same
// name but created at different times.
path: hash32(options.path + this.ctime)
path: options.p9.qid.path || hash32(options.path + this.ctime)
},
// permissions and flags
// TODO: I don't think I'm doing this correctly yet...
mode: getPOSIXMode(this.mode) || S_IFREG,
mode: options.p9.mode || (getPOSIXMode(this.mode) || S_IFREG),
// Name of file/dir. Must be / if the file is the root directory of the server
// TODO: do I need this or can I derive it from abs path?
name: options.path === ROOT_DIRECTORY_NAME ? ROOT_DIRECTORY_NAME : path.basename(options.path),
uid: 0x0, // owner name
gid: 0x0, // group name
muid: 0x0// name of the user who last modified the file
name: options.p9.name || (options.path === ROOT_DIRECTORY_NAME ? ROOT_DIRECTORY_NAME : path.basename(options.path)),
uid: options.p9.uid || 0x0, // owner name
gid: options.p9.gid || 0x0, // group name
muid: options.p9.muid || 0x0 // name of the user who last modified the file
};
console.log('Node', this);
}
// When the node's path changes, update info that relates to it.
Node.prototype.updatePathInfo = function(newPath, ctime) {
// XXX: need to confirm that qid's path actually changes on rename.
this.p9.qid.path = hash32(newPath + (ctime || this.ctime));
this.p9.name = newPath === ROOT_DIRECTORY_NAME ? ROOT_DIRECTORY_NAME : path.basename(newPath);
};
// Make sure the options object has an id on property,
// either from caller or one we generate using supplied guid fn.
function ensureID(options, prop, callback) {
@ -130,4 +138,31 @@ Node.create = function(options, callback) {
});
};
Node.fromObject = function(object) {
return new Node({
id: object.id,
mode: object.mode,
size: object.size,
atime: object.atime,
ctime: object.ctime,
mtime: object.mtime,
flags: object.flags,
xattrs: object.xattrs,
nlinks: object.nlinks,
data: object.data,
p9: {
qid: {
type: object.p9.qid.type,
version: object.p9.qid.version,
path: object.p9.qid.path
},
mode: object.p9.mode,
name: object.p9.name,
uid: object.p9.uid,
gid: object.p9.gid,
muid: object.p9.muid
}
});
};
module.exports = Node;

View File

@ -238,7 +238,9 @@ Shell.prototype.ls = function(dir, options, callback) {
links: stats.nlinks,
size: stats.size,
modified: stats.mtime,
type: stats.type
type: stats.type,
// Also expose the Plan 9 bits
p9: stats.p9
};
if(options.recursive && stats.type === 'DIRECTORY') {

View File

@ -9,6 +9,8 @@ function Stats(fileNode, devName) {
this.mtime = fileNode.mtime;
this.ctime = fileNode.ctime;
this.type = fileNode.mode;
// Expose extra Plan 9 bits too
this.p9 = fileNode.p9;
}
Stats.prototype.isFile = function() {