Skip to content

Commit

Permalink
fuse: add FileSystemOpenEx interface
Browse files Browse the repository at this point in the history
  • Loading branch information
billziss-gh committed Oct 4, 2019
1 parent aa125fa commit 8e41a0c
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 10 deletions.
29 changes: 29 additions & 0 deletions fuse/fsop.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,25 @@ type Stat_t struct {
Flags uint32
}

// FileInfo_t contains open file information.
// This structure is analogous to the FUSE struct fuse_file_info.
type FileInfo_t struct {
// Open flags: a combination of the fuse.O_* constants.
Flags int

// Use direct I/O on this file. [IGNORED on Windows]
DirectIo bool

// Do not invalidate file cache. [IGNORED on Windows]
KeepCache bool

// File is not seekable. [IGNORED on Windows]
NonSeekable bool

// File handle.
Fh uint64
}

/*
// Lock_t contains file locking information.
// This structure is analogous to the POSIX struct flock.
Expand Down Expand Up @@ -290,6 +309,16 @@ type FileSystemInterface interface {
Listxattr(path string, fill func(name string) bool) int
}

// FileSystemOpenEx is the interface that wraps the OpenEx and CreateEx methods.
//
// OpenEx and CreateEx are similar to Open and Create except that they allow
// direct manipulation of the FileInfo_t struct (which is analogous to the
// FUSE struct fuse_file_info).
type FileSystemOpenEx interface {
CreateEx(path string, mode uint32, fi *FileInfo_t) int
OpenEx(path string, fi *FileInfo_t) int
}

// FileSystemChflags is the interface that wraps the Chflags method.
//
// Chflags changes the BSD file flags (Windows file attributes). [OSX and Windows only]
Expand Down
50 changes: 40 additions & 10 deletions fuse/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,21 @@ func hostOpen(path0 *c_char, fi0 *c_struct_fuse_file_info) (errc0 c_int) {
defer recoverAsErrno(&errc0)
fsop := hostHandleGet(c_fuse_get_context().private_data).fsop
path := c_GoString(path0)
errc, rslt := fsop.Open(path, int(fi0.flags))
fi0.fh = c_uint64_t(rslt)
return c_int(errc)
intf, ok := fsop.(FileSystemOpenEx)
if ok {
fi := FileInfo_t{Flags: int(fi0.flags)}
errc := intf.OpenEx(path, &fi)
c_hostAsgnCfileinfo(fi0,
c_bool(fi.DirectIo),
c_bool(fi.KeepCache),
c_bool(fi.NonSeekable),
c_uint64_t(fi.Fh))
return c_int(errc)
} else {
errc, rslt := fsop.Open(path, int(fi0.flags))
fi0.fh = c_uint64_t(rslt)
return c_int(errc)
}
}

func hostRead(path0 *c_char, buff0 *c_char, size0 c_size_t, ofst0 c_fuse_off_t,
Expand Down Expand Up @@ -447,15 +459,33 @@ func hostCreate(path0 *c_char, mode0 c_fuse_mode_t, fi0 *c_struct_fuse_file_info
defer recoverAsErrno(&errc0)
fsop := hostHandleGet(c_fuse_get_context().private_data).fsop
path := c_GoString(path0)
errc, rslt := fsop.Create(path, int(fi0.flags), uint32(mode0))
if -ENOSYS == errc {
errc = fsop.Mknod(path, S_IFREG|uint32(mode0), 0)
if 0 == errc {
errc, rslt = fsop.Open(path, int(fi0.flags))
intf, ok := fsop.(FileSystemOpenEx)
if ok {
fi := FileInfo_t{Flags: int(fi0.flags)}
errc := intf.CreateEx(path, uint32(mode0), &fi)
if -ENOSYS == errc {
errc = fsop.Mknod(path, S_IFREG|uint32(mode0), 0)
if 0 == errc {
errc = intf.OpenEx(path, &fi)
}
}
c_hostAsgnCfileinfo(fi0,
c_bool(fi.DirectIo),
c_bool(fi.KeepCache),
c_bool(fi.NonSeekable),
c_uint64_t(fi.Fh))
return c_int(errc)
} else {
errc, rslt := fsop.Create(path, int(fi0.flags), uint32(mode0))
if -ENOSYS == errc {
errc = fsop.Mknod(path, S_IFREG|uint32(mode0), 0)
if 0 == errc {
errc, rslt = fsop.Open(path, int(fi0.flags))
}
}
fi0.fh = c_uint64_t(rslt)
return c_int(errc)
}
fi0.fh = c_uint64_t(rslt)
return c_int(errc)
}

func hostFtruncate(path0 *c_char, size0 c_fuse_off_t, fi0 *c_struct_fuse_file_info) (errc0 c_int) {
Expand Down
23 changes: 23 additions & 0 deletions fuse/host_cgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,18 @@ static inline void hostCstatFromFusestat(fuse_stat_t *stbuf,
#endif
}
static inline void hostAsgnCfileinfo(struct fuse_file_info *fi,
bool direct_io,
bool keep_cache,
bool nonseekable,
uint64_t fh)
{
fi->direct_io = direct_io;
fi->keep_cache = keep_cache;
fi->nonseekable = nonseekable;
fi->fh = fh;
}
static inline int hostFilldir(fuse_fill_dir_t filler, void *buf,
char *name, fuse_stat_t *stbuf, fuse_off_t off)
{
Expand Down Expand Up @@ -687,6 +699,17 @@ func c_hostCstatFromFusestat(stbuf *c_fuse_stat_t,
birthtimNsec,
flags)
}
func c_hostAsgnCfileinfo(fi *c_struct_fuse_file_info,
direct_io c_bool,
keep_cache c_bool,
nonseekable c_bool,
fh c_uint64_t) {
C.hostAsgnCfileinfo(fi,
direct_io,
keep_cache,
nonseekable,
fh)
}
func c_hostFilldir(filler c_fuse_fill_dir_t,
buf unsafe.Pointer, name *c_char, stbuf *c_fuse_stat_t, off c_fuse_off_t) c_int {
return C.hostFilldir(filler, buf, name, stbuf, off)
Expand Down
16 changes: 16 additions & 0 deletions fuse/host_nocgo_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,22 @@ func c_hostCstatFromFusestat(stbuf *c_fuse_stat_t,
stbuf.st_birthtim.tv_nsec = uintptr(ctimNsec)
}
}
func c_hostAsgnCfileinfo(fi *c_struct_fuse_file_info,
direct_io c_bool,
keep_cache c_bool,
nonseekable c_bool,
fh c_uint64_t) {
if direct_io {
fi.bits |= 1
}
if keep_cache {
fi.bits |= 2
}
if nonseekable {
fi.bits |= 8
}
fi.fh = fh
}
func c_hostFilldir(filler c_fuse_fill_dir_t,
buf unsafe.Pointer, name *c_char, stbuf *c_fuse_stat_t, off c_fuse_off_t) c_int {
var r uintptr
Expand Down

0 comments on commit 8e41a0c

Please sign in to comment.