mirror of https://github.com/perkeep/perkeep.git
fuse: add fsync support
Change-Id: Ia7351e70437df32b16648793dfc47d11ad8fdbea
This commit is contained in:
parent
1ea7c0c8c9
commit
9b9b837148
|
@ -545,7 +545,15 @@ func (c *Conn) ReadRequest() (Request, error) {
|
|||
}
|
||||
|
||||
case opFsync:
|
||||
panic("opFsync")
|
||||
in := (*fsyncIn)(m.data())
|
||||
if m.len() < unsafe.Sizeof(*in) {
|
||||
goto corrupt
|
||||
}
|
||||
req = &FsyncRequest{
|
||||
Header: m.Header(),
|
||||
Handle: HandleID(in.Fh),
|
||||
Flags: in.FsyncFlags,
|
||||
}
|
||||
|
||||
case opSetxattr:
|
||||
var size uint32
|
||||
|
@ -1591,6 +1599,21 @@ func (r *MknodRequest) Respond(resp *LookupResponse) {
|
|||
r.Conn.respond(&out.outHeader, unsafe.Sizeof(*out))
|
||||
}
|
||||
|
||||
type FsyncRequest struct {
|
||||
Header
|
||||
Handle HandleID
|
||||
Flags uint32
|
||||
}
|
||||
|
||||
func (r *FsyncRequest) String() string {
|
||||
return fmt.Sprintf("Fsync [%s] Handle %v Flags %v", &r.Header, r.Handle, r.Flags)
|
||||
}
|
||||
|
||||
func (r *FsyncRequest) Respond() {
|
||||
out := &outHeader{Unique: uint64(r.ID)}
|
||||
r.Conn.respond(out, unsafe.Sizeof(*out))
|
||||
}
|
||||
|
||||
/*{
|
||||
|
||||
// A XXXRequest xxx.
|
||||
|
|
|
@ -137,11 +137,12 @@ func (readAll1) test(path string, t *testing.T) {
|
|||
readAll{}.test(path, t)
|
||||
}
|
||||
|
||||
// Test Write calling basic Write.
|
||||
// Test Write calling basic Write, with an fsync thrown in too.
|
||||
|
||||
type write struct {
|
||||
file
|
||||
data []byte
|
||||
data []byte
|
||||
gotfsync bool
|
||||
}
|
||||
|
||||
func (w *write) Write(req *WriteRequest, resp *WriteResponse, intr Intr) Error {
|
||||
|
@ -150,6 +151,11 @@ func (w *write) Write(req *WriteRequest, resp *WriteResponse, intr Intr) Error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (w *write) Fsync(r *FsyncRequest, intr Intr) Error {
|
||||
w.gotfsync = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *write) test(path string, t *testing.T) {
|
||||
log.Printf("pre-write Create")
|
||||
f, err := os.Create(path)
|
||||
|
@ -164,6 +170,15 @@ func (w *write) test(path string, t *testing.T) {
|
|||
if n != len(hi) {
|
||||
t.Fatalf("short write; n=%d; hi=%d", n, len(hi))
|
||||
}
|
||||
|
||||
err = syscall.Fsync(int(f.Fd()))
|
||||
if err != nil {
|
||||
t.Fatalf("Fsync = %v", err)
|
||||
}
|
||||
if !w.gotfsync {
|
||||
t.Errorf("never received expected fsync call")
|
||||
}
|
||||
|
||||
log.Printf("pre-write Close")
|
||||
err = f.Close()
|
||||
if err != nil {
|
||||
|
@ -179,7 +194,13 @@ func (w *write) test(path string, t *testing.T) {
|
|||
|
||||
type writeAll struct {
|
||||
file
|
||||
data []byte
|
||||
data []byte
|
||||
gotfsync bool
|
||||
}
|
||||
|
||||
func (w *writeAll) Fsync(r *FsyncRequest, intr Intr) Error {
|
||||
w.gotfsync = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *writeAll) WriteAll(data []byte, intr Intr) Error {
|
||||
|
@ -259,7 +280,7 @@ func (f *mkdir1) test(path string, t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Test Create
|
||||
// Test Create (and fsync)
|
||||
|
||||
type create1 struct {
|
||||
dir
|
||||
|
@ -280,6 +301,16 @@ func (f *create1) test(path string, t *testing.T) {
|
|||
t.Errorf("create1 WriteFile: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = syscall.Fsync(int(ff.Fd()))
|
||||
if err != nil {
|
||||
t.Fatalf("Fsync = %v", err)
|
||||
}
|
||||
|
||||
if !f.f.gotfsync {
|
||||
t.Errorf("never received expected fsync call")
|
||||
}
|
||||
|
||||
ff.Close()
|
||||
if f.name != "foo" {
|
||||
t.Errorf("create1 name=%q want foo", f.name)
|
||||
|
|
|
@ -930,7 +930,26 @@ func (c *Conn) serve(fs FS, r Request) {
|
|||
done(s)
|
||||
r.Respond(s)
|
||||
|
||||
/* case *FsyncRequest, *FsyncdirRequest:
|
||||
case *FsyncRequest:
|
||||
n, ok := node.(interface {
|
||||
Fsync(r *FsyncRequest, intr Intr) Error
|
||||
})
|
||||
if !ok {
|
||||
log.Printf("Node %T missing Fsync method", node)
|
||||
done(EIO)
|
||||
r.RespondError(EIO)
|
||||
break
|
||||
}
|
||||
err := n.Fsync(r, intr)
|
||||
if err != nil {
|
||||
done(err)
|
||||
r.RespondError(err)
|
||||
break
|
||||
}
|
||||
done(nil)
|
||||
r.Respond()
|
||||
|
||||
/* case *FsyncdirRequest:
|
||||
done(ENOSYS)
|
||||
r.RespondError(ENOSYS)
|
||||
|
||||
|
|
Loading…
Reference in New Issue