Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 13 Sep 2014 15:34:12 +0000 (UTC)
From:      Xin LI <delphij@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org
Subject:   svn commit: r271518 - vendor-sys/illumos/dist/uts/common/fs/zfs
Message-ID:  <201409131534.s8DFYCkQ084883@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: delphij
Date: Sat Sep 13 15:34:12 2014
New Revision: 271518
URL: http://svnweb.freebsd.org/changeset/base/271518

Log:
  5139 SEEK_HOLE failed to report a hole at end of file
  Reviewed by: Adam Leventhal <adam.leventhal@delphix.com>
  Reviewed by: Alex Reece <alex.reece@delphix.com>
  Reviewed by: Christopher Siden <christopher.siden@delphix.com>
  Reviewed by: George Wilson <george.wilson@delphix.com>
  Reviewed by: Max Grossman <max.grossman@delphix.com>
  Reviewed by: Peng Dai <peng.dai@delphix.com>
  Reviewed by: Richard Elling <richard.elling@gmail.com>
  Approved by: Dan McDonald <danmcd@omniti.com>
  Author: Matthew Ahrens <mahrens@delphix.com>
  
  illumos/illumos-gate@0fbc0cd0e52a11f6c4397a1714f94412cbf98b60

Modified:
  vendor-sys/illumos/dist/uts/common/fs/zfs/dnode.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_vnops.c

Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/dnode.c
==============================================================================
--- vendor-sys/illumos/dist/uts/common/fs/zfs/dnode.c	Sat Sep 13 15:31:37 2014	(r271517)
+++ vendor-sys/illumos/dist/uts/common/fs/zfs/dnode.c	Sat Sep 13 15:34:12 2014	(r271518)
@@ -1943,6 +1943,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: vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_vnops.c
==============================================================================
--- vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_vnops.c	Sat Sep 13 15:31:37 2014	(r271517)
+++ vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_vnops.c	Sat Sep 13 15:34:12 2014	(r271518)
@@ -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 2014 Nexenta Systems, Inc.  All rights reserved.
  */
 
@@ -271,16 +271,19 @@ zfs_holey(vnode_t *vp, int cmd, offset_t
 
 	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?201409131534.s8DFYCkQ084883>