Skip to content

Commit e008995

Browse files
WeidiDenghanwen
authored andcommitted
fs: implement FileIoctler for loopbackDirStream
Change-Id: Ie39678e7cd97cbbc0d549aa4b74975afdc18abff
1 parent ce6eb47 commit e008995

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

fs/dirstream.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ import (
88
"context"
99
"sync"
1010
"syscall"
11+
"unsafe"
1112

1213
"github.com/hanwen/go-fuse/v2/fuse"
14+
"github.com/hanwen/go-fuse/v2/internal/ioctl"
1315
"golang.org/x/sys/unix"
1416
)
1517

@@ -202,6 +204,24 @@ func (ds *loopbackDirStream) Next() (fuse.DirEntry, syscall.Errno) {
202204
return res, 0
203205
}
204206

207+
var _ = (FileIoctler)((*loopbackDirStream)(nil))
208+
209+
func (ds *loopbackDirStream) Ioctl(ctx context.Context, cmd uint32, arg uint64, input []byte, output []byte) (result int32, errno syscall.Errno) {
210+
ds.mu.Lock()
211+
defer ds.mu.Unlock()
212+
213+
argWord := uintptr(arg)
214+
ioc := ioctl.Command(cmd)
215+
if ioc.Read() {
216+
argWord = uintptr(unsafe.Pointer(&input[0]))
217+
} else if ioc.Write() {
218+
argWord = uintptr(unsafe.Pointer(&output[0]))
219+
}
220+
221+
res, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(ds.fd), uintptr(cmd), argWord)
222+
return int32(res), errno
223+
}
224+
205225
func (ds *loopbackDirStream) load() {
206226
if len(ds.todo) > 0 {
207227
return

fs/loopback_linux_test.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ func flipNoAtime(fd uintptr) (bool, error) {
341341
return before, nil
342342
}
343343

344-
func TestIoctlLoopback(t *testing.T) {
344+
func TestIoctlLoopbackFile(t *testing.T) {
345345
tc := newTestCase(t, &testOptions{attrCache: true, entryCache: true})
346346

347347
f, err := os.Create(tc.origDir + "/file")
@@ -366,3 +366,33 @@ func TestIoctlLoopback(t *testing.T) {
366366
t.Fatalf("didn't work: after %v, before %v", after, before)
367367
}
368368
}
369+
370+
func TestIoctlLoopbackDir(t *testing.T) {
371+
tc := newTestCase(t, &testOptions{attrCache: true, entryCache: true})
372+
373+
err := os.Mkdir(tc.origDir+"/dir", 0777)
374+
if err != nil {
375+
t.Fatal(err)
376+
}
377+
d, err := os.Open(tc.origDir + "/dir")
378+
if err != nil {
379+
t.Fatal(err)
380+
}
381+
before, err := flipNoAtime(d.Fd())
382+
if err != nil {
383+
t.Fatal(err)
384+
}
385+
386+
d.Close()
387+
388+
d, err = os.Open(tc.mntDir + "/dir")
389+
if err != nil {
390+
t.Fatal(err)
391+
}
392+
defer d.Close()
393+
after, err := flipNoAtime(d.Fd())
394+
395+
if after != !before {
396+
t.Fatalf("didn't work: after %v, before %v", after, before)
397+
}
398+
}

0 commit comments

Comments
 (0)