Skip to content

Commit d58d576

Browse files
fvoznikagvisor-bot
authored andcommitted
Don't copy structs with sync.Mutex during initialization
During inititalization inode struct was copied around, but it isn't great pratice to copy it around since it contains ref count and sync.Mutex. Updates #1480 PiperOrigin-RevId: 315983788
1 parent 11dc95e commit d58d576

File tree

8 files changed

+65
-64
lines changed

8 files changed

+65
-64
lines changed

pkg/sentry/fsimpl/ext/block_map_file.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,16 @@ var _ io.ReaderAt = (*blockMapFile)(nil)
5858

5959
// newBlockMapFile is the blockMapFile constructor. It initializes the file to
6060
// physical blocks map with (at most) the first 12 (direct) blocks.
61-
func newBlockMapFile(regFile regularFile) (*blockMapFile, error) {
62-
file := &blockMapFile{regFile: regFile}
61+
func newBlockMapFile(args inodeArgs) (*blockMapFile, error) {
62+
file := &blockMapFile{}
6363
file.regFile.impl = file
64+
file.regFile.inode.init(args, &file.regFile)
6465

6566
for i := uint(0); i < 4; i++ {
66-
file.coverage[i] = getCoverage(regFile.inode.blkSize, i)
67+
file.coverage[i] = getCoverage(file.regFile.inode.blkSize, i)
6768
}
6869

69-
blkMap := regFile.inode.diskInode.Data()
70+
blkMap := file.regFile.inode.diskInode.Data()
7071
binary.Unmarshal(blkMap[:numDirectBlks*4], binary.LittleEndian, &file.directBlks)
7172
binary.Unmarshal(blkMap[numDirectBlks*4:(numDirectBlks+1)*4], binary.LittleEndian, &file.indirectBlk)
7273
binary.Unmarshal(blkMap[(numDirectBlks+1)*4:(numDirectBlks+2)*4], binary.LittleEndian, &file.doubleIndirectBlk)

pkg/sentry/fsimpl/ext/block_map_test.go

+13-16
Original file line numberDiff line numberDiff line change
@@ -85,20 +85,6 @@ func (n *blkNumGen) next() uint32 {
8585
// the inode covers and that is written to disk.
8686
func blockMapSetUp(t *testing.T) (*blockMapFile, []byte) {
8787
mockDisk := make([]byte, mockBMDiskSize)
88-
regFile := regularFile{
89-
inode: inode{
90-
fs: &filesystem{
91-
dev: bytes.NewReader(mockDisk),
92-
},
93-
diskInode: &disklayout.InodeNew{
94-
InodeOld: disklayout.InodeOld{
95-
SizeLo: getMockBMFileFize(),
96-
},
97-
},
98-
blkSize: uint64(mockBMBlkSize),
99-
},
100-
}
101-
10288
var fileData []byte
10389
blkNums := newBlkNumGen()
10490
var data []byte
@@ -125,9 +111,20 @@ func blockMapSetUp(t *testing.T) (*blockMapFile, []byte) {
125111
data = binary.Marshal(data, binary.LittleEndian, triplyIndirectBlk)
126112
fileData = append(fileData, writeFileDataToBlock(mockDisk, triplyIndirectBlk, 3, blkNums)...)
127113

128-
copy(regFile.inode.diskInode.Data(), data)
114+
args := inodeArgs{
115+
fs: &filesystem{
116+
dev: bytes.NewReader(mockDisk),
117+
},
118+
diskInode: &disklayout.InodeNew{
119+
InodeOld: disklayout.InodeOld{
120+
SizeLo: getMockBMFileFize(),
121+
},
122+
},
123+
blkSize: uint64(mockBMBlkSize),
124+
}
125+
copy(args.diskInode.Data(), data)
129126

130-
mockFile, err := newBlockMapFile(regFile)
127+
mockFile, err := newBlockMapFile(args)
131128
if err != nil {
132129
t.Fatalf("newBlockMapFile failed: %v", err)
133130
}

pkg/sentry/fsimpl/ext/directory.go

+5-6
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,15 @@ type directory struct {
5454
}
5555

5656
// newDirectory is the directory constructor.
57-
func newDirectory(inode inode, newDirent bool) (*directory, error) {
57+
func newDirectory(args inodeArgs, newDirent bool) (*directory, error) {
5858
file := &directory{
59-
inode: inode,
6059
childCache: make(map[string]*dentry),
6160
childMap: make(map[string]*dirent),
6261
}
63-
file.inode.impl = file
62+
file.inode.init(args, file)
6463

6564
// Initialize childList by reading dirents from the underlying file.
66-
if inode.diskInode.Flags().Index {
65+
if args.diskInode.Flags().Index {
6766
// TODO(b/134676337): Support hash tree directories. Currently only the '.'
6867
// and '..' entries are read in.
6968

@@ -74,15 +73,15 @@ func newDirectory(inode inode, newDirent bool) (*directory, error) {
7473

7574
// The dirents are organized in a linear array in the file data.
7675
// Extract the file data and decode the dirents.
77-
regFile, err := newRegularFile(inode)
76+
regFile, err := newRegularFile(args)
7877
if err != nil {
7978
return nil, err
8079
}
8180

8281
// buf is used as scratch space for reading in dirents from disk and
8382
// unmarshalling them into dirent structs.
8483
buf := make([]byte, disklayout.DirentSize)
85-
size := inode.diskInode.Size()
84+
size := args.diskInode.Size()
8685
for off, inc := uint64(0), uint64(0); off < size; off += inc {
8786
toRead := size - off
8887
if toRead > disklayout.DirentSize {

pkg/sentry/fsimpl/ext/extent_file.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@ var _ io.ReaderAt = (*extentFile)(nil)
3838
// newExtentFile is the extent file constructor. It reads the entire extent
3939
// tree into memory.
4040
// TODO(b/134676337): Build extent tree on demand to reduce memory usage.
41-
func newExtentFile(regFile regularFile) (*extentFile, error) {
42-
file := &extentFile{regFile: regFile}
41+
func newExtentFile(args inodeArgs) (*extentFile, error) {
42+
file := &extentFile{}
4343
file.regFile.impl = file
44+
file.regFile.inode.init(args, &file.regFile)
4445
err := file.buildExtTree()
4546
if err != nil {
4647
return nil, err

pkg/sentry/fsimpl/ext/extent_test.go

+10-12
Original file line numberDiff line numberDiff line change
@@ -177,21 +177,19 @@ func extentTreeSetUp(t *testing.T, root *disklayout.ExtentNode) (*extentFile, []
177177
t.Helper()
178178

179179
mockDisk := make([]byte, mockExtentBlkSize*10)
180-
mockExtentFile := &extentFile{
181-
regFile: regularFile{
182-
inode: inode{
183-
fs: &filesystem{
184-
dev: bytes.NewReader(mockDisk),
185-
},
186-
diskInode: &disklayout.InodeNew{
187-
InodeOld: disklayout.InodeOld{
188-
SizeLo: uint32(mockExtentBlkSize) * getNumPhyBlks(root),
189-
},
190-
},
191-
blkSize: mockExtentBlkSize,
180+
mockExtentFile := &extentFile{}
181+
args := inodeArgs{
182+
fs: &filesystem{
183+
dev: bytes.NewReader(mockDisk),
184+
},
185+
diskInode: &disklayout.InodeNew{
186+
InodeOld: disklayout.InodeOld{
187+
SizeLo: uint32(mockExtentBlkSize) * getNumPhyBlks(root),
192188
},
193189
},
190+
blkSize: mockExtentBlkSize,
194191
}
192+
mockExtentFile.regFile.inode.init(args, &mockExtentFile.regFile)
195193

196194
fileData := writeTree(&mockExtentFile.regFile.inode, mockDisk, node0, mockExtentBlkSize)
197195

pkg/sentry/fsimpl/ext/inode.go

+19-4
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func newInode(fs *filesystem, inodeNum uint32) (*inode, error) {
118118
}
119119

120120
// Build the inode based on its type.
121-
inode := inode{
121+
args := inodeArgs{
122122
fs: fs,
123123
inodeNum: inodeNum,
124124
blkSize: blkSize,
@@ -127,19 +127,19 @@ func newInode(fs *filesystem, inodeNum uint32) (*inode, error) {
127127

128128
switch diskInode.Mode().FileType() {
129129
case linux.ModeSymlink:
130-
f, err := newSymlink(inode)
130+
f, err := newSymlink(args)
131131
if err != nil {
132132
return nil, err
133133
}
134134
return &f.inode, nil
135135
case linux.ModeRegular:
136-
f, err := newRegularFile(inode)
136+
f, err := newRegularFile(args)
137137
if err != nil {
138138
return nil, err
139139
}
140140
return &f.inode, nil
141141
case linux.ModeDirectory:
142-
f, err := newDirectory(inode, fs.sb.IncompatibleFeatures().DirentFileType)
142+
f, err := newDirectory(args, fs.sb.IncompatibleFeatures().DirentFileType)
143143
if err != nil {
144144
return nil, err
145145
}
@@ -150,6 +150,21 @@ func newInode(fs *filesystem, inodeNum uint32) (*inode, error) {
150150
}
151151
}
152152

153+
type inodeArgs struct {
154+
fs *filesystem
155+
inodeNum uint32
156+
blkSize uint64
157+
diskInode disklayout.Inode
158+
}
159+
160+
func (in *inode) init(args inodeArgs, impl interface{}) {
161+
in.fs = args.fs
162+
in.inodeNum = args.inodeNum
163+
in.blkSize = args.blkSize
164+
in.diskInode = args.diskInode
165+
in.impl = impl
166+
}
167+
153168
// open creates and returns a file description for the dentry passed in.
154169
func (in *inode) open(rp *vfs.ResolvingPath, vfsd *vfs.Dentry, opts *vfs.OpenOptions) (*vfs.FileDescription, error) {
155170
ats := vfs.AccessTypesForOpenFlags(opts)

pkg/sentry/fsimpl/ext/regular_file.go

+4-13
Original file line numberDiff line numberDiff line change
@@ -43,28 +43,19 @@ type regularFile struct {
4343

4444
// newRegularFile is the regularFile constructor. It figures out what kind of
4545
// file this is and initializes the fileReader.
46-
func newRegularFile(inode inode) (*regularFile, error) {
47-
regFile := regularFile{
48-
inode: inode,
49-
}
50-
51-
inodeFlags := inode.diskInode.Flags()
52-
53-
if inodeFlags.Extents {
54-
file, err := newExtentFile(regFile)
46+
func newRegularFile(args inodeArgs) (*regularFile, error) {
47+
if args.diskInode.Flags().Extents {
48+
file, err := newExtentFile(args)
5549
if err != nil {
5650
return nil, err
5751
}
58-
59-
file.regFile.inode.impl = &file.regFile
6052
return &file.regFile, nil
6153
}
6254

63-
file, err := newBlockMapFile(regFile)
55+
file, err := newBlockMapFile(args)
6456
if err != nil {
6557
return nil, err
6658
}
67-
file.regFile.inode.impl = &file.regFile
6859
return &file.regFile, nil
6960
}
7061

pkg/sentry/fsimpl/ext/symlink.go

+6-7
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,17 @@ type symlink struct {
3030

3131
// newSymlink is the symlink constructor. It reads out the symlink target from
3232
// the inode (however it might have been stored).
33-
func newSymlink(inode inode) (*symlink, error) {
34-
var file *symlink
33+
func newSymlink(args inodeArgs) (*symlink, error) {
3534
var link []byte
3635

3736
// If the symlink target is lesser than 60 bytes, its stores in inode.Data().
3837
// Otherwise either extents or block maps will be used to store the link.
39-
size := inode.diskInode.Size()
38+
size := args.diskInode.Size()
4039
if size < 60 {
41-
link = inode.diskInode.Data()[:size]
40+
link = args.diskInode.Data()[:size]
4241
} else {
4342
// Create a regular file out of this inode and read out the target.
44-
regFile, err := newRegularFile(inode)
43+
regFile, err := newRegularFile(args)
4544
if err != nil {
4645
return nil, err
4746
}
@@ -52,8 +51,8 @@ func newSymlink(inode inode) (*symlink, error) {
5251
}
5352
}
5453

55-
file = &symlink{inode: inode, target: string(link)}
56-
file.inode.impl = file
54+
file := &symlink{target: string(link)}
55+
file.inode.init(args, file)
5756
return file, nil
5857
}
5958

0 commit comments

Comments
 (0)