Author: avg
Date: Fri Oct  7 06:29:24 2016
New Revision: 306801
URL: https://svnweb.freebsd.org/changeset/base/306801

Log:
  implement zfs_vptocnp() using z_parent property
  
  This should allow vn_fullpath() to work even when vfs name cache is
  disabled for zfs, which is the case when zfs properties like
  casesensitivity and normalization are set non-default values.
  
  The new code should be 100% reliable for directories and "mostly"
  reliable for files, that is, when hardlinks across directories are
  not used.
  
  Reported by:  Frederic Chardon <chardon.frede...@gmail.com>
  Reviewed by:  kib (vfs contract)
  MFC after:    2 weeks
  Differential Revision: https://reviews.freebsd.org/D8146

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h Fri Oct 
 7 06:11:15 2016        (r306800)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h Fri Oct 
 7 06:29:24 2016        (r306801)
@@ -355,6 +355,8 @@ extern zil_get_data_t zfs_get_data;
 extern zil_replay_func_t *zfs_replay_vector[TX_MAX_TYPE];
 extern int zfsfstype;
 
+extern int zfs_znode_parent_and_name(znode_t *zp, znode_t **dzpp, char *buf);
+
 #endif /* _KERNEL */
 
 extern int zfs_obj_to_path(objset_t *osp, uint64_t obj, char *buf, int len);

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c     Fri Oct 
 7 06:11:15 2016        (r306800)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c     Fri Oct 
 7 06:29:24 2016        (r306801)
@@ -5934,8 +5934,19 @@ zfs_vptocnp(struct vop_vptocnp_args *ap)
        }
 
        if (zp->z_id != parent || zfsvfs->z_parent == zfsvfs) {
+               char name[MAXNAMLEN + 1];
+               znode_t *dzp;
+               size_t len;
+
+               error = zfs_znode_parent_and_name(zp, &dzp, name);
+               if (error == 0) {
+                       len = strlen(name);
+                       *ap->a_buflen -= len;
+                       bcopy(name, ap->a_buf + *ap->a_buflen, len);
+                       *ap->a_vpp = ZTOV(dzp);
+               }
                ZFS_EXIT(zfsvfs);
-               return (vop_stdvptocnp(ap));
+               return (error);
        }
        ZFS_EXIT(zfsvfs);
 

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c     Fri Oct 
 7 06:11:15 2016        (r306800)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c     Fri Oct 
 7 06:29:24 2016        (r306801)
@@ -1936,7 +1936,6 @@ zfs_create_fs(objset_t *os, cred_t *cr, 
                mutex_destroy(&zfsvfs->z_hold_mtx[i]);
        kmem_free(zfsvfs, sizeof (zfsvfs_t));
 }
-
 #endif /* _KERNEL */
 
 static int
@@ -2192,3 +2191,35 @@ zfs_obj_to_stats(objset_t *osp, uint64_t
        zfs_release_sa_handle(hdl, db, FTAG);
        return (error);
 }
+
+#ifdef _KERNEL
+int
+zfs_znode_parent_and_name(znode_t *zp, znode_t **dzpp, char *buf)
+{
+       zfsvfs_t *zfsvfs = zp->z_zfsvfs;
+       uint64_t parent;
+       int is_xattrdir;
+       int err;
+
+       /* Extended attributes should not be visible as regular files. */
+       if ((zp->z_pflags & ZFS_XATTR) != 0)
+               return (SET_ERROR(EINVAL));
+
+       err = zfs_obj_to_pobj(zfsvfs->z_os, zp->z_sa_hdl, zfsvfs->z_attr_table,
+           &parent, &is_xattrdir);
+       if (err != 0)
+               return (err);
+       ASSERT0(is_xattrdir);
+
+       /* No name as this is a root object. */
+       if (parent == zp->z_id)
+               return (SET_ERROR(EINVAL));
+
+       err = zap_value_search(zfsvfs->z_os, parent, zp->z_id,
+           ZFS_DIRENT_OBJ(-1ULL), buf);
+       if (err != 0)
+               return (err);
+       err = zfs_zget(zfsvfs, parent, dzpp);
+       return (err);
+}
+#endif /* _KERNEL */
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to