diff options
| author | Rick Macklem <rmacklem@FreeBSD.org> | 2013-12-24 22:24:17 +0000 |
|---|---|---|
| committer | Rick Macklem <rmacklem@FreeBSD.org> | 2013-12-24 22:24:17 +0000 |
| commit | 0c695afb96b00adc8d9a28aac1178ec0e7d6952f (patch) | |
| tree | c79a388e973a44f073d63b536b54832a782bdc5e /sys/fs | |
| parent | bd28fb4d4c79dca8c1b92f19d34e86c93b550a3b (diff) | |
Notes
Diffstat (limited to 'sys/fs')
| -rw-r--r-- | sys/fs/nfsserver/nfs_nfsdport.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 2f9d40a8f2e32..89fc66e183d11 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -1984,6 +1984,27 @@ again: } /* + * Check to see if entries in this directory can be safely acquired + * via VFS_VGET() or if a switch to VOP_LOOKUP() is required. + * ZFS snapshot directories need VOP_LOOKUP(), so that any + * automount of the snapshot directory that is required will + * be done. + * This needs to be done here for NFSv4, since NFSv4 never does + * a VFS_VGET() for "." or "..". + */ + if (not_zfs == 0) { + r = VFS_VGET(mp, at.na_fileid, LK_SHARED, &nvp); + if (r == EOPNOTSUPP) { + usevget = 0; + cn.cn_nameiop = LOOKUP; + cn.cn_lkflags = LK_SHARED | LK_RETRY; + cn.cn_cred = nd->nd_cred; + cn.cn_thread = p; + } else if (r == 0) + vput(nvp); + } + + /* * Save this position, in case there is an error before one entry * is created. */ @@ -2120,6 +2141,22 @@ again: if (!r) r = nfsvno_getattr(nvp, nvap, nd->nd_cred, p, 1); + if (r == 0 && not_zfs == 0 && + nfsrv_enable_crossmntpt != 0 && + (nd->nd_flag & ND_NFSV4) != 0 && + nvp->v_type == VDIR && + vp->v_mount != nvp->v_mount) { + /* + * For a ZFS snapshot, there is a + * pseudo mount that does not set + * v_mountedhere, so it needs to + * be detected via a different + * mount structure. + */ + at_root = 1; + if (new_mp == mp) + new_mp = nvp->v_mount; + } } } else { nvp = NULL; |
