svn commit: r286889 - vendor-sys/illumos/dist/uts/common/fs/zfs vendor-sys/illumos/dist/uts/common/fs/zfs/sys vendor/illumos/dist/lib/libzfs/common

Andriy Gapon avg at FreeBSD.org
Tue Aug 18 14:10:06 UTC 2015


Author: avg
Date: Tue Aug 18 14:10:04 2015
New Revision: 286889
URL: https://svnweb.freebsd.org/changeset/base/286889

Log:
  5692 expose the number of hole blocks in a file
  
  illumos/illumos-gate at 2bcf0248e992f292c7b814458bcdce2f004925d6
  
  https://www.illumos.org/issues/5692
  we would like to expose the number of hole (sparse) blocks in a file. this
  can be useful to for example if you want to fill in the holes with some
  data; knowing the number of holes in advances allows you to report progress
  on hole filling. We could use SEEK_HOLE to do that but it would be O(n)
  where n is the number of holes present in the file.
  
  Author: Max Grossman <max.grossman at delphix.com>
  Reviewed by: Adam Leventhal <ahl at delphix.com>
  Reviewed by: Matthew Ahrens <mahrens at delphix.com>
  Reviewed by: Boris Protopopov <bprotopopov at hotmail.com>
  Approved by: Richard Lowe <richlowe at richlowe.net>

Modified:
  vendor/illumos/dist/lib/libzfs/common/libzfs.h
  vendor/illumos/dist/lib/libzfs/common/libzfs_util.c

Changes in other areas also in this revision:
Modified:
  vendor-sys/illumos/dist/uts/common/fs/zfs/dmu.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dmu.h
  vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_vnops.c

Modified: vendor/illumos/dist/lib/libzfs/common/libzfs.h
==============================================================================
--- vendor/illumos/dist/lib/libzfs/common/libzfs.h	Tue Aug 18 13:16:23 2015	(r286888)
+++ vendor/illumos/dist/lib/libzfs/common/libzfs.h	Tue Aug 18 14:10:04 2015	(r286889)
@@ -21,7 +21,7 @@
 
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2014 by Delphix. All rights reserved.
  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  * Copyright (c) 2013 Steven Hartland. All rights reserved.
  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
@@ -764,6 +764,8 @@ extern boolean_t libzfs_fru_compare(libz
 extern boolean_t libzfs_fru_notself(libzfs_handle_t *, const char *);
 extern int zpool_fru_set(zpool_handle_t *, uint64_t, const char *);
 
+extern int zfs_get_hole_count(const char *, uint64_t *, uint64_t *);
+
 #ifdef	__cplusplus
 }
 #endif

Modified: vendor/illumos/dist/lib/libzfs/common/libzfs_util.c
==============================================================================
--- vendor/illumos/dist/lib/libzfs/common/libzfs_util.c	Tue Aug 18 13:16:23 2015	(r286888)
+++ vendor/illumos/dist/lib/libzfs/common/libzfs_util.c	Tue Aug 18 14:10:04 2015	(r286889)
@@ -22,7 +22,7 @@
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2014 by Delphix. All rights reserved.
  */
 
 /*
@@ -39,6 +39,7 @@
 #include <unistd.h>
 #include <ctype.h>
 #include <math.h>
+#include <sys/filio.h>
 #include <sys/mnttab.h>
 #include <sys/mntent.h>
 #include <sys/types.h>
@@ -1499,3 +1500,49 @@ zprop_iter(zprop_func func, void *cb, bo
 {
 	return (zprop_iter_common(func, cb, show_all, ordered, type));
 }
+
+/*
+ * zfs_get_hole_count retrieves the number of holes (blocks which are
+ * zero-filled) in the specified file using the _FIO_COUNT_FILLED ioctl. It
+ * also optionally fetches the block size when bs is non-NULL. With hole count
+ * and block size the full space consumed by the holes of a file can be
+ * calculated.
+ *
+ * On success, zero is returned, the count argument is set to the
+ * number of holes, and the bs argument is set to the block size (if it is
+ * not NULL). On error, a non-zero errno is returned and the values in count
+ * and bs are undefined.
+ */
+int
+zfs_get_hole_count(const char *path, uint64_t *count, uint64_t *bs) {
+	int fd, err;
+	struct stat64 ss;
+	uint64_t fill;
+
+	fd = open(path, O_RDONLY | O_LARGEFILE);
+	if (fd == -1)
+		return (errno);
+
+	if (ioctl(fd, _FIO_COUNT_FILLED, &fill) == -1) {
+		err = errno;
+		(void) close(fd);
+		return (err);
+	}
+
+	if (fstat64(fd, &ss) == -1) {
+		err = errno;
+		(void) close(fd);
+		return (err);
+	}
+
+	*count = (ss.st_size + ss.st_blksize - 1) / ss.st_blksize - fill;
+	VERIFY3S(*count, >=, 0);
+	if (bs != NULL) {
+		*bs = ss.st_blksize;
+	}
+
+	if (close(fd) == -1) {
+		return (errno);
+	}
+	return (0);
+}


More information about the svn-src-all mailing list