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.
This commit is contained in:
Jakob Unterwurzacher 2015-12-06 15:05:52 +01:00
parent edc289fb75
commit 56888d83dd
2 changed files with 14 additions and 1 deletions

View File

@ -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()

View File

@ -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
}