file_container.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package gdrivefs
  2. import (
  3. "os"
  4. "sync"
  5. "github.com/jacobsa/fuse/fuseops"
  6. )
  7. type FileContainer struct {
  8. fileEntries map[fuseops.InodeID]*FileEntry
  9. tree *FileEntry
  10. fs *GDriveFS
  11. uid uint32
  12. gid uint32
  13. inodeMU *sync.Mutex
  14. }
  15. func NewFileContainer(fs *GDriveFS) *FileContainer {
  16. fc := &FileContainer{
  17. fileEntries: map[fuseops.InodeID]*FileEntry{},
  18. fs: fs,
  19. inodeMU: &sync.Mutex{},
  20. uid: fs.config.UID,
  21. gid: fs.config.GID,
  22. }
  23. rootEntry := fc.FileEntry(fuseops.RootInodeID)
  24. rootEntry.Attr.Mode = os.FileMode(0755) | os.ModeDir
  25. fc.tree = rootEntry
  26. return fc
  27. }
  28. func (fc *FileContainer) FindByInode(inode fuseops.InodeID) *FileEntry {
  29. return fc.fileEntries[inode]
  30. }
  31. func (fc *FileContainer) FindByGID(gid string) *FileEntry {
  32. for _, v := range fc.fileEntries {
  33. if v.GFile != nil && v.GFile.Id == gid {
  34. return v
  35. }
  36. }
  37. return nil
  38. }
  39. //Return or create inode
  40. func (fc *FileContainer) FileEntry(inodeOps ...fuseops.InodeID) *FileEntry {
  41. fc.inodeMU.Lock()
  42. defer fc.inodeMU.Unlock()
  43. var inode fuseops.InodeID
  44. if len(inodeOps) > 0 {
  45. inode = inodeOps[0]
  46. if fe, ok := fc.fileEntries[inode]; ok {
  47. return fe
  48. }
  49. } else { // generate new inode
  50. // Max Inode Number
  51. for inode = 2; inode < 99999; inode++ {
  52. _, ok := fc.fileEntries[inode]
  53. if !ok {
  54. break
  55. }
  56. }
  57. }
  58. fe := &FileEntry{
  59. Inode: inode,
  60. container: fc,
  61. children: []*FileEntry{},
  62. Attr: fuseops.InodeAttributes{
  63. Uid: fc.uid,
  64. Gid: fc.gid,
  65. },
  66. }
  67. fc.fileEntries[inode] = fe
  68. return fe
  69. }
  70. // RemoveEntry remove file entry
  71. func (fc *FileContainer) RemoveEntry(entry *FileEntry) {
  72. var inode fuseops.InodeID
  73. for k, e := range fc.fileEntries {
  74. if e == entry {
  75. inode = k
  76. }
  77. }
  78. delete(fc.fileEntries, inode)
  79. }