@@ -25,6 +25,7 @@ import (
2525 "github.com/rfjakob/gocryptfs/internal/tlog"
2626)
2727
28+ // File2 implements the go-fuse v2 API (github.com/hanwen/go-fuse/v2/fs)
2829type File2 struct {
2930 fd * os.File
3031 // Has Release() already been called on this file? This also means that the
@@ -129,7 +130,7 @@ func (f *File2) createHeader() (fileID []byte, err error) {
129130//
130131// Called by Read() for normal reading,
131132// by Write() and Truncate() via doWrite() for Read-Modify-Write.
132- func (f * File2 ) doRead (dst []byte , off uint64 , length uint64 ) ([]byte , fuse. Status ) {
133+ func (f * File2 ) doRead (dst []byte , off uint64 , length uint64 ) ([]byte , syscall. Errno ) {
133134 // Get the file ID, either from the open file table, or from disk.
134135 var fileID []byte
135136 f .fileTableEntry .IDLock .Lock ()
@@ -144,15 +145,15 @@ func (f *File2) doRead(dst []byte, off uint64, length uint64) ([]byte, fuse.Stat
144145 f .fileTableEntry .IDLock .Unlock ()
145146 if err == io .EOF {
146147 // Empty file
147- return nil , fuse . OK
148+ return nil , 0
148149 }
149150 buf := make ([]byte , 100 )
150151 n , _ := f .fd .ReadAt (buf , 0 )
151152 buf = buf [:n ]
152153 hexdump := hex .EncodeToString (buf )
153154 tlog .Warn .Printf ("doRead %d: corrupt header: %v\n File hexdump (%d bytes): %s" ,
154155 f .qIno .Ino , err , n , hexdump )
155- return nil , fuse .EIO
156+ return nil , syscall .EIO
156157 }
157158 // Save into the file table
158159 f .fileTableEntry .ID = fileID
@@ -173,12 +174,12 @@ func (f *File2) doRead(dst []byte, off uint64, length uint64) ([]byte, fuse.Stat
173174 n , err := f .fd .ReadAt (ciphertext , int64 (alignedOffset ))
174175 if err != nil && err != io .EOF {
175176 tlog .Warn .Printf ("read: ReadAt: %s" , err .Error ())
176- return nil , fuse . ToStatus (err )
177+ return nil , fs . ToErrno (err )
177178 }
178179 // The ReadAt came back empty. We can skip all the decryption and return early.
179180 if n == 0 {
180181 f .rootNode .contentEnc .CReqPool .Put (ciphertext )
181- return dst , fuse . OK
182+ return dst , 0
182183 }
183184 // Truncate ciphertext buffer down to actually read bytes
184185 ciphertext = ciphertext [0 :n ]
@@ -198,7 +199,7 @@ func (f *File2) doRead(dst []byte, off uint64, length uint64) ([]byte, fuse.Stat
198199 } else {
199200 curruptBlockNo := firstBlockNo + f .contentEnc .PlainOffToBlockNo (uint64 (len (plaintext )))
200201 tlog .Warn .Printf ("doRead %d: corrupt block #%d: %v" , f .qIno .Ino , curruptBlockNo , err )
201- return nil , fuse .EIO
202+ return nil , syscall .EIO
202203 }
203204 }
204205
@@ -216,15 +217,15 @@ func (f *File2) doRead(dst []byte, off uint64, length uint64) ([]byte, fuse.Stat
216217 out = append (dst , out ... )
217218 f .rootNode .contentEnc .PReqPool .Put (plaintext )
218219
219- return out , fuse . OK
220+ return out , 0
220221}
221222
222223// Read - FUSE call
223- func (f * File2 ) Read (buf []byte , off int64 ) (resultData fuse.ReadResult , code fuse. Status ) {
224+ func (f * File2 ) Read (ctx context. Context , buf []byte , off int64 ) (resultData fuse.ReadResult , errno syscall. Errno ) {
224225 if len (buf ) > fuse .MAX_KERNEL_WRITE {
225226 // This would crash us due to our fixed-size buffer pool
226227 tlog .Warn .Printf ("Read: rejecting oversized request with EMSGSIZE, len=%d" , len (buf ))
227- return nil , fuse . Status ( syscall .EMSGSIZE )
228+ return nil , syscall .EMSGSIZE
228229 }
229230 f .fdLock .RLock ()
230231 defer f .fdLock .RUnlock ()
@@ -236,15 +237,15 @@ func (f *File2) Read(buf []byte, off int64) (resultData fuse.ReadResult, code fu
236237 if f .rootNode .args .SerializeReads {
237238 serialize_reads .Wait (off , len (buf ))
238239 }
239- out , status := f .doRead (buf [:0 ], uint64 (off ), uint64 (len (buf )))
240+ out , errno := f .doRead (buf [:0 ], uint64 (off ), uint64 (len (buf )))
240241 if f .rootNode .args .SerializeReads {
241242 serialize_reads .Done ()
242243 }
243- if status != fuse . OK {
244- return nil , status
244+ if errno != 0 {
245+ return nil , errno
245246 }
246- tlog .Debug .Printf ("ino%d: Read: status %v , returning %d bytes" , f .qIno .Ino , status , len (out ))
247- return fuse .ReadResultData (out ), status
247+ tlog .Debug .Printf ("ino%d: Read: errno=%d , returning %d bytes" , f .qIno .Ino , errno , len (out ))
248+ return fuse .ReadResultData (out ), errno
248249}
249250
250251// doWrite - encrypt "data" and write it to plaintext offset "off"
@@ -256,7 +257,7 @@ func (f *File2) Read(buf []byte, off int64) (resultData fuse.ReadResult, code fu
256257// and by Truncate() to rewrite the last file block.
257258//
258259// Empty writes do nothing and are allowed.
259- func (f * File2 ) doWrite (data []byte , off int64 ) (uint32 , fuse. Status ) {
260+ func (f * File2 ) doWrite (data []byte , off int64 ) (uint32 , syscall. Errno ) {
260261 fileWasEmpty := false
261262 // Get the file ID, create a new one if it does not exist yet.
262263 var fileID []byte
@@ -274,7 +275,7 @@ func (f *File2) doWrite(data []byte, off int64) (uint32, fuse.Status) {
274275 fileWasEmpty = true
275276 }
276277 if err != nil {
277- return 0 , fuse . ToStatus (err )
278+ return 0 , fs . ToErrno (err )
278279 }
279280 f .fileTableEntry .ID = fileID
280281 }
@@ -287,10 +288,10 @@ func (f *File2) doWrite(data []byte, off int64) (uint32, fuse.Status) {
287288 // Incomplete block -> Read-Modify-Write
288289 if b .IsPartial () {
289290 // Read
290- oldData , status := f .doRead (nil , b .BlockPlainOff (), f .contentEnc .PlainBS ())
291- if status != fuse . OK {
292- tlog .Warn .Printf ("ino%d fh%d: RMW read failed: %s " , f .qIno .Ino , f .intFd (), status . String () )
293- return 0 , status
291+ oldData , errno := f .doRead (nil , b .BlockPlainOff (), f .contentEnc .PlainBS ())
292+ if errno != 0 {
293+ tlog .Warn .Printf ("ino%d fh%d: RMW read failed: errno=%d " , f .qIno .Ino , f .intFd (), errno )
294+ return 0 , errno
294295 }
295296 // Modify
296297 blockData = f .contentEnc .MergeBlocks (oldData , blockData , int (b .Skip ))
@@ -321,7 +322,7 @@ func (f *File2) doWrite(data []byte, off int64) (uint32, fuse.Status) {
321322 tlog .Warn .Printf ("ino%d fh%d: doWrite: rollback failed: %v" , f .qIno .Ino , f .intFd (), err2 )
322323 }
323324 }
324- return 0 , fuse . ToStatus (err )
325+ return 0 , fs . ToErrno (err )
325326 }
326327 }
327328 // Write
@@ -331,9 +332,9 @@ func (f *File2) doWrite(data []byte, off int64) (uint32, fuse.Status) {
331332 if err != nil {
332333 tlog .Warn .Printf ("ino%d fh%d: doWrite: WriteAt off=%d len=%d failed: %v" ,
333334 f .qIno .Ino , f .intFd (), cOff , len (ciphertext ), err )
334- return 0 , fuse . ToStatus (err )
335+ return 0 , fs . ToErrno (err )
335336 }
336- return uint32 (len (data )), fuse . OK
337+ return uint32 (len (data )), 0
337338}
338339
339340// isConsecutiveWrite returns true if the current write
@@ -349,18 +350,18 @@ func (f *File2) isConsecutiveWrite(off int64) bool {
349350// Write - FUSE call
350351//
351352// If the write creates a hole, pads the file to the next block boundary.
352- func (f * File2 ) Write (data []byte , off int64 ) (uint32 , fuse. Status ) {
353+ func (f * File2 ) Write (ctx context. Context , data []byte , off int64 ) (uint32 , syscall. Errno ) {
353354 if len (data ) > fuse .MAX_KERNEL_WRITE {
354355 // This would crash us due to our fixed-size buffer pool
355356 tlog .Warn .Printf ("Write: rejecting oversized request with EMSGSIZE, len=%d" , len (data ))
356- return 0 , fuse . Status ( syscall .EMSGSIZE )
357+ return 0 , syscall .EMSGSIZE
357358 }
358359 f .fdLock .RLock ()
359360 defer f .fdLock .RUnlock ()
360361 if f .released {
361362 // The file descriptor has been closed concurrently
362363 tlog .Warn .Printf ("ino%d fh%d: Write on released file" , f .qIno .Ino , f .intFd ())
363- return 0 , fuse .EBADF
364+ return 0 , syscall .EBADF
364365 }
365366 f .fileTableEntry .ContentLock .Lock ()
366367 defer f .fileTableEntry .ContentLock .Unlock ()
@@ -369,21 +370,21 @@ func (f *File2) Write(data []byte, off int64) (uint32, fuse.Status) {
369370 // But if the write directly follows an earlier write, it cannot create a
370371 // hole, and we can save one Stat() call.
371372 if ! f .isConsecutiveWrite (off ) {
372- status := f .writePadHole (off )
373- if ! status . Ok () {
374- return 0 , status
373+ errno := f .writePadHole (off )
374+ if errno != 0 {
375+ return 0 , errno
375376 }
376377 }
377- n , status := f .doWrite (data , off )
378- if status . Ok () {
378+ n , errno := f .doWrite (data , off )
379+ if errno != 0 {
379380 f .lastOpCount = openfiletable .WriteOpCount ()
380381 f .lastWrittenOffset = off + int64 (len (data )) - 1
381382 }
382- return n , status
383+ return n , errno
383384}
384385
385386// Release - FUSE call, close file
386- func (f * File2 ) Release () {
387+ func (f * File2 ) Release (ctx context. Context ) syscall. Errno {
387388 f .fdLock .Lock ()
388389 if f .released {
389390 log .Panicf ("ino%d fh%d: double release" , f .qIno .Ino , f .intFd ())
@@ -392,10 +393,11 @@ func (f *File2) Release() {
392393 openfiletable .Unregister (f .qIno )
393394 f .fd .Close ()
394395 f .fdLock .Unlock ()
396+ return 0
395397}
396398
397399// Flush - FUSE call
398- func (f * File2 ) Flush () fuse. Status {
400+ func (f * File2 ) Flush (ctx context. Context ) syscall. Errno {
399401 f .fdLock .RLock ()
400402 defer f .fdLock .RUnlock ()
401403
@@ -405,18 +407,18 @@ func (f *File2) Flush() fuse.Status {
405407 newFd , err := syscall .Dup (f .intFd ())
406408
407409 if err != nil {
408- return fuse . ToStatus (err )
410+ return fs . ToErrno (err )
409411 }
410412 err = syscall .Close (newFd )
411- return fuse . ToStatus (err )
413+ return fs . ToErrno (err )
412414}
413415
414416// Fsync FUSE call
415- func (f * File2 ) Fsync (flags int ) (code fuse. Status ) {
417+ func (f * File2 ) Fsync (ctx context. Context , flags uint32 ) (errno syscall. Errno ) {
416418 f .fdLock .RLock ()
417419 defer f .fdLock .RUnlock ()
418420
419- return fuse . ToStatus (syscall .Fsync (f .intFd ()))
421+ return fs . ToErrno (syscall .Fsync (f .intFd ()))
420422}
421423
422424// Getattr FUSE call (like stat)
0 commit comments