From owner-svn-src-all@freebsd.org Fri Apr 14 18:19:50 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5EFF6D3ECF1; Fri, 14 Apr 2017 18:19:50 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2E38FD88; Fri, 14 Apr 2017 18:19:50 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v3EIJnOw066590; Fri, 14 Apr 2017 18:19:49 GMT (envelope-from avg@FreeBSD.org) Received: (from avg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v3EIJnoY066587; Fri, 14 Apr 2017 18:19:49 GMT (envelope-from avg@FreeBSD.org) Message-Id: <201704141819.v3EIJnoY066587@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: avg set sender to avg@FreeBSD.org using -f From: Andriy Gapon Date: Fri, 14 Apr 2017 18:19:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r316906 - in vendor-sys/illumos/dist/uts/common: fs fs/zfs sys X-SVN-Group: vendor-sys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Apr 2017 18:19:50 -0000 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@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 Reviewed by: Marcel Telka Approved by: Dan McDonald Author: Jerry Jelinek 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 *));