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:
_______________________________________________
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