]> git.saurik.com Git - apple/libutil.git/blobdiff - wipefs.cpp
libutil-34.tar.gz
[apple/libutil.git] / wipefs.cpp
index d5efc0558507ea1e7a359fa07b29c4805d4bc9dd..d9d1d653304d730e389fbcc3fa998cc57916b3cc 100644 (file)
@@ -25,6 +25,7 @@
 //
 
 #include <fcntl.h>
+#include <unistd.h>
 #include <sys/uio.h>
 #include <sys/ioctl.h>
 #include <sys/disk.h>
@@ -40,7 +41,7 @@ struct __wipefs_ctx {
        class ExtentManager extMan;
 };
 
-void
+static void
 AddExtentsForFutureFS(class ExtentManager *extMan)
 {
        // we don't know what blocks future FS will use to recognize itself.  But we'd better be safe than sorry and write
@@ -50,7 +51,7 @@ AddExtentsForFutureFS(class ExtentManager *extMan)
        extMan->AddByteRangeExtent(extMan->totalBytes - size, size);
 }
 
-void
+static void
 AddExtentsForHFS(class ExtentManager *extMan)
 {
        // first 1KB is boot block, last 512B is reserved
@@ -59,14 +60,14 @@ AddExtentsForHFS(class ExtentManager *extMan)
        extMan->AddByteRangeExtent(extMan->totalBytes - 1024, 1024);
 }
 
-void
+static void
 AddExtentsForMSDOS(class ExtentManager *extMan)
 {
        // MSDOS needs the first block (in theory, up to 32KB)
        extMan->AddByteRangeExtent(0, 32 * 1024);
 }
 
-void
+static void
 AddExtentsForNTFS(class ExtentManager *extMan)
 {
        // NTFS supports block size from 256B to 32768B.  The first, middle and last block are needed
@@ -76,7 +77,7 @@ AddExtentsForNTFS(class ExtentManager *extMan)
        extMan->AddByteRangeExtent(extMan->totalBytes / 2 - 32 * 1024, 64 * 1024);
 }
 
-void
+static void
 AddExtentsForUDF(class ExtentManager *extMan)
 {
        off_t lastBlockAddr = extMan->totalBlocks - 1;
@@ -101,14 +102,14 @@ AddExtentsForUDF(class ExtentManager *extMan)
        }
 }
 
-void
+static void
 AddExtentsForUFS(class ExtentManager *extMan)
 {
        // UFS super block is 8KB at offset 8KB
        extMan->AddByteRangeExtent(8192, 8192);
 }
 
-void
+static void
 AddExtentsForZFS(class ExtentManager *extMan)
 {
        // ZFS needs the first 512KB and last 512KB for all the 4 disk labels
@@ -116,7 +117,7 @@ AddExtentsForZFS(class ExtentManager *extMan)
        extMan->AddByteRangeExtent(extMan->totalBytes - 512 * 1024, 512 * 1024);
 }
 
-void
+static void
 AddExtentsForPartitions(class ExtentManager *extMan)
 {
        // MBR (Master Boot Record) needs the first sector
@@ -202,6 +203,22 @@ wipefs_alloc(int fd, size_t block_size, wipefs_ctx *handle)
        return err;
 } // wipefs_alloc
 
+extern "C" int
+wipefs_include_blocks(wipefs_ctx handle, off_t block_offset, off_t nblocks)
+{
+       int err = 0;
+       try {
+               handle->extMan.AddBlockRangeExtent(block_offset, nblocks);
+       }
+       catch (bad_alloc &e) {
+               err = ENOMEM;
+       }
+       catch (...) { // currently only ENOMEM is possible
+               err = ENOMEM;
+       }
+       return err;
+}
+
 extern "C" int
 wipefs_except_blocks(wipefs_ctx handle, off_t block_offset, off_t nblocks)
 {
@@ -225,19 +242,27 @@ wipefs_wipe(wipefs_ctx handle)
        uint8_t *bufZero = NULL;
        ListExtIt curExt;
        size_t bufSize;
-       dk_discard_t discard;
+       dk_extent_t extent;
+       dk_unmap_t unmap;
 
-       memset(&discard, 0, sizeof(dk_discard_t));
-       discard.length = handle->extMan.totalBytes;
+       memset(&extent, 0, sizeof(dk_extent_t));
+       extent.length = handle->extMan.totalBytes;
+
+       memset(&unmap, 0, sizeof(dk_unmap_t));
+       unmap.extents = &extent;
+       unmap.extentsCount = 1;
 
        //
        // Don't bother to check the return value since this is mostly
        // informational for the lower-level drivers.
        //
-       ioctl(handle->fd, DKIOCDISCARD, (caddr_t)&discard);
+       ioctl(handle->fd, DKIOCUNMAP, (caddr_t)&unmap);
        
 
-       bufSize = 256 * 1024; // issue large I/O to get better performance
+       bufSize = 128 * 1024; // issue large I/O to get better performance
+       if (handle->extMan.nativeBlockSize > bufSize) {
+           bufSize = handle->extMan.nativeBlockSize;
+       }
        bufZero = new uint8_t[bufSize];
        bzero(bufZero, bufSize);