svn commit: r316906 - in vendor-sys/illumos/dist/uts/common: fs fs/zfs sys
Andriy Gapon
avg at FreeBSD.org
Fri Apr 14 18:19:50 UTC 2017
Author: avg
Date: Fri Apr 14 18:19:48 2017
New Revision: 316906
URL: https://svnweb.freebsd.org/changeset/base/316906
Log:
4242 file rename event fires before the rename happens
illumos/illumos-gate at 54207fd2e1e7ed01d0416da8cf296dbef920fbfc
https://github.com/illumos/illumos-gate/commit/54207fd2e1e7ed01d0416da8cf296dbef920fbfc
https://www.illumos.org/issues/4242
From Joyent's OS-2557:
So we're basically just doing a check here that after we got a 'rename' event
for our file, the file has actually been moved out of the way.
What I've seen in bh1-stage2 is that this happens as you'd expect for all zones
but many times over the last week it's failed because when we do the fs.exists
() check here, the file that we got the rename event for, still exists.
I've confirmed what's happening using the following dtrace script:
#!/usr/sbin/dtrace -s
#pragma D option quiet
#pragma D option bufsize=256k
syscall::open:entry,
syscall::open64:entry
/copyinstr(arg0) == "/var/svc/provisioning" || (strlen(copyinstr(arg0)) == 69
&& substr(copyinstr(arg0), 48) == "/var/svc/provisioning")/
{
this->watching_open = 1;
printf("%d zone %s process %s(%d) [%s] open(%s)\\n",
timestamp,
zonename,
execname,
pid,
curpsinfo->pr_psargs,
copyinstr(arg0));
}
syscall::open:return,
syscall::open64:return
/this->watching_open == 1/
Reviewed by: Robert Mustacchi <rm at joyent.com>
Reviewed by: Marcel Telka <marcel at telka.sk>
Approved by: Dan McDonald <danmcd at omniti.com>
Author: Jerry Jelinek <jerry.jelinek at joyent.com>
Modified:
vendor-sys/illumos/dist/uts/common/fs/vnode.c
vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_vnops.c
vendor-sys/illumos/dist/uts/common/sys/vnode.h
Modified: vendor-sys/illumos/dist/uts/common/fs/vnode.c
==============================================================================
--- vendor-sys/illumos/dist/uts/common/fs/vnode.c Fri Apr 14 18:15:47 2017 (r316905)
+++ vendor-sys/illumos/dist/uts/common/fs/vnode.c Fri Apr 14 18:19:48 2017 (r316906)
@@ -2557,6 +2557,36 @@ vnevent_rmdir(vnode_t *vp, vnode_t *dvp,
}
void
+vnevent_pre_rename_src(vnode_t *vp, vnode_t *dvp, char *name,
+ caller_context_t *ct)
+{
+ if (vp == NULL || vp->v_femhead == NULL) {
+ return;
+ }
+ (void) VOP_VNEVENT(vp, VE_PRE_RENAME_SRC, dvp, name, ct);
+}
+
+void
+vnevent_pre_rename_dest(vnode_t *vp, vnode_t *dvp, char *name,
+ caller_context_t *ct)
+{
+ if (vp == NULL || vp->v_femhead == NULL) {
+ return;
+ }
+ (void) VOP_VNEVENT(vp, VE_PRE_RENAME_DEST, dvp, name, ct);
+}
+
+void
+vnevent_pre_rename_dest_dir(vnode_t *vp, vnode_t *nvp, char *name,
+ caller_context_t *ct)
+{
+ if (vp == NULL || vp->v_femhead == NULL) {
+ return;
+ }
+ (void) VOP_VNEVENT(vp, VE_PRE_RENAME_DEST_DIR, nvp, name, ct);
+}
+
+void
vnevent_create(vnode_t *vp, caller_context_t *ct)
{
if (vp == NULL || vp->v_femhead == NULL) {
Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_vnops.c
==============================================================================
--- vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_vnops.c Fri Apr 14 18:15:47 2017 (r316905)
+++ vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_vnops.c Fri Apr 14 18:19:48 2017 (r316906)
@@ -23,6 +23,7 @@
* Copyright (c) 2012, 2015 by Delphix. All rights reserved.
* Copyright 2014 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
+ * Copyright 2015 Joyent, Inc.
*/
/* Portions Copyright 2007 Jeremy Teo */
@@ -3447,7 +3448,7 @@ zfs_rename(vnode_t *sdvp, char *snm, vno
dmu_tx_t *tx;
zfs_zlock_t *zl;
int cmp, serr, terr;
- int error = 0;
+ int error = 0, rm_err = 0;
int zflg = 0;
boolean_t waited = B_FALSE;
@@ -3659,16 +3660,16 @@ top:
}
}
- vnevent_rename_src(ZTOV(szp), sdvp, snm, ct);
+ vnevent_pre_rename_src(ZTOV(szp), sdvp, snm, ct);
if (tzp)
- vnevent_rename_dest(ZTOV(tzp), tdvp, tnm, ct);
+ vnevent_pre_rename_dest(ZTOV(tzp), tdvp, tnm, ct);
/*
* notify the target directory if it is not the same
* as source directory.
*/
if (tdvp != sdvp) {
- vnevent_rename_dest_dir(tdvp, ct);
+ vnevent_pre_rename_dest_dir(tdvp, ZTOV(szp), tnm, ct);
}
tx = dmu_tx_create(zfsvfs->z_os);
@@ -3712,7 +3713,7 @@ top:
}
if (tzp) /* Attempt to remove the existing target */
- error = zfs_link_destroy(tdl, tzp, tx, zflg, NULL);
+ error = rm_err = zfs_link_destroy(tdl, tzp, tx, zflg, NULL);
if (error == 0) {
error = zfs_link_create(tdl, szp, tx, ZRENAMING);
@@ -3754,6 +3755,16 @@ top:
}
dmu_tx_commit(tx);
+
+ if (tzp && rm_err == 0)
+ vnevent_rename_dest(ZTOV(tzp), tdvp, tnm, ct);
+
+ if (error == 0) {
+ vnevent_rename_src(ZTOV(szp), sdvp, snm, ct);
+ /* notify the target dir if it is not the same as source dir */
+ if (tdvp != sdvp)
+ vnevent_rename_dest_dir(tdvp, ct);
+ }
out:
if (zl != NULL)
zfs_rename_unlock(&zl);
Modified: vendor-sys/illumos/dist/uts/common/sys/vnode.h
==============================================================================
--- vendor-sys/illumos/dist/uts/common/sys/vnode.h Fri Apr 14 18:15:47 2017 (r316905)
+++ vendor-sys/illumos/dist/uts/common/sys/vnode.h Fri Apr 14 18:19:48 2017 (r316906)
@@ -724,7 +724,12 @@ typedef enum symfollow symfollow_t;
typedef enum vcexcl vcexcl_t;
typedef enum create create_t;
-/* Vnode Events - Used by VOP_VNEVENT */
+/*
+ * Vnode Events - Used by VOP_VNEVENT
+ * The VE_PRE_RENAME_* events fire before the rename operation and are
+ * primarily used for specialized applications, such as NFSv4 delegation, which
+ * need to know about rename before it occurs.
+ */
typedef enum vnevent {
VE_SUPPORT = 0, /* Query */
VE_RENAME_SRC = 1, /* Rename, with vnode as source */
@@ -735,7 +740,10 @@ typedef enum vnevent {
VE_LINK = 6, /* Link with vnode's name as source */
VE_RENAME_DEST_DIR = 7, /* Rename with vnode as target dir */
VE_MOUNTEDOVER = 8, /* File or Filesystem got mounted over vnode */
- VE_TRUNCATE = 9 /* Truncate */
+ VE_TRUNCATE = 9, /* Truncate */
+ VE_PRE_RENAME_SRC = 10, /* Pre-rename, with vnode as source */
+ VE_PRE_RENAME_DEST = 11, /* Pre-rename, with vnode as target/dest. */
+ VE_PRE_RENAME_DEST_DIR = 12 /* Pre-rename with vnode as target dir */
} vnevent_t;
/*
@@ -1294,6 +1302,12 @@ void vnevent_rename_dest_dir(vnode_t *,
void vnevent_mountedover(vnode_t *, caller_context_t *);
void vnevent_truncate(vnode_t *, caller_context_t *);
int vnevent_support(vnode_t *, caller_context_t *);
+void vnevent_pre_rename_src(vnode_t *, vnode_t *, char *,
+ caller_context_t *);
+void vnevent_pre_rename_dest(vnode_t *, vnode_t *, char *,
+ caller_context_t *);
+void vnevent_pre_rename_dest_dir(vnode_t *, vnode_t *, char *,
+ caller_context_t *);
/* Vnode specific data */
void vsd_create(uint_t *, void (*)(void *));
More information about the svn-src-all
mailing list