All basic operations now working in Linux 9P mounted fs
This commit is contained in:
parent
2e627cfe5b
commit
93633da622
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
55
src/node.js
55
src/node.js
|
@ -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;
|
||||
|
|
|
@ -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') {
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue