vold: Add an optional wipe paramter to the volume format command

The new wipe option to the vold format command will invoke BLKDISCARD
on the partition before invoking newfs_msdos.  This will be used whenever
a full wipe of the device is wanted, as this is more secure than just
doing newfs_msdos.

Bug: 9392982
Change-Id: Ie106f1b9cc70abc61206006d1821641c27c7ccae
diff --git a/Fat.cpp b/Fat.cpp
index 807f440..c967a90 100644
--- a/Fat.cpp
+++ b/Fat.cpp
@@ -30,6 +30,8 @@
 #include <sys/mman.h>
 #include <sys/mount.h>
 #include <sys/wait.h>
+#include <linux/fs.h>
+#include <sys/ioctl.h>
 
 #include <linux/kdev_t.h>
 
@@ -167,12 +169,16 @@
     return rc;
 }
 
-int Fat::format(const char *fsPath, unsigned int numSectors) {
+int Fat::format(const char *fsPath, unsigned int numSectors, bool wipe) {
     int fd;
     const char *args[10];
     int rc;
     int status;
 
+    if (wipe) {
+        Fat::wipe(fsPath, numSectors);
+    }
+
     args[0] = MKDOSFS_PATH;
     args[1] = "-F";
     args[2] = "32";
@@ -220,3 +226,30 @@
     }
     return 0;
 }
+
+void Fat::wipe(const char *fsPath, unsigned int numSectors) {
+    int fd;
+    unsigned long long range[2];
+
+    fd = open(fsPath, O_RDWR);
+    if (fd >= 0) {
+        if (numSectors == 0) {
+            numSectors = get_blkdev_size(fd);
+        }
+        if (numSectors == 0) {
+            SLOGE("Fat wipe failed to determine size of %s", fsPath);
+            close(fd);
+            return;
+        }
+        range[0] = 0;
+        range[1] = (unsigned long long)numSectors * 512;
+        if (ioctl(fd, BLKDISCARD, &range) < 0) {
+            SLOGE("Fat wipe failed to discard blocks on %s", fsPath);
+        } else {
+            SLOGI("Fat wipe %d sectors on %s succeeded", numSectors, fsPath);
+        }
+        close(fd);
+    } else {
+        SLOGE("Fat wipe failed to open device %s", fsPath);
+    }
+}