Skip to content

Commit

Permalink
fuse/test: clarify umask semantics
Browse files Browse the repository at this point in the history
Improve test to eliminate backing FS semantics
  • Loading branch information
hanwen committed Sep 24, 2018
1 parent 1d35017 commit 815666a
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 31 deletions.
28 changes: 1 addition & 27 deletions fuse/test/loopback_test.go
Expand Up @@ -11,7 +11,6 @@ import (
"io/ioutil"
"math/rand"
"os"
"os/exec"
"path/filepath"
"reflect"
"runtime"
Expand All @@ -25,8 +24,6 @@ import (
"github.com/hanwen/go-fuse/internal/testutil"
)

const mode uint32 = 0757

type testCase struct {
tmpDir string
orig string
Expand Down Expand Up @@ -148,6 +145,7 @@ func TestReadThrough(t *testing.T) {

content := randomData(125)
tc.WriteFile(tc.origFile, content, 0700)
var mode uint32 = 0757
err := os.Chmod(tc.mountFile, os.FileMode(mode))
if err != nil {
t.Fatalf("Chmod failed: %v", err)
Expand Down Expand Up @@ -916,31 +914,7 @@ func TestDoubleOpen(t *testing.T) {
t.Fatalf("OpenFile failed: %v", err)
}
defer rwFile.Close()
}

func TestUmask(t *testing.T) {
tc := NewTestCase(t)
defer tc.Cleanup()

// Make sure system setting does not affect test.
fn := tc.mnt + "/file"
mask := 020
cmd := exec.Command("/bin/sh", "-c",
fmt.Sprintf("umask %o && mkdir %s", mask, fn))
if err := cmd.Run(); err != nil {
t.Fatalf("cmd.Run: %v", err)
}

fi, err := os.Lstat(fn)
if err != nil {
t.Fatalf("Lstat failed: %v", err)
}

expect := mask ^ 0777
got := int(fi.Mode().Perm())
if got != expect {
t.Errorf("got %o, expect mode %o for file %s", got, expect, fn)
}
}

// Check that chgrp(1) works
Expand Down
91 changes: 91 additions & 0 deletions fuse/test/umask_test.go
@@ -0,0 +1,91 @@
// Copyright 2016 the Go-FUSE Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package test

import (
"fmt"
"os"
"os/exec"
"testing"

"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/nodefs"
"github.com/hanwen/go-fuse/fuse/pathfs"
"github.com/hanwen/go-fuse/internal/testutil"
)

type umaskFS struct {
pathfs.FileSystem

mkdirMode uint32
createMode uint32
}

func (fs *umaskFS) Create(name string, flags uint32, mode uint32, context *fuse.Context) (file nodefs.File, code fuse.Status) {
fs.createMode = mode
return fs.FileSystem.Create(name, flags, mode, context)
}

func (fs *umaskFS) Mkdir(name string, mode uint32, context *fuse.Context) (code fuse.Status) {
fs.mkdirMode = mode
return fs.FileSystem.Mkdir(name, mode, context)
}

func TestUmask(t *testing.T) {
tmpDir := testutil.TempDir()
orig := tmpDir + "/orig"
mnt := tmpDir + "/mnt"

os.Mkdir(orig, 0700)
os.Mkdir(mnt, 0700)

var pfs pathfs.FileSystem
pfs = pathfs.NewLoopbackFileSystem(orig)
pfs = pathfs.NewLockingFileSystem(pfs)
ufs := &umaskFS{FileSystem: pfs}

pathFs := pathfs.NewPathNodeFs(ufs, &pathfs.PathNodeFsOptions{
ClientInodes: true})
connector := nodefs.NewFileSystemConnector(pathFs.Root(),
&nodefs.Options{
EntryTimeout: testTtl,
AttrTimeout: testTtl,
NegativeTimeout: 0.0,
Debug: testutil.VerboseTest(),
LookupKnownChildren: true,
})
server, err := fuse.NewServer(
fuse.NewRawFileSystem(connector.RawFS()), mnt, &fuse.MountOptions{
SingleThreaded: true,
Debug: testutil.VerboseTest(),
})
if err != nil {
t.Fatal("NewServer:", err)
}

go server.Serve()
if err := server.WaitMount(); err != nil {
t.Fatal("WaitMount", err)
}

// Make sure system setting does not affect test.
mask := 020
cmd := exec.Command("/bin/sh", "-c",
fmt.Sprintf("umask %o && cd %s && mkdir x && touch y", mask, mnt))
if err := cmd.Run(); err != nil {
t.Fatalf("cmd.Run: %v", err)
}

if err := server.Unmount(); err != nil {
t.Fatalf("Unmount %v", err)
}

if got, want := ufs.mkdirMode&0777, uint32(0757); got != want {
t.Errorf("got dirMode %o want %o", got, want)
}
if got, want := ufs.createMode&0666, uint32(0646); got != want {
t.Errorf("got createMode %o want %o", got, want)
}
}
3 changes: 3 additions & 0 deletions fuse/types.go
Expand Up @@ -86,6 +86,9 @@ type _BatchForgetIn struct {

type MkdirIn struct {
InHeader

// The mode for the new directory. The calling process' umask
// is already factored into the mode.
Mode uint32
Umask uint32
}
Expand Down
14 changes: 10 additions & 4 deletions fuse/types_linux.go
Expand Up @@ -61,14 +61,20 @@ func (g *GetAttrIn) Fh() uint64 {

type CreateIn struct {
InHeader
Flags uint32
Mode uint32
Umask uint32
Pading uint32
Flags uint32

// Mode for the new file; already takes Umask into account.
Mode uint32

// Umask used for this create call.
Umask uint32
Padding uint32
}

type MknodIn struct {
InHeader

// Mode to use, including the Umask value
Mode uint32
Rdev uint32
Umask uint32
Expand Down

0 comments on commit 815666a

Please sign in to comment.