func TestCreationChecks(t *testing.T) { wd, clean := setup(t) defer clean() err := os.Mkdir(wd+"/store/foo", 0755) CheckSuccess(err) os.Symlink(wd+"/ro", wd+"/store/foo/READONLY") CheckSuccess(err) err = os.Mkdir(wd+"/store/ws2", 0755) CheckSuccess(err) os.Symlink(wd+"/ro", wd+"/store/ws2/READONLY") CheckSuccess(err) err = os.Symlink(wd+"/store/foo", wd+"/mount/config/bar") CheckSuccess(err) err = os.Symlink(wd+"/store/foo", wd+"/mount/config/foo") code := fuse.OsErrorToErrno(err) if code != fuse.EBUSY { t.Error("Should return EBUSY", err) } err = os.Symlink(wd+"/store/ws2", wd+"/mount/config/config") code = fuse.OsErrorToErrno(err) if code != fuse.EINVAL { t.Error("Should return EINVAL", err) } }
func (me *UnionFs) GetAttr(name string) (a *os.FileInfo, s fuse.Status) { if name == _READONLY { return nil, fuse.ENOENT } if name == _DROP_CACHE { return &os.FileInfo{ Mode: fuse.S_IFREG | 0777, }, fuse.OK } if name == me.options.DeletionDirName { return nil, fuse.ENOENT } isDel, err := me.isDeleted(name) if err != nil { return nil, fuse.OsErrorToErrno(err) } if isDel { return nil, fuse.ENOENT } r := me.getBranch(name) if r.branch < 0 { return nil, fuse.ENOENT } return r.attr, r.code }
func TestChmod(t *testing.T) { wd, clean := setupUfs(t) defer clean() ro_fn := wd + "/ro/file" m_fn := wd + "/mount/file" writeToFile(ro_fn, "a") err := os.Chmod(m_fn, 07070) CheckSuccess(err) err = os.Chown(m_fn, 0, 0) code := fuse.OsErrorToErrno(err) if code != fuse.EPERM { t.Error("Unexpected error code", code, err) } fi, err := os.Lstat(m_fn) CheckSuccess(err) if fi.Mode&07777 != 07272 { t.Errorf("Unexpected mode found: %o", fi.Mode) } _, err = os.Lstat(wd + "/rw/file") if err != nil { t.Errorf("File not promoted") } }
func (me *ProcFs) Open(name string, flags uint32, context *fuse.Context) (fuse.File, fuse.Status) { p := me.LoopbackFileSystem.GetPath(name) content, err := ioutil.ReadFile(p) if err == nil { return fuse.NewReadOnlyFile(content), fuse.OK } return nil, fuse.OsErrorToErrno(err) }
func (me *RpcFs) Open(name string, flags uint32, context *fuse.Context) (fuse.File, fuse.Status) { if flags&fuse.O_ANYWRITE != 0 { return nil, fuse.EPERM } a := me.getFileAttr(name) if a == nil { return nil, fuse.ENOENT } if !a.Status.Ok() { return nil, a.Status } if contents := me.cache.ContentsIfLoaded(a.Hash); contents != nil { return &fuse.WithFlags{ File: fuse.NewReadOnlyFile(contents), FuseFlags: fuse.FOPEN_KEEP_CACHE, }, fuse.OK } p := me.cache.Path(a.Hash) if _, err := os.Lstat(p); fuse.OsErrorToErrno(err) == fuse.ENOENT { log.Printf("Fetching contents for file %s: %x", name, a.Hash) err = me.FetchHash(a.FileInfo.Size, a.Hash) // should return something else? if err != nil { return nil, fuse.ENOENT } } f, err := os.Open(p) if err != nil { return nil, fuse.OsErrorToErrno(err) } return &fuse.WithFlags{ File: &rpcFsFile{ fuse.LoopbackFile{File: f}, *a.FileInfo, }, FuseFlags: fuse.FOPEN_KEEP_CACHE, }, fuse.OK }
func (me *RpcFs) Open(name string, flags uint32) (fuse.File, fuse.Status) { if flags&fuse.O_ANYWRITE != 0 { return nil, fuse.EPERM } a := me.getAttrResponse(name) if !a.Status.Ok() { return nil, a.Status } p := me.cache.Path(a.Hash) if _, err := os.Lstat(p); fuse.OsErrorToErrno(err) == fuse.ENOENT { log.Printf("Fetching contents for file %s", name) me.FetchHash(a.FileInfo.Size, a.Hash) } f, err := os.Open(p) if err != nil { return nil, fuse.OsErrorToErrno(err) } return &fuse.LoopbackFile{File: f}, fuse.OK }
func TestChown(t *testing.T) { wd, clean := setupUfs(t) defer clean() ro_fn := wd + "/ro/file" m_fn := wd + "/mount/file" writeToFile(ro_fn, "a") err := os.Chown(m_fn, 0, 0) code := fuse.OsErrorToErrno(err) if code != fuse.EPERM { t.Error("Unexpected error code", code, err) } }
func (me *FsServer) oneGetAttr(name string) (rep *FileAttr) { // TODO - this is not a good security measure, as we are not // checking the prefix; someone might directly ask for // /forbidden/subdir/ if me.excluded[name] { return &FileAttr{ Path: name, Status: fuse.ENOENT, } } me.attrCacheMutex.RLock() rep, ok := me.attrCache[name] me.attrCacheMutex.RUnlock() if ok { return rep } me.attrCacheMutex.Lock() defer me.attrCacheMutex.Unlock() for me.attrCacheBusy[name] && me.attrCache[name] == nil { me.attrCacheCond.Wait() } rep, ok = me.attrCache[name] if ok { return rep } me.attrCacheBusy[name] = true me.attrCacheMutex.Unlock() p := me.path(name) fi, err := os.Lstat(p) rep = &FileAttr{ FileInfo: fi, Status: fuse.OsErrorToErrno(err), Path: name, } if fi != nil { me.fillContent(rep) } me.attrCacheMutex.Lock() me.attrCache[name] = rep me.attrCacheCond.Broadcast() me.attrCacheBusy[name] = false, false return rep }
func (me *FsServer) GetAttr(req *AttrRequest, rep *AttrResponse) os.Error { log.Println("GetAttr req", req.Name) if me.excluded[req.Name] { rep.Status = fuse.ENOENT return nil } fi, err := os.Lstat(me.path(req.Name)) rep.FileInfo = fi rep.Status = fuse.OsErrorToErrno(err) if fi == nil { return nil } if fi.IsSymlink() { rep.Link, err = os.Readlink(req.Name) } if fi.IsRegular() { rep.Hash = me.cache.SavePath(req.Name) } log.Println("GetAttr", req.Name, rep) return nil }