summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan McDonald <danmcd@mnx.io>2022-10-03 14:13:13 -0400
committerDan McDonald <danmcd@mnx.io>2022-10-03 14:13:13 -0400
commit80d7725bf1e4fb33051ad152f649814a6aea8d62 (patch)
tree508febb84b3f87b333098cdcd668f94c9d63f1c1
parent4e09adb1ae71f9570a14be2e9c2e7d1fcd64b0cc (diff)
parent00bfaff92dad2fa278f0e40718333cf4864ad7d5 (diff)
downloadillumos-joyent-80d7725bf1e4fb33051ad152f649814a6aea8d62.tar.gz
[illumos-gate merge]
commit 00bfaff92dad2fa278f0e40718333cf4864ad7d5 14519 zfs_root should cache vnode commit b93865c3d90e9b0d73e338c9abb3293c35c571a8 14985 adjtime could be more const
-rw-r--r--usr/src/lib/libc/common/sys/adjtime.s2
-rw-r--r--usr/src/man/man2/adjtime.213
-rw-r--r--usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h1
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_vfsops.c61
-rw-r--r--usr/src/uts/common/os/sysent.c2
-rw-r--r--usr/src/uts/common/sys/time.h2
-rw-r--r--usr/src/uts/common/syscall/adjtime.c4
7 files changed, 55 insertions, 30 deletions
diff --git a/usr/src/lib/libc/common/sys/adjtime.s b/usr/src/lib/libc/common/sys/adjtime.s
index a860d6738d..be16f641aa 100644
--- a/usr/src/lib/libc/common/sys/adjtime.s
+++ b/usr/src/lib/libc/common/sys/adjtime.s
@@ -30,7 +30,7 @@
.file "adjtime.s"
/* C Library -- adjtime */
-/* int adjtime(struct timeval *delta, struct timeval *olddelta) */
+/* int adjtime(const struct timeval *delta, struct timeval *olddelta) */
#include "SYS.h"
diff --git a/usr/src/man/man2/adjtime.2 b/usr/src/man/man2/adjtime.2
index 93b0e4ac22..b4586b358a 100644
--- a/usr/src/man/man2/adjtime.2
+++ b/usr/src/man/man2/adjtime.2
@@ -1,19 +1,16 @@
'\" te
.\" Copyright 1989 AT&T Copyright (c) 1980 Regents of the University of California. All rights reserved. The Berkeley software License Agreement specifies the terms and conditions for redistribution. Copyright (c) 2003, Sun Microsystems, Inc. All Rights Reserved
-.TH ADJTIME 2 "Jan 20, 2003"
+.TH ADJTIME 2 "Sep 19, 2022"
.SH NAME
adjtime \- correct the time to allow synchronization of the system clock
.SH SYNOPSIS
-.LP
.nf
#include <sys/time.h>
-\fBint\fR \fBadjtime\fR(\fBstruct timeval *\fR\fIdelta\fR, \fBstruct timeval *\fR\fIolddelta\fR);
+\fBint\fR \fBadjtime\fR(\fBconst struct timeval *\fR\fIdelta\fR, \fBstruct timeval *\fR\fIolddelta\fR);
.fi
.SH DESCRIPTION
-.sp
-.LP
The \fBadjtime()\fR function adjusts the system's notion of the current time as
returned by \fBgettimeofday\fR(3C), advancing or retarding it by the amount of
time specified in the \fBstruct\fR \fBtimeval\fR pointed to by \fIdelta\fR.
@@ -47,13 +44,9 @@ Only a processes with appropriate privileges can adjust the time of day.
The adjustment value will be silently rounded to the resolution of the system
clock.
.SH RETURN VALUES
-.sp
-.LP
Upon successful completion, \fBadjtime()\fR returns \fB0\fR. Otherwise, it
returns \fB\(mi1\fR and sets \fBerrno\fR to indicate the error.
.SH ERRORS
-.sp
-.LP
The \fBadjtime()\fR function will fail if:
.sp
.ne 2
@@ -100,8 +93,6 @@ by \fIolddelta\fR is too small to contain the correct number of seconds.
.RE
.SH SEE ALSO
-.sp
-.LP
.BR date (1),
.BR gettimeofday (3C),
.BR privileges (7)
diff --git a/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h b/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h
index 0d1611b66c..e1d7139f60 100644
--- a/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h
+++ b/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h
@@ -68,6 +68,7 @@ struct zfsvfs {
krwlock_t z_teardown_inactive_lock;
list_t z_all_znodes; /* all vnodes in the fs */
kmutex_t z_znodes_lock; /* lock for z_all_znodes */
+ vnode_t *z_rootdir; /* mount root directory pointer */
vnode_t *z_ctldir; /* .zfs directory pointer */
boolean_t z_show_ctldir; /* expose .zfs in the root dir */
boolean_t z_issnap; /* true if this is a snapshot */
diff --git a/usr/src/uts/common/fs/zfs/zfs_vfsops.c b/usr/src/uts/common/fs/zfs/zfs_vfsops.c
index 86d83e7ace..606bcb8999 100644
--- a/usr/src/uts/common/fs/zfs/zfs_vfsops.c
+++ b/usr/src/uts/common/fs/zfs/zfs_vfsops.c
@@ -26,6 +26,7 @@
* Copyright 2020 Joyent, Inc.
* Copyright 2020 Joshua M. Clulow <josh@sysmgr.org>
* Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
+ * Copyright 2022 Oxide Computer Company
*/
/* Portions Copyright 2010 Robert Milkowski */
@@ -1435,6 +1436,13 @@ zfs_domount(vfs_t *vfsp, char *osname)
error = zfsvfs_setup(zfsvfs, B_TRUE);
}
+ /* cache the root vnode for this mount */
+ znode_t *rootzp;
+ if (error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp)) {
+ goto out;
+ }
+ zfsvfs->z_rootdir = ZTOV(rootzp);
+
if (!zfsvfs->z_issnap)
zfsctl_create(zfsvfs);
out:
@@ -1837,22 +1845,21 @@ zfs_mountroot(vfs_t *vfsp, enum whymountroot why)
goto out;
}
+ /* zfs_domount has already cached the root vnode for us */
zfsvfs = (zfsvfs_t *)vfsp->vfs_data;
ASSERT(zfsvfs);
- if (error = zfs_zget(zfsvfs, zfsvfs->z_root, &zp)) {
- cmn_err(CE_NOTE, "zfs_zget: error %d", error);
- goto out;
- }
+ ASSERT(zfsvfs->z_rootdir);
- vp = ZTOV(zp);
+ vp = zfsvfs->z_rootdir;
mutex_enter(&vp->v_lock);
vp->v_flag |= VROOT;
mutex_exit(&vp->v_lock);
- rootvp = vp;
/*
* Leave rootvp held. The root file system is never unmounted.
*/
+ VN_HOLD(vp);
+ rootvp = vp;
vfs_add((struct vnode *)0, vfsp,
(vfsp->vfs_flag & VFS_RDONLY) ? MS_RDONLY : 0);
@@ -2085,17 +2092,24 @@ static int
zfs_root(vfs_t *vfsp, vnode_t **vpp)
{
zfsvfs_t *zfsvfs = vfsp->vfs_data;
- znode_t *rootzp;
+ struct vnode *vp;
int error;
ZFS_ENTER(zfsvfs);
- error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp);
- if (error == 0)
- *vpp = ZTOV(rootzp);
+ vp = zfsvfs->z_rootdir;
+ if (vp != NULL) {
+ VN_HOLD(vp);
+ error = 0;
+ } else {
+ /* forced unmount */
+ error = EIO;
+ }
+ *vpp = vp;
ZFS_EXIT(zfsvfs);
return (error);
+
}
/*
@@ -2167,9 +2181,20 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
* other vops will fail with EIO.
*/
if (unmounting) {
+ /*
+ * Clear the cached root vnode now that we are unmounted.
+ * Its release must be performed outside the teardown locks to
+ * avoid recursive lock entry via zfs_inactive().
+ */
+ vnode_t *vp = zfsvfs->z_rootdir;
+ zfsvfs->z_rootdir = NULL;
+
zfsvfs->z_unmounted = B_TRUE;
rw_exit(&zfsvfs->z_teardown_inactive_lock);
rrm_exit(&zfsvfs->z_teardown_lock, FTAG);
+
+ /* Drop the cached root vp now that it is safe */
+ VN_RELE(vp);
}
/*
@@ -2237,14 +2262,24 @@ zfs_umount(vfs_t *vfsp, int fflag, cred_t *cr)
*/
boolean_t draining;
uint_t thresh = 1;
+ vnode_t *ctlvp, *rvp;
+
+ /*
+ * The cached vnode for the root directory of the mount also
+ * maintains a hold on the vfs structure.
+ */
+ rvp = zfsvfs->z_rootdir;
+ thresh++;
/*
* The '.zfs' directory maintains a reference of its own, and
* any active references underneath are reflected in the vnode
* count. Allow one additional reference for it.
*/
- if (zfsvfs->z_ctldir != NULL)
+ ctlvp = zfsvfs->z_ctldir;
+ if (ctlvp != NULL) {
thresh++;
+ }
/*
* If it's running, the asynchronous unlinked drain task needs
@@ -2255,8 +2290,8 @@ zfs_umount(vfs_t *vfsp, int fflag, cred_t *cr)
if (draining)
zfs_unlinked_drain_stop_wait(zfsvfs);
- if (vfsp->vfs_count > thresh || (zfsvfs->z_ctldir != NULL &&
- zfsvfs->z_ctldir->v_count > 1)) {
+ if (vfsp->vfs_count > thresh || rvp->v_count > 1 ||
+ (ctlvp != NULL && ctlvp->v_count > 1)) {
if (draining) {
/* If it was draining, restart the task */
zfs_unlinked_drain(zfsvfs);
diff --git a/usr/src/uts/common/os/sysent.c b/usr/src/uts/common/os/sysent.c
index dca168b642..41f421c505 100644
--- a/usr/src/uts/common/os/sysent.c
+++ b/usr/src/uts/common/os/sysent.c
@@ -206,7 +206,7 @@ int getpmsg(int, struct strbuf *, struct strbuf *, int *, int *);
int putpmsg(int, struct strbuf *, struct strbuf *, int, int);
int memcntl(caddr_t, size_t, int, caddr_t, int, int);
long sysconfig(int);
-int adjtime(struct timeval *, struct timeval *);
+int adjtime(const struct timeval *, struct timeval *);
long systeminfo(int, char *, long);
int setegid(gid_t);
int seteuid(uid_t);
diff --git a/usr/src/uts/common/sys/time.h b/usr/src/uts/common/sys/time.h
index f6cfa1a7e5..d82508e6b3 100644
--- a/usr/src/uts/common/sys/time.h
+++ b/usr/src/uts/common/sys/time.h
@@ -397,7 +397,7 @@ extern void hrt2ts32(hrtime_t, timestruc32_t *);
#endif /* _KERNEL */
#if !defined(_KERNEL) && !defined(__XOPEN_OR_POSIX) || defined(__EXTENSIONS__)
-int adjtime(struct timeval *, struct timeval *);
+int adjtime(const struct timeval *, struct timeval *);
#endif /* !defined(_KERNEL) && !defined(__XOPEN_OR_POSIX) ... */
#if !defined(_KERNEL) && !defined(__XOPEN_OR_POSIX) || \
diff --git a/usr/src/uts/common/syscall/adjtime.c b/usr/src/uts/common/syscall/adjtime.c
index dc2dde5306..5093e2d632 100644
--- a/usr/src/uts/common/syscall/adjtime.c
+++ b/usr/src/uts/common/syscall/adjtime.c
@@ -28,8 +28,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI" /* from SVr4.0 1.78 */
-
#include <sys/param.h>
#include <sys/types.h>
#include <sys/sysmacros.h>
@@ -43,7 +41,7 @@
#include <sys/policy.h>
int
-adjtime(struct timeval *delta, struct timeval *olddelta)
+adjtime(const struct timeval *delta, struct timeval *olddelta)
{
struct timeval atv, oatv;
int64_t ndelta;