Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 25 Sep 2014 21:28:20 +0000 (UTC)
From:      Xin LI <delphij@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r272134 - stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Message-ID:  <201409252128.s8PLSKsG007898@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: delphij
Date: Thu Sep 25 21:28:19 2014
New Revision: 272134
URL: http://svnweb.freebsd.org/changeset/base/272134

Log:
  MFC r271536: MFV r271518:
  
  Correctly report hole at end of file.
  
  When asked to find a hole, the DMU sees that there are no holes in the
  object, and returns ESRCH.  The ZPL interprets this as "no holes before
  the end of the file", and therefore inserts the "virtual hole" at the
  end of the file.  Because DMU and ZPL have different ideas of where the
  end of an object/file is, we will end up returning the end of file,
  which is generally larger, instead of returning the end of object.
  
  The fix is to handle the "virtual hole" in the DMU. If no hole is found,
  the DMU will return a hole at the end of the file, rather than an error.
  
  Illumos issue:
      5139 SEEK_HOLE failed to report a hole at end of file
  
  Approved by:	re (gjb)

Modified:
  stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
  stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c	Thu Sep 25 21:07:30 2014	(r272133)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c	Thu Sep 25 21:28:19 2014	(r272134)
@@ -1948,6 +1948,15 @@ dnode_next_offset(dnode_t *dn, int flags
 		    flags, offset, lvl, blkfill, txg);
 	}
 
+	/*
+	 * There's always a "virtual hole" at the end of the object, even
+	 * if all BP's which physically exist are non-holes.
+	 */
+	if ((flags & DNODE_FIND_HOLE) && error == ESRCH && txg == 0 &&
+	    minlvl == 1 && blkfill == 1 && !(flags & DNODE_FIND_BACKWARDS)) {
+		error = 0;
+	}
+
 	if (error == 0 && (flags & DNODE_FIND_BACKWARDS ?
 	    initial_offset < *offset : initial_offset > *offset))
 		error = SET_ERROR(ESRCH);

Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Thu Sep 25 21:07:30 2014	(r272133)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Thu Sep 25 21:28:19 2014	(r272134)
@@ -20,7 +20,7 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2013, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  */
 
@@ -266,16 +266,19 @@ zfs_holey(vnode_t *vp, u_long cmd, offse
 
 	error = dmu_offset_next(zp->z_zfsvfs->z_os, zp->z_id, hole, &noff);
 
-	/* end of file? */
-	if ((error == ESRCH) || (noff > file_sz)) {
-		/*
-		 * Handle the virtual hole at the end of file.
-		 */
-		if (hole) {
-			*off = file_sz;
-			return (0);
-		}
+	if (error == ESRCH)
 		return (SET_ERROR(ENXIO));
+
+	/*
+	 * We could find a hole that begins after the logical end-of-file,
+	 * because dmu_offset_next() only works on whole blocks.  If the
+	 * EOF falls mid-block, then indicate that the "virtual hole"
+	 * at the end of the file begins at the logical EOF, rather than
+	 * at the end of the last block.
+	 */
+	if (noff > file_sz) {
+		ASSERT(hole);
+		noff = file_sz;
 	}
 
 	if (noff < *off)



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