internal static NeoVirtFSContent NewCache(ReadOnlySpan <byte> path, ObjectId nodeObj) { var fileuuid = GuidUtility.Create(GuidUtility.UrlNamespace, path.ToArray()); var fileg = fileuuid.ToString().ToLower(); // 8478e36a-669c-11ec-8541-17df4f57891e // 0123456789012345678901234567890123456789 // 000000000011111111112222222222333333333 // Ultimately will need real pool mechanism here // Original scheme was absurd - the 3 digit is 4096. If we're sufficiently event driven and reactive then this shouldn't get // out of hand -- it should handle millions of physical cache files without too much difficulty, and really if they're annealled // quickly enough there should never be that many on a given filesystem //var cacheFile = $"/ua/NeoVirtCache/{fileg.Substring(0, 2)}/{fileg.Substring(2, 2)}/{fileg.Substring(4, 2)}/{fileg.Substring(6, 2)}/{fileg}_{nodeObj}"; var cacheFile = $"/ua/NeoVirtCache/{fileg.Substring(0, 3)}/{fileg}_{nodeObj}"; var rec = new NeoVirtFSContent { CachePoolGuid = fileuuid, ContentType = VirtFSContentTypes.CachePool, CacheFile = Encoding.UTF8.GetBytes(cacheFile) }; return(rec); }
} // serialized version of CachePoolGuid, full path, split public static NeoVirtFSContent Dir() { var ret = new NeoVirtFSContent { ContentType = VirtFSContentTypes.NotAFile, NotAFile = true }; return(ret); }
public override int MkDir(ReadOnlySpan <byte> path, mode_t mode) { if (verbosity > 5) { Console.WriteLine($"MkDir {path.GetString()} mode={mode}"); } int error = 0, level = 0; var procs = ProcPath(path, ref error, ref level, mustExist: false, isADir: true); if (error != 0) { return(-LibC.ENOENT); } if (procs.Count < 2) { Console.WriteLine($"Mkdir - path < 2"); return(-LibC.EPERM); } var cNode = procs.Pop(); var inNode = procs.Pop(); if (cNode.Item2 != null) { return(-LibC.EEXIST); // File (or directory) already exists } if (inNode.Item2 == null) { return(-LibC.ENOENT); // SHouldn't happen (2nd level will get error) } var createIn = inNode.Item2; if (createIn.MaintLevel) { return(-LibC.EPERM); // Nobody can create in the maintenance levels (Namespace levels) } var newRec = new NeoAssets.Mongo.NeoVirtFS() { _id = ObjectId.GenerateNewId(), Content = NeoVirtFSContent.Dir(), Stat = NeoVirtFSStat.DirDefault((uint)mode), Name = cNode.Item1, VolumeId = createIn.VolumeId, ParentId = createIn._id, MaintLevel = false, }; // It will assign it's own objectId _id NeoVirtFSCol.InsertOne(newRec); Console.WriteLine($"Create Directory {cNode.Item1.GetString()} id={newRec._id}"); return(0); }
public static NeoVirtFSContent PhysicalFilePath(byte[] filePath) { var ret = new NeoVirtFSContent { ContentType = VirtFSContentTypes.PhysicalFile, NotAFile = false, PhysicalFile = filePath }; return(ret); }
public static NeoVirtFSContent AnnealedAsset(byte[] AssetSHA1, bool lost) { var ret = new NeoVirtFSContent { ContentType = VirtFSContentTypes.Asset, NotAFile = false, AssetSHA1 = AssetSHA1, AssetLost = lost }; return(ret); }
public static NeoVirtFS CreateDirectory(ObjectId parId, ObjectId volId, byte[] name, mode_t mode) { var newRec = new NeoVirtFS() { _id = ObjectId.GenerateNewId(), Content = NeoVirtFSContent.Dir(), Stat = NeoVirtFSStat.DirDefault((uint)mode), Name = name, VolumeId = volId, ParentId = parId, MaintLevel = false, }; return(newRec); }
public static NeoVirtFS CreateNewFile(ObjectId parId, ObjectId volId, byte[] name, ReadOnlySpan <byte> path, mode_t mode, NeoVirtFSContent cont = null) { var id = ObjectId.GenerateNewId(); if (cont == null) { cont = NeoVirtFSContent.NewCache(path, id); } //Console.WriteLine($"Set newId for file to {id}"); var newRec = new NeoVirtFS { _id = id, Name = name, VolumeId = volId, ParentId = parId, Stat = NeoVirtFSStat.FileDefault((uint)mode), Content = cont, MaintLevel = false }; return(newRec); }
public static ObjectId EnsureVolumeSetUpProperly(IMongoDatabase db, string volumeNamePath) { var HaveRoot = false; var NamespaceNames = new Dictionary <string, NeoVirtFSNamespaces>(); var Namespaces = new Dictionary <ObjectId, NeoVirtFSNamespaces>(); NeoVirtFSNamespaces RootNameSpace = null; var NeoVirtFSCol = db.NeoVirtFS(); var NeoVirtFSDeletedCol = db.NeoVirtFSDeleted(); var NeoVirtFSNamespacesCol = db.NeoVirtFSNamespaces(); var NeoVirtFSVolumesCol = db.NeoVirtFSVolumes(); var NeoVirtFSSecPrincipalsCol = db.NeoVirtFSSecPrincipals(); var NeoVirtFSSecACLsCol = db.NeoVirtFSSecACLs(); // Prepare for bulk update var updates = new List <WriteModel <NeoVirtFS> >(); // Load up the namespaces -- there just shouldn't be too many of these ProcessNamespaces(db, NamespaceNames, Namespaces, ref RootNameSpace, ref HaveRoot, updates); if (!HaveRoot) { throw new ApplicationException("Volume Namespaces don't define a Root - Setup Issue"); } // Now do volumes var(parentPath, VolumeName) = FindVolumeNameWithPath(volumeNamePath, Namespaces, RootNameSpace); if (parentPath == null) // We won't really get here - the above will throw { throw new ArgumentException($"Volume Path Not Valid: {volumeNamePath}"); } // So we actually need to create this volume into NeoVirtFSVolumes, which unfortunately needs business logic // We need some sort of policy for this. Maybe we're overthinking. Maybe we just need to be passed the path so we // don't need to decide? We have the Namespaces above so we can decode var volume = NeoVirtFSVolumesCol.FindSync(Builders <NeoVirtFSVolumes> .Filter.Eq(x => x.Name, VolumeName)).FirstOrDefault(); if (volume == null) { Console.WriteLine($"[Create Volume {VolumeName} into Namespace {parentPath.NameSpace}]"); var newNode = ObjectId.GenerateNewId(); // If the namespace moved then this isn't going to change it, though we may assert below NeoVirtFSVolumesCol.InsertOne(new NeoVirtFSVolumes() { _id = newNode, Name = VolumeName, NameSpace = parentPath._id, NodeId = newNode, // These are intentionally the same VolumeDefaultACL = null, ImportLocked = false, VolumeLocked = false, }); } // This is only going to return our one volume (which we may have just created) var volFilter = Builders <NeoVirtFSVolumes> .Filter.Eq(x => x.Name, VolumeName); var v = NeoVirtFSVolumesCol.FindSync(volFilter).FirstOrDefault(); // This is making sure that the NeoVirtFS elements match the Volume setup (they use the same keys for clarity) Console.WriteLine($"Volume: {v.Name}, NameSpace: {Namespaces[v.NameSpace].NameSpace}"); // Assert if the namespace has moved - We can just move it if (v.NameSpace != parentPath._id) { Console.WriteLine($"Volume Namespace {Namespaces[v.NameSpace].NameSpace} is not same as current Namespace {Namespaces[parentPath._id].NameSpace}"); v.NameSpace = parentPath._id; // Just move the node to the correct place within namespaces // And do it in the table (not bulk) var fixPar = new UpdateDefinitionBuilder <NeoVirtFSVolumes>() .Set("NameSpace", parentPath._id); NeoVirtFSVolumesCol.UpdateOne(volFilter, fixPar); } // Ensure that the filesystem nodes exist at the top level FilterDefinition <NeoVirtFS> filter = Builders <NeoAssets.Mongo.NeoVirtFS> .Filter.Eq(x => x._id, v._id); var upd = new UpdateDefinitionBuilder <NeoAssets.Mongo.NeoVirtFS>() .Set("_id", v._id) .SetOnInsert("Content", NeoVirtFSContent.Dir()) .SetOnInsert("Stat", NeoVirtFSStat.DirDefault()) .Set("VolumeId", v.NameSpace) .Set("ParentId", Namespaces[v.NameSpace]._id) // Set's see what root does - this will also move the Node to match the Volume .Set("Name", Encoding.UTF8.GetBytes(v.Name)) .Set("MaintLevel", false); // This is the volume level - users can do stuff here (by their policy) UpdateOneModel <NeoVirtFS> update = new UpdateOneModel <NeoAssets.Mongo.NeoVirtFS>(filter, upd) { IsUpsert = true }; updates.Add(update); // Persist NeoVirtFSCol.BulkWrite(updates); return(v._id); }
public static bool PullNamespacesAndVolumes(IMongoDatabase db, ref Dictionary <string, NeoVirtFSNamespaces> NamespaceNames, ref Dictionary <ObjectId, NeoVirtFSNamespaces> Namespaces, ref NeoVirtFSNamespaces RootNameSpace) { bool HaveRoot = false; var NeoVirtFSCol = db.NeoVirtFS(); var NeoVirtFSDeletedCol = db.NeoVirtFSDeleted(); var NeoVirtFSNamespacesCol = db.NeoVirtFSNamespaces(); var NeoVirtFSVolumesCol = db.NeoVirtFSVolumes(); var NeoVirtFSSecPrincipalsCol = db.NeoVirtFSSecPrincipals(); var NeoVirtFSSecACLsCol = db.NeoVirtFSSecACLs(); // Prepare for bulk update var updates = new List <WriteModel <NeoAssets.Mongo.NeoVirtFS> >(); // Load up the namespaces -- there just shouldn't be too many of these var nCount = ProcessNamespaces(db, NamespaceNames, Namespaces, ref RootNameSpace, ref HaveRoot, updates); if (!HaveRoot) { throw new ApplicationException("Volume Namespaces don't define a Root - Setup Issue"); } // Now do volumes int vCount = 0; var volumes = NeoVirtFSVolumesCol.FindSync(Builders <NeoVirtFSVolumes> .Filter.Empty).ToList(); foreach (var v in volumes) { //Console.WriteLine($"Volume: {v.Name}"); vCount++; // Ensure that the filesystem nodes exist at the top level FilterDefinition <NeoVirtFS> filter = Builders <NeoAssets.Mongo.NeoVirtFS> .Filter.Eq(x => x._id, v._id); var upd = new UpdateDefinitionBuilder <NeoAssets.Mongo.NeoVirtFS>() .Set("_id", v._id) .SetOnInsert("Content", NeoVirtFSContent.Dir()) .SetOnInsert("Stat", NeoVirtFSStat.DirDefault()) .Set("VolumeId", v.NameSpace) .Set("ParentId", Namespaces[v.NameSpace]._id) // Set's see what root does .Set("Name", Encoding.UTF8.GetBytes(v.Name)) .Set("MaintLevel", false); // This is the volume level - users can do stuff here (by their policy) UpdateOneModel <NeoVirtFS> update = new UpdateOneModel <NeoAssets.Mongo.NeoVirtFS>(filter, upd) { IsUpsert = true }; updates.Add(update); } Console.WriteLine($"[Loaded {nCount} Namespaces and {vCount} Volumes]"); // Persist NeoVirtFSCol.BulkWrite(updates); return(HaveRoot); }