func (n *pathInode) GetAttr(out *fuse.Attr, file nodefs.File, context *fuse.Context) (code fuse.Status) { var fi *fuse.Attr if file == nil { // Linux currently (tested on v4.4) does not pass a file descriptor for // fstat. To be able to stat a deleted file we have to find ourselves // an open fd. file = n.Inode().AnyFile() } if file != nil { code = file.GetAttr(out) } if file == nil || code == fuse.ENOSYS || code == fuse.EBADF { fi, code = n.fs.GetAttr(n.GetPath(), context) } if fi != nil { n.setClientInode(fi.Ino) } if fi != nil && !fi.IsDir() && fi.Nlink == 0 { fi.Nlink = 1 } if fi != nil { *out = *fi } return code }
func (n *pathInode) GetAttr(out *fuse.Attr, file nodefs.File, context *fuse.Context) (code fuse.Status) { var fi *fuse.Attr if file == nil { // called on a deleted files. file = n.Inode().AnyFile() } if file != nil { code = file.GetAttr(out) } if file == nil || code == fuse.ENOSYS || code == fuse.EBADF { fi, code = n.fs.GetAttr(n.GetPath(), context) } if fi != nil { n.setClientInode(fi.Ino) } if fi != nil && !fi.IsDir() && fi.Nlink == 0 { fi.Nlink = 1 } if fi != nil { *out = *fi } return code }
func (n *classicNode) Truncate(file nodefs.File, size uint64, context *fuse.Context) (code fuse.Status) { if file != nil { return file.Truncate(size) } else if n.backing != "" { return fuse.ToStatus(os.Truncate(n.backing, int64(size))) } return fuse.OK }
func getAdbFile(file nodefs.File) *AdbFile { for { if file, ok := file.(*AdbFile); ok { return file } if file == nil { panic("no AdbFile") } file = file.InnerFile() } }
func (me *memNode) Truncate(file nodefs.File, size uint64, context *fuse.Context) (code fuse.Status) { me.mutex.Lock() defer me.mutex.Unlock() me.promote() if file != nil { code = file.Truncate(size) } else { code = fuse.ToStatus(os.Truncate(me.backing, int64(size))) } if code.Ok() { me.info.Size = size me.touch() } return code }
func (n *pathInode) Fallocate(file nodefs.File, off uint64, size uint64, mode uint32, context *fuse.Context) (code fuse.Status) { if file != nil { code = file.Allocate(off, size, mode) if code.Ok() { return code } } files := n.Inode().Files(fuse.O_ANYWRITE) for _, f := range files { // TODO - pass context code = f.Allocate(off, size, mode) if code.Ok() { return code } } return code }
func (me *memNode) GetAttr(out *fuse.Attr, file nodefs.File, context *fuse.Context) (code fuse.Status) { var sz uint64 if file != nil { code := file.GetAttr(out) if code.Ok() { sz = out.Size } else { msg := fmt.Sprintf("File.GetAttr(%s) = %v, %v", file.String(), out, code) panic(msg) } } me.mutex.RLock() defer me.mutex.RUnlock() *out = me.info if file != nil { out.Size = sz } return fuse.OK }
// GetAttr - FUSE call func (rfs *ReverseFS) GetAttr(relPath string, context *fuse.Context) (*fuse.Attr, fuse.Status) { if rfs.isTranslatedConfig(relPath) { return rfs.inoAwareStat(configfile.ConfReverseName) } // Handle virtual files var f nodefs.File var status fuse.Status virtual := false if rfs.isDirIV(relPath) { virtual = true f, status = rfs.newDirIVFile(relPath) } if rfs.isNameFile(relPath) { virtual = true f, status = rfs.newNameFile(relPath) } if virtual { if !status.Ok() { fmt.Printf("GetAttr %q: newXFile failed: %v\n", relPath, status) return nil, status } var a fuse.Attr status = f.GetAttr(&a) return &a, status } cPath, err := rfs.decryptPath(relPath) if err != nil { return nil, fuse.ToStatus(err) } a, status := rfs.inoAwareStat(cPath) if !status.Ok() { return nil, status } // Calculate encrypted file size if a.IsRegular() { a.Size = rfs.contentEnc.PlainSizeToCipherSize(a.Size) } return a, fuse.OK }
func (n *pathInode) Utimens(file nodefs.File, atime *time.Time, mtime *time.Time, context *fuse.Context) (code fuse.Status) { // Note that Linux currently (Linux 4.4) DOES NOT pass a file descriptor // to FUSE for futimens. We still check because it may change in the future. if file != nil { code = file.Utimens(atime, mtime) if code != fuse.ENOSYS { return code } } files := n.Inode().Files(fuse.O_ANYWRITE) for _, f := range files { // TODO - pass context code = f.Utimens(atime, mtime) if code.Ok() { return code } } if len(files) == 0 || code == fuse.ENOSYS || code == fuse.EBADF { code = n.fs.Utimens(n.GetPath(), atime, mtime, context) } return code }
func (n *pathInode) Truncate(file nodefs.File, size uint64, context *fuse.Context) (code fuse.Status) { // A file descriptor was passed in AND the filesystem implements the // operation on the file handle. This the common case for ftruncate. if file != nil { code = file.Truncate(size) if code != fuse.ENOSYS { return code } } files := n.Inode().Files(fuse.O_ANYWRITE) for _, f := range files { // TODO - pass context code = f.Truncate(size) if code.Ok() { return code } } if len(files) == 0 || code == fuse.ENOSYS || code == fuse.EBADF { code = n.fs.Truncate(n.GetPath(), size, context) } return code }
func (n *pathInode) Chown(file nodefs.File, uid uint32, gid uint32, context *fuse.Context) (code fuse.Status) { // Note that Linux currently (Linux 4.4) DOES NOT pass a file descriptor // to FUSE for fchown. We still check because it may change in the future. if file != nil { code = file.Chown(uid, gid) if code != fuse.ENOSYS { return code } } files := n.Inode().Files(fuse.O_ANYWRITE) for _, f := range files { // TODO - pass context code = f.Chown(uid, gid) if code.Ok() { return code } } if len(files) == 0 || code == fuse.ENOSYS || code == fuse.EBADF { // TODO - can we get just FATTR_GID but not FATTR_UID ? code = n.fs.Chown(n.GetPath(), uid, gid, context) } return code }
func (n *pathInode) Chmod(file nodefs.File, perms uint32, context *fuse.Context) (code fuse.Status) { // Note that Linux currently (Linux 4.4) DOES NOT pass a file descriptor // to FUSE for fchmod. We still check because that may change in the future. if file != nil { code = file.Chmod(perms) if code != fuse.ENOSYS { return code } } files := n.Inode().Files(fuse.O_ANYWRITE) for _, f := range files { // TODO - pass context code = f.Chmod(perms) if code.Ok() { return } } if len(files) == 0 || code == fuse.ENOSYS || code == fuse.EBADF { code = n.fs.Chmod(n.GetPath(), perms, context) } return code }
func (fs *unionFS) putDeletion(name string) (code fuse.Status) { code = fs.createDeletionStore() if !code.Ok() { return code } marker := fs.deletionPath(name) fs.deletionCache.AddEntry(path.Base(marker)) // Is there a WriteStringToFileOrDie ? writable := fs.fileSystems[0] fi, code := writable.GetAttr(marker, nil) if code.Ok() && fi.Size == uint64(len(name)) { return fuse.OK } var f nodefs.File if code == fuse.ENOENT { f, code = writable.Create(marker, uint32(os.O_TRUNC|os.O_WRONLY), 0644, nil) } else { writable.Chmod(marker, 0644, nil) f, code = writable.Open(marker, uint32(os.O_TRUNC|os.O_WRONLY), nil) } if !code.Ok() { log.Printf("could not create deletion file %v: %v", marker, code) return fuse.EPERM } defer f.Release() defer f.Flush() n, code := f.Write([]byte(name), 0) if int(n) != len(name) || !code.Ok() { panic(fmt.Sprintf("Error for writing %v: %v, %v (exp %v) %v", name, marker, n, len(name), code)) } return fuse.OK }
func (n *pathInode) Flush(file nodefs.File, openFlags uint32, context *fuse.Context) (code fuse.Status) { return file.Flush() }
func (n *pathInode) Write(file nodefs.File, data []byte, off int64, context *fuse.Context) (written uint32, code fuse.Status) { if file != nil { return file.Write(data, off) } return 0, fuse.ENOSYS }
func (n *pathInode) Read(file nodefs.File, dest []byte, off int64, context *fuse.Context) (fuse.ReadResult, fuse.Status) { if file != nil { return file.Read(dest, off) } return nil, fuse.ENOSYS }