summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fs
AgeCommit message (Collapse)Author
2019-05-14Start of support for /proc/pid/cgroup file.Nicolas Lacasse
PiperOrigin-RevId: 248263378 Change-Id: Ic057d2bb0b6212110f43ac4df3f0ac9bf931ab98
2019-05-14Remove false commentMichael Pratt
PiperOrigin-RevId: 248249285 Change-Id: I9b6d267baa666798b22def590ff20c9a118efd47
2019-05-09Implement fallocate(2)Fabricio Voznika
Closes #225 PiperOrigin-RevId: 247508791 Change-Id: I04f47cf2770b30043e5a272aba4ba6e11d0476cc
2019-05-08Set the FilesytemType in MountSource from the Filesystem.Nicolas Lacasse
And stop storing the Filesystem in the MountSource. This allows us to decouple the MountSource filesystem type from the name of the filesystem. PiperOrigin-RevId: 247292982 Change-Id: I49cbcce3c17883b7aa918ba76203dfd6d1b03cc8
2019-05-07Remove defers from gofer.contextFileFabricio Voznika
Most are single line methods in hot paths. PiperOrigin-RevId: 247050267 Change-Id: I428d78723fe00b57483185899dc8fa9e1f01e2ea
2019-05-03gofer: don't leak file descriptorsAndrei Vagin
Fixes #219 PiperOrigin-RevId: 246568639 Change-Id: Ic7afd15dde922638d77f6429c508d1cbe2e4288a
2019-04-30Update reference to old typeMichael Pratt
PiperOrigin-RevId: 246036806 Change-Id: I5554a43a1f8146c927402db3bf98488a2da0fbe7
2019-04-30Implement async MemoryFile eviction, and use it in CachingInodeOperations.Jamie Liu
This feature allows MemoryFile to delay eviction of "optional" allocations, such as unused cached file pages. Note that this incidentally makes CachingInodeOperations writeback asynchronous, in the sense that it doesn't occur until eviction; this is necessary because between when a cached page becomes evictable and when it's evicted, file writes (via CachingInodeOperations.Write) may dirty the page. As currently implemented, this feature won't meaningfully impact steady-state memory usage or caching; the reclaimer goroutine will schedule eviction as soon as it runs out of other work to do. Future CLs increase caching by adding constraints on when eviction is scheduled. PiperOrigin-RevId: 246014822 Change-Id: Ia85feb25a2de92a48359eb84434b6ec6f9bea2cb
2019-04-29Implement the MSG_CTRUNC msghdr flag for Unix sockets.Ian Gudger
Updates google/gvisor#206 PiperOrigin-RevId: 245880573 Change-Id: Ifa715e98d47f64b8a32b04ae9378d6cd6bd4025e
2019-04-29Change copyright notice to "The gVisor Authors"Michael Pratt
Based on the guidelines at https://opensource.google.com/docs/releasing/authors/. 1. $ rg -l "Google LLC" | xargs sed -i 's/Google LLC.*/The gVisor Authors./' 2. Manual fixup of "Google Inc" references. 3. Add AUTHORS file. Authors may request to be added to this file. 4. Point netstack AUTHORS to gVisor AUTHORS. Drop CONTRIBUTORS. Fixes #209 PiperOrigin-RevId: 245823212 Change-Id: I64530b24ad021a7d683137459cafc510f5ee1de9
2019-04-29Allow and document bug ids in gVisor codebase.Nicolas Lacasse
PiperOrigin-RevId: 245818639 Change-Id: I03703ef0fb9b6675955637b9fe2776204c545789
2019-04-26Fix reference counting bug in /proc/PID/fdinfo/.Kevin Krakauer
PiperOrigin-RevId: 245452217 Change-Id: I7164d8f57fe34c17e601079eb9410a6d95af1869
2019-04-25Don't enforce NAME_MAX in fs.Dirent.walk().Jamie Liu
Maximum filename length is filesystem-dependent, and obtained via statfs::f_namelen. This limit is usually 255 bytes (NAME_MAX), but not always. For example, VFAT supports filenames of up to 255... UCS-2 characters, which Linux conservatively takes to mean UTF-8-encoded bytes: fs/fat/inode.c:fat_statfs(), FAT_LFN_LEN * NLS_MAX_CHARSET_SIZE. As a result, Linux's VFS does not enforce NAME_MAX: $ rg --maxdepth=1 '\WNAME_MAX\W' fs/ include/linux/ fs/libfs.c 38: buf->f_namelen = NAME_MAX; 64: if (dentry->d_name.len > NAME_MAX) include/linux/relay.h 74: char base_filename[NAME_MAX]; /* saved base filename */ include/linux/fscrypt.h 149: * filenames up to NAME_MAX bytes, since base64 encoding expands the length. include/linux/exportfs.h 176: * understanding that it is already pointing to a a %NAME_MAX+1 sized Remove this check from core VFS, and add it to ramfs (and by extension tmpfs), where it is actually applicable: mm/shmem.c:shmem_dir_inode_operations.lookup == simple_lookup *does* enforce NAME_MAX. PiperOrigin-RevId: 245324748 Change-Id: I17567c4324bfd60e31746a5270096e75db963fac
2019-04-22Fix doc typoMichael Pratt
PiperOrigin-RevId: 244773890 Change-Id: I2d0cd7789771276ba545b38efff6d3e24133baaa
2019-04-17Use FD limit and file size limit from hostFabricio Voznika
FD limit and file size limit is read from the host, instead of using hard-coded defaults, given that they effect the sandbox process. Also limit the direct cache to use no more than half if the available FDs. PiperOrigin-RevId: 244050323 Change-Id: I787ad0fdf07c49d589e51aebfeae477324fe26e6
2019-04-11Use open fids when fstat()ing gofer files.Jamie Liu
PiperOrigin-RevId: 243018347 Change-Id: I1e5b80607c1df0747482abea61db7fcf24536d37
2019-04-10Fix uses of RootFromContext.Nicolas Lacasse
RootFromContext can return a dirent with reference taken, or nil. We must call DecRef if (and only if) a real dirent is returned. PiperOrigin-RevId: 242965515 Change-Id: Ie2b7b4cb19ee09b6ccf788b71f3fd7efcdf35a11
2019-04-10DATA RACE in fs.(*Dirent).fullNameYong He
add renameMu.Lock when oldParent == newParent in order to avoid data race in following report: WARNING: DATA RACE Read at 0x00c000ba2160 by goroutine 405: gvisor.googlesource.com/gvisor/pkg/sentry/fs.(*Dirent).fullName() pkg/sentry/fs/dirent.go:246 +0x6c gvisor.googlesource.com/gvisor/pkg/sentry/fs.(*Dirent).FullName() pkg/sentry/fs/dirent.go:356 +0x8b gvisor.googlesource.com/gvisor/pkg/sentry/kernel.(*FDMap).String() pkg/sentry/kernel/fd_map.go:135 +0x1e0 fmt.(*pp).handleMethods() GOROOT/src/fmt/print.go:603 +0x404 fmt.(*pp).printArg() GOROOT/src/fmt/print.go:686 +0x255 fmt.(*pp).doPrintf() GOROOT/src/fmt/print.go:1003 +0x33f fmt.Fprintf() GOROOT/src/fmt/print.go:188 +0x7f gvisor.googlesource.com/gvisor/pkg/log.(*Writer).Emit() pkg/log/log.go:121 +0x89 gvisor.googlesource.com/gvisor/pkg/log.GoogleEmitter.Emit() pkg/log/glog.go:162 +0x1acc gvisor.googlesource.com/gvisor/pkg/log.(*GoogleEmitter).Emit() <autogenerated>:1 +0xe1 gvisor.googlesource.com/gvisor/pkg/log.(*BasicLogger).Debugf() pkg/log/log.go:177 +0x111 gvisor.googlesource.com/gvisor/pkg/log.Debugf() pkg/log/log.go:235 +0x66 gvisor.googlesource.com/gvisor/pkg/sentry/kernel.(*Task).Debugf() pkg/sentry/kernel/task_log.go:48 +0xfe gvisor.googlesource.com/gvisor/pkg/sentry/kernel.(*Task).DebugDumpState() pkg/sentry/kernel/task_log.go:66 +0x11f gvisor.googlesource.com/gvisor/pkg/sentry/kernel.(*runApp).execute() pkg/sentry/kernel/task_run.go:272 +0xc80 gvisor.googlesource.com/gvisor/pkg/sentry/kernel.(*Task).run() pkg/sentry/kernel/task_run.go:91 +0x24b Previous write at 0x00c000ba2160 by goroutine 423: gvisor.googlesource.com/gvisor/pkg/sentry/fs.Rename() pkg/sentry/fs/dirent.go:1628 +0x61f gvisor.googlesource.com/gvisor/pkg/sentry/syscalls/linux.renameAt.func1.1() pkg/sentry/syscalls/linux/sys_file.go:1864 +0x1f8 gvisor.googlesource.com/gvisor/pkg/sentry/syscalls/linux.fileOpAt( gvisor.googlesource.com/g/linux/sys_file.go:51 +0x20f gvisor.googlesource.com/gvisor/pkg/sentry/syscalls/linux.renameAt.func1() pkg/sentry/syscalls/linux/sys_file.go:1852 +0x218 gvisor.googlesource.com/gvisor/pkg/sentry/syscalls/linux.fileOpAt() pkg/sentry/syscalls/linux/sys_file.go:51 +0x20f gvisor.googlesource.com/gvisor/pkg/sentry/syscalls/linux.renameAt() pkg/sentry/syscalls/linux/sys_file.go:1840 +0x180 gvisor.googlesource.com/gvisor/pkg/sentry/syscalls/linux.Rename() pkg/sentry/syscalls/linux/sys_file.go:1873 +0x60 gvisor.googlesource.com/gvisor/pkg/sentry/kernel.(*Task).executeSyscall() pkg/sentry/kernel/task_syscall.go:165 +0x17a gvisor.googlesource.com/gvisor/pkg/sentry/kernel.(*Task).doSyscallInvoke() pkg/sentry/kernel/task_syscall.go:283 +0xb4 gvisor.googlesource.com/gvisor/pkg/sentry/kernel.(*Task).doSyscallEnter() pkg/sentry/kernel/task_syscall.go:244 +0x10c gvisor.googlesource.com/gvisor/pkg/sentry/kernel.(*Task).doSyscall() pkg/sentry/kernel/task_syscall.go:219 +0x1e3 gvisor.googlesource.com/gvisor/pkg/sentry/kernel.(*runApp).execute() pkg/sentry/kernel/task_run.go:215 +0x15a9 gvisor.googlesource.com/gvisor/pkg/sentry/kernel.(*Task).run() pkg/sentry/kernel/task_run.go:91 +0x24b Reported-by: syzbot+e1babbf756fab380dfff@syzkaller.appspotmail.com Change-Id: Icd2620bb3ea28b817bf0672d454a22b9d8ee189a PiperOrigin-RevId: 242938741
2019-04-10Start saving MountSource.DirentCache.Nicolas Lacasse
DirentCache is already a savable type, and it ensures that it is empty at the point of Save. There is no reason not to save it along with the MountSource. This did uncover an issue where not all MountSources were properly flushed before Save. If a mount point has an open file and is then unmounted, we save the MountSource without flushing it first. This CL also fixes that by flushing all MountSources for all open FDs on Save. PiperOrigin-RevId: 242906637 Change-Id: I3acd9d52b6ce6b8c989f835a408016cb3e67018f
2019-04-10Fixed /proc/cpuinfo permissionsShiva Prasanth
This also applies these permissions to other static proc files. Change-Id: I4167e585fed49ad271aa4e1f1260babb3239a73d PiperOrigin-RevId: 242898575
2019-04-08Export kernel.SignalInfoPriv.Jamie Liu
Also add kernel.SignalInfoNoInfo, and use it in RLIMIT_FSIZE checks. PiperOrigin-RevId: 242562428 Change-Id: I4887c0e1c8f5fddcabfe6d4281bf76d2f2eafe90
2019-04-08Intermediate ram fs dirs should be writable.Nicolas Lacasse
We construct a ramfs tree of "scaffolding" directories for all mount points, so that a directory exists that each mount point can be mounted over. We were creating these directories without write permissions, which meant that they were not wribable even when underlayed under a writable filesystem. They should be writable. PiperOrigin-RevId: 242507789 Change-Id: I86645e35417560d862442ff5962da211dbe9b731
2019-04-05Use string type for extended attribute values, instead of []byte.Nicolas Lacasse
Strings are a better fit for this usage because they are immutable in Go, and can contain arbitrary bytes. It also allows us to avoid casting bytes to string (and the associated allocation) in the hot path when checking for overlay whiteouts. PiperOrigin-RevId: 242208856 Change-Id: I7699ae6302492eca71787dd0b72e0a5a217a3db2
2019-04-04gvisor: Add support for the MS_NOEXEC mount optionAndrei Vagin
https://github.com/google/gvisor/issues/145 PiperOrigin-RevId: 242044115 Change-Id: I8f140fe05e32ecd438b6be218e224e4b7fe05878
2019-04-03Don't release d.mu in checks for child-existence.Nicolas Lacasse
Dirent.exists() is called in Create to check whether a child with the given name already exists. Dirent.exists() calls walk(), and before this CL allowed walk() to drop d.mu while calling d.Inode.Lookup. During this existence check, a racing Rename() can acquire d.mu and create a new child of the dirent with the same name. (Note that the source and destination of the rename must be in the same directory, otherwise renameMu will be taken preventing the race.) In this case, d.exists() can return false, even though a child with the same name actually does exist. This CL changes d.exists() so that it does not release d.mu while walking, thus preventing the race with Rename. It also adds comments noting that lockForRename may not take renameMu if the source and destination are in the same directory, as this is a bit surprising (at least it was to me). PiperOrigin-RevId: 241842579 Change-Id: I56524870e39dfcd18cab82054eb3088846c34813
2019-04-03Fix index out of bounds in tty implementation.Kevin Krakauer
The previous implementation revolved around runes instead of bytes, which caused weird behavior when converting between the two. For example, peekRune would read the byte 0xff from a buffer, convert it to a rune, then return it. As rune is an alias of int32, 0xff was 0-padded to int32(255), which is the hex code point for ?. However, peekRune also returned the length of the byte (1). When calling utf8.EncodeRune, we only allocated 1 byte, but tried the write the 2-byte character ?. tl;dr: I apparently didn't understand runes when I wrote this. PiperOrigin-RevId: 241789081 Change-Id: I14c788af4d9754973137801500ef6af7ab8a8727
2019-04-03Addresses data race in tty implementation.Kevin Krakauer
Also makes the safemem reading and writing inline, as it makes it easier to see what locks are held. PiperOrigin-RevId: 241775201 Change-Id: Ib1072f246773ef2d08b5b9a042eb7e9e0284175c
2019-04-02Add test that symlinking over a directory returns EEXIST.Nicolas Lacasse
Also remove comments in InodeOperations that required that implementation of some Create* operations ensure that the name does not already exist, since these checks are all centralized in the Dirent. PiperOrigin-RevId: 241637335 Change-Id: Id098dc6063ff7c38347af29d1369075ad1e89a58
2019-04-02device: fix device major/minorWei Zhang
Current gvisor doesn't give devices a right major and minor number. When testing golang supporting of gvisor, I run the test case below: ``` $ docker run -ti --runtime runsc golang:1.12.1 bash -c "cd /usr/local/go/src && ./run.bash " ``` And it reports some errors, one of them is: "--- FAIL: TestDevices (0.00s) --- FAIL: TestDevices//dev/null_1:3 (0.00s) dev_linux_test.go:45: for /dev/null Major(0x0) == 0, want 1 dev_linux_test.go:48: for /dev/null Minor(0x0) == 0, want 3 dev_linux_test.go:51: for /dev/null Mkdev(1, 3) == 0x103, want 0x0 --- FAIL: TestDevices//dev/zero_1:5 (0.00s) dev_linux_test.go:45: for /dev/zero Major(0x0) == 0, want 1 dev_linux_test.go:48: for /dev/zero Minor(0x0) == 0, want 5 dev_linux_test.go:51: for /dev/zero Mkdev(1, 5) == 0x105, want 0x0 --- FAIL: TestDevices//dev/random_1:8 (0.00s) dev_linux_test.go:45: for /dev/random Major(0x0) == 0, want 1 dev_linux_test.go:48: for /dev/random Minor(0x0) == 0, want 8 dev_linux_test.go:51: for /dev/random Mkdev(1, 8) == 0x108, want 0x0 --- FAIL: TestDevices//dev/full_1:7 (0.00s) dev_linux_test.go:45: for /dev/full Major(0x0) == 0, want 1 dev_linux_test.go:48: for /dev/full Minor(0x0) == 0, want 7 dev_linux_test.go:51: for /dev/full Mkdev(1, 7) == 0x107, want 0x0 --- FAIL: TestDevices//dev/urandom_1:9 (0.00s) dev_linux_test.go:45: for /dev/urandom Major(0x0) == 0, want 1 dev_linux_test.go:48: for /dev/urandom Minor(0x0) == 0, want 9 dev_linux_test.go:51: for /dev/urandom Mkdev(1, 9) == 0x109, want 0x0 " So I think we'd better assign to them correct major/minor numbers following linux spec. Signed-off-by: Wei Zhang <zhangwei198900@gmail.com> Change-Id: I4521ee7884b4e214fd3a261929e3b6dac537ada9 PiperOrigin-RevId: 241609021
2019-04-01gvisor: convert ilist to ilist:generic_listAndrei Vagin
ilist:generic_list works faster (cl/240185278) and the code looks cleaner without type casting. PiperOrigin-RevId: 241381175 Change-Id: I8487ab1d73637b3e9733c253c56dce9e79f0d35f
2019-03-29Return srclen in proc.idMapFileOperations.Write.Jamie Liu
PiperOrigin-RevId: 241037926 Change-Id: I4b0381ac1c7575e8b861291b068d3da22bc03850
2019-03-28Internal change.Googler
PiperOrigin-RevId: 240842801 Change-Id: Ibbd6f849f9613edc1b1dd7a99a97d1ecdb6e9188
2019-03-28Clean up gofer handle caching.Jamie Liu
- Document fsutil.CachedFileObject.FD() requirements on access permissions, and change gofer.inodeFileState.FD() to honor them. Fixes #147. - Combine gofer.inodeFileState.readonly and gofer.inodeFileState.readthrough, and simplify handle caching logic. - Inline gofer.cachePolicy.cacheHandles into gofer.inodeFileState.setSharedHandles, because users with access to gofer.inodeFileState don't necessarily have access to the fs.Inode (predictably, this is a save/restore problem). Before this CL: $ docker run --runtime=runsc-d -v $(pwd)/gvisor/repro:/root/repro -it ubuntu bash root@34d51017ed67:/# /root/repro/runsc-b147 mmap: 0x7f3c01e45000 Segmentation fault After this CL: $ docker run --runtime=runsc-d -v $(pwd)/gvisor/repro:/root/repro -it ubuntu bash root@d3c3cb56bbf9:/# /root/repro/runsc-b147 mmap: 0x7f78987ec000 o PiperOrigin-RevId: 240818413 Change-Id: I49e1d4a81a0cb9177832b0a9f31a10da722a896b
2019-03-27Add rsslim field in /proc/pid/stat.Nicolas Lacasse
PiperOrigin-RevId: 240681675 Change-Id: Ib214106e303669fca2d5c744ed5c18e835775161
2019-03-27Add start time to /proc/<pid>/stat.Nicolas Lacasse
The start time is the number of clock ticks between the boot time and application start time. PiperOrigin-RevId: 240619475 Change-Id: Ic8bd7a73e36627ed563988864b0c551c052492a5
2019-03-27Dev device methods should take pointer receiver.Nicolas Lacasse
PiperOrigin-RevId: 240600504 Change-Id: I7dd5f27c8da31f24b68b48acdf8f1c19dbd0c32d
2019-03-26Implement memfd_create.Rahat Mahmood
Memfds are simply anonymous tmpfs files with no associated mounts. Also implementing file seals, which Linux only implements for memfds at the moment. PiperOrigin-RevId: 240450031 Change-Id: I31de78b950101ae8d7a13d0e93fe52d98ea06f2f
2019-03-25Call memmap.Mappable.Translate with more conservative usermem.AccessType.Jamie Liu
MM.insertPMAsLocked() passes vma.maxPerms to memmap.Mappable.Translate (although it unsets AccessType.Write if the vma is private). This somewhat simplifies handling of pmas, since it means only COW-break needs to replace existing pmas. However, it also means that a MAP_SHARED mapping of a file opened O_RDWR dirties the file, regardless of the mapping's permissions and whether or not the mapping is ever actually written to with I/O that ignores permissions (e.g. ptrace(PTRACE_POKEDATA)). To fix this: - Change the pma-getting path to request only the permissions that are required for the calling access. - Change memmap.Mappable.Translate to take requested permissions, and return allowed permissions. This preserves the existing behavior in the common cases where the memmap.Mappable isn't fsutil.CachingInodeOperations and doesn't care if the translated platform.File pages are written to. - Change the MM.getPMAsLocked path to support permission upgrading of pmas outside of copy-on-write. PiperOrigin-RevId: 240196979 Change-Id: Ie0147c62c1fbc409467a6fa16269a413f3d7d571
2019-03-21Replace manual pty copies to/from userspace with safemem operations.Kevin Krakauer
Also, changing queue.writeBuf from a buffer.Bytes to a [][]byte should reduce copying and reallocating of slices. PiperOrigin-RevId: 239713547 Change-Id: I6ee5ff19c3ee2662f1af5749cae7b73db0569e96
2019-03-19netstack: reduce MSS from SYN to account tcp optionsAndrei Vagin
See: https://tools.ietf.org/html/rfc6691#section-2 PiperOrigin-RevId: 239305632 Change-Id: Ie8eb912a43332e6490045dc95570709c5b81855e
2019-03-18Remove references to replaced child in Rename in ramfs/agentfsMichael Pratt
In the case of a rename replacing an existing destination inode, ramfs Rename failed to first remove the replaced inode. This caused: 1. A leak of a reference to the inode (making it live indefinitely). 2. For directories, a leak of the replaced directory's .. link to the parent. This would cause the parent's link count to incorrectly increase. (2) is much simpler to test than (1), so that's what I've done. agentfs has a similar bug with link count only, so the Dirent layer informs the Inode if this is a replacing rename. Fixes #133 PiperOrigin-RevId: 239105698 Change-Id: I4450af2462d8ae3339def812287213d2cbeebde0
2019-03-14Decouple filemem from platform and move it to pgalloc.MemoryFile.Jamie Liu
This is in preparation for improved page cache reclaim, which requires greater integration between the page cache and page allocator. PiperOrigin-RevId: 238444706 Change-Id: Id24141b3678d96c7d7dc24baddd9be555bffafe4
2019-03-14Use WalkGetAttr in gofer.inodeOperations.Create.Jamie Liu
p9.Twalk.handle() with a non-empty path also stats the walked-to path anyway, so the preceding GetAttr is completely wasted. PiperOrigin-RevId: 238440645 Change-Id: I7fbc7536f46b8157639d0d1f491e6aaa9ab688a3
2019-03-13Allow filesystem.Mount to take an optional interface argument.Nicolas Lacasse
PiperOrigin-RevId: 238360231 Change-Id: I5eaf8d26f8892f77d71c7fbd6c5225ef471cedf1
2019-03-12Clarify the platform.File interface.Jamie Liu
- Redefine some memmap.Mappable, platform.File, and platform.Memory semantics in terms of File reference counts (no functional change). - Make AddressSpace.MapFile take a platform.File instead of a raw FD, and replace platform.File.MapInto with platform.File.FD. This allows kvm.AddressSpace.MapFile to always use platform.File.MapInternal instead of maintaining its own (redundant) cache of file mappings in the sentry address space. PiperOrigin-RevId: 238044504 Change-Id: Ib73a11e4275c0da0126d0194aa6c6017a9cef64f
2019-03-06No need to check for negative uintptr.Nicolas Lacasse
Fixes #134 PiperOrigin-RevId: 237128306 Change-Id: I396e808484c18931fc5775970ec1f5ae231e1cb9
2019-03-04Make tmpfs respect MountNoATime now that fs.Handle is gone.Nicolas Lacasse
PiperOrigin-RevId: 236752802 Change-Id: I9e50600b2ae25d5f2ac632c4405a7a185bdc3c92
2019-03-01DecRef replaced dirent in inode_overlay.Nicolas Lacasse
PiperOrigin-RevId: 236352158 Change-Id: Ide5104620999eaef6820917505e7299c7b0c5a03
2019-02-28Fix procfs bugsRuidong Cao
Current procfs has some bugs. After executing ls twice, many dirs come out with same name like "1" or ".". Files like "cpuinfo" disappear. Here variable names is a slice with cap() > len(). Sort after appending to it will not alloc a new space and impact orignal slice. Same to m. Signed-off-by: Ruidong Cao <crdfrank@gmail.com> Change-Id: I83e5cd1c7968c6fe28c35ea4fee497488d4f9eef PiperOrigin-RevId: 236222270
2019-02-28Hold dataMu for writing in CachingInodeOperations.WriteOut.Jamie Liu
fsutil.SyncDirtyAll mutates the DirtySet. PiperOrigin-RevId: 236183349 Change-Id: I7e809d5b406ac843407e61eff17d81259a819b4f