Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 Dec 2017 19:07:24 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r326987 - in head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs: . sys
Message-ID:  <201712191907.vBJJ7Oat067538@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Tue Dec 19 19:07:24 2017
New Revision: 326987
URL: https://svnweb.freebsd.org/changeset/base/326987

Log:
  Adjust ZFS' link count handling for ino64.
  
  - Define a ZFS_LINK_MAX as the ZFS version of LINK_MAX which is set to
    UINT64_MAX to match the on-disk format.
  - Enable the currently #if 0'd code to check for link overflows and
    return EMLINK.
  - Don't clamp the link count reported in stat() to LINK_MAX as that is
    still the 16-bit limit, but report the full link counts.  Also,
    avoid possibly overflowing the reported link count to 0 when adjusting
    the link count to account for ".snapshot".
  - Update the LINK_MAX reported by pathconf() to report ZFS_LINK_MAX
    rather than LINK_MAX (but clamped to LONG_MAX for 32-bit systems).
  
  Reviewed by:	avg (earlier version)
  Sponsored by:	Chelsio Communications

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.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	Tue Dec 19 18:20:38 2017	(r326986)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h	Tue Dec 19 19:07:24 2017	(r326987)
@@ -201,6 +201,7 @@ typedef struct znode {
 	boolean_t	z_is_sa;	/* are we native sa? */
 } znode_t;
 
+#define	ZFS_LINK_MAX	UINT64_MAX
 
 /*
  * Range locking rules

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c	Tue Dec 19 18:20:38 2017	(r326986)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c	Tue Dec 19 19:07:24 2017	(r326987)
@@ -527,10 +527,10 @@ zfs_link_create(znode_t *dzp, const char *name, znode_
 
 	ASSERT_VOP_ELOCKED(ZTOV(dzp), __func__);
 	ASSERT_VOP_ELOCKED(ZTOV(zp), __func__);
-#if 0
+#ifdef __FreeBSD__
 	if (zp_is_dir) {
 		error = 0;
-		if (dzp->z_links >= LINK_MAX)
+		if (dzp->z_links >= ZFS_LINK_MAX)
 			error = SET_ERROR(EMLINK);
 		return (error);
 	}
@@ -540,8 +540,8 @@ zfs_link_create(znode_t *dzp, const char *name, znode_
 			ASSERT(!(flag & (ZNEW | ZEXISTS)));
 			return (SET_ERROR(ENOENT));
 		}
-#if 0
-		if (zp->z_links >= LINK_MAX) {
+#ifdef __FreeBSD__
+		if (zp->z_links >= ZFS_LINK_MAX - zp_is_dir) {
 			return (SET_ERROR(EMLINK));
 		}
 #endif

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	Tue Dec 19 18:20:38 2017	(r326986)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Tue Dec 19 19:07:24 2017	(r326987)
@@ -2643,7 +2643,6 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred
 	int	error = 0;
 	uint32_t blksize;
 	u_longlong_t nblocks;
-	uint64_t links;
 	uint64_t mtime[2], ctime[2], crtime[2], rdev;
 	xvattr_t *xvap = (xvattr_t *)vap;	/* vap may be an xvattr_t * */
 	xoptattr_t *xoap = NULL;
@@ -2695,11 +2694,10 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred
 	vn_fsid(vp, vap);
 #endif
 	vap->va_nodeid = zp->z_id;
-	if ((vp->v_flag & VROOT) && zfs_show_ctldir(zp))
-		links = zp->z_links + 1;
-	else
-		links = zp->z_links;
-	vap->va_nlink = MIN(links, LINK_MAX);	/* nlink_t limit! */
+	vap->va_nlink = zp->z_links;
+	if ((vp->v_flag & VROOT) && zfs_show_ctldir(zp) &&
+	    zp->z_links < ZFS_LINK_MAX)
+		vap->va_nlink++;
 	vap->va_size = zp->z_size;
 #ifdef illumos
 	vap->va_rdev = vp->v_rdev;
@@ -4404,7 +4402,7 @@ zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred
 
 	switch (cmd) {
 	case _PC_LINK_MAX:
-		*valp = INT_MAX;
+		*valp = MIN(LONG_MAX, ZFS_LINK_MAX);
 		return (0);
 
 	case _PC_FILESIZEBITS:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201712191907.vBJJ7Oat067538>