file.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833
  1. package vfs
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "os"
  7. "path"
  8. "sync"
  9. "sync/atomic"
  10. "time"
  11. "github.com/rclone/rclone/fs"
  12. "github.com/rclone/rclone/fs/log"
  13. "github.com/rclone/rclone/fs/operations"
  14. "github.com/rclone/rclone/vfs/vfscommon"
  15. )
  16. // The File object is tightly coupled to the Dir object. Since they
  17. // both have locks there is plenty of potential for deadlocks. In
  18. // order to mitigate this, we use the following conventions
  19. //
  20. // File may **only** call these methods from Dir with the File lock
  21. // held.
  22. //
  23. // Dir.Fs
  24. // Dir.VFS
  25. //
  26. // (As these are read only and do not need to take the Dir mutex.)
  27. //
  28. // File may **not** call any other Dir methods with the File lock
  29. // held. This preserves total lock ordering and makes File subordinate
  30. // to Dir as far as locking is concerned, preventing deadlocks.
  31. //
  32. // File may **not** read any members of Dir directly.
  33. // File represents a file
  34. type File struct {
  35. inode uint64 // inode number - read only
  36. size atomic.Int64 // size of file
  37. muRW sync.Mutex // synchronize RWFileHandle.openPending(), RWFileHandle.close() and File.Remove
  38. mu sync.RWMutex // protects the following
  39. d *Dir // parent directory
  40. dPath string // path of parent directory. NB dir rename means all Files are flushed
  41. o fs.Object // NB o may be nil if file is being written
  42. leaf string // leaf name of the object
  43. writers []Handle // writers for this file
  44. virtualModTime *time.Time // modtime for backends with Precision == fs.ModTimeNotSupported
  45. pendingModTime time.Time // will be applied once o becomes available, i.e. after file was written
  46. pendingRenameFun func(ctx context.Context) error // will be run/renamed after all writers close
  47. sys atomic.Value // user defined info to be attached here
  48. nwriters atomic.Int32 // len(writers)
  49. appendMode bool // file was opened with O_APPEND
  50. }
  51. // newFile creates a new File
  52. //
  53. // o may be nil
  54. func newFile(d *Dir, dPath string, o fs.Object, leaf string) *File {
  55. f := &File{
  56. d: d,
  57. dPath: dPath,
  58. o: o,
  59. leaf: leaf,
  60. inode: newInode(),
  61. }
  62. if o != nil {
  63. f.size.Store(o.Size())
  64. }
  65. return f
  66. }
  67. // String converts it to printable
  68. func (f *File) String() string {
  69. if f == nil {
  70. return "<nil *File>"
  71. }
  72. return f.Path()
  73. }
  74. // IsFile returns true for File - satisfies Node interface
  75. func (f *File) IsFile() bool {
  76. return true
  77. }
  78. // IsDir returns false for File - satisfies Node interface
  79. func (f *File) IsDir() bool {
  80. return false
  81. }
  82. // Mode bits of the file or directory - satisfies Node interface
  83. func (f *File) Mode() (mode os.FileMode) {
  84. f.mu.RLock()
  85. defer f.mu.RUnlock()
  86. mode = f.d.vfs.Opt.FilePerms
  87. if f.appendMode {
  88. mode |= os.ModeAppend
  89. }
  90. return mode
  91. }
  92. // Name (base) of the directory - satisfies Node interface
  93. func (f *File) Name() (name string) {
  94. f.mu.RLock()
  95. defer f.mu.RUnlock()
  96. return f.leaf
  97. }
  98. // _path returns the full path of the file
  99. // use when lock is held
  100. func (f *File) _path() string {
  101. return path.Join(f.dPath, f.leaf)
  102. }
  103. // Path returns the full path of the file
  104. func (f *File) Path() string {
  105. f.mu.RLock()
  106. dPath, leaf := f.dPath, f.leaf
  107. f.mu.RUnlock()
  108. return path.Join(dPath, leaf)
  109. }
  110. // Sys returns underlying data source (can be nil) - satisfies Node interface
  111. func (f *File) Sys() interface{} {
  112. return f.sys.Load()
  113. }
  114. // SetSys sets the underlying data source (can be nil) - satisfies Node interface
  115. func (f *File) SetSys(x interface{}) {
  116. f.sys.Store(x)
  117. }
  118. // Inode returns the inode number - satisfies Node interface
  119. func (f *File) Inode() uint64 {
  120. return f.inode
  121. }
  122. // Node returns the Node associated with this - satisfies Noder interface
  123. func (f *File) Node() Node {
  124. return f
  125. }
  126. // renameDir - call when parent directory has been renamed
  127. func (f *File) renameDir(dPath string) {
  128. f.mu.RLock()
  129. f.dPath = dPath
  130. f.mu.RUnlock()
  131. }
  132. // applyPendingRename runs a previously set rename operation if there are no
  133. // more remaining writers. Call without lock held.
  134. func (f *File) applyPendingRename() {
  135. f.mu.RLock()
  136. fun := f.pendingRenameFun
  137. writing := f._writingInProgress()
  138. f.mu.RUnlock()
  139. if fun == nil || writing {
  140. return
  141. }
  142. fs.Debugf(f.Path(), "Running delayed rename now")
  143. if err := fun(context.TODO()); err != nil {
  144. fs.Errorf(f.Path(), "delayed File.Rename error: %v", err)
  145. }
  146. }
  147. // rename attempts to immediately rename a file if there are no open writers.
  148. // Otherwise it will queue the rename operation on the remote until no writers
  149. // remain.
  150. func (f *File) rename(ctx context.Context, destDir *Dir, newName string) error {
  151. f.mu.RLock()
  152. d := f.d
  153. oldPendingRenameFun := f.pendingRenameFun
  154. f.mu.RUnlock()
  155. if features := d.Fs().Features(); features.Move == nil && features.Copy == nil {
  156. err := fmt.Errorf("Fs %q can't rename files (no server-side Move or Copy)", d.Fs())
  157. fs.Errorf(f.Path(), "Dir.Rename error: %v", err)
  158. return err
  159. }
  160. oldPath := f.Path()
  161. // File.mu is unlocked here to call Dir.Path()
  162. newPath := path.Join(destDir.Path(), newName)
  163. renameCall := func(ctx context.Context) (err error) {
  164. // chain rename calls if any
  165. if oldPendingRenameFun != nil {
  166. err := oldPendingRenameFun(ctx)
  167. if err != nil {
  168. return err
  169. }
  170. }
  171. f.mu.RLock()
  172. o := f.o
  173. d := f.d
  174. f.mu.RUnlock()
  175. var newObject fs.Object
  176. // if o is nil then are writing the file so no need to rename the object
  177. if o != nil {
  178. if o.Remote() == newPath {
  179. return nil // no need to rename
  180. }
  181. // do the move of the remote object
  182. dstOverwritten, _ := d.Fs().NewObject(ctx, newPath)
  183. newObject, err = operations.Move(ctx, d.Fs(), dstOverwritten, newPath, o)
  184. if err != nil {
  185. fs.Errorf(f.Path(), "File.Rename error: %v", err)
  186. return err
  187. }
  188. // newObject can be nil here for example if --dry-run
  189. if newObject == nil {
  190. err = errors.New("rename failed: nil object returned")
  191. fs.Errorf(f.Path(), "File.Rename %v", err)
  192. return err
  193. }
  194. }
  195. // Rename in the cache
  196. if d.vfs.cache != nil && d.vfs.cache.Exists(oldPath) {
  197. if err := d.vfs.cache.Rename(oldPath, newPath, newObject); err != nil {
  198. fs.Infof(f.Path(), "File.Rename failed in Cache: %v", err)
  199. }
  200. }
  201. // Update the node with the new details
  202. fs.Debugf(f.Path(), "Updating file with %v %p", newObject, f)
  203. // f.rename(destDir, newObject)
  204. f.mu.Lock()
  205. if newObject != nil {
  206. f.o = newObject
  207. }
  208. f.pendingRenameFun = nil
  209. f.mu.Unlock()
  210. return nil
  211. }
  212. // rename the file object
  213. dPath := destDir.Path()
  214. f.mu.Lock()
  215. f.d = destDir
  216. f.dPath = dPath
  217. f.leaf = newName
  218. writing := f._writingInProgress()
  219. f.mu.Unlock()
  220. // Delay the rename if not using RW caching. For the minimal case we
  221. // need to look in the cache to see if caching is in use.
  222. CacheMode := d.vfs.Opt.CacheMode
  223. if writing &&
  224. (CacheMode < vfscommon.CacheModeMinimal ||
  225. (CacheMode == vfscommon.CacheModeMinimal && !destDir.vfs.cache.Exists(oldPath))) {
  226. fs.Debugf(oldPath, "File is currently open, delaying rename %p", f)
  227. f.mu.Lock()
  228. f.pendingRenameFun = renameCall
  229. f.mu.Unlock()
  230. return nil
  231. }
  232. return renameCall(ctx)
  233. }
  234. // addWriter adds a write handle to the file
  235. func (f *File) addWriter(h Handle) {
  236. f.mu.Lock()
  237. f.writers = append(f.writers, h)
  238. f.nwriters.Add(1)
  239. f.mu.Unlock()
  240. }
  241. // delWriter removes a write handle from the file
  242. func (f *File) delWriter(h Handle) {
  243. f.mu.Lock()
  244. defer f.applyPendingRename()
  245. defer f.mu.Unlock()
  246. var found = -1
  247. for i := range f.writers {
  248. if f.writers[i] == h {
  249. found = i
  250. break
  251. }
  252. }
  253. if found >= 0 {
  254. f.writers = append(f.writers[:found], f.writers[found+1:]...)
  255. f.nwriters.Add(-1)
  256. } else {
  257. fs.Debugf(f._path(), "File.delWriter couldn't find handle")
  258. }
  259. }
  260. // activeWriters returns the number of writers on the file
  261. //
  262. // Note that we don't take the mutex here. If we do then we can get a
  263. // deadlock.
  264. func (f *File) activeWriters() int {
  265. return int(f.nwriters.Load())
  266. }
  267. // _roundModTime rounds the time passed in to the Precision of the
  268. // underlying Fs
  269. //
  270. // It should be called with the lock held
  271. func (f *File) _roundModTime(modTime time.Time) time.Time {
  272. precision := f.d.f.Precision()
  273. if precision == fs.ModTimeNotSupported {
  274. return modTime
  275. }
  276. return modTime.Truncate(precision)
  277. }
  278. // ModTime returns the modified time of the file
  279. //
  280. // if NoModTime is set then it returns the mod time of the directory
  281. func (f *File) ModTime() (modTime time.Time) {
  282. f.mu.RLock()
  283. d, o, pendingModTime, virtualModTime := f.d, f.o, f.pendingModTime, f.virtualModTime
  284. f.mu.RUnlock()
  285. // Set the virtual modtime up for backends which don't support setting modtime
  286. //
  287. // Note that we only cache modtime values that we have returned to the OS
  288. // if we haven't returned a value to the OS then we can change it
  289. defer func() {
  290. if f.d.f.Precision() == fs.ModTimeNotSupported && (virtualModTime == nil || !virtualModTime.Equal(modTime)) {
  291. f.virtualModTime = &modTime
  292. fs.Debugf(f._path(), "Set virtual modtime to %v", f.virtualModTime)
  293. }
  294. }()
  295. if d.vfs.Opt.NoModTime {
  296. return d.ModTime()
  297. }
  298. // Read the modtime from a dirty item if it exists
  299. if f.d.vfs.Opt.CacheMode >= vfscommon.CacheModeMinimal {
  300. if item := f.d.vfs.cache.DirtyItem(f._path()); item != nil {
  301. modTime, err := item.GetModTime()
  302. if err != nil {
  303. fs.Errorf(f._path(), "ModTime: Item GetModTime failed: %v", err)
  304. } else {
  305. return f._roundModTime(modTime)
  306. }
  307. }
  308. }
  309. if !pendingModTime.IsZero() {
  310. return f._roundModTime(pendingModTime)
  311. }
  312. if virtualModTime != nil && !virtualModTime.IsZero() {
  313. fs.Debugf(f._path(), "Returning virtual modtime %v", f.virtualModTime)
  314. return f._roundModTime(*virtualModTime)
  315. }
  316. if o == nil {
  317. return time.Now()
  318. }
  319. return o.ModTime(context.TODO())
  320. }
  321. // nonNegative returns 0 if i is -ve, i otherwise
  322. func nonNegative(i int64) int64 {
  323. if i >= 0 {
  324. return i
  325. }
  326. return 0
  327. }
  328. // Size of the file
  329. func (f *File) Size() int64 {
  330. f.mu.RLock()
  331. defer f.mu.RUnlock()
  332. // Read the size from a dirty item if it exists
  333. if f.d.vfs.Opt.CacheMode >= vfscommon.CacheModeMinimal {
  334. if item := f.d.vfs.cache.DirtyItem(f._path()); item != nil {
  335. size, err := item.GetSize()
  336. if err != nil {
  337. fs.Errorf(f._path(), "Size: Item GetSize failed: %v", err)
  338. } else {
  339. return size
  340. }
  341. }
  342. }
  343. // if o is nil it isn't valid yet or there are writers, so return the size so far
  344. if f._writingInProgress() {
  345. return f.size.Load()
  346. }
  347. return nonNegative(f.o.Size())
  348. }
  349. // SetModTime sets the modtime for the file
  350. //
  351. // if NoModTime is set then it does nothing
  352. func (f *File) SetModTime(modTime time.Time) error {
  353. f.mu.Lock()
  354. defer f.mu.Unlock()
  355. if f.d.vfs.Opt.NoModTime {
  356. return nil
  357. }
  358. if f.d.vfs.Opt.ReadOnly {
  359. return EROFS
  360. }
  361. f.pendingModTime = modTime
  362. // set the time of the file in the cache
  363. if f.d.vfs.cache != nil && f.d.vfs.cache.Exists(f._path()) {
  364. f.d.vfs.cache.SetModTime(f._path(), f.pendingModTime)
  365. }
  366. // Only update the ModTime when there are no writers, setObject will do it
  367. if !f._writingInProgress() {
  368. return f._applyPendingModTime()
  369. }
  370. // queue up for later, hoping f.o becomes available
  371. return nil
  372. }
  373. // Apply a pending mod time
  374. // Call with the mutex held
  375. func (f *File) _applyPendingModTime() error {
  376. if f.pendingModTime.IsZero() {
  377. return nil
  378. }
  379. defer func() { f.pendingModTime = time.Time{} }()
  380. if f.o == nil {
  381. return errors.New("cannot apply ModTime, file object is not available")
  382. }
  383. dt := f.pendingModTime.Sub(f.o.ModTime(context.Background()))
  384. modifyWindow := f.o.Fs().Precision()
  385. if dt < modifyWindow && dt > -modifyWindow {
  386. fs.Debugf(f.o, "Not setting pending mod time %v as it is already set", f.pendingModTime)
  387. return nil
  388. }
  389. // set the time of the object
  390. err := f.o.SetModTime(context.TODO(), f.pendingModTime)
  391. switch err {
  392. case nil:
  393. fs.Debugf(f.o, "Applied pending mod time %v OK", f.pendingModTime)
  394. case fs.ErrorCantSetModTime, fs.ErrorCantSetModTimeWithoutDelete:
  395. // do nothing, in order to not break "touch somefile" if it exists already
  396. default:
  397. fs.Errorf(f.o, "Failed to apply pending mod time %v: %v", f.pendingModTime, err)
  398. return err
  399. }
  400. return nil
  401. }
  402. // Apply a pending mod time
  403. func (f *File) applyPendingModTime() error {
  404. f.mu.Lock()
  405. defer f.mu.Unlock()
  406. return f._applyPendingModTime()
  407. }
  408. // _writingInProgress returns true of there are any open writers
  409. // Call with read lock held
  410. func (f *File) _writingInProgress() bool {
  411. return f.o == nil || len(f.writers) != 0
  412. }
  413. // writingInProgress returns true of there are any open writers
  414. func (f *File) writingInProgress() bool {
  415. f.mu.RLock()
  416. defer f.mu.RUnlock()
  417. return f.o == nil || len(f.writers) != 0
  418. }
  419. // Update the size while writing
  420. func (f *File) setSize(n int64) {
  421. f.size.Store(n)
  422. }
  423. // Update the object when written and add it to the directory
  424. func (f *File) setObject(o fs.Object) {
  425. f.mu.Lock()
  426. f.o = o
  427. _ = f._applyPendingModTime()
  428. d := f.d
  429. f.mu.Unlock()
  430. // Release File.mu before calling Dir method
  431. d.addObject(f)
  432. }
  433. // Update the object but don't update the directory cache - for use by
  434. // the directory cache
  435. func (f *File) setObjectNoUpdate(o fs.Object) {
  436. f.mu.Lock()
  437. f.o = o
  438. f.virtualModTime = nil
  439. fs.Debugf(f._path(), "Reset virtual modtime")
  440. f.mu.Unlock()
  441. }
  442. // Get the current fs.Object - may be nil
  443. func (f *File) getObject() fs.Object {
  444. f.mu.RLock()
  445. defer f.mu.RUnlock()
  446. return f.o
  447. }
  448. // exists returns whether the file exists already
  449. func (f *File) exists() bool {
  450. f.mu.RLock()
  451. defer f.mu.RUnlock()
  452. return f.o != nil
  453. }
  454. // Wait for f.o to become non nil for a short time returning it or an
  455. // error. Use when opening a read handle.
  456. //
  457. // Call without the mutex held
  458. func (f *File) waitForValidObject() (o fs.Object, err error) {
  459. for i := 0; i < 50; i++ {
  460. f.mu.RLock()
  461. o = f.o
  462. nwriters := len(f.writers)
  463. f.mu.RUnlock()
  464. if o != nil {
  465. return o, nil
  466. }
  467. if nwriters == 0 {
  468. return nil, errors.New("can't open file - writer failed")
  469. }
  470. time.Sleep(100 * time.Millisecond)
  471. }
  472. return nil, ENOENT
  473. }
  474. // openRead open the file for read
  475. func (f *File) openRead() (fh *ReadFileHandle, err error) {
  476. // if o is nil it isn't valid yet
  477. _, err = f.waitForValidObject()
  478. if err != nil {
  479. return nil, err
  480. }
  481. // fs.Debugf(f.Path(), "File.openRead")
  482. fh, err = newReadFileHandle(f)
  483. if err != nil {
  484. fs.Debugf(f.Path(), "File.openRead failed: %v", err)
  485. return nil, err
  486. }
  487. return fh, nil
  488. }
  489. // openWrite open the file for write
  490. func (f *File) openWrite(flags int) (fh *WriteFileHandle, err error) {
  491. f.mu.RLock()
  492. d := f.d
  493. f.mu.RUnlock()
  494. if d.vfs.Opt.ReadOnly {
  495. return nil, EROFS
  496. }
  497. // fs.Debugf(f.Path(), "File.openWrite")
  498. fh, err = newWriteFileHandle(d, f, f.Path(), flags)
  499. if err != nil {
  500. fs.Debugf(f.Path(), "File.openWrite failed: %v", err)
  501. return nil, err
  502. }
  503. return fh, nil
  504. }
  505. // openRW open the file for read and write using a temporary file
  506. //
  507. // It uses the open flags passed in.
  508. func (f *File) openRW(flags int) (fh *RWFileHandle, err error) {
  509. f.mu.RLock()
  510. d := f.d
  511. f.mu.RUnlock()
  512. // FIXME chunked
  513. if flags&accessModeMask != os.O_RDONLY && d.vfs.Opt.ReadOnly {
  514. return nil, EROFS
  515. }
  516. // fs.Debugf(f.Path(), "File.openRW")
  517. fh, err = newRWFileHandle(d, f, flags)
  518. if err != nil {
  519. fs.Debugf(f.Path(), "File.openRW failed: %v", err)
  520. return nil, err
  521. }
  522. return fh, nil
  523. }
  524. // Sync the file
  525. //
  526. // Note that we don't do anything except return OK
  527. func (f *File) Sync() error {
  528. return nil
  529. }
  530. // Remove the file
  531. func (f *File) Remove() (err error) {
  532. defer log.Trace(f.Path(), "")("err=%v", &err)
  533. f.mu.RLock()
  534. d := f.d
  535. f.mu.RUnlock()
  536. if d.vfs.Opt.ReadOnly {
  537. return EROFS
  538. }
  539. // Remove the object from the cache
  540. wasWriting := false
  541. if d.vfs.cache != nil && d.vfs.cache.Exists(f.Path()) {
  542. wasWriting = d.vfs.cache.Remove(f.Path())
  543. }
  544. f.muRW.Lock() // muRW must be locked before mu to avoid
  545. f.mu.Lock() // deadlock in RWFileHandle.openPending and .close
  546. if f.o != nil {
  547. err = f.o.Remove(context.TODO())
  548. }
  549. f.mu.Unlock()
  550. f.muRW.Unlock()
  551. if err != nil {
  552. if wasWriting {
  553. // Ignore error deleting file if was writing it as it may not be uploaded yet
  554. err = nil
  555. fs.Debugf(f._path(), "Ignoring File.Remove file error as uploading: %v", err)
  556. } else {
  557. fs.Debugf(f._path(), "File.Remove file error: %v", err)
  558. }
  559. }
  560. // Remove the item from the directory listing
  561. // called with File.mu released when there is no error removing the underlying file
  562. if err == nil {
  563. d.delObject(f.Name())
  564. }
  565. return err
  566. }
  567. // RemoveAll the file - same as remove for files
  568. func (f *File) RemoveAll() error {
  569. return f.Remove()
  570. }
  571. // DirEntry returns the underlying fs.DirEntry - may be nil
  572. func (f *File) DirEntry() (entry fs.DirEntry) {
  573. f.mu.RLock()
  574. defer f.mu.RUnlock()
  575. return f.o
  576. }
  577. // Dir returns the directory this file is in
  578. func (f *File) Dir() *Dir {
  579. f.mu.RLock()
  580. defer f.mu.RUnlock()
  581. return f.d
  582. }
  583. // VFS returns the instance of the VFS
  584. func (f *File) VFS() *VFS {
  585. f.mu.RLock()
  586. defer f.mu.RUnlock()
  587. return f.d.vfs
  588. }
  589. // Fs returns the underlying Fs for the file
  590. func (f *File) Fs() fs.Fs {
  591. f.mu.RLock()
  592. defer f.mu.RUnlock()
  593. return f.d.Fs()
  594. }
  595. // Open a file according to the flags provided
  596. //
  597. // O_RDONLY open the file read-only.
  598. // O_WRONLY open the file write-only.
  599. // O_RDWR open the file read-write.
  600. //
  601. // O_APPEND append data to the file when writing.
  602. // O_CREATE create a new file if none exists.
  603. // O_EXCL used with O_CREATE, file must not exist
  604. // O_SYNC open for synchronous I/O.
  605. // O_TRUNC if possible, truncate file when opened
  606. //
  607. // We ignore O_SYNC and O_EXCL
  608. func (f *File) Open(flags int) (fd Handle, err error) {
  609. defer log.Trace(f.Path(), "flags=%s", decodeOpenFlags(flags))("fd=%v, err=%v", &fd, &err)
  610. var (
  611. write bool // if set need write support
  612. read bool // if set need read support
  613. rdwrMode = flags & accessModeMask
  614. )
  615. // http://pubs.opengroup.org/onlinepubs/7908799/xsh/open.html
  616. // The result of using O_TRUNC with O_RDONLY is undefined.
  617. // Linux seems to truncate the file, but we prefer to return EINVAL
  618. if rdwrMode == os.O_RDONLY && flags&os.O_TRUNC != 0 {
  619. return nil, EINVAL
  620. }
  621. // Figure out the read/write intents
  622. switch {
  623. case rdwrMode == os.O_RDONLY:
  624. read = true
  625. case rdwrMode == os.O_WRONLY:
  626. write = true
  627. case rdwrMode == os.O_RDWR:
  628. read = true
  629. write = true
  630. default:
  631. fs.Debugf(f.Path(), "Can't figure out how to open with flags: 0x%X", flags)
  632. return nil, EPERM
  633. }
  634. // If append is set then set read to force openRW
  635. if flags&os.O_APPEND != 0 {
  636. read = true
  637. f.mu.Lock()
  638. f.appendMode = true
  639. f.mu.Unlock()
  640. }
  641. // If truncate is set then set write to force openRW
  642. if flags&os.O_TRUNC != 0 {
  643. write = true
  644. }
  645. // If create is set then set write to force openRW
  646. if flags&os.O_CREATE != 0 {
  647. write = true
  648. }
  649. // Open the correct sort of handle
  650. f.mu.RLock()
  651. d := f.d
  652. f.mu.RUnlock()
  653. CacheMode := d.vfs.Opt.CacheMode
  654. if CacheMode >= vfscommon.CacheModeMinimal && (d.vfs.cache.InUse(f.Path()) || d.vfs.cache.Exists(f.Path())) {
  655. fd, err = f.openRW(flags)
  656. } else if read && write {
  657. if CacheMode >= vfscommon.CacheModeMinimal {
  658. fd, err = f.openRW(flags)
  659. } else {
  660. // Open write only and hope the user doesn't
  661. // want to read. If they do they will get an
  662. // EPERM plus an Error log.
  663. fd, err = f.openWrite(flags)
  664. }
  665. } else if write {
  666. if CacheMode >= vfscommon.CacheModeWrites {
  667. fd, err = f.openRW(flags)
  668. } else {
  669. fd, err = f.openWrite(flags)
  670. }
  671. } else if read {
  672. if CacheMode >= vfscommon.CacheModeFull {
  673. fd, err = f.openRW(flags)
  674. } else {
  675. fd, err = f.openRead()
  676. }
  677. } else {
  678. fs.Debugf(f.Path(), "Can't figure out how to open with flags: 0x%X", flags)
  679. return nil, EPERM
  680. }
  681. // if creating a file, add the file to the directory
  682. if err == nil && flags&os.O_CREATE != 0 {
  683. // called without File.mu held
  684. d.addObject(f)
  685. }
  686. return fd, err
  687. }
  688. // Truncate changes the size of the named file.
  689. func (f *File) Truncate(size int64) (err error) {
  690. // make a copy of fh.writers with the lock held then unlock so
  691. // we can call other file methods.
  692. f.mu.Lock()
  693. writers := make([]Handle, len(f.writers))
  694. copy(writers, f.writers)
  695. f.mu.Unlock()
  696. // If have writers then call truncate for each writer
  697. if len(writers) != 0 {
  698. var openWriters = len(writers)
  699. fs.Debugf(f.Path(), "Truncating %d file handles", len(writers))
  700. for _, h := range writers {
  701. truncateErr := h.Truncate(size)
  702. if truncateErr == ECLOSED {
  703. // Ignore ECLOSED since file handle can get closed while this is running
  704. openWriters--
  705. } else if truncateErr != nil {
  706. err = truncateErr
  707. }
  708. }
  709. // If at least one open writer return here
  710. if openWriters > 0 {
  711. return err
  712. }
  713. }
  714. // if o is nil it isn't valid yet
  715. o, err := f.waitForValidObject()
  716. if err != nil {
  717. return err
  718. }
  719. // If no writers, and size is already correct then all done
  720. if o.Size() == size {
  721. return nil
  722. }
  723. fs.Debugf(f.Path(), "Truncating file")
  724. // Otherwise if no writers then truncate the file by opening
  725. // the file and truncating it.
  726. flags := os.O_WRONLY
  727. if size == 0 {
  728. flags |= os.O_TRUNC
  729. }
  730. fh, err := f.Open(flags)
  731. if err != nil {
  732. return err
  733. }
  734. defer fs.CheckClose(fh, &err)
  735. if size != 0 {
  736. return fh.Truncate(size)
  737. }
  738. return nil
  739. }