kern/125149: [zfs][nfs] changing into .zfs dir from nfs
clientcauses endless panic loop
Jaakko Heinonen
jh at saunalahti.fi
Thu Oct 9 19:50:04 UTC 2008
The following reply was made to PR kern/125149; it has been noted by GNATS.
From: Jaakko Heinonen <jh at saunalahti.fi>
To: Weldon Godfrey <wgodfrey at ena.com>
Cc: bug-followup at freebsd.org
Subject: Re: kern/125149: [zfs][nfs] changing into .zfs dir from nfs
clientcauses endless panic loop
Date: Thu, 9 Oct 2008 22:44:38 +0300
On 2008-10-09, Weldon Godfrey wrote:
> Is this patch based on 8-CURRENT or 7-RELEASE? If 8-CURRENT, I don't
> know if I can test as I would like to stick with 7-RELEASE for now.
Patches are against head. Sorry that I didn't mention that. The nfs
patch applies against RELENG_7 with offset and here's the zfs patch
against RELENG_7. (Disclaimer: compile tested only)
%%%
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c (revision 183727)
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c (working copy)
@@ -759,9 +759,10 @@ zfs_vget(vfs_t *vfsp, ino_t ino, int fla
VN_RELE(ZTOV(zp));
err = EINVAL;
}
- if (err != 0)
- *vpp = NULL;
- else {
+ if (err != 0) {
+ /* try .zfs control directory */
+ err = zfsctl_vget(vfsp, ino, flags, vpp);
+ } else {
*vpp = ZTOV(zp);
vn_lock(*vpp, flags, curthread);
}
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c (revision 183727)
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c (working copy)
@@ -1044,6 +1044,63 @@ zfsctl_lookup_objset(vfs_t *vfsp, uint64
return (error);
}
+int
+zfsctl_vget(vfs_t *vfsp, uint64_t nodeid, int flags, vnode_t **vpp)
+{
+ zfsvfs_t *zfsvfs = vfsp->vfs_data;
+ vnode_t *dvp, *vp;
+ zfsctl_snapdir_t *sdp;
+ zfsctl_node_t *zcp;
+ zfs_snapentry_t *sep;
+ int error;
+
+ *vpp = NULL;
+
+ ASSERT(zfsvfs->z_ctldir != NULL);
+ error = zfsctl_root_lookup(zfsvfs->z_ctldir, "snapshot", &dvp,
+ NULL, 0, NULL, kcred);
+ if (error != 0)
+ return (error);
+
+ if (nodeid == ZFSCTL_INO_ROOT || nodeid == ZFSCTL_INO_SNAPDIR) {
+ if (nodeid == ZFSCTL_INO_SNAPDIR)
+ *vpp = dvp;
+ else {
+ VN_RELE(dvp);
+ *vpp = zfsvfs->z_ctldir;
+ VN_HOLD(*vpp);
+ }
+ /* XXX: LK_RETRY? */
+ vn_lock(*vpp, flags | LK_RETRY, curthread);
+ return (0);
+ }
+
+ sdp = dvp->v_data;
+
+ mutex_enter(&sdp->sd_lock);
+ sep = avl_first(&sdp->sd_snaps);
+ while (sep != NULL) {
+ vp = sep->se_root;
+ zcp = vp->v_data;
+ if (zcp->zc_id == nodeid)
+ break;
+
+ sep = AVL_NEXT(&sdp->sd_snaps, sep);
+ }
+
+ if (sep != NULL) {
+ VN_HOLD(vp);
+ *vpp = vp;
+ vn_lock(*vpp, flags, curthread);
+ } else
+ error = EINVAL;
+
+ mutex_exit(&sdp->sd_lock);
+
+ VN_RELE(dvp);
+
+ return (error);
+}
/*
* Unmount any snapshots for the given filesystem. This is called from
* zfs_umount() - if we have a ctldir, then go through and unmount all the
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ctldir.h
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ctldir.h (revision 183727)
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ctldir.h (working copy)
@@ -60,6 +60,7 @@ int zfsctl_root_lookup(vnode_t *dvp, cha
int flags, vnode_t *rdir, cred_t *cr);
int zfsctl_lookup_objset(vfs_t *vfsp, uint64_t objsetid, zfsvfs_t **zfsvfsp);
+int zfsctl_vget(vfs_t *vfsp, uint64_t nodeid, int flags, vnode_t **vpp);
#define ZFSCTL_INO_ROOT 0x1
#define ZFSCTL_INO_SNAPDIR 0x2
%%%
--
Jaakko
More information about the freebsd-fs
mailing list