aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Unterwurzacher2016-06-26 18:35:19 +0200
committerJakob Unterwurzacher2016-06-26 18:41:04 +0200
commit38767ab5278f6fe62dcf70fc151e8a56cfffcfe4 (patch)
treebc191fb2c2a6389b4535eaba8e250202d0a303c5
parent1de5ceed586335361baae02160d61400fbf71e15 (diff)
fuserfrontend: support truncate(2) by wrapping ftruncate(2)
Support truncate(2) by opening the file and calling ftruncate(2) While the glibc "truncate" wrapper seems to always use ftruncate, fsstress from xfstests uses this a lot by calling "truncate64" directly.
-rw-r--r--internal/fusefrontend/file.go2
-rw-r--r--internal/fusefrontend/fs.go17
2 files changed, 12 insertions, 7 deletions
diff --git a/internal/fusefrontend/file.go b/internal/fusefrontend/file.go
index 7f25172..780a792 100644
--- a/internal/fusefrontend/file.go
+++ b/internal/fusefrontend/file.go
@@ -489,6 +489,8 @@ func (f *file) GetAttr(a *fuse.Attr) fuse.Status {
var allocateWarnOnce sync.Once
// Allocate - FUSE call, fallocate(2)
+// This is not implemented yet in gocryptfs, but it is neither in EncFS. This
+// suggests that the user demand is low.
func (f *file) Allocate(off uint64, sz uint64, mode uint32) fuse.Status {
allocateWarnOnce.Do(func() {
tlog.Warn.Printf("fallocate(2) is not supported, returning ENOSYS - see https://github.com/rfjakob/gocryptfs/issues/1")
diff --git a/internal/fusefrontend/fs.go b/internal/fusefrontend/fs.go
index 20079b2..640c45d 100644
--- a/internal/fusefrontend/fs.go
+++ b/internal/fusefrontend/fs.go
@@ -207,14 +207,17 @@ func (fs *FS) Mknod(path string, mode uint32, dev uint32, context *fuse.Context)
return fs.FileSystem.Mknod(cPath, mode, dev, context)
}
-// Only warn once
-var truncateWarnOnce sync.Once
-
+// Support truncate(2) by opening the file and calling ftruncate(2)
+// While the glibc "truncate" wrapper seems to always use ftruncate, fsstress from
+// xfstests uses this a lot by calling "truncate64" directly.
func (fs *FS) Truncate(path string, offset uint64, context *fuse.Context) (code fuse.Status) {
- truncateWarnOnce.Do(func() {
- tlog.Warn.Printf("truncate(2) is not supported, returning ENOSYS - use ftruncate(2)")
- })
- return fuse.ENOSYS
+ file, code := fs.Open(path, uint32(os.O_RDWR), context)
+ if code != fuse.OK {
+ return code
+ }
+ code = file.Truncate(offset)
+ file.Release()
+ return code
}
func (fs *FS) Utimens(path string, Atime *time.Time, Mtime *time.Time, context *fuse.Context) (code fuse.Status) {