mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
[vfs] [2/2] kernfs: kernfs: Internally use kernfs.Dentry instead of vfs.Dentry.
Update signatures for: - All methods in inodeDirectory - deferDecRef() and Filesystem.droppedDentries - newSyntheticDirectory() - `slot`s used in OrderedChildren and subsequent methods like replaceChildLocked() and checkExistingLocked() - stepExistingLocked(), walkParentDirLocked(), checkCreateLocked() Updates #1193 PiperOrigin-RevId: 333558866
This commit is contained in:
@@ -426,7 +426,7 @@ func (*inode) Valid(ctx context.Context) bool {
|
||||
}
|
||||
|
||||
// NewFile implements kernfs.Inode.NewFile.
|
||||
func (i *inode) NewFile(ctx context.Context, name string, opts vfs.OpenOptions) (*vfs.Dentry, error) {
|
||||
func (i *inode) NewFile(ctx context.Context, name string, opts vfs.OpenOptions) (*kernfs.Dentry, error) {
|
||||
kernelTask := kernel.TaskFromContext(ctx)
|
||||
if kernelTask == nil {
|
||||
log.Warningf("fusefs.Inode.NewFile: couldn't get kernel task from context", i.nodeID)
|
||||
@@ -440,15 +440,11 @@ func (i *inode) NewFile(ctx context.Context, name string, opts vfs.OpenOptions)
|
||||
},
|
||||
Name: name,
|
||||
}
|
||||
d, err := i.newEntry(ctx, name, linux.S_IFREG, linux.FUSE_CREATE, &in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return d.VFSDentry(), nil
|
||||
return i.newEntry(ctx, name, linux.S_IFREG, linux.FUSE_CREATE, &in)
|
||||
}
|
||||
|
||||
// NewNode implements kernfs.Inode.NewNode.
|
||||
func (i *inode) NewNode(ctx context.Context, name string, opts vfs.MknodOptions) (*vfs.Dentry, error) {
|
||||
func (i *inode) NewNode(ctx context.Context, name string, opts vfs.MknodOptions) (*kernfs.Dentry, error) {
|
||||
in := linux.FUSEMknodIn{
|
||||
MknodMeta: linux.FUSEMknodMeta{
|
||||
Mode: uint32(opts.Mode),
|
||||
@@ -457,28 +453,20 @@ func (i *inode) NewNode(ctx context.Context, name string, opts vfs.MknodOptions)
|
||||
},
|
||||
Name: name,
|
||||
}
|
||||
d, err := i.newEntry(ctx, name, opts.Mode.FileType(), linux.FUSE_MKNOD, &in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return d.VFSDentry(), nil
|
||||
return i.newEntry(ctx, name, opts.Mode.FileType(), linux.FUSE_MKNOD, &in)
|
||||
}
|
||||
|
||||
// NewSymlink implements kernfs.Inode.NewSymlink.
|
||||
func (i *inode) NewSymlink(ctx context.Context, name, target string) (*vfs.Dentry, error) {
|
||||
func (i *inode) NewSymlink(ctx context.Context, name, target string) (*kernfs.Dentry, error) {
|
||||
in := linux.FUSESymLinkIn{
|
||||
Name: name,
|
||||
Target: target,
|
||||
}
|
||||
d, err := i.newEntry(ctx, name, linux.S_IFLNK, linux.FUSE_SYMLINK, &in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return d.VFSDentry(), nil
|
||||
return i.newEntry(ctx, name, linux.S_IFLNK, linux.FUSE_SYMLINK, &in)
|
||||
}
|
||||
|
||||
// Unlink implements kernfs.Inode.Unlink.
|
||||
func (i *inode) Unlink(ctx context.Context, name string, child *vfs.Dentry) error {
|
||||
func (i *inode) Unlink(ctx context.Context, name string, child *kernfs.Dentry) error {
|
||||
kernelTask := kernel.TaskFromContext(ctx)
|
||||
if kernelTask == nil {
|
||||
log.Warningf("fusefs.Inode.newEntry: couldn't get kernel task from context", i.nodeID)
|
||||
@@ -501,7 +489,7 @@ func (i *inode) Unlink(ctx context.Context, name string, child *vfs.Dentry) erro
|
||||
}
|
||||
|
||||
// NewDir implements kernfs.Inode.NewDir.
|
||||
func (i *inode) NewDir(ctx context.Context, name string, opts vfs.MkdirOptions) (*vfs.Dentry, error) {
|
||||
func (i *inode) NewDir(ctx context.Context, name string, opts vfs.MkdirOptions) (*kernfs.Dentry, error) {
|
||||
in := linux.FUSEMkdirIn{
|
||||
MkdirMeta: linux.FUSEMkdirMeta{
|
||||
Mode: uint32(opts.Mode),
|
||||
@@ -509,15 +497,11 @@ func (i *inode) NewDir(ctx context.Context, name string, opts vfs.MkdirOptions)
|
||||
},
|
||||
Name: name,
|
||||
}
|
||||
d, err := i.newEntry(ctx, name, linux.S_IFDIR, linux.FUSE_MKDIR, &in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return d.VFSDentry(), nil
|
||||
return i.newEntry(ctx, name, linux.S_IFDIR, linux.FUSE_MKDIR, &in)
|
||||
}
|
||||
|
||||
// RmDir implements kernfs.Inode.RmDir.
|
||||
func (i *inode) RmDir(ctx context.Context, name string, child *vfs.Dentry) error {
|
||||
func (i *inode) RmDir(ctx context.Context, name string, child *kernfs.Dentry) error {
|
||||
fusefs := i.fs
|
||||
task, creds := kernel.TaskFromContext(ctx), auth.CredentialsFromContext(ctx)
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ func (f *DynamicBytesFile) Init(creds *auth.Credentials, devMajor, devMinor uint
|
||||
// Open implements Inode.Open.
|
||||
func (f *DynamicBytesFile) Open(ctx context.Context, rp *vfs.ResolvingPath, d *Dentry, opts vfs.OpenOptions) (*vfs.FileDescription, error) {
|
||||
fd := &DynamicBytesFD{}
|
||||
if err := fd.Init(rp.Mount(), d.VFSDentry(), f.data, &f.locks, opts.Flags); err != nil {
|
||||
if err := fd.Init(rp.Mount(), d, f.data, &f.locks, opts.Flags); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &fd.vfsfd, nil
|
||||
@@ -87,12 +87,12 @@ type DynamicBytesFD struct {
|
||||
}
|
||||
|
||||
// Init initializes a DynamicBytesFD.
|
||||
func (fd *DynamicBytesFD) Init(m *vfs.Mount, d *vfs.Dentry, data vfs.DynamicBytesSource, locks *vfs.FileLocks, flags uint32) error {
|
||||
func (fd *DynamicBytesFD) Init(m *vfs.Mount, d *Dentry, data vfs.DynamicBytesSource, locks *vfs.FileLocks, flags uint32) error {
|
||||
fd.LockFD.Init(locks)
|
||||
if err := fd.vfsfd.Init(fd, flags, m, d, &vfs.FileDescriptionOptions{}); err != nil {
|
||||
if err := fd.vfsfd.Init(fd, flags, m, d.VFSDentry(), &vfs.FileDescriptionOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
fd.inode = d.Impl().(*Dentry).inode
|
||||
fd.inode = d.inode
|
||||
fd.SetDataSource(data)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -201,8 +201,7 @@ func (fd *GenericDirectoryFD) IterDirents(ctx context.Context, cb vfs.IterDirent
|
||||
// these.
|
||||
childIdx := fd.off - 2
|
||||
for it := fd.children.nthLocked(childIdx); it != nil; it = it.Next() {
|
||||
inode := it.Dentry.Impl().(*Dentry).inode
|
||||
stat, err := inode.Stat(ctx, fd.filesystem(), opts)
|
||||
stat, err := it.Dentry.inode.Stat(ctx, fd.filesystem(), opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -37,8 +37,7 @@ import (
|
||||
// * !rp.Done().
|
||||
//
|
||||
// Postcondition: Caller must call fs.processDeferredDecRefs*.
|
||||
func (fs *Filesystem) stepExistingLocked(ctx context.Context, rp *vfs.ResolvingPath, vfsd *vfs.Dentry, mayFollowSymlinks bool) (*vfs.Dentry, error) {
|
||||
d := vfsd.Impl().(*Dentry)
|
||||
func (fs *Filesystem) stepExistingLocked(ctx context.Context, rp *vfs.ResolvingPath, d *Dentry, mayFollowSymlinks bool) (*Dentry, error) {
|
||||
if !d.isDir() {
|
||||
return nil, syserror.ENOTDIR
|
||||
}
|
||||
@@ -55,20 +54,20 @@ afterSymlink:
|
||||
// calls d_revalidate(), but walk_component() => handle_dots() does not.
|
||||
if name == "." {
|
||||
rp.Advance()
|
||||
return vfsd, nil
|
||||
return d, nil
|
||||
}
|
||||
if name == ".." {
|
||||
if isRoot, err := rp.CheckRoot(ctx, vfsd); err != nil {
|
||||
if isRoot, err := rp.CheckRoot(ctx, d.VFSDentry()); err != nil {
|
||||
return nil, err
|
||||
} else if isRoot || d.parent == nil {
|
||||
rp.Advance()
|
||||
return vfsd, nil
|
||||
return d, nil
|
||||
}
|
||||
if err := rp.CheckMount(ctx, &d.parent.vfsd); err != nil {
|
||||
if err := rp.CheckMount(ctx, d.parent.VFSDentry()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rp.Advance()
|
||||
return &d.parent.vfsd, nil
|
||||
return d.parent, nil
|
||||
}
|
||||
if len(name) > linux.NAME_MAX {
|
||||
return nil, syserror.ENAMETOOLONG
|
||||
@@ -79,7 +78,7 @@ afterSymlink:
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rp.CheckMount(ctx, &next.vfsd); err != nil {
|
||||
if err := rp.CheckMount(ctx, next.VFSDentry()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Resolve any symlink at current path component.
|
||||
@@ -102,7 +101,7 @@ afterSymlink:
|
||||
goto afterSymlink
|
||||
}
|
||||
rp.Advance()
|
||||
return &next.vfsd, nil
|
||||
return next, nil
|
||||
}
|
||||
|
||||
// revalidateChildLocked must be called after a call to parent.vfsd.Child(name)
|
||||
@@ -122,7 +121,7 @@ func (fs *Filesystem) revalidateChildLocked(ctx context.Context, vfsObj *vfs.Vir
|
||||
if !child.inode.Valid(ctx) {
|
||||
delete(parent.children, name)
|
||||
vfsObj.InvalidateDentry(ctx, &child.vfsd)
|
||||
fs.deferDecRef(&child.vfsd) // Reference from Lookup.
|
||||
fs.deferDecRef(child) // Reference from Lookup.
|
||||
child = nil
|
||||
}
|
||||
}
|
||||
@@ -149,15 +148,14 @@ func (fs *Filesystem) revalidateChildLocked(ctx context.Context, vfsObj *vfs.Vir
|
||||
//
|
||||
// Postconditions: Caller must call fs.processDeferredDecRefs*.
|
||||
func (fs *Filesystem) walkExistingLocked(ctx context.Context, rp *vfs.ResolvingPath) (*Dentry, error) {
|
||||
vfsd := rp.Start()
|
||||
d := rp.Start().Impl().(*Dentry)
|
||||
for !rp.Done() {
|
||||
var err error
|
||||
vfsd, err = fs.stepExistingLocked(ctx, rp, vfsd, true /* mayFollowSymlinks */)
|
||||
d, err = fs.stepExistingLocked(ctx, rp, d, true /* mayFollowSymlinks */)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
d := vfsd.Impl().(*Dentry)
|
||||
if rp.MustBeDir() && !d.isDir() {
|
||||
return nil, syserror.ENOTDIR
|
||||
}
|
||||
@@ -176,20 +174,19 @@ func (fs *Filesystem) walkExistingLocked(ctx context.Context, rp *vfs.ResolvingP
|
||||
// * !rp.Done().
|
||||
//
|
||||
// Postconditions: Caller must call fs.processDeferredDecRefs*.
|
||||
func (fs *Filesystem) walkParentDirLocked(ctx context.Context, rp *vfs.ResolvingPath) (*vfs.Dentry, Inode, error) {
|
||||
vfsd := rp.Start()
|
||||
func (fs *Filesystem) walkParentDirLocked(ctx context.Context, rp *vfs.ResolvingPath) (*Dentry, error) {
|
||||
d := rp.Start().Impl().(*Dentry)
|
||||
for !rp.Final() {
|
||||
var err error
|
||||
vfsd, err = fs.stepExistingLocked(ctx, rp, vfsd, true /* mayFollowSymlinks */)
|
||||
d, err = fs.stepExistingLocked(ctx, rp, d, true /* mayFollowSymlinks */)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
d := vfsd.Impl().(*Dentry)
|
||||
if !d.isDir() {
|
||||
return nil, nil, syserror.ENOTDIR
|
||||
return nil, syserror.ENOTDIR
|
||||
}
|
||||
return vfsd, d.inode, nil
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// checkCreateLocked checks that a file named rp.Component() may be created in
|
||||
@@ -197,10 +194,9 @@ func (fs *Filesystem) walkParentDirLocked(ctx context.Context, rp *vfs.Resolving
|
||||
//
|
||||
// Preconditions:
|
||||
// * Filesystem.mu must be locked for at least reading.
|
||||
// * parentInode == parentVFSD.Impl().(*Dentry).Inode.
|
||||
// * isDir(parentInode) == true.
|
||||
func checkCreateLocked(ctx context.Context, rp *vfs.ResolvingPath, parentVFSD *vfs.Dentry, parentInode Inode) (string, error) {
|
||||
if err := parentInode.CheckPermissions(ctx, rp.Credentials(), vfs.MayWrite|vfs.MayExec); err != nil {
|
||||
func checkCreateLocked(ctx context.Context, rp *vfs.ResolvingPath, parent *Dentry) (string, error) {
|
||||
if err := parent.inode.CheckPermissions(ctx, rp.Credentials(), vfs.MayWrite|vfs.MayExec); err != nil {
|
||||
return "", err
|
||||
}
|
||||
pc := rp.Component()
|
||||
@@ -211,10 +207,10 @@ func checkCreateLocked(ctx context.Context, rp *vfs.ResolvingPath, parentVFSD *v
|
||||
return "", syserror.ENAMETOOLONG
|
||||
}
|
||||
// FIXME(gvisor.dev/issue/1193): Data race due to not holding dirMu.
|
||||
if _, ok := parentVFSD.Impl().(*Dentry).children[pc]; ok {
|
||||
if _, ok := parent.children[pc]; ok {
|
||||
return "", syserror.EEXIST
|
||||
}
|
||||
if parentVFSD.IsDead() {
|
||||
if parent.VFSDentry().IsDead() {
|
||||
return "", syserror.ENOENT
|
||||
}
|
||||
return pc, nil
|
||||
@@ -288,12 +284,12 @@ func (fs *Filesystem) GetParentDentryAt(ctx context.Context, rp *vfs.ResolvingPa
|
||||
fs.mu.RLock()
|
||||
defer fs.processDeferredDecRefs(ctx)
|
||||
defer fs.mu.RUnlock()
|
||||
vfsd, _, err := fs.walkParentDirLocked(ctx, rp)
|
||||
d, err := fs.walkParentDirLocked(ctx, rp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vfsd.IncRef() // Ownership transferred to caller.
|
||||
return vfsd, nil
|
||||
d.IncRef() // Ownership transferred to caller.
|
||||
return d.VFSDentry(), nil
|
||||
}
|
||||
|
||||
// LinkAt implements vfs.FilesystemImpl.LinkAt.
|
||||
@@ -303,12 +299,12 @@ func (fs *Filesystem) LinkAt(ctx context.Context, rp *vfs.ResolvingPath, vd vfs.
|
||||
}
|
||||
fs.mu.Lock()
|
||||
defer fs.mu.Unlock()
|
||||
parentVFSD, parentInode, err := fs.walkParentDirLocked(ctx, rp)
|
||||
parent, err := fs.walkParentDirLocked(ctx, rp)
|
||||
fs.processDeferredDecRefsLocked(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pc, err := checkCreateLocked(ctx, rp, parentVFSD, parentInode)
|
||||
pc, err := checkCreateLocked(ctx, rp, parent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -325,11 +321,11 @@ func (fs *Filesystem) LinkAt(ctx context.Context, rp *vfs.ResolvingPath, vd vfs.
|
||||
return syserror.EPERM
|
||||
}
|
||||
|
||||
childVFSD, err := parentInode.NewLink(ctx, pc, d.inode)
|
||||
child, err := parent.inode.NewLink(ctx, pc, d.inode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
parentVFSD.Impl().(*Dentry).InsertChild(pc, childVFSD.Impl().(*Dentry))
|
||||
parent.InsertChild(pc, child)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -340,12 +336,12 @@ func (fs *Filesystem) MkdirAt(ctx context.Context, rp *vfs.ResolvingPath, opts v
|
||||
}
|
||||
fs.mu.Lock()
|
||||
defer fs.mu.Unlock()
|
||||
parentVFSD, parentInode, err := fs.walkParentDirLocked(ctx, rp)
|
||||
parent, err := fs.walkParentDirLocked(ctx, rp)
|
||||
fs.processDeferredDecRefsLocked(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pc, err := checkCreateLocked(ctx, rp, parentVFSD, parentInode)
|
||||
pc, err := checkCreateLocked(ctx, rp, parent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -353,14 +349,14 @@ func (fs *Filesystem) MkdirAt(ctx context.Context, rp *vfs.ResolvingPath, opts v
|
||||
return err
|
||||
}
|
||||
defer rp.Mount().EndWrite()
|
||||
childVFSD, err := parentInode.NewDir(ctx, pc, opts)
|
||||
child, err := parent.inode.NewDir(ctx, pc, opts)
|
||||
if err != nil {
|
||||
if !opts.ForSyntheticMountpoint || err == syserror.EEXIST {
|
||||
return err
|
||||
}
|
||||
childVFSD = newSyntheticDirectory(rp.Credentials(), opts.Mode)
|
||||
child = newSyntheticDirectory(rp.Credentials(), opts.Mode)
|
||||
}
|
||||
parentVFSD.Impl().(*Dentry).InsertChild(pc, childVFSD.Impl().(*Dentry))
|
||||
parent.InsertChild(pc, child)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -371,12 +367,12 @@ func (fs *Filesystem) MknodAt(ctx context.Context, rp *vfs.ResolvingPath, opts v
|
||||
}
|
||||
fs.mu.Lock()
|
||||
defer fs.mu.Unlock()
|
||||
parentVFSD, parentInode, err := fs.walkParentDirLocked(ctx, rp)
|
||||
parent, err := fs.walkParentDirLocked(ctx, rp)
|
||||
fs.processDeferredDecRefsLocked(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pc, err := checkCreateLocked(ctx, rp, parentVFSD, parentInode)
|
||||
pc, err := checkCreateLocked(ctx, rp, parent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -384,11 +380,11 @@ func (fs *Filesystem) MknodAt(ctx context.Context, rp *vfs.ResolvingPath, opts v
|
||||
return err
|
||||
}
|
||||
defer rp.Mount().EndWrite()
|
||||
newVFSD, err := parentInode.NewNode(ctx, pc, opts)
|
||||
newD, err := parent.inode.NewNode(ctx, pc, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
parentVFSD.Impl().(*Dentry).InsertChild(pc, newVFSD.Impl().(*Dentry))
|
||||
parent.InsertChild(pc, newD)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -450,13 +446,13 @@ func (fs *Filesystem) OpenAt(ctx context.Context, rp *vfs.ResolvingPath, opts vf
|
||||
return d.inode.Open(ctx, rp, d, opts)
|
||||
}
|
||||
afterTrailingSymlink:
|
||||
parentVFSD, parentInode, err := fs.walkParentDirLocked(ctx, rp)
|
||||
parent, err := fs.walkParentDirLocked(ctx, rp)
|
||||
fs.processDeferredDecRefsLocked(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Check for search permission in the parent directory.
|
||||
if err := parentInode.CheckPermissions(ctx, rp.Credentials(), vfs.MayExec); err != nil {
|
||||
if err := parent.inode.CheckPermissions(ctx, rp.Credentials(), vfs.MayExec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Reject attempts to open directories with O_CREAT.
|
||||
@@ -471,10 +467,10 @@ afterTrailingSymlink:
|
||||
return nil, syserror.ENAMETOOLONG
|
||||
}
|
||||
// Determine whether or not we need to create a file.
|
||||
childVFSD, err := fs.stepExistingLocked(ctx, rp, parentVFSD, false /* mayFollowSymlinks */)
|
||||
child, err := fs.stepExistingLocked(ctx, rp, parent, false /* mayFollowSymlinks */)
|
||||
if err == syserror.ENOENT {
|
||||
// Already checked for searchability above; now check for writability.
|
||||
if err := parentInode.CheckPermissions(ctx, rp.Credentials(), vfs.MayWrite); err != nil {
|
||||
if err := parent.inode.CheckPermissions(ctx, rp.Credentials(), vfs.MayWrite); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rp.Mount().CheckBeginWrite(); err != nil {
|
||||
@@ -482,12 +478,11 @@ afterTrailingSymlink:
|
||||
}
|
||||
defer rp.Mount().EndWrite()
|
||||
// Create and open the child.
|
||||
childVFSD, err = parentInode.NewFile(ctx, pc, opts)
|
||||
child, err := parent.inode.NewFile(ctx, pc, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
child := childVFSD.Impl().(*Dentry)
|
||||
parentVFSD.Impl().(*Dentry).InsertChild(pc, child)
|
||||
parent.InsertChild(pc, child)
|
||||
child.inode.IncRef()
|
||||
defer child.inode.DecRef(ctx)
|
||||
unlock()
|
||||
@@ -500,7 +495,6 @@ afterTrailingSymlink:
|
||||
if mustCreate {
|
||||
return nil, syserror.EEXIST
|
||||
}
|
||||
child := childVFSD.Impl().(*Dentry)
|
||||
if rp.ShouldFollowSymlink() && child.isSymlink() {
|
||||
targetVD, targetPathname, err := child.inode.Getlink(ctx, rp.Mount())
|
||||
if err != nil {
|
||||
@@ -559,11 +553,10 @@ func (fs *Filesystem) RenameAt(ctx context.Context, rp *vfs.ResolvingPath, oldPa
|
||||
|
||||
// Resolve the destination directory first to verify that it's on this
|
||||
// Mount.
|
||||
dstDirVFSD, dstDirInode, err := fs.walkParentDirLocked(ctx, rp)
|
||||
dstDir, err := fs.walkParentDirLocked(ctx, rp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dstDir := dstDirVFSD.Impl().(*Dentry)
|
||||
mnt := rp.Mount()
|
||||
if mnt != oldParentVD.Mount() {
|
||||
return syserror.EXDEV
|
||||
@@ -589,7 +582,7 @@ func (fs *Filesystem) RenameAt(ctx context.Context, rp *vfs.ResolvingPath, oldPa
|
||||
|
||||
// Can we create the dst dentry?
|
||||
var dst *Dentry
|
||||
pc, err := checkCreateLocked(ctx, rp, dstDirVFSD, dstDirInode)
|
||||
pc, err := checkCreateLocked(ctx, rp, dstDir)
|
||||
switch err {
|
||||
case nil:
|
||||
// Ok, continue with rename as replacement.
|
||||
@@ -600,14 +593,14 @@ func (fs *Filesystem) RenameAt(ctx context.Context, rp *vfs.ResolvingPath, oldPa
|
||||
}
|
||||
dst = dstDir.children[pc]
|
||||
if dst == nil {
|
||||
panic(fmt.Sprintf("Child %q for parent Dentry %+v disappeared inside atomic section?", pc, dstDirVFSD))
|
||||
panic(fmt.Sprintf("Child %q for parent Dentry %+v disappeared inside atomic section?", pc, dstDir))
|
||||
}
|
||||
default:
|
||||
return err
|
||||
}
|
||||
var dstVFSD *vfs.Dentry
|
||||
if dst != nil {
|
||||
dstVFSD = &dst.vfsd
|
||||
dstVFSD = dst.VFSDentry()
|
||||
}
|
||||
|
||||
mntns := vfs.MountNamespaceFromContext(ctx)
|
||||
@@ -627,14 +620,14 @@ func (fs *Filesystem) RenameAt(ctx context.Context, rp *vfs.ResolvingPath, oldPa
|
||||
if err := virtfs.PrepareRenameDentry(mntns, srcVFSD, dstVFSD); err != nil {
|
||||
return err
|
||||
}
|
||||
replaced, err := srcDir.inode.Rename(ctx, src.name, pc, srcVFSD, dstDirVFSD)
|
||||
replaced, err := srcDir.inode.Rename(ctx, src.name, pc, src, dstDir)
|
||||
if err != nil {
|
||||
virtfs.AbortRenameDentry(srcVFSD, dstVFSD)
|
||||
return err
|
||||
}
|
||||
delete(srcDir.children, src.name)
|
||||
if srcDir != dstDir {
|
||||
fs.deferDecRef(srcDirVFSD)
|
||||
fs.deferDecRef(srcDir)
|
||||
dstDir.IncRef()
|
||||
}
|
||||
src.parent = dstDir
|
||||
@@ -643,7 +636,11 @@ func (fs *Filesystem) RenameAt(ctx context.Context, rp *vfs.ResolvingPath, oldPa
|
||||
dstDir.children = make(map[string]*Dentry)
|
||||
}
|
||||
dstDir.children[pc] = src
|
||||
virtfs.CommitRenameReplaceDentry(ctx, srcVFSD, replaced)
|
||||
var replaceVFSD *vfs.Dentry
|
||||
if replaced != nil {
|
||||
replaceVFSD = replaced.VFSDentry()
|
||||
}
|
||||
virtfs.CommitRenameReplaceDentry(ctx, srcVFSD, replaceVFSD)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -682,7 +679,7 @@ func (fs *Filesystem) RmdirAt(ctx context.Context, rp *vfs.ResolvingPath) error
|
||||
return err
|
||||
}
|
||||
|
||||
if err := parentDentry.inode.RmDir(ctx, d.name, d.VFSDentry()); err != nil {
|
||||
if err := parentDentry.inode.RmDir(ctx, d.name, d); err != nil {
|
||||
virtfs.AbortDeleteDentry(vfsd)
|
||||
return err
|
||||
}
|
||||
@@ -736,12 +733,12 @@ func (fs *Filesystem) SymlinkAt(ctx context.Context, rp *vfs.ResolvingPath, targ
|
||||
}
|
||||
fs.mu.Lock()
|
||||
defer fs.mu.Unlock()
|
||||
parentVFSD, parentInode, err := fs.walkParentDirLocked(ctx, rp)
|
||||
parent, err := fs.walkParentDirLocked(ctx, rp)
|
||||
fs.processDeferredDecRefsLocked(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pc, err := checkCreateLocked(ctx, rp, parentVFSD, parentInode)
|
||||
pc, err := checkCreateLocked(ctx, rp, parent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -749,11 +746,11 @@ func (fs *Filesystem) SymlinkAt(ctx context.Context, rp *vfs.ResolvingPath, targ
|
||||
return err
|
||||
}
|
||||
defer rp.Mount().EndWrite()
|
||||
childVFSD, err := parentInode.NewSymlink(ctx, pc, target)
|
||||
child, err := parent.inode.NewSymlink(ctx, pc, target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
parentVFSD.Impl().(*Dentry).InsertChild(pc, childVFSD.Impl().(*Dentry))
|
||||
parent.InsertChild(pc, child)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -787,7 +784,7 @@ func (fs *Filesystem) UnlinkAt(ctx context.Context, rp *vfs.ResolvingPath) error
|
||||
if err := virtfs.PrepareDeleteDentry(mntns, vfsd); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := parentDentry.inode.Unlink(ctx, d.name, d.VFSDentry()); err != nil {
|
||||
if err := parentDentry.inode.Unlink(ctx, d.name, d); err != nil {
|
||||
virtfs.AbortDeleteDentry(vfsd)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -57,27 +57,27 @@ func (InodeNoopRefCount) TryIncRef() bool {
|
||||
type InodeDirectoryNoNewChildren struct{}
|
||||
|
||||
// NewFile implements Inode.NewFile.
|
||||
func (InodeDirectoryNoNewChildren) NewFile(context.Context, string, vfs.OpenOptions) (*vfs.Dentry, error) {
|
||||
func (InodeDirectoryNoNewChildren) NewFile(context.Context, string, vfs.OpenOptions) (*Dentry, error) {
|
||||
return nil, syserror.EPERM
|
||||
}
|
||||
|
||||
// NewDir implements Inode.NewDir.
|
||||
func (InodeDirectoryNoNewChildren) NewDir(context.Context, string, vfs.MkdirOptions) (*vfs.Dentry, error) {
|
||||
func (InodeDirectoryNoNewChildren) NewDir(context.Context, string, vfs.MkdirOptions) (*Dentry, error) {
|
||||
return nil, syserror.EPERM
|
||||
}
|
||||
|
||||
// NewLink implements Inode.NewLink.
|
||||
func (InodeDirectoryNoNewChildren) NewLink(context.Context, string, Inode) (*vfs.Dentry, error) {
|
||||
func (InodeDirectoryNoNewChildren) NewLink(context.Context, string, Inode) (*Dentry, error) {
|
||||
return nil, syserror.EPERM
|
||||
}
|
||||
|
||||
// NewSymlink implements Inode.NewSymlink.
|
||||
func (InodeDirectoryNoNewChildren) NewSymlink(context.Context, string, string) (*vfs.Dentry, error) {
|
||||
func (InodeDirectoryNoNewChildren) NewSymlink(context.Context, string, string) (*Dentry, error) {
|
||||
return nil, syserror.EPERM
|
||||
}
|
||||
|
||||
// NewNode implements Inode.NewNode.
|
||||
func (InodeDirectoryNoNewChildren) NewNode(context.Context, string, vfs.MknodOptions) (*vfs.Dentry, error) {
|
||||
func (InodeDirectoryNoNewChildren) NewNode(context.Context, string, vfs.MknodOptions) (*Dentry, error) {
|
||||
return nil, syserror.EPERM
|
||||
}
|
||||
|
||||
@@ -96,42 +96,42 @@ func (InodeNotDirectory) HasChildren() bool {
|
||||
}
|
||||
|
||||
// NewFile implements Inode.NewFile.
|
||||
func (InodeNotDirectory) NewFile(context.Context, string, vfs.OpenOptions) (*vfs.Dentry, error) {
|
||||
func (InodeNotDirectory) NewFile(context.Context, string, vfs.OpenOptions) (*Dentry, error) {
|
||||
panic("NewFile called on non-directory inode")
|
||||
}
|
||||
|
||||
// NewDir implements Inode.NewDir.
|
||||
func (InodeNotDirectory) NewDir(context.Context, string, vfs.MkdirOptions) (*vfs.Dentry, error) {
|
||||
func (InodeNotDirectory) NewDir(context.Context, string, vfs.MkdirOptions) (*Dentry, error) {
|
||||
panic("NewDir called on non-directory inode")
|
||||
}
|
||||
|
||||
// NewLink implements Inode.NewLinkink.
|
||||
func (InodeNotDirectory) NewLink(context.Context, string, Inode) (*vfs.Dentry, error) {
|
||||
func (InodeNotDirectory) NewLink(context.Context, string, Inode) (*Dentry, error) {
|
||||
panic("NewLink called on non-directory inode")
|
||||
}
|
||||
|
||||
// NewSymlink implements Inode.NewSymlink.
|
||||
func (InodeNotDirectory) NewSymlink(context.Context, string, string) (*vfs.Dentry, error) {
|
||||
func (InodeNotDirectory) NewSymlink(context.Context, string, string) (*Dentry, error) {
|
||||
panic("NewSymlink called on non-directory inode")
|
||||
}
|
||||
|
||||
// NewNode implements Inode.NewNode.
|
||||
func (InodeNotDirectory) NewNode(context.Context, string, vfs.MknodOptions) (*vfs.Dentry, error) {
|
||||
func (InodeNotDirectory) NewNode(context.Context, string, vfs.MknodOptions) (*Dentry, error) {
|
||||
panic("NewNode called on non-directory inode")
|
||||
}
|
||||
|
||||
// Unlink implements Inode.Unlink.
|
||||
func (InodeNotDirectory) Unlink(context.Context, string, *vfs.Dentry) error {
|
||||
func (InodeNotDirectory) Unlink(context.Context, string, *Dentry) error {
|
||||
panic("Unlink called on non-directory inode")
|
||||
}
|
||||
|
||||
// RmDir implements Inode.RmDir.
|
||||
func (InodeNotDirectory) RmDir(context.Context, string, *vfs.Dentry) error {
|
||||
func (InodeNotDirectory) RmDir(context.Context, string, *Dentry) error {
|
||||
panic("RmDir called on non-directory inode")
|
||||
}
|
||||
|
||||
// Rename implements Inode.Rename.
|
||||
func (InodeNotDirectory) Rename(context.Context, string, string, *vfs.Dentry, *vfs.Dentry) (*vfs.Dentry, error) {
|
||||
func (InodeNotDirectory) Rename(context.Context, string, string, *Dentry, *Dentry) (*Dentry, error) {
|
||||
panic("Rename called on non-directory inode")
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ func (a *InodeAttrs) DecLinks() {
|
||||
// +stateify savable
|
||||
type slot struct {
|
||||
Name string
|
||||
Dentry *vfs.Dentry
|
||||
Dentry *Dentry
|
||||
slotEntry
|
||||
}
|
||||
|
||||
@@ -407,7 +407,7 @@ func (o *OrderedChildren) Populate(d *Dentry, children map[string]*Dentry) uint3
|
||||
if child.isDir() {
|
||||
links++
|
||||
}
|
||||
if err := o.Insert(name, child.VFSDentry()); err != nil {
|
||||
if err := o.Insert(name, child); err != nil {
|
||||
panic(fmt.Sprintf("Collision when attempting to insert child %q (%+v) into %+v", name, child, d))
|
||||
}
|
||||
d.InsertChild(name, child)
|
||||
@@ -424,7 +424,7 @@ func (o *OrderedChildren) HasChildren() bool {
|
||||
|
||||
// Insert inserts child into o. This ignores the writability of o, as this is
|
||||
// not part of the vfs.FilesystemImpl interface, and is a lower-level operation.
|
||||
func (o *OrderedChildren) Insert(name string, child *vfs.Dentry) error {
|
||||
func (o *OrderedChildren) Insert(name string, child *Dentry) error {
|
||||
o.mu.Lock()
|
||||
defer o.mu.Unlock()
|
||||
if _, ok := o.set[name]; ok {
|
||||
@@ -448,10 +448,10 @@ func (o *OrderedChildren) removeLocked(name string) {
|
||||
}
|
||||
|
||||
// Precondition: caller must hold o.mu for writing.
|
||||
func (o *OrderedChildren) replaceChildLocked(name string, new *vfs.Dentry) *vfs.Dentry {
|
||||
func (o *OrderedChildren) replaceChildLocked(name string, new *Dentry) *Dentry {
|
||||
if s, ok := o.set[name]; ok {
|
||||
// Existing slot with given name, simply replace the dentry.
|
||||
var old *vfs.Dentry
|
||||
var old *Dentry
|
||||
old, s.Dentry = s.Dentry, new
|
||||
return old
|
||||
}
|
||||
@@ -467,7 +467,7 @@ func (o *OrderedChildren) replaceChildLocked(name string, new *vfs.Dentry) *vfs.
|
||||
}
|
||||
|
||||
// Precondition: caller must hold o.mu for reading or writing.
|
||||
func (o *OrderedChildren) checkExistingLocked(name string, child *vfs.Dentry) error {
|
||||
func (o *OrderedChildren) checkExistingLocked(name string, child *Dentry) error {
|
||||
s, ok := o.set[name]
|
||||
if !ok {
|
||||
return syserror.ENOENT
|
||||
@@ -479,7 +479,7 @@ func (o *OrderedChildren) checkExistingLocked(name string, child *vfs.Dentry) er
|
||||
}
|
||||
|
||||
// Unlink implements Inode.Unlink.
|
||||
func (o *OrderedChildren) Unlink(ctx context.Context, name string, child *vfs.Dentry) error {
|
||||
func (o *OrderedChildren) Unlink(ctx context.Context, name string, child *Dentry) error {
|
||||
if !o.writable {
|
||||
return syserror.EPERM
|
||||
}
|
||||
@@ -495,7 +495,7 @@ func (o *OrderedChildren) Unlink(ctx context.Context, name string, child *vfs.De
|
||||
}
|
||||
|
||||
// Rmdir implements Inode.Rmdir.
|
||||
func (o *OrderedChildren) RmDir(ctx context.Context, name string, child *vfs.Dentry) error {
|
||||
func (o *OrderedChildren) RmDir(ctx context.Context, name string, child *Dentry) error {
|
||||
// We're not responsible for checking that child is a directory, that it's
|
||||
// empty, or updating any link counts; so this is the same as unlink.
|
||||
return o.Unlink(ctx, name, child)
|
||||
@@ -517,8 +517,8 @@ func (renameAcrossDifferentImplementationsError) Error() string {
|
||||
// that will support Rename.
|
||||
//
|
||||
// Postcondition: reference on any replaced dentry transferred to caller.
|
||||
func (o *OrderedChildren) Rename(ctx context.Context, oldname, newname string, child, dstDir *vfs.Dentry) (*vfs.Dentry, error) {
|
||||
dst, ok := dstDir.Impl().(*Dentry).inode.(interface{}).(*OrderedChildren)
|
||||
func (o *OrderedChildren) Rename(ctx context.Context, oldname, newname string, child, dstDir *Dentry) (*Dentry, error) {
|
||||
dst, ok := dstDir.inode.(interface{}).(*OrderedChildren)
|
||||
if !ok {
|
||||
return nil, renameAcrossDifferentImplementationsError{}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ type Filesystem struct {
|
||||
// droppedDentries is a list of dentries waiting to be DecRef()ed. This is
|
||||
// used to defer dentry destruction until mu can be acquired for
|
||||
// writing. Protected by droppedDentriesMu.
|
||||
droppedDentries []*vfs.Dentry
|
||||
droppedDentries []*Dentry
|
||||
|
||||
// mu synchronizes the lifetime of Dentries on this filesystem. Holding it
|
||||
// for reading guarantees continued existence of any resolved dentries, but
|
||||
@@ -110,7 +110,7 @@ type Filesystem struct {
|
||||
// processDeferredDecRefs{,Locked}. See comment on Filesystem.mu.
|
||||
//
|
||||
// Precondition: d must not already be pending destruction.
|
||||
func (fs *Filesystem) deferDecRef(d *vfs.Dentry) {
|
||||
func (fs *Filesystem) deferDecRef(d *Dentry) {
|
||||
fs.droppedDentriesMu.Lock()
|
||||
fs.droppedDentries = append(fs.droppedDentries, d)
|
||||
fs.droppedDentriesMu.Unlock()
|
||||
@@ -277,7 +277,7 @@ func (d *Dentry) InsertChildLocked(name string, child *Dentry) {
|
||||
// isn't sufficient to remove a child from a directory.
|
||||
//
|
||||
// Precondition: d must represent a directory inode.
|
||||
func (d *Dentry) RemoveChild(name string, child *vfs.Dentry) error {
|
||||
func (d *Dentry) RemoveChild(name string, child *Dentry) error {
|
||||
d.dirMu.Lock()
|
||||
defer d.dirMu.Unlock()
|
||||
return d.RemoveChildLocked(name, child)
|
||||
@@ -287,7 +287,7 @@ func (d *Dentry) RemoveChild(name string, child *vfs.Dentry) error {
|
||||
// preconditions.
|
||||
//
|
||||
// Precondition: d.dirMu must be locked.
|
||||
func (d *Dentry) RemoveChildLocked(name string, child *vfs.Dentry) error {
|
||||
func (d *Dentry) RemoveChildLocked(name string, child *Dentry) error {
|
||||
if !d.isDir() {
|
||||
panic(fmt.Sprintf("RemoveChild called on non-directory Dentry: %+v.", d))
|
||||
}
|
||||
@@ -295,7 +295,7 @@ func (d *Dentry) RemoveChildLocked(name string, child *vfs.Dentry) error {
|
||||
if !ok {
|
||||
return syserror.ENOENT
|
||||
}
|
||||
if &c.vfsd != child {
|
||||
if c != child {
|
||||
panic(fmt.Sprintf("Dentry hashed into inode doesn't match what vfs thinks! Child: %+v, vfs: %+v", c, child))
|
||||
}
|
||||
delete(d.children, name)
|
||||
@@ -404,30 +404,30 @@ type inodeDirectory interface {
|
||||
HasChildren() bool
|
||||
|
||||
// NewFile creates a new regular file inode.
|
||||
NewFile(ctx context.Context, name string, opts vfs.OpenOptions) (*vfs.Dentry, error)
|
||||
NewFile(ctx context.Context, name string, opts vfs.OpenOptions) (*Dentry, error)
|
||||
|
||||
// NewDir creates a new directory inode.
|
||||
NewDir(ctx context.Context, name string, opts vfs.MkdirOptions) (*vfs.Dentry, error)
|
||||
NewDir(ctx context.Context, name string, opts vfs.MkdirOptions) (*Dentry, error)
|
||||
|
||||
// NewLink creates a new hardlink to a specified inode in this
|
||||
// directory. Implementations should create a new kernfs Dentry pointing to
|
||||
// target, and update target's link count.
|
||||
NewLink(ctx context.Context, name string, target Inode) (*vfs.Dentry, error)
|
||||
NewLink(ctx context.Context, name string, target Inode) (*Dentry, error)
|
||||
|
||||
// NewSymlink creates a new symbolic link inode.
|
||||
NewSymlink(ctx context.Context, name, target string) (*vfs.Dentry, error)
|
||||
NewSymlink(ctx context.Context, name, target string) (*Dentry, error)
|
||||
|
||||
// NewNode creates a new filesystem node for a mknod syscall.
|
||||
NewNode(ctx context.Context, name string, opts vfs.MknodOptions) (*vfs.Dentry, error)
|
||||
NewNode(ctx context.Context, name string, opts vfs.MknodOptions) (*Dentry, error)
|
||||
|
||||
// Unlink removes a child dentry from this directory inode.
|
||||
Unlink(ctx context.Context, name string, child *vfs.Dentry) error
|
||||
Unlink(ctx context.Context, name string, child *Dentry) error
|
||||
|
||||
// RmDir removes an empty child directory from this directory
|
||||
// inode. Implementations must update the parent directory's link count,
|
||||
// if required. Implementations are not responsible for checking that child
|
||||
// is a directory, checking for an empty directory.
|
||||
RmDir(ctx context.Context, name string, child *vfs.Dentry) error
|
||||
RmDir(ctx context.Context, name string, child *Dentry) error
|
||||
|
||||
// Rename is called on the source directory containing an inode being
|
||||
// renamed. child should point to the resolved child in the source
|
||||
@@ -435,7 +435,7 @@ type inodeDirectory interface {
|
||||
// should return the replaced dentry or nil otherwise.
|
||||
//
|
||||
// Precondition: Caller must serialize concurrent calls to Rename.
|
||||
Rename(ctx context.Context, oldname, newname string, child, dstDir *vfs.Dentry) (replaced *vfs.Dentry, err error)
|
||||
Rename(ctx context.Context, oldname, newname string, child, dstDir *Dentry) (replaced *Dentry, err error)
|
||||
}
|
||||
|
||||
type inodeDynamicLookup interface {
|
||||
|
||||
@@ -176,38 +176,36 @@ func (d *dir) DecRef(context.Context) {
|
||||
d.dirRefs.DecRef(d.Destroy)
|
||||
}
|
||||
|
||||
func (d *dir) NewDir(ctx context.Context, name string, opts vfs.MkdirOptions) (*vfs.Dentry, error) {
|
||||
func (d *dir) NewDir(ctx context.Context, name string, opts vfs.MkdirOptions) (*kernfs.Dentry, error) {
|
||||
creds := auth.CredentialsFromContext(ctx)
|
||||
dir := d.fs.newDir(creds, opts.Mode, nil)
|
||||
dirVFSD := dir.VFSDentry()
|
||||
if err := d.OrderedChildren.Insert(name, dirVFSD); err != nil {
|
||||
if err := d.OrderedChildren.Insert(name, dir); err != nil {
|
||||
dir.DecRef(ctx)
|
||||
return nil, err
|
||||
}
|
||||
d.IncLinks(1)
|
||||
return dirVFSD, nil
|
||||
return dir, nil
|
||||
}
|
||||
|
||||
func (d *dir) NewFile(ctx context.Context, name string, opts vfs.OpenOptions) (*vfs.Dentry, error) {
|
||||
func (d *dir) NewFile(ctx context.Context, name string, opts vfs.OpenOptions) (*kernfs.Dentry, error) {
|
||||
creds := auth.CredentialsFromContext(ctx)
|
||||
f := d.fs.newFile(creds, "")
|
||||
fVFSD := f.VFSDentry()
|
||||
if err := d.OrderedChildren.Insert(name, fVFSD); err != nil {
|
||||
if err := d.OrderedChildren.Insert(name, f); err != nil {
|
||||
f.DecRef(ctx)
|
||||
return nil, err
|
||||
}
|
||||
return fVFSD, nil
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (*dir) NewLink(context.Context, string, kernfs.Inode) (*vfs.Dentry, error) {
|
||||
func (*dir) NewLink(context.Context, string, kernfs.Inode) (*kernfs.Dentry, error) {
|
||||
return nil, syserror.EPERM
|
||||
}
|
||||
|
||||
func (*dir) NewSymlink(context.Context, string, string) (*vfs.Dentry, error) {
|
||||
func (*dir) NewSymlink(context.Context, string, string) (*kernfs.Dentry, error) {
|
||||
return nil, syserror.EPERM
|
||||
}
|
||||
|
||||
func (*dir) NewNode(context.Context, string, vfs.MknodOptions) (*vfs.Dentry, error) {
|
||||
func (*dir) NewNode(context.Context, string, vfs.MknodOptions) (*kernfs.Dentry, error) {
|
||||
return nil, syserror.EPERM
|
||||
}
|
||||
|
||||
|
||||
@@ -41,12 +41,12 @@ type syntheticDirectory struct {
|
||||
|
||||
var _ Inode = (*syntheticDirectory)(nil)
|
||||
|
||||
func newSyntheticDirectory(creds *auth.Credentials, perm linux.FileMode) *vfs.Dentry {
|
||||
func newSyntheticDirectory(creds *auth.Credentials, perm linux.FileMode) *Dentry {
|
||||
inode := &syntheticDirectory{}
|
||||
inode.Init(creds, 0 /* devMajor */, 0 /* devMinor */, 0 /* ino */, perm)
|
||||
d := &Dentry{}
|
||||
d.Init(inode)
|
||||
return &d.vfsd
|
||||
return d
|
||||
}
|
||||
|
||||
func (dir *syntheticDirectory) Init(creds *auth.Credentials, devMajor, devMinor uint32, ino uint64, perm linux.FileMode) {
|
||||
@@ -69,12 +69,12 @@ func (dir *syntheticDirectory) Open(ctx context.Context, rp *vfs.ResolvingPath,
|
||||
}
|
||||
|
||||
// NewFile implements Inode.NewFile.
|
||||
func (dir *syntheticDirectory) NewFile(ctx context.Context, name string, opts vfs.OpenOptions) (*vfs.Dentry, error) {
|
||||
func (dir *syntheticDirectory) NewFile(ctx context.Context, name string, opts vfs.OpenOptions) (*Dentry, error) {
|
||||
return nil, syserror.EPERM
|
||||
}
|
||||
|
||||
// NewDir implements Inode.NewDir.
|
||||
func (dir *syntheticDirectory) NewDir(ctx context.Context, name string, opts vfs.MkdirOptions) (*vfs.Dentry, error) {
|
||||
func (dir *syntheticDirectory) NewDir(ctx context.Context, name string, opts vfs.MkdirOptions) (*Dentry, error) {
|
||||
if !opts.ForSyntheticMountpoint {
|
||||
return nil, syserror.EPERM
|
||||
}
|
||||
@@ -87,16 +87,16 @@ func (dir *syntheticDirectory) NewDir(ctx context.Context, name string, opts vfs
|
||||
}
|
||||
|
||||
// NewLink implements Inode.NewLink.
|
||||
func (dir *syntheticDirectory) NewLink(ctx context.Context, name string, target Inode) (*vfs.Dentry, error) {
|
||||
func (dir *syntheticDirectory) NewLink(ctx context.Context, name string, target Inode) (*Dentry, error) {
|
||||
return nil, syserror.EPERM
|
||||
}
|
||||
|
||||
// NewSymlink implements Inode.NewSymlink.
|
||||
func (dir *syntheticDirectory) NewSymlink(ctx context.Context, name, target string) (*vfs.Dentry, error) {
|
||||
func (dir *syntheticDirectory) NewSymlink(ctx context.Context, name, target string) (*Dentry, error) {
|
||||
return nil, syserror.EPERM
|
||||
}
|
||||
|
||||
// NewNode implements Inode.NewNode.
|
||||
func (dir *syntheticDirectory) NewNode(ctx context.Context, name string, opts vfs.MknodOptions) (*vfs.Dentry, error) {
|
||||
func (dir *syntheticDirectory) NewNode(ctx context.Context, name string, opts vfs.MknodOptions) (*Dentry, error) {
|
||||
return nil, syserror.EPERM
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user