dir.go 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179
  1. package vfs
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. "path"
  7. "sort"
  8. "strings"
  9. "sync"
  10. "sync/atomic"
  11. "time"
  12. "github.com/rclone/rclone/fs"
  13. "github.com/rclone/rclone/fs/dirtree"
  14. "github.com/rclone/rclone/fs/list"
  15. "github.com/rclone/rclone/fs/log"
  16. "github.com/rclone/rclone/fs/operations"
  17. "github.com/rclone/rclone/fs/walk"
  18. "github.com/rclone/rclone/vfs/vfscommon"
  19. "golang.org/x/text/unicode/norm"
  20. )
  21. // Dir represents a directory entry
  22. type Dir struct {
  23. vfs *VFS // read only
  24. inode uint64 // read only: inode number
  25. f fs.Fs // read only
  26. cleanupTimer *time.Timer // read only: timer to call cacheCleanup
  27. mu sync.RWMutex // protects the following
  28. parent *Dir // parent, nil for root
  29. path string
  30. entry fs.Directory
  31. read time.Time // time directory entry last read
  32. items map[string]Node // directory entries - can be empty but not nil
  33. virtual map[string]vState // virtual directory entries - may be nil
  34. sys atomic.Value // user defined info to be attached here
  35. modTimeMu sync.Mutex // protects the following
  36. modTime time.Time
  37. _hasVirtual atomic.Bool // shows if the directory has virtual entries
  38. }
  39. //go:generate stringer -type=vState
  40. // vState describes the state of the virtual directory entries
  41. type vState byte
  42. const (
  43. vOK vState = iota // Not virtual
  44. vAddFile // added file
  45. vAddDir // added directory
  46. vDel // removed file or directory
  47. )
  48. func newDir(vfs *VFS, f fs.Fs, parent *Dir, fsDir fs.Directory) *Dir {
  49. d := &Dir{
  50. vfs: vfs,
  51. f: f,
  52. parent: parent,
  53. entry: fsDir,
  54. path: fsDir.Remote(),
  55. modTime: fsDir.ModTime(context.TODO()),
  56. inode: newInode(),
  57. items: make(map[string]Node),
  58. }
  59. d.cleanupTimer = time.AfterFunc(vfs.Opt.DirCacheTime*2, d.cacheCleanup)
  60. d.setHasVirtual(false)
  61. return d
  62. }
  63. func (d *Dir) cacheCleanup() {
  64. defer func() {
  65. // We should never panic here
  66. _ = recover()
  67. }()
  68. when := time.Now()
  69. d.mu.Lock()
  70. _, stale := d._age(when)
  71. d.mu.Unlock()
  72. if stale {
  73. d.ForgetAll()
  74. }
  75. }
  76. // String converts it to printable
  77. func (d *Dir) String() string {
  78. if d == nil {
  79. return "<nil *Dir>"
  80. }
  81. d.mu.RLock()
  82. defer d.mu.RUnlock()
  83. return d.path + "/"
  84. }
  85. // Dumps the directory tree to the string builder with the given indent
  86. //
  87. //lint:ignore U1000 false positive when running staticcheck,
  88. //nolint:unused // Don't include unused when running golangci-lint
  89. func (d *Dir) dumpIndent(out *strings.Builder, indent string) {
  90. if d == nil {
  91. fmt.Fprintf(out, "%s<nil *Dir>\n", indent)
  92. return
  93. }
  94. d.mu.RLock()
  95. defer d.mu.RUnlock()
  96. fmt.Fprintf(out, "%sPath: %s\n", indent, d.path)
  97. fmt.Fprintf(out, "%sEntry: %v\n", indent, d.entry)
  98. fmt.Fprintf(out, "%sRead: %v\n", indent, d.read)
  99. fmt.Fprintf(out, "%s- items %d\n", indent, len(d.items))
  100. // Sort?
  101. for leaf, node := range d.items {
  102. switch x := node.(type) {
  103. case *Dir:
  104. fmt.Fprintf(out, "%s %s/ - %v\n", indent, leaf, x)
  105. // check the parent is correct
  106. if x.parent != d {
  107. fmt.Fprintf(out, "%s PARENT POINTER WRONG\n", indent)
  108. }
  109. x.dumpIndent(out, indent+"\t")
  110. case *File:
  111. fmt.Fprintf(out, "%s %s - %v\n", indent, leaf, x)
  112. default:
  113. panic("bad dir entry")
  114. }
  115. }
  116. fmt.Fprintf(out, "%s- virtual %d\n", indent, len(d.virtual))
  117. for leaf, state := range d.virtual {
  118. fmt.Fprintf(out, "%s %s - %v\n", indent, leaf, state)
  119. }
  120. }
  121. // Dumps a nicely formatted directory tree to a string
  122. //
  123. //lint:ignore U1000 false positive when running staticcheck,
  124. //nolint:unused // Don't include unused when running golangci-lint
  125. func (d *Dir) dump() string {
  126. var out strings.Builder
  127. d.dumpIndent(&out, "")
  128. return out.String()
  129. }
  130. // IsFile returns false for Dir - satisfies Node interface
  131. func (d *Dir) IsFile() bool {
  132. return false
  133. }
  134. // IsDir returns true for Dir - satisfies Node interface
  135. func (d *Dir) IsDir() bool {
  136. return true
  137. }
  138. // Mode bits of the directory - satisfies Node interface
  139. func (d *Dir) Mode() (mode os.FileMode) {
  140. return d.vfs.Opt.DirPerms
  141. }
  142. // Name (base) of the directory - satisfies Node interface
  143. func (d *Dir) Name() (name string) {
  144. d.mu.RLock()
  145. name = path.Base(d.path)
  146. d.mu.RUnlock()
  147. if name == "." {
  148. name = "/"
  149. }
  150. return name
  151. }
  152. // Path of the directory - satisfies Node interface
  153. func (d *Dir) Path() (name string) {
  154. d.mu.RLock()
  155. defer d.mu.RUnlock()
  156. return d.path
  157. }
  158. // Sys returns underlying data source (can be nil) - satisfies Node interface
  159. func (d *Dir) Sys() interface{} {
  160. return d.sys.Load()
  161. }
  162. // SetSys sets the underlying data source (can be nil) - satisfies Node interface
  163. func (d *Dir) SetSys(x interface{}) {
  164. d.sys.Store(x)
  165. }
  166. // Inode returns the inode number - satisfies Node interface
  167. func (d *Dir) Inode() uint64 {
  168. return d.inode
  169. }
  170. // Node returns the Node associated with this - satisfies Noder interface
  171. func (d *Dir) Node() Node {
  172. return d
  173. }
  174. // hasVirtual returns whether the directory has virtual entries
  175. func (d *Dir) hasVirtual() bool {
  176. return d._hasVirtual.Load()
  177. }
  178. // setHasVirtual sets the hasVirtual flag for the directory
  179. func (d *Dir) setHasVirtual(hasVirtual bool) {
  180. d._hasVirtual.Store(hasVirtual)
  181. }
  182. // ForgetAll forgets directory entries for this directory and any children.
  183. //
  184. // It does not invalidate or clear the cache of the parent directory.
  185. //
  186. // It returns true if the directory or any of its children had virtual entries
  187. // so could not be forgotten. Children which didn't have virtual entries and
  188. // children with virtual entries will be forgotten even if true is returned.
  189. func (d *Dir) ForgetAll() (hasVirtual bool) {
  190. d.mu.RLock()
  191. fs.Debugf(d.path, "forgetting directory cache")
  192. for _, node := range d.items {
  193. if dir, ok := node.(*Dir); ok {
  194. if dir.ForgetAll() {
  195. d.setHasVirtual(true)
  196. }
  197. }
  198. }
  199. d.mu.RUnlock()
  200. d.mu.Lock()
  201. defer d.mu.Unlock()
  202. // Purge any unnecessary virtual entries
  203. d._purgeVirtual()
  204. d.read = time.Time{}
  205. // Check if this dir has virtual entries
  206. if len(d.virtual) != 0 {
  207. d.setHasVirtual(true)
  208. }
  209. // Don't clear directory entries if there are virtual entries in this
  210. // directory or any children
  211. if !d.hasVirtual() {
  212. d.items = make(map[string]Node)
  213. d.cleanupTimer.Stop()
  214. }
  215. return d.hasVirtual()
  216. }
  217. // forgetDirPath clears the cache for itself and all subdirectories if
  218. // they match the given path. The path is specified relative from the
  219. // directory it is called from.
  220. //
  221. // It does not invalidate or clear the cache of the parent directory.
  222. func (d *Dir) forgetDirPath(relativePath string) {
  223. dir := d.cachedDir(relativePath)
  224. if dir == nil {
  225. return
  226. }
  227. dir.ForgetAll()
  228. }
  229. // invalidateDir invalidates the directory cache for absPath relative to the root
  230. func (d *Dir) invalidateDir(absPath string) {
  231. node := d.vfs.root.cachedNode(absPath)
  232. if dir, ok := node.(*Dir); ok {
  233. dir.mu.Lock()
  234. if !dir.read.IsZero() {
  235. fs.Debugf(dir.path, "invalidating directory cache")
  236. dir.read = time.Time{}
  237. }
  238. dir.mu.Unlock()
  239. }
  240. }
  241. // changeNotify invalidates the directory cache for the relativePath
  242. // passed in.
  243. //
  244. // if entryType is a directory it invalidates the parent of the directory too.
  245. func (d *Dir) changeNotify(relativePath string, entryType fs.EntryType) {
  246. defer log.Trace(d.path, "relativePath=%q, type=%v", relativePath, entryType)("")
  247. d.mu.RLock()
  248. absPath := path.Join(d.path, relativePath)
  249. d.mu.RUnlock()
  250. d.invalidateDir(vfscommon.FindParent(absPath))
  251. if entryType == fs.EntryDirectory {
  252. d.invalidateDir(absPath)
  253. }
  254. }
  255. // ForgetPath clears the cache for itself and all subdirectories if
  256. // they match the given path. The path is specified relative from the
  257. // directory it is called from. The cache of the parent directory is
  258. // marked as stale, but not cleared otherwise.
  259. // It is not possible to traverse the directory tree upwards, i.e.
  260. // you cannot clear the cache for the Dir's ancestors or siblings.
  261. func (d *Dir) ForgetPath(relativePath string, entryType fs.EntryType) {
  262. defer log.Trace(d.path, "relativePath=%q, type=%v", relativePath, entryType)("")
  263. d.mu.RLock()
  264. absPath := path.Join(d.path, relativePath)
  265. d.mu.RUnlock()
  266. if absPath != "" {
  267. d.invalidateDir(vfscommon.FindParent(absPath))
  268. }
  269. if entryType == fs.EntryDirectory {
  270. d.forgetDirPath(relativePath)
  271. }
  272. }
  273. // walk runs a function on all cached directories. It will be called
  274. // on a directory's children first.
  275. //
  276. // The mutex will be held for the directory when fun is called
  277. func (d *Dir) walk(fun func(*Dir)) {
  278. d.mu.Lock()
  279. defer d.mu.Unlock()
  280. for _, node := range d.items {
  281. if dir, ok := node.(*Dir); ok {
  282. dir.walk(fun)
  283. }
  284. }
  285. fun(d)
  286. }
  287. // countActiveWriters returns the number of writers active in this
  288. // directory and any subdirectories.
  289. func (d *Dir) countActiveWriters() (writers int) {
  290. d.walk(func(d *Dir) {
  291. // NB d.mu is held by walk() here
  292. fs.Debugf(d.path, "Looking for writers")
  293. for leaf, item := range d.items {
  294. fs.Debugf(leaf, "reading active writers")
  295. if file, ok := item.(*File); ok {
  296. n := file.activeWriters()
  297. if n != 0 {
  298. fs.Debugf(file, "active writers %d", n)
  299. }
  300. writers += n
  301. }
  302. }
  303. })
  304. return writers
  305. }
  306. // age returns the duration since the last time the directory contents
  307. // was read and the content is considered stale. age will be 0 and
  308. // stale true if the last read time is empty.
  309. // age must be called with d.mu held.
  310. func (d *Dir) _age(when time.Time) (age time.Duration, stale bool) {
  311. if d.read.IsZero() {
  312. return age, true
  313. }
  314. age = when.Sub(d.read)
  315. stale = age > d.vfs.Opt.DirCacheTime
  316. return
  317. }
  318. // renameTree renames the directories under this directory
  319. //
  320. // path should be the desired path
  321. func (d *Dir) renameTree(dirPath string) {
  322. d.mu.Lock()
  323. defer d.mu.Unlock()
  324. // Make sure the path is correct for each node
  325. if d.path != dirPath {
  326. fs.Debugf(d.path, "Renaming to %q", dirPath)
  327. d.path = dirPath
  328. d.entry = fs.NewDirCopy(context.TODO(), d.entry).SetRemote(dirPath)
  329. }
  330. // Do the same to any child directories and files
  331. for leaf, node := range d.items {
  332. switch x := node.(type) {
  333. case *Dir:
  334. x.renameTree(path.Join(dirPath, leaf))
  335. case *File:
  336. x.renameDir(dirPath)
  337. default:
  338. panic("bad dir entry")
  339. }
  340. }
  341. }
  342. // rename should be called after the directory is renamed
  343. //
  344. // Reset the directory to new state, discarding all the objects and
  345. // reading everything again
  346. func (d *Dir) rename(newParent *Dir, fsDir fs.Directory) {
  347. d.ForgetAll()
  348. d.modTimeMu.Lock()
  349. d.modTime = fsDir.ModTime(context.TODO())
  350. d.modTimeMu.Unlock()
  351. d.mu.Lock()
  352. oldPath := d.path
  353. d.parent = newParent
  354. d.entry = fsDir
  355. d.path = fsDir.Remote()
  356. newPath := d.path
  357. d.read = time.Time{}
  358. d.mu.Unlock()
  359. // Rename any remaining items in the tree that we couldn't forget
  360. d.renameTree(d.path)
  361. // Rename in the cache
  362. if d.vfs.cache != nil && d.vfs.cache.DirExists(oldPath) {
  363. if err := d.vfs.cache.DirRename(oldPath, newPath); err != nil {
  364. fs.Infof(d, "Dir.Rename failed in Cache: %v", err)
  365. }
  366. }
  367. }
  368. // addObject adds a new object or directory to the directory
  369. //
  370. // The name passed in is marked as virtual as it hasn't been read from a remote
  371. // directory listing.
  372. //
  373. // note that we add new objects rather than updating old ones
  374. func (d *Dir) addObject(node Node) {
  375. d.mu.Lock()
  376. leaf := node.Name()
  377. d.items[leaf] = node
  378. if d.virtual == nil {
  379. d.virtual = make(map[string]vState)
  380. }
  381. vAdd := vAddFile
  382. if node.IsDir() {
  383. vAdd = vAddDir
  384. }
  385. d.virtual[leaf] = vAdd
  386. d.setHasVirtual(true)
  387. fs.Debugf(d.path, "Added virtual directory entry %v: %q", vAdd, leaf)
  388. d.mu.Unlock()
  389. }
  390. // AddVirtual adds a virtual object of name and size to the directory
  391. //
  392. // This will be replaced with a real object when it is read back from the
  393. // remote.
  394. //
  395. // This is used to add directory entries while things are uploading
  396. func (d *Dir) AddVirtual(leaf string, size int64, isDir bool) {
  397. var node Node
  398. d.mu.RLock()
  399. dPath := d.path
  400. _, found := d.items[leaf]
  401. d.mu.RUnlock()
  402. if found {
  403. // Don't overwrite existing objects
  404. return
  405. }
  406. if isDir {
  407. remote := path.Join(dPath, leaf)
  408. entry := fs.NewDir(remote, time.Now())
  409. node = newDir(d.vfs, d.f, d, entry)
  410. } else {
  411. f := newFile(d, dPath, nil, leaf)
  412. f.setSize(size)
  413. node = f
  414. }
  415. d.addObject(node)
  416. }
  417. // delObject removes an object from the directory
  418. //
  419. // The name passed in is marked as virtual as the delete it hasn't been read
  420. // from a remote directory listing.
  421. func (d *Dir) delObject(leaf string) {
  422. d.mu.Lock()
  423. delete(d.items, leaf)
  424. if d.virtual == nil {
  425. d.virtual = make(map[string]vState)
  426. }
  427. d.virtual[leaf] = vDel
  428. d.setHasVirtual(true)
  429. fs.Debugf(d.path, "Added virtual directory entry %v: %q", vDel, leaf)
  430. d.mu.Unlock()
  431. }
  432. // DelVirtual removes an object from the directory listing
  433. //
  434. // It marks it as removed until it has confirmed the object is missing when the
  435. // directory entries are re-read in.
  436. //
  437. // This is used to remove directory entries after things have been deleted or
  438. // renamed but before we've had confirmation from the backend.
  439. func (d *Dir) DelVirtual(leaf string) {
  440. d.delObject(leaf)
  441. }
  442. // read the directory and sets d.items - must be called with the lock held
  443. func (d *Dir) _readDir() error {
  444. when := time.Now()
  445. if age, stale := d._age(when); stale {
  446. if age != 0 {
  447. fs.Debugf(d.path, "Re-reading directory (%v old)", age)
  448. }
  449. } else {
  450. return nil
  451. }
  452. entries, err := list.DirSorted(context.TODO(), d.f, false, d.path)
  453. if err == fs.ErrorDirNotFound {
  454. // We treat directory not found as empty because we
  455. // create directories on the fly
  456. } else if err != nil {
  457. return err
  458. }
  459. if d.vfs.Opt.BlockNormDupes { // do this only if requested, as it will have a performance hit
  460. ci := fs.GetConfig(context.TODO())
  461. // sort entries such that NFD comes before NFC of same name
  462. sort.Slice(entries, func(i, j int) bool {
  463. if entries[i] != entries[j] && fs.DirEntryType(entries[i]) == fs.DirEntryType(entries[j]) && norm.NFC.String(entries[i].Remote()) == norm.NFC.String(entries[j].Remote()) {
  464. if norm.NFD.IsNormalString(entries[i].Remote()) && !norm.NFD.IsNormalString(entries[j].Remote()) {
  465. return true
  466. }
  467. }
  468. return entries.Less(i, j)
  469. })
  470. // detect dupes, remove them from the list and log an error
  471. normalizedNames := make(map[string]struct{}, entries.Len())
  472. filteredEntries := make(fs.DirEntries, 0)
  473. for _, e := range entries {
  474. normName := fmt.Sprintf("%s-%T", operations.ToNormal(e.Remote(), !ci.NoUnicodeNormalization, (ci.IgnoreCaseSync || d.vfs.Opt.CaseInsensitive)), e) // include type to track objects and dirs separately
  475. _, found := normalizedNames[normName]
  476. if found {
  477. fs.Errorf(e.Remote(), "duplicate normalized names detected - skipping")
  478. continue
  479. }
  480. normalizedNames[normName] = struct{}{}
  481. filteredEntries = append(filteredEntries, e)
  482. }
  483. entries = filteredEntries
  484. }
  485. err = d._readDirFromEntries(entries, nil, time.Time{})
  486. if err != nil {
  487. return err
  488. }
  489. d.read = when
  490. d.cleanupTimer.Reset(d.vfs.Opt.DirCacheTime * 2)
  491. return nil
  492. }
  493. // update d.items for each dir in the DirTree below this one and
  494. // set the last read time - must be called with the lock held
  495. func (d *Dir) _readDirFromDirTree(dirTree dirtree.DirTree, when time.Time) error {
  496. return d._readDirFromEntries(dirTree[d.path], dirTree, when)
  497. }
  498. // Remove the virtual directory entry leaf
  499. func (d *Dir) _deleteVirtual(name string) {
  500. virtualState, ok := d.virtual[name]
  501. if !ok {
  502. return
  503. }
  504. delete(d.virtual, name)
  505. if len(d.virtual) == 0 {
  506. d.virtual = nil
  507. d.setHasVirtual(false)
  508. }
  509. fs.Debugf(d.path, "Removed virtual directory entry %v: %q", virtualState, name)
  510. }
  511. // Purge virtual entries assuming the directory has just been re-read
  512. //
  513. // Remove all the entries except:
  514. //
  515. // 1) vDirAdd on remotes which can't have empty directories. These will remain
  516. // virtual as long as the directory is empty. When the directory becomes real
  517. // (ie files are added) the virtual directory will be removed. This means that
  518. // directories will disappear when the last file is deleted which is probably
  519. // OK.
  520. //
  521. // 2) vFileAdd that are being written or uploaded
  522. func (d *Dir) _purgeVirtual() {
  523. canHaveEmptyDirectories := d.f.Features().CanHaveEmptyDirectories
  524. for name, virtualState := range d.virtual {
  525. switch virtualState {
  526. case vAddDir:
  527. if canHaveEmptyDirectories {
  528. // if remote can have empty directories then a
  529. // new dir will be read in the listing
  530. d._deleteVirtual(name)
  531. //} else {
  532. // leave the empty directory marker
  533. }
  534. case vAddFile:
  535. // Delete all virtual file adds that have finished uploading
  536. node, ok := d.items[name]
  537. if !ok {
  538. // if the object has disappeared somehow then remove the virtual
  539. d._deleteVirtual(name)
  540. continue
  541. }
  542. f, ok := node.(*File)
  543. if !ok {
  544. // if the object isn't a file then remove the virtual as it is wrong
  545. d._deleteVirtual(name)
  546. continue
  547. }
  548. if f.writingInProgress() {
  549. // if writing in progress then leave virtual
  550. continue
  551. }
  552. if d.vfs.Opt.CacheMode >= vfscommon.CacheModeMinimal && d.vfs.cache.InUse(f.Path()) {
  553. // if object in use or dirty then leave virtual
  554. continue
  555. }
  556. d._deleteVirtual(name)
  557. default:
  558. d._deleteVirtual(name)
  559. }
  560. }
  561. }
  562. // Manage the virtuals in a listing
  563. //
  564. // This keeps a record of the names listed in this directory so far
  565. type manageVirtuals map[string]struct{}
  566. // Create a new manageVirtuals and purge the d.virtuals of any entries which can
  567. // be removed.
  568. //
  569. // must be called with the Dir lock held
  570. func (d *Dir) _newManageVirtuals() manageVirtuals {
  571. tv := make(manageVirtuals)
  572. d._purgeVirtual()
  573. return tv
  574. }
  575. // This should be called for every entry added to the directory
  576. //
  577. // It returns true if this entry should be skipped.
  578. //
  579. // must be called with the Dir lock held
  580. func (mv manageVirtuals) add(d *Dir, name string) bool {
  581. // Keep a record of all names listed
  582. mv[name] = struct{}{}
  583. // Remove virtuals if possible
  584. switch d.virtual[name] {
  585. case vAddFile, vAddDir:
  586. // item was added to the dir but since it is found in a
  587. // listing is no longer virtual
  588. d._deleteVirtual(name)
  589. case vDel:
  590. // item is deleted from the dir so skip it
  591. return true
  592. case vOK:
  593. }
  594. return false
  595. }
  596. // This should be called after the directory entry is read to update d.items
  597. // with virtual entries
  598. //
  599. // must be called with the Dir lock held
  600. func (mv manageVirtuals) end(d *Dir) {
  601. // delete unused d.items
  602. for name := range d.items {
  603. if _, ok := mv[name]; !ok {
  604. // name was previously in the directory but wasn't found
  605. // in the current listing
  606. switch d.virtual[name] {
  607. case vAddFile, vAddDir:
  608. // virtually added so leave virtual item
  609. default:
  610. // otherwise delete it
  611. delete(d.items, name)
  612. }
  613. }
  614. }
  615. // delete unused d.virtual~s
  616. for name, virtualState := range d.virtual {
  617. if _, ok := mv[name]; !ok {
  618. // name exists as a virtual but isn't in the current
  619. // listing so if it is a virtual delete we can remove it
  620. // as it is no longer needed.
  621. if virtualState == vDel {
  622. d._deleteVirtual(name)
  623. }
  624. }
  625. }
  626. }
  627. // update d.items and if dirTree is not nil update each dir in the DirTree below this one and
  628. // set the last read time - must be called with the lock held
  629. func (d *Dir) _readDirFromEntries(entries fs.DirEntries, dirTree dirtree.DirTree, when time.Time) error {
  630. var err error
  631. mv := d._newManageVirtuals()
  632. for _, entry := range entries {
  633. name := path.Base(entry.Remote())
  634. if name == "." || name == ".." {
  635. continue
  636. }
  637. node := d.items[name]
  638. if mv.add(d, name) {
  639. continue
  640. }
  641. switch item := entry.(type) {
  642. case fs.Object:
  643. obj := item
  644. // Reuse old file value if it exists
  645. if file, ok := node.(*File); node != nil && ok {
  646. file.setObjectNoUpdate(obj)
  647. } else {
  648. node = newFile(d, d.path, obj, name)
  649. }
  650. case fs.Directory:
  651. // Reuse old dir value if it exists
  652. if node == nil || !node.IsDir() {
  653. node = newDir(d.vfs, d.f, d, item)
  654. }
  655. dir := node.(*Dir)
  656. dir.mu.Lock()
  657. dir.modTime = item.ModTime(context.TODO())
  658. if dirTree != nil {
  659. err = dir._readDirFromDirTree(dirTree, when)
  660. if err != nil {
  661. dir.read = time.Time{}
  662. } else {
  663. dir.read = when
  664. dir.cleanupTimer.Reset(d.vfs.Opt.DirCacheTime * 2)
  665. }
  666. }
  667. dir.mu.Unlock()
  668. if err != nil {
  669. return err
  670. }
  671. default:
  672. err = fmt.Errorf("unknown type %T", item)
  673. fs.Errorf(d, "readDir error: %v", err)
  674. return err
  675. }
  676. d.items[name] = node
  677. }
  678. mv.end(d)
  679. return nil
  680. }
  681. // readDirTree forces a refresh of the complete directory tree
  682. func (d *Dir) readDirTree() error {
  683. d.mu.RLock()
  684. f, path := d.f, d.path
  685. d.mu.RUnlock()
  686. when := time.Now()
  687. fs.Debugf(path, "Reading directory tree")
  688. dt, err := walk.NewDirTree(context.TODO(), f, path, false, -1)
  689. if err != nil {
  690. return err
  691. }
  692. d.mu.Lock()
  693. defer d.mu.Unlock()
  694. d.read = time.Time{}
  695. err = d._readDirFromDirTree(dt, when)
  696. if err != nil {
  697. return err
  698. }
  699. fs.Debugf(d.path, "Reading directory tree done in %s", time.Since(when))
  700. d.read = when
  701. d.cleanupTimer.Reset(d.vfs.Opt.DirCacheTime * 2)
  702. return nil
  703. }
  704. // readDir forces a refresh of the directory
  705. func (d *Dir) readDir() error {
  706. d.mu.Lock()
  707. defer d.mu.Unlock()
  708. d.read = time.Time{}
  709. return d._readDir()
  710. }
  711. // stat a single item in the directory
  712. //
  713. // returns ENOENT if not found.
  714. // returns a custom error if directory on a case-insensitive file system
  715. // contains files with names that differ only by case.
  716. func (d *Dir) stat(leaf string) (Node, error) {
  717. d.mu.Lock()
  718. defer d.mu.Unlock()
  719. err := d._readDir()
  720. if err != nil {
  721. return nil, err
  722. }
  723. item, ok := d.items[leaf]
  724. ci := fs.GetConfig(context.TODO())
  725. normUnicode := !ci.NoUnicodeNormalization
  726. normCase := ci.IgnoreCaseSync || d.vfs.Opt.CaseInsensitive
  727. if !ok && (normUnicode || normCase) {
  728. leafNormalized := operations.ToNormal(leaf, normUnicode, normCase) // this handles both case and unicode normalization
  729. for name, node := range d.items {
  730. if operations.ToNormal(name, normUnicode, normCase) == leafNormalized {
  731. if ok {
  732. // duplicate normalized match is an error
  733. return nil, fmt.Errorf("duplicate filename %q detected with case/unicode normalization settings", leaf)
  734. }
  735. // found a normalized match
  736. ok = true
  737. item = node
  738. }
  739. }
  740. }
  741. if !ok {
  742. return nil, ENOENT
  743. }
  744. return item, nil
  745. }
  746. // Check to see if a directory is empty
  747. func (d *Dir) isEmpty() (bool, error) {
  748. d.mu.Lock()
  749. defer d.mu.Unlock()
  750. err := d._readDir()
  751. if err != nil {
  752. return false, err
  753. }
  754. return len(d.items) == 0, nil
  755. }
  756. // ModTime returns the modification time of the directory
  757. func (d *Dir) ModTime() time.Time {
  758. d.modTimeMu.Lock()
  759. defer d.modTimeMu.Unlock()
  760. // fs.Debugf(d.path, "Dir.ModTime %v", d.modTime)
  761. return d.modTime
  762. }
  763. // Size of the directory
  764. func (d *Dir) Size() int64 {
  765. return 0
  766. }
  767. // SetModTime sets the modTime for this dir
  768. func (d *Dir) SetModTime(modTime time.Time) error {
  769. if d.vfs.Opt.ReadOnly {
  770. return EROFS
  771. }
  772. d.modTimeMu.Lock()
  773. d.modTime = modTime
  774. d.modTimeMu.Unlock()
  775. return nil
  776. }
  777. func (d *Dir) cachedDir(relativePath string) (dir *Dir) {
  778. dir, _ = d.cachedNode(relativePath).(*Dir)
  779. return
  780. }
  781. func (d *Dir) cachedNode(relativePath string) Node {
  782. segments := strings.Split(strings.Trim(relativePath, "/"), "/")
  783. var node Node = d
  784. for _, s := range segments {
  785. if s == "" {
  786. continue
  787. }
  788. if dir, ok := node.(*Dir); ok {
  789. dir.mu.Lock()
  790. node = dir.items[s]
  791. dir.mu.Unlock()
  792. if node != nil {
  793. continue
  794. }
  795. }
  796. return nil
  797. }
  798. return node
  799. }
  800. // Stat looks up a specific entry in the receiver.
  801. //
  802. // Stat should return a Node corresponding to the entry. If the
  803. // name does not exist in the directory, Stat should return ENOENT.
  804. //
  805. // Stat need not to handle the names "." and "..".
  806. func (d *Dir) Stat(name string) (node Node, err error) {
  807. // fs.Debugf(path, "Dir.Stat")
  808. node, err = d.stat(name)
  809. if err != nil {
  810. if err != ENOENT {
  811. fs.Errorf(d, "Dir.Stat error: %v", err)
  812. }
  813. return nil, err
  814. }
  815. // fs.Debugf(path, "Dir.Stat OK")
  816. return node, nil
  817. }
  818. // ReadDirAll reads the contents of the directory sorted
  819. func (d *Dir) ReadDirAll() (items Nodes, err error) {
  820. // fs.Debugf(d.path, "Dir.ReadDirAll")
  821. d.mu.Lock()
  822. err = d._readDir()
  823. if err != nil {
  824. fs.Debugf(d.path, "Dir.ReadDirAll error: %v", err)
  825. d.mu.Unlock()
  826. return nil, err
  827. }
  828. for _, item := range d.items {
  829. items = append(items, item)
  830. }
  831. d.mu.Unlock()
  832. sort.Sort(items)
  833. // fs.Debugf(d.path, "Dir.ReadDirAll OK with %d entries", len(items))
  834. return items, nil
  835. }
  836. // accessModeMask masks off the read modes from the flags
  837. const accessModeMask = (os.O_RDONLY | os.O_WRONLY | os.O_RDWR)
  838. // Open the directory according to the flags provided
  839. func (d *Dir) Open(flags int) (fd Handle, err error) {
  840. rdwrMode := flags & accessModeMask
  841. if rdwrMode != os.O_RDONLY {
  842. fs.Errorf(d, "Can only open directories read only")
  843. return nil, EPERM
  844. }
  845. return newDirHandle(d), nil
  846. }
  847. // Create makes a new file node
  848. func (d *Dir) Create(name string, flags int) (*File, error) {
  849. // fs.Debugf(path, "Dir.Create")
  850. // Return existing node if one exists
  851. node, err := d.stat(name)
  852. switch err {
  853. case ENOENT:
  854. // not found, carry on
  855. case nil:
  856. // found so check what it is
  857. if node.IsFile() {
  858. return node.(*File), err
  859. }
  860. return nil, EEXIST // EISDIR would be better but we don't have that
  861. default:
  862. // a different error - report
  863. fs.Errorf(d, "Dir.Create stat failed: %v", err)
  864. return nil, err
  865. }
  866. // node doesn't exist so create it
  867. if d.vfs.Opt.ReadOnly {
  868. return nil, EROFS
  869. }
  870. if err = d.SetModTime(time.Now()); err != nil {
  871. fs.Errorf(d, "Dir.Create failed to set modtime on parent dir: %v", err)
  872. return nil, err
  873. }
  874. // This gets added to the directory when the file is opened for write
  875. return newFile(d, d.Path(), nil, name), nil
  876. }
  877. // Mkdir creates a new directory
  878. func (d *Dir) Mkdir(name string) (*Dir, error) {
  879. if d.vfs.Opt.ReadOnly {
  880. return nil, EROFS
  881. }
  882. path := path.Join(d.path, name)
  883. node, err := d.stat(name)
  884. switch err {
  885. case ENOENT:
  886. // not found, carry on
  887. case nil:
  888. // found so check what it is
  889. if node.IsDir() {
  890. return node.(*Dir), err
  891. }
  892. return nil, EEXIST
  893. default:
  894. // a different error - report
  895. fs.Errorf(d, "Dir.Mkdir failed to read directory: %v", err)
  896. return nil, err
  897. }
  898. // fs.Debugf(path, "Dir.Mkdir")
  899. err = d.f.Mkdir(context.TODO(), path)
  900. if err != nil {
  901. fs.Errorf(d, "Dir.Mkdir failed to create directory: %v", err)
  902. return nil, err
  903. }
  904. fsDir := fs.NewDir(path, time.Now())
  905. dir := newDir(d.vfs, d.f, d, fsDir)
  906. d.addObject(dir)
  907. if err = d.SetModTime(time.Now()); err != nil {
  908. fs.Errorf(d, "Dir.Mkdir failed to set modtime on parent dir: %v", err)
  909. return nil, err
  910. }
  911. // fs.Debugf(path, "Dir.Mkdir OK")
  912. return dir, nil
  913. }
  914. // Remove the directory
  915. func (d *Dir) Remove() error {
  916. if d.vfs.Opt.ReadOnly {
  917. return EROFS
  918. }
  919. // Check directory is empty first
  920. empty, err := d.isEmpty()
  921. if err != nil {
  922. fs.Errorf(d, "Dir.Remove dir error: %v", err)
  923. return err
  924. }
  925. if !empty {
  926. fs.Errorf(d, "Dir.Remove not empty")
  927. return ENOTEMPTY
  928. }
  929. // remove directory
  930. err = d.f.Rmdir(context.TODO(), d.path)
  931. if err != nil {
  932. fs.Errorf(d, "Dir.Remove failed to remove directory: %v", err)
  933. return err
  934. }
  935. // Remove the item from the parent directory listing
  936. if d.parent != nil {
  937. d.parent.delObject(d.Name())
  938. }
  939. return nil
  940. }
  941. // RemoveAll removes the directory and any contents recursively
  942. func (d *Dir) RemoveAll() error {
  943. if d.vfs.Opt.ReadOnly {
  944. return EROFS
  945. }
  946. // Remove contents of the directory
  947. nodes, err := d.ReadDirAll()
  948. if err != nil {
  949. fs.Errorf(d, "Dir.RemoveAll failed to read directory: %v", err)
  950. return err
  951. }
  952. for _, node := range nodes {
  953. err = node.RemoveAll()
  954. if err != nil {
  955. fs.Errorf(node.Path(), "Dir.RemoveAll failed to remove: %v", err)
  956. return err
  957. }
  958. }
  959. return d.Remove()
  960. }
  961. // DirEntry returns the underlying fs.DirEntry
  962. func (d *Dir) DirEntry() (entry fs.DirEntry) {
  963. return d.entry
  964. }
  965. // RemoveName removes the entry with the given name from the receiver,
  966. // which must be a directory. The entry to be removed may correspond
  967. // to a file (unlink) or to a directory (rmdir).
  968. func (d *Dir) RemoveName(name string) error {
  969. if d.vfs.Opt.ReadOnly {
  970. return EROFS
  971. }
  972. // fs.Debugf(path, "Dir.Remove")
  973. node, err := d.stat(name)
  974. if err != nil {
  975. fs.Errorf(d, "Dir.Remove error: %v", err)
  976. return err
  977. }
  978. if err = d.SetModTime(time.Now()); err != nil {
  979. fs.Errorf(d, "Dir.Remove failed to set modtime on parent dir: %v", err)
  980. return err
  981. }
  982. return node.Remove()
  983. }
  984. // Rename the file
  985. func (d *Dir) Rename(oldName, newName string, destDir *Dir) error {
  986. // fs.Debugf(d, "BEFORE\n%s", d.dump())
  987. if d.vfs.Opt.ReadOnly {
  988. return EROFS
  989. }
  990. oldPath := path.Join(d.path, oldName)
  991. newPath := path.Join(destDir.path, newName)
  992. // fs.Debugf(oldPath, "Dir.Rename to %q", newPath)
  993. oldNode, err := d.stat(oldName)
  994. if err != nil {
  995. fs.Errorf(oldPath, "Dir.Rename error: %v", err)
  996. return err
  997. }
  998. switch x := oldNode.DirEntry().(type) {
  999. case nil:
  1000. if oldFile, ok := oldNode.(*File); ok {
  1001. if err = oldFile.rename(context.TODO(), destDir, newName); err != nil {
  1002. fs.Errorf(oldPath, "Dir.Rename error: %v", err)
  1003. return err
  1004. }
  1005. } else {
  1006. fs.Errorf(oldPath, "Dir.Rename can't rename open file that is not a vfs.File")
  1007. return EPERM
  1008. }
  1009. case fs.Object:
  1010. if oldFile, ok := oldNode.(*File); ok {
  1011. if err = oldFile.rename(context.TODO(), destDir, newName); err != nil {
  1012. fs.Errorf(oldPath, "Dir.Rename error: %v", err)
  1013. return err
  1014. }
  1015. } else {
  1016. err := fmt.Errorf("Fs %q can't rename file that is not a vfs.File", d.f)
  1017. fs.Errorf(oldPath, "Dir.Rename error: %v", err)
  1018. return err
  1019. }
  1020. case fs.Directory:
  1021. features := d.f.Features()
  1022. if features.DirMove == nil && features.Move == nil && features.Copy == nil {
  1023. err := fmt.Errorf("Fs %q can't rename directories (no DirMove, Move or Copy)", d.f)
  1024. fs.Errorf(oldPath, "Dir.Rename error: %v", err)
  1025. return err
  1026. }
  1027. srcRemote := x.Remote()
  1028. dstRemote := newPath
  1029. err = operations.DirMove(context.TODO(), d.f, srcRemote, dstRemote)
  1030. if err != nil {
  1031. fs.Errorf(oldPath, "Dir.Rename error: %v", err)
  1032. return err
  1033. }
  1034. newDir := fs.NewDirCopy(context.TODO(), x).SetRemote(newPath)
  1035. // Update the node with the new details
  1036. if oldNode != nil {
  1037. if oldDir, ok := oldNode.(*Dir); ok {
  1038. fs.Debugf(x, "Updating dir with %v %p", newDir, oldDir)
  1039. oldDir.rename(destDir, newDir)
  1040. }
  1041. }
  1042. default:
  1043. err = fmt.Errorf("unknown type %T", oldNode)
  1044. fs.Errorf(d.path, "Dir.Rename error: %v", err)
  1045. return err
  1046. }
  1047. // Show moved - delete from old dir and add to new
  1048. d.delObject(oldName)
  1049. destDir.addObject(oldNode)
  1050. if err = d.SetModTime(time.Now()); err != nil {
  1051. fs.Errorf(d, "Dir.Rename failed to set modtime on parent dir: %v", err)
  1052. return err
  1053. }
  1054. // fs.Debugf(newPath, "Dir.Rename renamed from %q", oldPath)
  1055. // fs.Debugf(d, "AFTER\n%s", d.dump())
  1056. return nil
  1057. }
  1058. // Sync the directory
  1059. //
  1060. // Note that we don't do anything except return OK
  1061. func (d *Dir) Sync() error {
  1062. return nil
  1063. }
  1064. // VFS returns the instance of the VFS
  1065. func (d *Dir) VFS() *VFS {
  1066. // No locking required
  1067. return d.vfs
  1068. }
  1069. // Fs returns the Fs that the Dir is on
  1070. func (d *Dir) Fs() fs.Fs {
  1071. // No locking required
  1072. return d.f
  1073. }
  1074. // Truncate changes the size of the named file.
  1075. func (d *Dir) Truncate(size int64) error {
  1076. return ENOSYS
  1077. }