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