fusefrontend: handle empty xattrs efficiently

We handle empty files by storing an actual empty file
on disk. Handle xattrs similarily and encrypt the
empty value to the empty value.
This commit is contained in:
Jakob Unterwurzacher 2018-03-25 21:02:33 +02:00
parent 1ed3d51df1
commit db778aae7d
2 changed files with 62 additions and 0 deletions

View File

@ -348,7 +348,11 @@ func (fs *FS) StatFs(path string) *fuse.StatfsOut {
// decryptSymlinkTarget: "cData64" is base64-decoded and decrypted
// like file contents (GCM).
// The empty string decrypts to the empty string.
func (fs *FS) decryptSymlinkTarget(cData64 string) (string, error) {
if cData64 == "" {
return "", nil
}
cData, err := fs.nameTransform.B64.DecodeString(cData64)
if err != nil {
return "", err
@ -409,7 +413,11 @@ func (fs *FS) Unlink(path string, context *fuse.Context) (code fuse.Status) {
// encryptSymlinkTarget: "data" is encrypted like file contents (GCM)
// and base64-encoded.
// The empty string encrypts to the empty string.
func (fs *FS) encryptSymlinkTarget(data string) (cData64 string) {
if data == "" {
return ""
}
cData := fs.contentEnc.EncryptBlock([]byte(data), 0, nil)
cData64 = fs.nameTransform.B64.EncodeToString(cData)
return cData64

View File

@ -66,6 +66,60 @@ func TestXattrSetGetRm(t *testing.T) {
}
}
func TestXattrSetEmpty(t *testing.T) {
attr := "user.foo"
fn := test_helpers.DefaultPlainDir + "/TestXattrSetEmpty1"
err := ioutil.WriteFile(fn, nil, 0700)
if err != nil {
t.Fatalf("creating empty file failed: %v", err)
}
// Make sure it does not exist already
_, err = xattr.Get(fn, attr)
if err == nil {
t.Fatal("we should have got an error here")
}
// Set empty value
err = xattr.Set(fn, attr, nil)
if err != nil {
t.Fatal(err)
}
// Read back
val, err := xattr.Get(fn, attr)
if err != nil {
t.Fatal(err)
}
if len(val) != 0 {
t.Errorf("wrong length: want=0 have=%d", len(val))
}
// Overwrite empty value with something
val1 := []byte("xyz123")
err = xattr.Set(fn, attr, val1)
if err != nil {
t.Fatal(err)
}
// Read back
val2, err := xattr.Get(fn, attr)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(val1, val2) {
t.Fatalf("wrong readback value: %v != %v", val1, val2)
}
// Overwrite something with empty value
err = xattr.Set(fn, attr, nil)
if err != nil {
t.Fatal(err)
}
// Read back
val, err = xattr.Get(fn, attr)
if err != nil {
t.Fatal(err)
}
if len(val) != 0 {
t.Errorf("wrong length: want=0 have=%d", len(val2))
}
}
func TestXattrList(t *testing.T) {
fn := test_helpers.DefaultPlainDir + "/TestXattrList"
err := ioutil.WriteFile(fn, nil, 0700)