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:
|
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:
|
case opSetxattr:
|
||||||
var size uint32
|
var size uint32
|
||||||
|
@ -1591,6 +1599,21 @@ func (r *MknodRequest) Respond(resp *LookupResponse) {
|
||||||
r.Conn.respond(&out.outHeader, unsafe.Sizeof(*out))
|
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.
|
// A XXXRequest xxx.
|
||||||
|
|
|
@ -137,11 +137,12 @@ func (readAll1) test(path string, t *testing.T) {
|
||||||
readAll{}.test(path, t)
|
readAll{}.test(path, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test Write calling basic Write.
|
// Test Write calling basic Write, with an fsync thrown in too.
|
||||||
|
|
||||||
type write struct {
|
type write struct {
|
||||||
file
|
file
|
||||||
data []byte
|
data []byte
|
||||||
|
gotfsync bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *write) Write(req *WriteRequest, resp *WriteResponse, intr Intr) Error {
|
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
|
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) {
|
func (w *write) test(path string, t *testing.T) {
|
||||||
log.Printf("pre-write Create")
|
log.Printf("pre-write Create")
|
||||||
f, err := os.Create(path)
|
f, err := os.Create(path)
|
||||||
|
@ -164,6 +170,15 @@ func (w *write) test(path string, t *testing.T) {
|
||||||
if n != len(hi) {
|
if n != len(hi) {
|
||||||
t.Fatalf("short write; n=%d; hi=%d", 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")
|
log.Printf("pre-write Close")
|
||||||
err = f.Close()
|
err = f.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -179,7 +194,13 @@ func (w *write) test(path string, t *testing.T) {
|
||||||
|
|
||||||
type writeAll struct {
|
type writeAll struct {
|
||||||
file
|
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 {
|
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 {
|
type create1 struct {
|
||||||
dir
|
dir
|
||||||
|
@ -280,6 +301,16 @@ func (f *create1) test(path string, t *testing.T) {
|
||||||
t.Errorf("create1 WriteFile: %v", err)
|
t.Errorf("create1 WriteFile: %v", err)
|
||||||
return
|
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()
|
ff.Close()
|
||||||
if f.name != "foo" {
|
if f.name != "foo" {
|
||||||
t.Errorf("create1 name=%q want foo", f.name)
|
t.Errorf("create1 name=%q want foo", f.name)
|
||||||
|
|
|
@ -930,7 +930,26 @@ func (c *Conn) serve(fs FS, r Request) {
|
||||||
done(s)
|
done(s)
|
||||||
r.Respond(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)
|
done(ENOSYS)
|
||||||
r.RespondError(ENOSYS)
|
r.RespondError(ENOSYS)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue