public unsafe override int GetAttr(ReadOnlySpan <byte> path, ref stat stat, FuseFileInfoRef fiRef)
        {
            try
            {
                if (verbosity > 10)
                {
                    Console.WriteLine($"GetAttr {path.GetString()}");
                }

                int error = 0, level = 0;
                var procs = ProcPath(path, ref error, ref level, mustExist: true);
                if (error != 0)
                {
                    return(-LibC.ENOENT);
                }

                var last = procs.Pop();
                //Console.WriteLine($"   getAttr - last {last.Item1.GetString()} error {last.Item3}");

                if (last.Item2 == null)
                {
                    return(-last.Item3);
                }

                //Console.WriteLine($" return: {last.Item2.Stat.st_mode.ModMask()}");

                last.Item2.GetStat(ref stat);
                var physFile = last.Item2.GetStatPhysical();
                if (physFile != null)
                {
                    var nstat = new stat();

                    var lc = LibC.lstat(RawDirs.ToBytePtr(physFile.ToArray()), &nstat);
                    if (lc < 0)
                    {
                        return(-LibC.errno);
                    }

                    // Real stat is kept in a physical backing file (mostly st_size)
                    // Not trying to keep this syned in the database yet
                    last.Item2.GetStat(ref stat, nstat);
                }
                //Console.WriteLine($"Length Stat={stat.st_size}");

                return(0);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error GetAttr: {ex.Message} {ex.StackTrace}");
                return(-LibC.EIO);
            }
        }
        public override int Chown(ReadOnlySpan <byte> path, uint uid, uint gid, FuseFileInfoRef fiRef, Guid fileGuid)
        {
            path = base.TransformPath(path);

            if (debug)
            {
                Console.WriteLine($"NeoFS::Chown()");
            }
            var res = LibC.chown(toBp(path), uid, gid);

            if (res < 0)
            {
                return(-LibC.errno);
            }
            return(0);
        }
        public override int Truncate(ReadOnlySpan <byte> path, ulong length, FuseFileInfoRef fiRef, Guid fileGuid)
        {
            path = base.TransformPath(path);
            if (debug)
            {
                Console.WriteLine($"NeoFS::Truncate()");
            }

            var res = LibC.truncate(toBp(path), (long)length);

            if (res < 0)
            {
                res = -LibC.errno;
            }

            return(res);
        }
        public override int Chown(ReadOnlySpan <byte> path, uint uid, uint gid, FuseFileInfoRef fiRef)
        {
            if (verbosity > 5)
            {
                Console.WriteLine($"Chown {path.GetString()}");
            }

            int error = 0, level = 0;
            var procs = ProcPath(path, ref error, ref level);

            if (error != 0)
            {
                return(-LibC.ENOENT);
            }


            return(0);
        }
 public override int GetAttr(ReadOnlySpan <byte> path, ref stat stat, FuseFileInfoRef fiRef)
 {
     if (path.SequenceEqual(RootPath))
     {
         stat.st_mode  = S_IFDIR | 0b111_101_101; // rwxr-xr-x
         stat.st_nlink = 2;                       // 2 + nr of subdirectories
         return(0);
     }
     else if (path.SequenceEqual(_helloFilePath))
     {
         stat.st_mode  = S_IFREG | 0b100_100_100; // r--r--r--
         stat.st_nlink = 1;
         stat.st_size  = _helloFileContent.Length;
         return(0);
     }
     else
     {
         return(-ENOENT);
     }
 }
        public override int Truncate(ReadOnlySpan <byte> path, ulong length, FuseFileInfoRef fiRef)
        {
            if (verbosity > 5)
            {
                Console.WriteLine($"Truncate {path.GetString()} to {length}");
            }


            int error = 0, level = 0;
            var procs = ProcPath(path, ref error, ref level, mustExist: true);

            if (error != 0)
            {
                return(-LibC.ENOENT);
            }

            var fromProc = procs.Pop();
            var fromRec  = fromProc.Item2;

            return(fromRec.Truncate(length)); // Ironically the object doesn't know it's path
        }
 public override int GetAttr(ReadOnlySpan <byte> path, ref stat stat, FuseFileInfoRef fiRef)
 {
     if (path.SequenceEqual(Encoding.UTF8.GetBytes("/GetAttr_file1")))
     {
         stat.st_atim  = new DateTime(2000, 12, 1, 23, 13, 59, 200, DateTimeKind.Utc).ToTimespec();
         stat.st_mtim  = new DateTime(2001, 11, 2, 22, 12, 58, 199, DateTimeKind.Utc).ToTimespec();
         stat.st_ctim  = new DateTime(2002, 10, 3, 21, 11, 57, 198, DateTimeKind.Utc).ToTimespec();
         stat.st_nlink = 10;
         stat.st_uid   = 13;
         stat.st_gid   = 15;
         stat.st_size  = 200;
         stat.st_mode  = S_IFREG | 0b100_010_001;
         return(0);
     }
     else if (path.SequenceEqual(Encoding.UTF8.GetBytes("/GetAttr_dir1")))
     {
         stat.st_mode = S_IFDIR | 0b100_010_001;
         return(0);
     }
     return(-ENOENT);
 }
        // Not sure this will get hit.   We may need to return / itself
        public override int GetAttr(ReadOnlySpan <byte> path, ref stat stat, FuseFileInfoRef fiRef, Guid fileGuid)
        {
            if (debug)
            {
                Console.WriteLine($"TopLevel::GetAttr({RawDirs.HR(path)})");
            }

            if (path.SequenceEqual(Encoding.ASCII.GetBytes("/").AsSpan()))
            {
                stat.st_nlink = 1;
                stat.st_mode  = LibC.S_IFDIR | (mode_t)0b111_110_110; // 444 protection for now
                stat.st_uid   = 10010;                                // aRec.Stat.uid;
                stat.st_gid   = 10010;                                // aRec.Stat.gid;

                stat.st_size = 0;

                var now = DateTimeOffset.Now.ToUnixTimeSeconds();

                stat.st_ctim = new timespec
                {
                    tv_sec  = now,
                    tv_nsec = 0
                };
                stat.st_mtim = new timespec
                {
                    tv_sec  = now,
                    tv_nsec = 0
                };
                stat.st_atim = new timespec
                {
                    tv_sec  = now,
                    tv_nsec = 0
                };

                return(0);
            }

            return(-LibC.ENOSYS);
        }
        public override int ChMod(ReadOnlySpan <byte> path, mode_t mode, FuseFileInfoRef fiRef)
        {
            if (verbosity > 5)
            {
                Console.WriteLine($"ChMod {path.GetString()}");
            }

            int error = 0, level = 0;
            var procs = ProcPath(path, ref error, ref level);

            if (error != 0)
            {
                return(-LibC.ENOENT);
            }

            var ent = procs.Pop();

            if (ent.Item2 == null)
            {
                return(-LibC.ENOENT);
            }

            var rec = ent.Item2;

            if (rec.MaintLevel)
            {
                return(-LibC.EPERM);
            }

            var update = new UpdateDefinitionBuilder <NeoAssets.Mongo.NeoVirtFS>()
                         .Set(rec => rec.Stat.st_mode, (NeoMode_T)(uint)mode);

            var result = NeoVirtFSCol.UpdateOne(Builders <NeoAssets.Mongo.NeoVirtFS> .Filter.Eq(x => x._id, rec._id), update);

            return(0);
        }
        public override int UpdateTimestamps(ReadOnlySpan <byte> path, ref timespec atime, ref timespec mtime, FuseFileInfoRef fiRef)
        {
            if (verbosity > 5)
            {
                Console.WriteLine($"UpdateTimestamps {path.GetString()} atime={atime.ToDTO()} mtime={mtime.ToDTO()}");
            }

            int error = 0, level = 0;
            var procs = ProcPath(path, ref error, ref level);

            if (error != 0)
            {
                return(-LibC.ENOENT);
            }

            var ent = procs.Pop();

            if (ent.Item2 == null)
            {
                return(-LibC.ENOENT);
            }

            var rec = ent.Item2;

            var update = new UpdateDefinitionBuilder <NeoAssets.Mongo.NeoVirtFS>()
                         .Set(rec => rec.Stat.st_atim, atime.ToDTO())
                         .Set(rec => rec.Stat.st_mtim, mtime.ToDTO());

            var result = NeoVirtFSCol.UpdateOne(Builders <NeoAssets.Mongo.NeoVirtFS> .Filter.Eq(x => x._id, rec._id), update);

            return(0);
        }
        public override int GetAttr(ReadOnlySpan <byte> path, ref stat stat, FuseFileInfoRef fiRef)
        {
            Console.WriteLine("GetAttr -> " + Encoding.UTF8.GetString(path));
            Console.WriteLine("GetAttr -> " + fiRef.IsNull);
            //Console.WriteLine("GetAttr -> " + _openFiles.ContainsKey(fiRef.Value.fh));
            if (path.SequenceEqual(RootPath))
            {
                stat.st_mode  = S_IFDIR | 0b111_111_111;
                stat.st_nlink = 2; // 2 + nr of subdirectories
                return(0);
            }

            if (!fiRef.IsNull)
            {
                Console.WriteLine("GetAttr -> " + "fiRef not null");
                stat.st_mode  = S_IFREG | 0b111_111_111;
                stat.st_size  = 0;
                stat.st_atim  = DateTime.Now.ToTimespec();
                stat.st_ctim  = DateTime.Now.ToTimespec();
                stat.st_mtim  = DateTime.Now.ToTimespec();
                stat.st_nlink = 1;
                return(0);
            }

            string strPath = Encoding.UTF8.GetString(path);

            if (strPath == "/stats")
            {
                Console.WriteLine("GetAttr -> " + "stats file");
                stat.st_mode  = S_IFREG | 0b111_111_111;
                stat.st_size  = GetStats().Length;
                stat.st_atim  = DateTime.Now.ToTimespec();
                stat.st_ctim  = DateTime.Now.ToTimespec();
                stat.st_mtim  = DateTime.Now.ToTimespec();
                stat.st_nlink = 1;
                return(0);
            }

            var ents = fs.GetExtendedEntities(FileSystemPath.Parse(strPath).ParentPath);

            if (ents.Count == 0)
            {
                return(-ENOENT);
            }

            foreach (var e in ents)
            {
                //Console.WriteLine("fullname -> " + e.FullName);
                if (e.FullName == Encoding.UTF8.GetString(path))
                {
                    if (e.IsDirectory)
                    {
                        stat.st_mode  = S_IFDIR | 0b111_111_111;
                        stat.st_atim  = e.LastAccessTime.ToTimespec();
                        stat.st_ctim  = e.CreationTime.ToTimespec();
                        stat.st_mtim  = e.LastWriteTime.ToTimespec();
                        stat.st_nlink = 2;
                        return(0);
                    }
                    else
                    {
                        stat.st_mode  = S_IFREG | 0b111_111_111;
                        stat.st_size  = e.Size;
                        stat.st_atim  = e.LastAccessTime.ToTimespec();
                        stat.st_ctim  = e.CreationTime.ToTimespec();
                        stat.st_mtim  = e.LastWriteTime.ToTimespec();
                        stat.st_nlink = 1;
                        return(0);
                    }
                }
            }

            Console.WriteLine("GetAttr -> " + "-ENOENT");
            return(-ENOENT);
        }
 public override int GetAttr(ReadOnlySpan <byte> path, ref stat stat, FuseFileInfoRef fiRef)
 {
     return(base.GetAttr(path, ref stat, fiRef));
 }
        public override int GetAttr(ReadOnlySpan <byte> path, ref stat stat, FuseFileInfoRef fiRef, Guid fileGuid)
        {
            try
            {
                path = base.TransformPath(path);

                if (debug)
                {
                    Console.WriteLine($"NeoFS::GetAttr({RawDirs.HR(path)})");
                    fixed(stat *st = &stat)
                    {
                        var lc = LibC.lstat(toBp(path), st);

                        if (lc < 0)
                        {
                            // Windows file explorer hits lot of files that don't exist
                            //Console.WriteLine($"Stat error: {lc} errno={LibC.errno} path={RawDirs.HR(path)}");
                            return(-LibC.errno);
                        }
                    }

                    // Intercept an asset - we must provide the asset's Attr, not the link of the baked file
                    if ((stat.st_mode & LibC.S_IFMT) == LibC.S_IFLNK)
                    {
                        if (debug)
                        {
                            Console.WriteLine($"Link Seen: Stat mode={stat.st_mode}, S_IFMT={LibC.S_IFMT}, link={LibC.S_IFLNK}");
                        }
                        ssize_t retl;
                        var     buffer = new byte[1024];
                        fixed(byte *b = buffer)
                        {
                            retl = LibC.readlink(toBp(path), b, buffer.Length);
                        }

                        // Trying to do something like startswith for bytes that's fast
                        var link = MemoryExtensions.AsSpan(buffer, 0, assetTag.Length);

                        if (debug)
                        {
                            Console.WriteLine($"NeoFS::GetAttr Asset Detected - ({RawDirs.HR(path)}, {RawDirs.HR(link)}");
                        }

                        if (link.SequenceEqual(assetTag))
                        {
                            link = MemoryExtensions.AsSpan(buffer, 0, (int)retl);
                            if (debug)
                            {
                                Console.WriteLine($"Found ASSET {RawDirs.HR(link)}");
                            }

                            base.GetAssetAttr(path, link, ref stat, fileGuid);
                            return(0);
                        }
                    }

                    if (debug)
                    {
                        Console.WriteLine($"Stat Dump: size={stat.st_size}, mode={stat.st_mode}, mtim={stat.st_mtim}");
                    }

                    return(0);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"GetAttr error: {ex.Message} {ex.StackTrace}");
                return(-LibC.ENOENT);
            }
        }
 public virtual int UpdateTimestamps(ReadOnlySpan <byte> path, ref timespec atime, ref timespec mtime, FuseFileInfoRef fiRef, Guid fileGuid)
 => - LibC.ENOSYS;
 public virtual int Truncate(ReadOnlySpan <byte> path, ulong length, FuseFileInfoRef fiRef, Guid fileGuid)
 => - LibC.ENOSYS;
 public virtual int GetAttr(ReadOnlySpan <byte> path, ref stat stat, FuseFileInfoRef fiRef, Guid fileGuid)
 => - LibC.ENOSYS;
 public virtual int Chown(ReadOnlySpan <byte> path, uint uid, uint gid, FuseFileInfoRef fiRef, Guid fileGuid)
 => - LibC.ENOSYS;
 public virtual int ChMod(ReadOnlySpan <byte> path, mode_t mode, FuseFileInfoRef fiRef, Guid fileGuid)
 => - LibC.ENOSYS;
 public override int Chown(ReadOnlySpan <byte> path, uint uid, uint gid, FuseFileInfoRef fiRef)
 {
     Console.WriteLine("Chown -> " + Encoding.UTF8.GetString(path));
     return(0);
 }
 public override int Chown(ReadOnlySpan <byte> path, uint uid, uint gid, FuseFileInfoRef fiRef)
 {
     return(base.Chown(path, uid, gid, fiRef));
 }
 public override int UpdateTimestamps(ReadOnlySpan <byte> path, ref timespec atime, ref timespec mtime, FuseFileInfoRef fiRef)
 {
     Console.WriteLine("UpdateTimestamps -> " + Encoding.UTF8.GetString(path));
     return(0);
 }
 public override int Truncate(ReadOnlySpan <byte> path, ulong length, FuseFileInfoRef fiRef)
 {
     return(base.Truncate(path, length, fiRef));
 }
 public override int ChMod(ReadOnlySpan <byte> path, mode_t mode, FuseFileInfoRef fiRef)
 {
     Console.WriteLine("ChMod -> " + Encoding.UTF8.GetString(path));
     return(0);
 }
 public override int ChMod(ReadOnlySpan <byte> path, mode_t mode, FuseFileInfoRef fiRef)
 {
     return(base.ChMod(path, mode, fiRef));
 }
        public override int UpdateTimestamps(ReadOnlySpan <byte> path, ref timespec atime, ref timespec mtime, FuseFileInfoRef fiRef, Guid fileGuid)
        {
            path = base.TransformPath(path);

            if (debug)
            {
                Console.WriteLine($"NeoFS::UpdateTimestamps()");
            }

            timespec[] timeList = new timespec[2];
            timeList[0].tv_sec  = atime.tv_sec;
            timeList[0].tv_nsec = atime.tv_nsec;
            timeList[1].tv_sec  = mtime.tv_sec;
            timeList[1].tv_nsec = mtime.tv_nsec;

            fixed(timespec *timeA = &timeList[0])
            {
                var res = LibC.utimensat(0, toBp(path), timeA, 0);

                if (res < 0)
                    return(-LibC.errno); }
            }
 public override int UpdateTimestamps(ReadOnlySpan <byte> path, ref timespec atime, ref timespec mtime, FuseFileInfoRef fiRef)
 {
     return(base.UpdateTimestamps(path, ref atime, ref mtime, fiRef));
 }
Beispiel #27
0
 public override int GetAttr(ReadOnlySpan <byte> path, ref stat stat, FuseFileInfoRef fiRef)
 {
     stat.st_nlink = 1;
     stat.st_mode  = S_IFREG;
     return(0);
 }