Module Name: src Committed By: riastradh Date: Sat Apr 22 11:22:36 UTC 2023
Modified Files: src/sys/kern: vfs_vnops.c Log Message: readdir(2), lseek(2): Fix races in access to struct file::f_offset. For non-directory vnodes: - reading f_offset requires a shared or exclusive vnode lock - writing f_offset requires an exclusive vnode lock For directory vnodes, access (read or write) requires either: - a shared vnode lock AND f_lock, or - an exclusive vnode lock. This way, two files for the same underlying directory vnode can still do VOP_READDIR in parallel, but if two readdir(2) or lseek(2) calls run in parallel on the same file, the load and store of f_offset is atomic (otherwise, e.g., on 32-bit systems it might be torn and lead to corrupt offsets). There is still a potential problem: the _whole transaction_ of readdir(2) may not be atomic. For example, if thread A and thread B read n bytes of directory content, thread A might get bytes [0,n) and thread B might get bytes [n,2n) but f_offset might end up at n instead of 2n once both operations complete. (However, f_offset wouldn't be some corrupt garbled number like n & 0xffffffff00000000.) Fixing this would require either: (a) using an exclusive vnode lock in vn_readdir, (b) introducing a new lock that serializes vn_readdir on the same file (but ont necessarily the same vnode), or (c) proving it is safe to hold f_lock across VOP_READDIR, VOP_SEEK, and VOP_GETATTR. To generate a diff of this commit: cvs rdiff -u -r1.237 -r1.238 src/sys/kern/vfs_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.