github.com/rohankumardubey/proxyfs@v0.0.0-20210108201508-653efa9ab00e/docs/source/architecture/uml/samba-create-write.uml (about)

     1  @startuml
     2  
     3  title Open and Create New File with Write, Flush Close
     4  
     5  autonumber
     6  
     7  box "Samba"
     8  participant smb
     9  end box
    10  box "ProxyFS"
    11  participant RpcSvr
    12  participant Fs
    13  participant Inode
    14  participant InodeObj
    15  participant LS
    16  participant LS2
    17  participant SockSwift
    18  end box
    19  participant SwiftBE
    20  
    21  ' Create file
    22  ->smb:open(newfile, O_CREAT)
    23  smb-> RpcSvr: RpcCreate(mountId,\nin_inode_number, in_basename)
    24  RpcSvr -> Fs:fs.Create(mountId, dirInodeNumber,\nbasename)
    25  Fs -> Fs:getMount(mountId)\nLooks up mountId in map\nand returns Mount object
    26  
    27  Fs -> Inode:inode.CreateFile()
    28  Inode -> InodeObj:CreateFile()\ncalls inode.makeInMemoryInode()
    29  InodeObj -> InodeObj:makeInMemoryInode() gets new\ninodeNumber\nand inMemoryInode
    30  InodeObj -> LS:calls\nstartNewLogSegment()
    31  LS -> LS2:startNewLogSegment()\ncalls NewLogSegment()
    32  LS2 ->  LS2:NewLogSegment()\ncalls ProvisionObject() which gets\nnew log segment number and\ncalculates Swift container
    33  LS2 -> LS2:NewLogSegment() then does\nheadhunter.PutLogSegmentRec(\nlogSegmentNumber, objectPathBytes)
    34  LS2 -> LS:NewLogSegment()\nreturns logSegent and err
    35  LS -> LS:startNewLogSegment()\nsets pendingLogSegment to\nnew logSegment
    36  LS -> InodeObj:Returns err
    37  InodeObj -> SockSwift:startNewLogSegment()\ncalls segment.NewChunkedContext()
    38  SockSwift -> InodeObj:segment.NewChunkedContext()\nreturns SwiftContext
    39  InodeObj -> Inode:makeInMemoryInode()\nReturns err and new inode
    40  Inode -> Inode:Add new inode to globals.inodecache
    41  Inode -> Fs: inode.CreateFile()\nreturns newFileInodeNumber, err
    42  Fs -> Inode:inode.Link(dirInodeNumber, basename,\nfileInodeNumber)
    43  
    44  ' Link file to directory
    45  Inode -> Inode:Link calls dirInode.preparePendingLogSegment()\nThis calls startNewLogSegment()\nif pendingLogSegment is nil.
    46  note left :NOTE: Not showing whole startNewLogSegment() steps since shown above.
    47  Inode -> Inode:Link calls\ntargetInode.preparePendingLogSegment().pendingLogSegment()\nshould be !NULL since was set when created in\nmakeInMemoryInode().
    48  note left :Shouldn't we call this on targetInode first since if set pending could flush before directory?
    49  Inode -> Inode:Call inode.flushInode(\ndirInode.InodeNumber)
    50  Inode -> Inode:flushInode() calls appendOnDiskInodeThenTrailer()
    51  Inode -> SockSwift:appendOnDiskInodeThenTrailer() calls PutChunked(buf) which writes\nbuffer with suffix and prefix to socket.
    52  SockSwift ->SwiftBE:PutChunked(buf)\nwrites buffer to Swift
    53  SwiftBE ->SockSwift:Swift returns err
    54  SockSwift -> Inode:Returns err
    55  Inode -> SockSwift:appendOnDiskInodeThenTrailer() calls Close() which calls\nputChunkedEnd() which completes update to Swift
    56  SockSwift ->SwiftBE:Close()\nwrites buffer to Swift
    57  SwiftBE ->SockSwift:Swift returns err
    58  Inode -> Fs: inode.Link()return err
    59  note left :We don't seem to be flushing the file inode to Swift before returning.
    60  Fs -> RpcSvr:fs.Create returns fileInodeNumber,\nerr
    61  RpcSvr -> smb:return err
    62  
    63  ' Write file
    64  ->smb:write(newfile, 10MB)
    65  smb-> RpcSvr: RpcWrite(mountId,\nin_inode_number, in_basename)
    66  RpcSvr -> Fs:Calls fs.Write(mountId,\ninodeNumber, offset, buf)
    67  Fs -> Inode:Gets getMount(mountId)
    68  Inode -> Fs:returns mount
    69  Fs -> Inode:Calls inode.Write(inodeNumber,\noffset, buf) returns szWritten, err
    70  Inode -> Inode:inode.Write() calls preparePendingLogSegment()
    71  note left :NOTE: Not showing whole\npreparePendingLogSegment() steps since shown above.
    72  Inode -> Inode:inode.Write() calls PutChunked(buf)\nwhich writes buffer with suffix and prefix to socket.
    73  note left :NOTE: Not showing whole PutChunked() since shown above
    74  Inode -> Inode:inode.Write() calls recordWrite() to update payload record\nof BTree+ with extents in file.
    75  Inode -> Fs:inode.Write() returns err
    76  Fs -> RpcSvr:fs.Write() returns szWritten, err
    77  RpcSvr -> smb:return szWritten, err
    78  
    79  ' Show async event when flusher runs
    80  ->smb:sleep 5\nallows flush thread\n to run
    81  
    82  ' Time based flush to Swift
    83  Inode -> SwiftBE:ASYNC - Time based flush thread calls inode.flushInode() to flush to Swift.  Locking is "queue" off in memory inode.
    84  note left :NOTE: Not showing whole flushInode() since shown above.
    85  
    86  ' Samba close of file causing a flush
    87  ->smb:close(newfile)\ncauses flush()
    88  smb-> RpcSvr: RpcFlush(mountId,\nin_inode_number)
    89  RpcSvr -> Fs:Flush(mountId, in_inode_number)
    90  Fs -> Inode:Flush(inodeNumber, false) returns err
    91  Inode -> Fs:Returns err
    92  Fs -> RpcSvr:Return err
    93  RpcSvr -> smb:return err
    94  
    95  @enduml