1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: Apache-2.0
12 // A deferrednode wraps an inode that's expensive to build. Initially,
13 // it responds to basic directory functions by proxying to the given
14 // placeholder. If a caller uses a read/write/lock operation,
15 // deferrednode calls the create() func to create the real inode, and
16 // proxies to the real inode from then on.
18 // In practice, this means a deferrednode's parent's directory listing
19 // can be generated using only the placeholder, instead of waiting for
21 type deferrednode struct {
28 func (dn *deferrednode) realinode() inode {
32 dn.wrapped = dn.create()
38 func (dn *deferrednode) currentinode() inode {
44 func (dn *deferrednode) Read(p []byte, pos filenodePtr) (int, filenodePtr, error) {
45 return dn.realinode().Read(p, pos)
48 func (dn *deferrednode) Write(p []byte, pos filenodePtr) (int, filenodePtr, error) {
49 return dn.realinode().Write(p, pos)
52 func (dn *deferrednode) Child(name string, replace func(inode) (inode, error)) (inode, error) {
53 return dn.realinode().Child(name, replace)
56 // Sync is a no-op if the real inode hasn't even been created yet.
57 func (dn *deferrednode) Sync() error {
62 } else if syncer, ok := dn.wrapped.(syncer); ok {
65 return ErrInvalidOperation
69 func (dn *deferrednode) Truncate(size int64) error { return dn.realinode().Truncate(size) }
70 func (dn *deferrednode) SetParent(p inode, name string) { dn.realinode().SetParent(p, name) }
71 func (dn *deferrednode) IsDir() bool { return dn.currentinode().IsDir() }
72 func (dn *deferrednode) Readdir() ([]os.FileInfo, error) { return dn.realinode().Readdir() }
73 func (dn *deferrednode) Size() int64 { return dn.currentinode().Size() }
74 func (dn *deferrednode) FileInfo() os.FileInfo { return dn.currentinode().FileInfo() }
75 func (dn *deferrednode) Lock() { dn.realinode().Lock() }
76 func (dn *deferrednode) Unlock() { dn.realinode().Unlock() }
77 func (dn *deferrednode) RLock() { dn.realinode().RLock() }
78 func (dn *deferrednode) RUnlock() { dn.realinode().RUnlock() }
79 func (dn *deferrednode) FS() FileSystem { return dn.currentinode().FS() }
80 func (dn *deferrednode) Parent() inode { return dn.currentinode().Parent() }
81 func (dn *deferrednode) MemorySize() int64 { return dn.currentinode().MemorySize() }
82 func (dn *deferrednode) Snapshot() (inode, error) { return dn.realinode().Snapshot() }
83 func (dn *deferrednode) Splice(repl inode) error { return dn.realinode().Splice(repl) }