From 56888d83dd50a10bad56eaa512ce0b6a2f2d41ed Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 6 Dec 2015 15:05:52 +0100 Subject: fallocate the space needed for the file header beforehand This makes sure writing to a file fails early if the underlying filesystem does not support fallocate. It also prevents partial header write due to ENOSPC. --- cryptfs/names_diriv.go | 2 ++ pathfs_frontend/file.go | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/cryptfs/names_diriv.go b/cryptfs/names_diriv.go index 3e24a73..035eac1 100644 --- a/cryptfs/names_diriv.go +++ b/cryptfs/names_diriv.go @@ -22,6 +22,7 @@ type DirIVCache struct { lock sync.RWMutex } +// lookup - fetch entry for "dir" from the cache func (c *DirIVCache) lookup(dir string) (bool, []byte, string) { c.lock.RLock() defer c.lock.RUnlock() @@ -31,6 +32,7 @@ func (c *DirIVCache) lookup(dir string) (bool, []byte, string) { return false, nil, "" } +// store - write entry for "dir" into the caches func (c *DirIVCache) store(dir string, iv []byte, translatedDir string) { c.lock.Lock() defer c.lock.Unlock() diff --git a/pathfs_frontend/file.go b/pathfs_frontend/file.go index 5c76fb1..16d83c1 100644 --- a/pathfs_frontend/file.go +++ b/pathfs_frontend/file.go @@ -93,7 +93,18 @@ func (f *file) readHeader() error { func (f *file) createHeader() error { h := cryptfs.RandomHeader() buf := h.Pack() - _, err := f.fd.WriteAt(buf, 0) + + // Prevent partially written (=corrupt) header by preallocating the space beforehand + f.fdLock.Lock() + defer f.fdLock.Unlock() + err := syscall.Fallocate(int(f.fd.Fd()), FALLOC_FL_KEEP_SIZE, 0, cryptfs.HEADER_LEN) + if err != nil { + cryptfs.Warn.Printf("createHeader: Fallocate failed: %s\n", err.Error()) + return err + } + + // Actually write header + _, err = f.fd.WriteAt(buf, 0) if err != nil { return err } -- cgit v1.2.3