1. 15 Feb, 2019 1 commit
    • Kirill Smelkov's avatar
      X review feedback on newapi · 7e1f11bc
      Kirill Smelkov authored
      - add nodefs package overview; in particular describe what inode is so
        that there is no confusion about its meaning.
      
      - Draftly implement Lookup / Forget. They work not under global
        rawBridge.mu and still there should be no race of Lookup / Forget due to
        careful locking of inode -> (inode, ichild) + retrying.
        Add description of Forget semantic and what happens when we receive
        forget for a directory for which children are not forgotten yet.
      
        ( it is too late here now and I did not checked the implementation with
          a fresh head. I thought that it is better to release current state
          for discussion as I likely won't be able to work on newapi for at
          least another week )
      
      - use atomics in DefaultNode setInode/inode; see Lookup and
        corresponding description nearby DefaultNode.setInode for why it is
        needed.
      
      - inode.{lookupCount,nodeID} are now protected not by global
        rawBridge.mu, but instead by inode.mu .
      
      - change Node operation to return Nodes, not Inode. In particulare
        Node.Lookup should now return Node. Inodes are internal index of
        nodefs VFS (see package description) and we should not load filesystem
        implementations to think about them where we can. Also it makes a
        more closed interface when filesystem works in terms it nodes
        completely. Also this way we offload filesystems for caring about
        tricky details of how to create inode for a hardlinked entry (see
        Lookup for details which handles about it)
      
      - Remove Node.Inode -> nodefs.InodeOf(Node). this way there will be no
        possibility to override Node.Inode and we can specify InodeOf semantic
        exactly in API docs.
      
      - unlockNodes: sort is not needed
      
      - lock/unlock Nodes: avoid duplicates (e.g. there can be duplicates if dir/a and
        dir/b are hardlinks to the same file. If we don't avoid duplicates lockNodes will deadlock)
      
      - made some other edits, part of them not complete...
      7e1f11bc
  2. 13 Feb, 2019 1 commit
    • Han-Wen Nienhuys's avatar
      nodefs: sketch for a better NodeFS API · 9d7cb89b
      Han-Wen Nienhuys authored
      Credits: navytux, rfjakob for general feedback.
      
      
      Next:
      - Opendir
      
      TODO
      - context for PID/caller
      
      Open questions: grep for NOSUBMIT/TODO
      - how many interfaces?
      - explode SetAttr ?
      9d7cb89b
  3. 05 Feb, 2019 1 commit
  4. 04 Feb, 2019 3 commits
  5. 01 Feb, 2019 2 commits
  6. 30 Jan, 2019 13 commits
    • Han-Wen Nienhuys's avatar
      unionfs: copy fuse.Attr before modifying return value of branch cache · 32b02fb6
      Han-Wen Nienhuys authored
      Fixes a race condition.
      32b02fb6
    • Han-Wen Nienhuys's avatar
    • Han-Wen Nienhuys's avatar
      unionfs: clarify test error message · 40675bc3
      Han-Wen Nienhuys authored
      40675bc3
    • Han-Wen Nienhuys's avatar
    • Jakob Unterwurzacher's avatar
      fuse: improve BATCH_FORGET debug log output · 8020c188
      Jakob Unterwurzacher authored
      Node numbers are now written as "i1234" everywhere except in the
      BATCH_FORGET output, fix that. Also show the transaction number
      so we can follow where each forget comes from.
      
      As a normal FORGET looks like this:
      
      	2019/01/27 14:38:07 rx 1488: FORGET i822 {Nlookup=1}
      
      with the new output, "grep FORGET i1234 " will catch both single forgets
      and batch forgets.
      
      Before:
      
      	2019/01/20 18:15:31 rx 1372: BATCH_FORGET i0 {Count=3}  48b
      	2019/01/20 18:15:31 doBatchForget: forgetting 1 of 3: NodeId: 40, Nlookup: 1
      	2019/01/20 18:15:31 doBatchForget: forgetting 2 of 3: NodeId: 41, Nlookup: 1
      	2019/01/20 18:15:31 doBatchForget: forgetting 3 of 3: NodeId: 42, Nlookup: 1
      
      After:
      
      	2019/01/27 14:48:35 rx 2982: BATCH_FORGET i0 {Count=2}  32b
      	2019/01/27 14:48:35 doBatchForget: rx 2982 1/2: FORGET i804 {Nlookup=1}
      	2019/01/27 14:48:35 doBatchForget: rx 2982 2/2: FORGET i803 {Nlookup=1}
      8020c188
    • Kirill Smelkov's avatar
      nodefs: Don't crash on handleless WithFlags opens · 402331d4
      Kirill Smelkov authored
      Since https://git.kernel.org/linus/7678ac5061 FUSE filesystems were allowed to
      return ENOSYS from open and, open seeing this, the kernel will not send any
      open request anymore and just use Fh=0 for all opened files. This is handy for
      filesystems that don't have any per-opened-file state.
      
      However if there is at least one node for which opened files should have
      their own state, it is not correct to return ENOSYS from open _ever_, as that
      would prevent the kernel to call open on all nodes - in particular on the node
      where open needs to create a state associated with the file handle(*).
      
      It is already explicitly documented that Node.Open can return File=nil
      in which case filesystem operations like Read and Write will be called
      on the node directly. This way a filesystem could try to simulate an
      Open that was returning ENOSYS with Open that returns File=nil. However
      it is not the same as ENOSYS open also prevents the kernel from dropping
      the file cache:
      
      https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/fuse/file.c?id=v5.0-rc3-241-g7c2614bf7a1f#n131
      
      From this point of view Opens that were returning ENOSYS should be
      replaced with Open that returns WithFlags{File=nil, flags=FOPEN_KEEP_CACHE}.
      
      Unfortunately if one tries to do that, go-fuse segfaults as the test
      included in this patch demonstrates:
      
      	13:36:53.238706 rx 13: LOOKUP i1 ["world.txt"] 10b
      	13:36:53.238745 tx 13:     OK, {i4 g3 tE=1s tA=1s {M0100644 SZ=5 L=1 1000:1000 B0*0 i0:4 A 0.000000 M 0.000000 C 0.000000}}
      	13:36:53.238780 rx 14: OPEN i4 {O_RDONLY,0x8000}
      	13:36:53.238791 tx 14:     OK, {Fh 2 CACHE}				<-- NOTE Fh != 0
      	13:36:53.238706 rx 12: RELEASE i3 {Fh 0 NONBLOCK,0x8000  L0}
      	13:36:53.238804 tx 12:     OK
      	13:36:53.238823 rx 15: READ i4 {Fh 2 [0 +4096)  L 0 NONBLOCK,0x8000}
      	13:36:53.238830 tx 15:     OK,  5b data "world"
      	13:36:53.238846 rx 16: GETATTR i4 {Fh 2}
      	13:36:53.238865 tx 16:     OK, {tA=1s {M0100644 SZ=5 L=1 1000:1000 B0*0 i0:4 A 0.000000 M 0.000000 C 0.000000}}
      	13:36:53.238879 rx 17: FLUSH i4 {Fh 2}
      	panic: runtime error: invalid memory address or nil pointer dereference
      	[signal SIGSEGV: segmentation violation code=0x1 addr=0x30 pc=0x539f9f]
      
      	goroutine 6 [running]:
      	github.com/hanwen/go-fuse/fuse/nodefs.(*rawBridge).Flush(0xc000010960, 0xc000104180, 0x0)
      	        /home/kirr/src/neo/src/github.com/hanwen/go-fuse/fuse/nodefs/fsops.go:490 +0x6f
      	github.com/hanwen/go-fuse/fuse.doFlush(0xc0000de000, 0xc000104000)
      	        /home/kirr/src/neo/src/github.com/hanwen/go-fuse/fuse/opcode.go:373 +0x42
      	github.com/hanwen/go-fuse/fuse.(*Server).handleRequest(0xc0000de000, 0xc000104000, 0xc000104000)
      	        /home/kirr/src/neo/src/github.com/hanwen/go-fuse/fuse/server.go:431 +0x26b
      	github.com/hanwen/go-fuse/fuse.(*Server).loop(0xc0000de000, 0x0)
      	        /home/kirr/src/neo/src/github.com/hanwen/go-fuse/fuse/server.go:403 +0x18f
      	github.com/hanwen/go-fuse/fuse.(*Server).Serve(0xc0000de000)
      	        /home/kirr/src/neo/src/github.com/hanwen/go-fuse/fuse/server.go:331 +0x6d
      	created by github.com/hanwen/go-fuse/fuse/test.TestNoFile
      	        /home/kirr/src/neo/src/github.com/hanwen/go-fuse/fuse/test/nofile_test.go:73 +0x442
      
      Fix it by teaching registerFileHandle not to register any handle at all
      and return Fh=0, if the inner file (file itself, or the file that was wrapped
      with WithFlags) is nil.
      
      After the patch the trace for world.txt open/read (that is opened with
      WithFlags{File=nil, Flags=FOPEN_KEEP_CACHE} is as follows.
      
      	14:59:31.714048 rx 13: LOOKUP i1 ["world.txt"] 10b
      	14:59:31.714062 tx 13:     OK, {i4 g3 tE=1s tA=1s {M0100644 SZ=5 L=1 1000:1000 B0*0 i0:4 A 0.000000 M 0.000000 C 0.000000}}
      	14:59:31.714081 rx 14: OPEN i4 {O_RDONLY,0x8000}
      	14:59:31.714091 tx 14:     OK, {Fh 0 CACHE}				<-- NOTE Fh = 0
      	14:59:31.714123 rx 15: READ i4 {Fh 0 [0 +4096)  L 0 NONBLOCK,0x8000}
      	14:59:31.714132 tx 15:     OK,  5b data "world"
      	14:59:31.714150 rx 16: GETATTR i4 {Fh 0}
      	14:59:31.714159 tx 16:     OK, {tA=1s {M0100644 SZ=5 L=1 1000:1000 B0*0 i0:4 A 0.000000 M 0.000000 C 0.000000}}
      	14:59:31.714181 rx 17: FLUSH i4 {Fh 0}
      	14:59:31.714186 tx 17:     OK
      	14:59:31.714202 rx 18: RELEASE i4 {Fh 0 NONBLOCK,0x8000  L0}
      	14:59:31.714208 tx 18:     OK
      
      (*) my particular case is filesystem where many nodes are just data, but
      additionally there are files that behave like sockets - for every client
      who opens such file the filesystem establishes separate bidirectional
      channel for control exchange via that stream:
      
      https://lab.nexedi.com/kirr/wendelin.core/blob/a50da567fd/wcfs/misc.go#L205
      402331d4
    • Han-Wen Nienhuys's avatar
      unionfs: fix capitalization of TTL · f45e18d6
      Han-Wen Nienhuys authored
      f45e18d6
    • Han-Wen Nienhuys's avatar
      fuse/nodefs: protect mutable memnode fields with lock · 7f7894d2
      Han-Wen Nienhuys authored
      This fixes race conditions found by the race detector.
      7f7894d2
    • Han-Wen Nienhuys's avatar
      unionfs: update in-memory dircache as the last step. · e6fa1a12
      Han-Wen Nienhuys authored
      If we call AddEntry/RemoveEntry before the update to the deletion list
      in storage, a poorly timed cache refill that happens just before the
      storage update will result in storing the old state for as long as the
      cache's TTL.
      e6fa1a12
    • Han-Wen Nienhuys's avatar
      e00a5f2a
    • Han-Wen Nienhuys's avatar
      aed5935e
    • Han-Wen Nienhuys's avatar
    • Han-Wen Nienhuys's avatar
      Use subtests for rename tests · 33c1cab5
      Han-Wen Nienhuys authored
      33c1cab5
  7. 23 Jan, 2019 1 commit
    • Jakob Unterwurzacher's avatar
      server: print debug message on ENODEV · dfd0ceb2
      Jakob Unterwurzacher authored
      This makes it clear when (and why) the filesystem was unmounted.
      
      Example output:
      
      $ gocryptfs -fg -nosyslog -fusedebug a b
      Password:
      Decrypting master key
      Filesystem mounted and ready.
      2019/01/23 21:52:59 rx 2: ACCESS i1 {r}
      2019/01/23 21:52:59 tx 2:     OK
      2019/01/23 21:52:59 rx 3: LOOKUP i1 [".Trash"] 7b
      2019/01/23 21:52:59 tx 3:     OK, {i0 g0 tE=1s tA=0s {M00 SZ=0 L=0 0:0 B0*0 i0:0 A 0.000000 M 0.000000 C 0.000000}}
      2019/01/23 21:52:59 rx 4: LOOKUP i1 [".Trash-1026"] 12b
      2019/01/23 21:52:59 tx 4:     OK, {i0 g0 tE=1s tA=0s {M00 SZ=0 L=0 0:0 B0*0 i0:0 A 0.000000 M 0.000000 C 0.000000}}
      2019/01/23 21:53:02 received ENODEV (unmount request), thread exiting
      2019/01/23 21:53:02 received ENODEV (unmount request), thread exiting
      2019/01/23 21:53:02 received ENODEV (unmount request), thread exiting
      dfd0ceb2
  8. 11 Jan, 2019 1 commit
    • Kirill Smelkov's avatar
      readme: Add appendix about how to read Go-FUSE debug log output · 425e8d53
      Kirill Smelkov authored
      d1c826d1 ("fuse: increase signal/noise in log messages",
      https://github.com/hanwen/go-fuse/pull/249) changed log to use
      abbreviations in the name of improving signal/noise ratio. However it
      might be not evident offhand what an abbreviation means.
      
      Add a short reference in the readme with the summary on how to read the
      log and a short example.
      
      The summary is incomplete - for example I don't describe Fh and other
      attributes that d1c826d1 did not change. I propose we review logging
      more, e.g. consider doing `Fh X` -> `fX` and maybe similarly for other
      fields, and while doing so, also populate/update the summary and example
      in the readme. In other words it is good to document current state, but
      it is not fixed in stone and can be evolved.
      425e8d53
  9. 08 Jan, 2019 1 commit
    • Kirill Smelkov's avatar
      fuse: increase signal/noise in log messages · d1c826d1
      Kirill Smelkov authored
      - use tA=...s instead of `A...` or `AttrValid=...` for time(Attr valid);
      - use tE=...s instead of `EntryValid` for time(Entry valid);
      - use iX instead of `NodeId: X` for inode X;
      - use gX instead of `Generation=X` for generation X;
      - use `[<off> +<size>)` instead of `off <off> sz <sz>`;
      
      - use
      
              rx uniq: Op iX opargs
              tx uniq: status reply...
      
        instead of
      
              Dispatch uniq: Op NodeId: X opargs
              Serialize uniq: Op code: status reply...
      
        for received/replied messages;
      
      - use `["file1", "file2"]` instead of `names: [file1, file2]` for filenames.
      
      - use `xb` instead of `x bytes`
      
      - for replied data, also log data content, but only up to first 8 bytes.
        This does not flood the log, but at the same time makes filesystem
        diagnostics easier.
      d1c826d1
  10. 17 Dec, 2018 2 commits
  11. 12 Dec, 2018 2 commits
  12. 11 Dec, 2018 1 commit
  13. 27 Oct, 2018 1 commit
  14. 26 Oct, 2018 1 commit
  15. 15 Oct, 2018 1 commit
  16. 11 Oct, 2018 2 commits
    • Kirill Smelkov's avatar
      fuse: Correct NOTIFY constants/operation names · b760b557
      Kirill Smelkov authored
      - it is not NOTIFY_INVAL_DELETE, but just NOTIFY_DELETE as the kernel is
        notified of entry being deleted and there is no invalidation here.
        uapi/linux/fuse.h does not use "_INVAL_" for NOTIFY_DELETE neither.
      
      - similarly for "notify store/retrieve" _INVAL_ is not appropriate and
        neither is used in uapi/linux/fuse.h . However since we took more
        explicit approach for "notify store/retrieve" naming (see bdca0e6a
        "Add support for store notify") let's also add _CACHE suffix for
        "notify store/retrieve" operation names for consistency and for being
        less ambiguous.
      
      - for inode/entry invalidation operations, let's use _INVAL_ in internal
        _OP_NOTIFY_*, similarly to how it is used in corresponding NOTIFY_*
        constant. For example:
      
      	_OP_NOTIFY_ENTRY -> _OP_NOTIFY_INVAL_ENTRY	(corresponds to NOTIFY_INVAL_ENTRY)
      b760b557
    • Han-Wen Nienhuys's avatar
      fuse/nodefs: fix some lint errors · 6df8ddc4
      Han-Wen Nienhuys authored
      6df8ddc4
  17. 10 Oct, 2018 1 commit
  18. 09 Oct, 2018 5 commits