// Creates a new Inode at name and returns its File based on the session's cache policy.
//
// Ownership is currently ignored.
Creates a new Inode at name and returns its File based on the session's cache policy.

Ownership is currently ignored.
// Creates a new Inode at name and returns its File based on the session ' s cache policy . // // Ownership is currently ignored .
func (i *inodeOperations) Create(ctx context.Context, dir *fs.Inode, name string, flags fs.FileFlags, perm fs.FilePermissions) (*fs.File, error) {
	if len(name) > maxFilenameLen {
		return nil, syserror.ENAMETOOLONG
	}
	_, newFile, err := i.fileState.file.walk(ctx, nil)
	if err != nil {
		return nil, err
	}
	var openFlags p9.OpenFlags
	switch {
	case flags.Read && flags.Write:
		openFlags = p9.ReadWrite
	case flags.Read:
		openFlags = p9.ReadOnly
	case flags.Write:
		openFlags = p9.WriteOnly
	default:
		panic(fmt.Sprintf("Create called with unknown or unset open flags: %v", flags))
	}
	owner := fs.FileOwnerFromContext(ctx)
	parentUattr, err := dir.UnstableAttr(ctx)
	if err != nil {
		return nil, err
	}
	if parentUattr.Perms.SetGID {
		owner.GID = parentUattr.Owner.GID
	}
	hostFile, err := newFile.create(ctx, name, openFlags, p9.FileMode(perm.LinuxMode()), p9.UID(owner.UID), p9.GID(owner.GID))
	if err != nil {
		newFile.close(ctx)
		return nil, err
	}
	i.touchModificationAndStatusChangeTime(ctx, dir)
	qids, unopened, mask, p9attr, err := i.fileState.file.walkGetAttr(ctx, []string{name})
	if err != nil {
		newFile.close(ctx)
		if hostFile != nil {
			hostFile.Close()
		}
		return nil, err
	}
	if len(qids) != 1 {
		log.Warningf("WalkGetAttr(%s) succeeded, but returned %d QIDs (%v), wanted 1", name, len(qids), qids)
		newFile.close(ctx)
		if hostFile != nil {
			hostFile.Close()
		}
		unopened.close(ctx)
		return nil, syserror.EIO
	}
	qid := qids[0]
	sattr, iops := newInodeOperations(ctx, i.fileState.s, unopened, qid, mask, p9attr)
	d := fs.NewDirent(ctx, fs.NewInode(ctx, iops, dir.MountSource, sattr), name)
	defer d.DecRef(ctx)
	h := handles{
		File: newFile,
		Host: hostFile,
	}
	h.EnableLeakCheck("gofer.handles")
	if iops.fileState.canShareHandles() {
		iops.fileState.handlesMu.Lock()
		iops.fileState.setSharedHandlesLocked(flags, &h)
		iops.fileState.handlesMu.Unlock()
	}
	return NewFile(ctx, d, name, flags, iops, &h), nil
}
func ( i * inodeOperations ) Create ( ctx context . Context , dir * fs . Inode , name string , flags fs . FileFlags , perm fs . FilePermissions ) ( * fs . File , error ) { if len ( name ) > maxFilenameLen { return nil , syserror . ENAMETOOLONG } _ , newFile , err := i . fileState . file . walk ( ctx , nil ) if err != nil { return nil , err } var openFlags p9 . OpenFlags switch { case flags . Read && flags . Write : openFlags = p9 . ReadWrite case flags . Read : openFlags = p9 . ReadOnly case flags . Write : openFlags = p9 . WriteOnly default : panic ( fmt . Sprintf ( " " , flags ) ) } owner := fs . FileOwnerFromContext ( ctx ) parentUattr , err := dir . UnstableAttr ( ctx ) if err != nil { return nil , err } if parentUattr . Perms . SetGID { owner . GID = parentUattr . Owner . GID } hostFile , err := newFile . create ( ctx , name , openFlags , p9 . FileMode ( perm . LinuxMode ( ) ) , p9 . UID ( owner . UID ) , p9 . GID ( owner . GID ) ) if err != nil { newFile . close ( ctx ) return nil , err } i . touchModificationAndStatusChangeTime ( ctx , dir ) qids , unopened , mask , p9attr , err := i . fileState . file . walkGetAttr ( ctx , [ ] string { name } ) if err != nil { newFile . close ( ctx ) if hostFile != nil { hostFile . Close ( ) } return nil , err } if len ( qids ) != 1 { log . Warningf ( " " , name , len ( qids ) , qids ) newFile . close ( ctx ) if hostFile != nil { hostFile . Close ( ) } unopened . close ( ctx ) return nil , syserror . EIO } qid := qids [ 0 ] sattr , iops := newInodeOperations ( ctx , i . fileState . s , unopened , qid , mask , p9attr ) d := fs . NewDirent ( ctx , fs . NewInode ( ctx , iops , dir . MountSource , sattr ) , name ) defer d . DecRef ( ctx ) h := handles { File : newFile , Host : hostFile , } h . EnableLeakCheck ( " " ) if iops . fileState . canShareHandles ( ) { iops . fileState . handlesMu . Lock ( ) iops . fileState . setSharedHandlesLocked ( flags , & h ) iops . fileState . handlesMu . Unlock ( ) } return NewFile ( ctx , d , name , flags , iops , & h ) , nil }
Creates a new Inode at name and returns its File based on the session's cache policy.
Creates a new Inode at name and returns its File based on the session ' s cache policy .
// Create replaces the directory fid with the newly created/opened // file, so clone this directory so it doesn't change out from under // this node. // Map the FileFlags to p9 OpenFlags. // If the parent directory has setgid enabled, change the new file's owner. // Could not create the file. // Get an unopened p9.File for the file we created so that it can be cloned // and re-opened multiple times after creation, while also getting its // attributes. Both are required for inodeOperations. // Construct the InodeOperations. // Construct the positive Dirent. // Construct the new file, caching the handles if allowed.