Support chmod and chtimes.

geesefs-0-30-9
Aaron Jacobs 2015-03-06 06:05:00 +11:00
commit 02803ae811
5 changed files with 63 additions and 8 deletions

View File

@ -433,7 +433,10 @@ type SetInodeAttributesRequest struct {
Inode InodeID Inode InodeID
// The attributes to modify, or nil for attributes that don't need a change. // The attributes to modify, or nil for attributes that don't need a change.
Size *uint64 Size *uint64
Mode *os.FileMode
Atime *time.Time
Mtime *time.Time
} }
type SetInodeAttributesResponse struct { type SetInodeAttributesResponse struct {

View File

@ -281,7 +281,7 @@ func (fs *memFS) SetInodeAttributes(
defer inode.mu.Unlock() defer inode.mu.Unlock()
// Handle the request. // Handle the request.
inode.SetAttributes(req.Size) inode.SetAttributes(req.Size, req.Mode, req.Mtime)
// Fill in the response. // Fill in the response.
resp.Attributes = inode.attributes resp.Attributes = inode.attributes

View File

@ -18,6 +18,7 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"time"
"github.com/jacobsa/fuse" "github.com/jacobsa/fuse"
"github.com/jacobsa/fuse/fuseutil" "github.com/jacobsa/fuse/fuseutil"
@ -373,7 +374,10 @@ func (inode *inode) WriteAt(p []byte, off int64) (n int, err error) {
// Update attributes from non-nil parameters. // Update attributes from non-nil parameters.
// //
// EXCLUSIVE_LOCKS_REQUIRED(inode.mu) // EXCLUSIVE_LOCKS_REQUIRED(inode.mu)
func (inode *inode) SetAttributes(size *uint64) { func (inode *inode) SetAttributes(
size *uint64,
mode *os.FileMode,
mtime *time.Time) {
// Update the modification time. // Update the modification time.
inode.attributes.Mtime = inode.clock.Now() inode.attributes.Mtime = inode.clock.Now()
@ -392,4 +396,14 @@ func (inode *inode) SetAttributes(size *uint64) {
// Update attributes. // Update attributes.
inode.attributes.Size = *size inode.attributes.Size = *size
} }
// Change mode?
if mode != nil {
inode.attributes.Mode = *mode
}
// Change mtime?
if mtime != nil {
inode.attributes.Mtime = *mtime
}
} }

View File

@ -859,7 +859,6 @@ func (t *MemFSTest) ReadsPastEndOfFile() {
func (t *MemFSTest) Truncate_Smaller() { func (t *MemFSTest) Truncate_Smaller() {
var err error var err error
fileName := path.Join(t.mfs.Dir(), "foo") fileName := path.Join(t.mfs.Dir(), "foo")
// Create a file. // Create a file.
@ -888,7 +887,6 @@ func (t *MemFSTest) Truncate_Smaller() {
func (t *MemFSTest) Truncate_SameSize() { func (t *MemFSTest) Truncate_SameSize() {
var err error var err error
fileName := path.Join(t.mfs.Dir(), "foo") fileName := path.Join(t.mfs.Dir(), "foo")
// Create a file. // Create a file.
@ -917,7 +915,6 @@ func (t *MemFSTest) Truncate_SameSize() {
func (t *MemFSTest) Truncate_Larger() { func (t *MemFSTest) Truncate_Larger() {
var err error var err error
fileName := path.Join(t.mfs.Dir(), "foo") fileName := path.Join(t.mfs.Dir(), "foo")
// Create a file. // Create a file.
@ -945,9 +942,38 @@ func (t *MemFSTest) Truncate_Larger() {
} }
func (t *MemFSTest) Chmod() { func (t *MemFSTest) Chmod() {
AssertTrue(false, "TODO") var err error
fileName := path.Join(t.mfs.Dir(), "foo")
// Create a file.
err = ioutil.WriteFile(fileName, []byte(""), 0600)
AssertEq(nil, err)
// Chmod it.
err = os.Chmod(fileName, 0754)
AssertEq(nil, err)
// Stat it.
fi, err := os.Stat(fileName)
AssertEq(nil, err)
ExpectEq(os.FileMode(0754), fi.Mode())
} }
func (t *MemFSTest) Chtimes() { func (t *MemFSTest) Chtimes() {
AssertTrue(false, "TODO") var err error
fileName := path.Join(t.mfs.Dir(), "foo")
// Create a file.
err = ioutil.WriteFile(fileName, []byte(""), 0600)
AssertEq(nil, err)
// Chtimes it.
expectedMtime := time.Now().Add(123 * time.Second).Round(time.Second)
err = os.Chtimes(fileName, time.Time{}, expectedMtime)
AssertEq(nil, err)
// Stat it.
fi, err := os.Stat(fileName)
AssertEq(nil, err)
ExpectEq(0, fi.ModTime().Sub(expectedMtime))
} }

View File

@ -182,6 +182,18 @@ func (s *server) handleFuseRequest(fuseReq bazilfuse.Request) {
req.Size = &typed.Size req.Size = &typed.Size
} }
if typed.Valid&bazilfuse.SetattrMode != 0 {
req.Mode = &typed.Mode
}
if typed.Valid&bazilfuse.SetattrAtime != 0 {
req.Atime = &typed.Atime
}
if typed.Valid&bazilfuse.SetattrMtime != 0 {
req.Mtime = &typed.Mtime
}
// Call the file system. // Call the file system.
resp, err := s.fs.SetInodeAttributes(ctx, req) resp, err := s.fs.SetInodeAttributes(ctx, req)
if err != nil { if err != nil {