| Age | Commit message (Collapse) | Author |
|
No functional change intended.
|
|
|
|
If a file or device's open function returns ERESTART, respect that --
restart the syscall; don't pretend a signal has been delivered when
it was not. If an SA_RESTART signal was delivered, POSIX does not
allow it to fail with EINTR:
SA_RESTART
This flag affects the behavior of interruptible functions;
that is, those specified to fail with errno set to [EINTR].
If set, and a function specified as interruptible is
interrupted by this signal, the function shall restart and
shall not fail with [EINTR] unless otherwise specified. If
an interruptible function which uses a timeout is restarted,
the duration of the timeout following the restart is set to
an unspecified value that does not exceed the original
timeout value. If the flag is not set, interruptible
functions interrupted by this signal shall fail with errno
set to [EINTR].
https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaction.html
Nothing in the POSIX definition of open specifies otherwise.
In 1990, Kirk McKusick added these lines with a mysterious commit
message:
Author: Kirk McKusick <mckusick>
Date: Tue Apr 10 19:36:33 1990 -0800
eliminate longjmp from the kernel (for karels)
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 7bc7b39bbf..d572d3a32d 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -14,7 +14,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * @(#)vfs_syscalls.c 7.42 (Berkeley) 3/26/90
+ * @(#)vfs_syscalls.c 7.43 (Berkeley) 4/10/90
*/
#include "param.h"
@@ -530,8 +530,10 @@ copen(scp, fmode, cmode, ndp, resultfd)
if (error = vn_open(ndp, fmode, (cmode & 07777) &~ S_ISVTX)) {
crfree(fp->f_cred);
fp->f_count--;
- if (error == -1) /* XXX from fdopen */
- return (0); /* XXX from fdopen */
+ if (error == EJUSTRETURN) /* XXX from fdopen */
+ return (0); /* XXX from fdopen */
+ if (error == ERESTART)
+ error = EINTR;
scp->sc_ofile[indx] = NULL;
return (error);
}
(found via this git import of the CSRG history:
https://github.com/robohack/ucb-csrg-bsd/commit/cce2869b7ae5d360921eb411005b328a29c4a3fe)
This change appears to have served two related purposes:
1. The fdopen function (the erstwhile open routine for /dev/fd/N)
used to return -1 as a hack to mean it had just duplicated the fd;
it was recently changed by Mike Karels, in kern_descrip.c 7.9, to
return EJUSTRETURN, now defined to be -2, presumably to avoid a
conflict with ERESTART, defined to be -1. So this change finished
part of the change by Mike Karels to use a different magic return
code from fdopen.
Of course, today we use still another disgusting hack, EDUPFD, for
the same purpose, so none of this is relevant any more.
2. Prior to April 1990, the kernel handled signals during tsleep(9)
by longjmping out to the system call entry point or similar. In
April 1990, Mike Karels worked to convert all of that into
explicit unwind logic by passing through EINTR or ERESTART as
appropriate, instead of setjmp at each entry point.
However, it's not clear to me why this setjmp/longjmp and
fdopen/-1/EJUSTRETURN renovation justifies unconditional logic to map
ERESTART to EINTR in open(2). I suspect it was a mistake.
In 2013, the corresponding logic to map ERESTART to EINTR in open(2)
was removed from FreeBSD:
r246472 | kib | 2013-02-07 14:53:33 +0000 (Thu, 07 Feb 2013) | 11 lines
Stop translating the ERESTART error from the open(2) into EINTR.
Posix requires that open(2) is restartable for SA_RESTART.
For non-posix objects, in particular, devfs nodes, still disable
automatic restart of the opens. The open call to a driver could have
significant side effects for the hardware.
Noted and reviewed by: jilles
Discussed with: bde
MFC after: 2 weeks
Index: vfs_syscalls.c
===================================================================
--- vfs_syscalls.c (revision 246471)
+++ vfs_syscalls.c (revision 246472)
@@ -1106,8 +1106,6 @@
goto success;
}
- if (error == ERESTART)
- error = EINTR;
goto bad;
}
td->td_dupfd = 0;
https://cgit.freebsd.org/src/commit/sys/kern/vfs_syscalls.c?id=2ca49983425886121b506cb5126b60a705afc38c
It's not clear to me that there's any reason to treat device nodes
specially here; in fact, if a driver's .d_open routine sleeps and is
woken by a concurrent revoke without a signal pending or with an
SA_RESTART signal pending, it is wrong for it to fail with EINTR.
But it MUST restart the whole system call rather than continue
sleeping in a loop or just exit the loop and continue to open,
because it is mandatory in the security model of revoke for open(2)
to retry the permissions check at that point.
PR kern/57260
XXX pullup-8
XXX pullup-9
XXX pullup-10
|
|
|
|
via kn_selnext:
- klist_init()
- klist_fini()
- klist_insert()
- klist_remove()
These provide some API insulation from the implementation details of these
lists (but not completely; see vn_knote_attach() and vn_knote_detach()).
Currently just a wrapper around SLIST(9).
This will make it significantly easier to switch kn_selnext linkage
to a different kind of list.
|
|
|
|
fs_klist and take the kqueue_misc_lock inside the event callback.
However, that list can be modified by the attach and detach callbacks,
which could result in the walker stepping right off a cliff.
Instead, we give the fs_klist it's own lock, and hold it while we
call knote(), using the NOTE_SUBMIT protocol. Also, fs_filtops
into vfs_syscalls.c so all of the locking logic is contained in one
file (there is precedence with sig_filtops). fs_filtops is now marked
MPSAFE.
|
|
Previously only vnodes allowed lseek/pread[v]/pwrite[v], which meant
converting a regular device to a cloning device doesn't always work.
Semantics is:
(*fp->f_ops->fo_seek)(fp, delta, whence, newoffp, flags)
1. Compute a new offset according to whence + delta -- that is, if
whence is SEEK_CUR, add delta to fp->f_offset; if whence is
SEEK_END, add delta to end of file; if whence is SEEK_CUR, use delta
as is.
2. If newoffp is nonnull, return the new offset in *newoffp.
3. If flags & FOF_UPDATE_OFFSET, set fp->f_offset to the new offset.
Access to fp->f_offset, and *newoffp if newoffp = &fp->f_offset, must
happen under the object lock (e.g., vnode lock), in order to
synchronize fp->f_offset reads and writes.
This change has the side effect that every call to VOP_SEEK happens
under the vnode lock now, when previously it didn't. However, from a
review of all the VOP_SEEK implementations, it does not appear that
any file system even examines the vnode, let alone locks it. So I
think this is safe -- and essentially the only reasonable way to do
things, given that it is used to validate a change from oldoff to
newoff, and oldoff becomes stale the moment we unlock the vnode.
No kernel bump because this reuses a spare entry in struct fileops,
and it is safe for the entry to be null, so all existing fileops will
continue to work as before (rejecting seek).
|
|
|
|
Cloning devices (and also things like /dev/stderr) work by allocating
a struct file, stuffing it in the file table (which is a layer
violation), stuffing the file descriptor number for it in a magic
field of struct lwp (which is gross), and then "failing" with one of
two magic errnos, EDUPFD or EMOVEFD.
Before this commit, all callers of vn_open in the kernel (there are
quite a few) were expected to check for these errors and handle the
situation. Needless to say, none of them except for open() itself did,
resulting in internal negative errnos being returned to userspace.
This hack is fairly deeply rooted and cannot be eliminated all at
once. This commit adds logic to handle the magic errnos inside
vn_open; now on success vn_open returns either a vnode or an integer
file descriptor, along with a flag that says whether the underlying
code requested EDUPFD or EMOVEFD. Callers not prepared to cope with
file descriptors can pass NULL for the extra return values, in which
case if a file descriptor would be produced vn_open fails with
EOPNOTSUPP.
Since I'm rearranging vn_open's signature anyway, stop exposing struct
nameidata. Instead, take three arguments: an optional vnode to use as
the starting point (like openat()), the path, and additional namei
flags to use, restricted to NOCHROOT and TRYEMULROOT. (Other namei
behavior, e.g. NOFOLLOW, can be requested via the open flags.)
This change requires a kernel bump. Ride the one an hour ago.
(That was supposed to be coordinated; did not intend to let an hour
slip by. My fault.)
|
|
(also prohibit syncing ranges at start offsets less than zero)
|
|
|
|
which relied on taking extra vnode refs.
Having benchmarked various experimental changes over the past few months it
seems that it's better to avoid vnode refs as much as possible. cwdi_lock
as a RW lock already did that to some extent for getcwd() and will permit
the same for namei() too.
|
|
rather than BC_BUSY. Removes the dependency on bufhash.
|
|
and getcwd():
- push vnode locking back as far as possible.
- do most lookups directly in the namecache, avoiding vnode locks & refs.
- don't block new refs to vnodes across VOP_INACTIVE().
- get shared locks for VOP_LOOKUP() if the file system supports it.
- correct lock types for VOP_ACCESS() / VOP_GETATTR() in a few places.
Possible future enhancements:
- make the lookups lockless.
- support dotdot lookups by being lockless and inferring absence of chroot.
- maybe make it work for layered file systems.
- avoid vnode references at the root & cwd.
|
|
The restriction that a fd passed to fdatasync(2) must be writable was
added in 2003 in order to comply with POSIX. Since then, POSIX has
removed that requirement, and POSIX-valid programs have been therefore
encountering errors on NetBSD.
Patch by Paul Ripke after discussion on netbsd-users. Issue
discovered with pkgsrc/databases/mongodb3 as used by pkgsrc/net/unifi.
|
|
|
|
- Have a stab at clustering the members of vnode_t and vnode_impl_t in a
more cache-conscious way. With that done, go back to adjusting v_usecount
with atomics and keep vi_lock directly in vnode_impl_t (saves KVA).
- Allow VOP_LOCK(LK_NONE) for the benefit of VFS_VGET() and VFS_ROOT().
Make sure LK_UPGRADE always comes with LK_NOWAIT.
- Make cwdinfo use mostly lockless.
|
|
false positive with kMSan.
Here, LLVM reorders the conditions and checks 'vattr' before 'error'. But
if 'error' is non-zero then 'vattr' is not initialized, and kMSan notices
the uninitialized memory read.
|
|
allow us to get shared locks (or no lock) on the returned vnode. Matches
FreeBSD.
|
|
|
|
|
|
unsigned in compat code)
|
|
The new member is caled f_mntfromlabel and it is the dkw_wname
of the corresponding wedge. This is now used by df -W to display
the mountpoint name as NAME=
|
|
sys/kern/vfs_syscalls.c:3939:4, signed integer overflow: 503923632 * 1000 cannot be represented in type 'int'
Reported-by: syzbot+4cfc86ffd30e8678f68d@syzkaller.appspotmail.com
|
|
|
|
should depend on tptr[] instead.
|
|
This behavior is requested in ATF tests.
|
|
mknod with mode & S_IFIFO and dev=0 shall behave like mkfifo.
Update the documentation to reflect this state.
Add ATF tests.
This is an in-kernel implementation as typically user-space programs use
mkfifo(2) directly, however whenever there is need to bypass libc (like in
valgrind) then portable POSIX software calls the mknod syscall.
Noted on tech-kern@ by Greg Troxel.
|
|
It was introduced by an accident in previous commit to this file.
Detected by syzbot:
https://syzkaller.appspot.com/text?tag=CrashLog&x=16635d9ea00000
|
|
No functional change intended.
|
|
|
|
discussed on irc.
NFCI intended.
Ride the earlier kernel bump - it;s getting crowded.
|
|
The v_mount field for vnodes on the same file system as "from"
is now stable for referenced vnodes.
VFS_RENAMELOCK no longer may use lock from an unreferenced and
freed "struct mount".
|
|
Fixes PR 53850
|
|
Restore the original behavior before merging the compat refactoring branch.
Now:
- no compat_10 -> perform pathbuf_copyin() and report EFAULT
- compat_10 and error -> report error
- compat_10 and success -> return file descriptor for "."
PR kern/53948
|
|
the rest of the syscall; don't return prematurely, as we'll report
success (return value 0) but won't have set up the fd.
|
|
This should address kern/53948 (thanks, kamil@, for the PR and for
testing the fix)
|
|
Opengroup says "The openat() function shall be equivalent to the open() function except in the case where path specifies a relative path", but
says nothing about fdat usage when path is absolute;
https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html
We used to always reslove fdat, leading to error if it was invalid (e.g.: -1). That caused portability problem with other systems that
just ignore it. See discussion in a pull request to work around that
problem with MariaDB: https://github.com/MariaDB/server/pull/838
We fix the problem by ignoring fdat when path is absolute.
|
|
<subsystem>_<function>_<version>_hook
NFCI
XXX Note that although this introduces a change in the kernel-to-
XXX module interface, we are NOT bumping the kernel version number.
XXX We will bump the version number once the interface stabilizes.
|
|
|
|
XXX: Does not work yet
|
|
|
|
kmem_alloc() with KM_SLEEP
kmem_zalloc() with KM_SLEEP
percpu_alloc()
pserialize_create()
psref_class_create()
all of these paths include an assertion that the allocation has not failed,
so callers should not assert that again.
|
|
Adapt sched_sync() and do_sys_sync().
|
|
|
|
No change to vp -- the plan is to replace the node by the
componentname in the vop parameters, and let all directory vops do
lookups internally.
Proposed on tech-kern with no objections:
https://mail-index.netbsd.org/tech-kern/2017/04/17/msg021825.html
|
|
Remove argument "keepref" from vfs_unbusy() and add vfs_ref() where needed.
|
|
struct mount. Rename vfs_destroy(mp) to vfs_rele(mp) and replace
incrementing mp->mnt_refcnt with vfs_ref(mp).
|
|
|