indirect.c \
uuid.c \
sha1.c \
- sparse_crc32.c
+ sparse_crc32.c \
+ wipe.c
LOCAL_SRC_FILES := $(libext4_utils_src_files)
LOCAL_MODULE := libext4_utils
close(fd);
- write_ext4_image(out, gzip, sparse, crc);
+ write_ext4_image(out, gzip, sparse, crc, 0);
return 0;
}
}
/* Write the filesystem image to a file */
-void write_ext4_image(const char *filename, int gz, int sparse, int crc)
+void write_ext4_image(const char *filename, int gz, int sparse, int crc,
+ int wipe)
{
int ret = 0;
struct output_file *out = open_output_file(filename, gz, sparse,
- count_sparse_chunks(), crc);
+ count_sparse_chunks(), crc, wipe);
if (!out)
return;
}
int ext4_bg_has_super_block(int bg);
-void write_ext4_image(const char *filename, int gz, int sparse, int crc);
+void write_ext4_image(const char *filename, int gz, int sparse, int crc,
+ int wipe);
void ext4_create_fs_aux_info(void);
void ext4_free_fs_aux_info(void);
void ext4_fill_in_sb(void);
{
reset_ext4fs_info();
info.len = len;
- return make_ext4fs_internal(filename, NULL, NULL, 0, 0, 0, 0);
+ return make_ext4fs_internal(filename, NULL, NULL, 0, 0, 0, 0, 1);
}
int make_ext4fs_internal(const char *filename, const char *directory,
char *mountpoint, int android, int gzip, int sparse,
- int crc)
+ int crc, int wipe)
{
u32 root_inode_num;
u16 root_mode;
aux_info.sb->s_blocks_count_lo - aux_info.sb->s_free_blocks_count_lo,
aux_info.sb->s_blocks_count_lo);
- write_ext4_image(filename, gzip, sparse, crc);
+ write_ext4_image(filename, gzip, sparse, crc, wipe);
return 0;
}
int make_ext4fs(const char *filename, s64 len);
int make_ext4fs_internal(const char *filename, const char *directory,
char *mountpoint, int android, int gzip, int sparse,
- int crc);
+ int crc, int wipe);
#endif
int gzip = 0;
int sparse = 0;
int crc = 0;
+ int wipe = 0;
- while ((opt = getopt(argc, argv, "l:j:b:g:i:I:L:a:fzJsc")) != -1) {
+ while ((opt = getopt(argc, argv, "l:j:b:g:i:I:L:a:fwzJsc")) != -1) {
switch (opt) {
case 'l':
info.len = parse_num(optarg);
android = 1;
mountpoint = optarg;
break;
+ case 'w':
+ wipe = 1;
+ break;
case 'z':
gzip = 1;
break;
exit(EXIT_FAILURE);
}
+ if (wipe && sparse) {
+ fprintf(stderr, "Cannot specifiy both wipe and sparse\n");
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ if (wipe && gzip) {
+ fprintf(stderr, "Cannot specifiy both wipe and gzip\n");
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
if (optind >= argc) {
fprintf(stderr, "Expected filename after options\n");
usage(argv[0]);
}
return make_ext4fs_internal(filename, directory, mountpoint, android, gzip,
- sparse, crc);
+ sparse, crc, wipe);
}
#include "output_file.h"
#include "sparse_format.h"
#include "sparse_crc32.h"
+#include "wipe.h"
#include <sys/types.h>
#include <sys/stat.h>
}
struct output_file *open_output_file(const char *filename, int gz, int sparse,
- int chunks, int crc)
+ int chunks, int crc, int wipe)
{
int ret;
struct output_file *out = malloc(sizeof(struct output_file));
out->crc32 = 0;
out->use_crc = crc;
+ if (wipe)
+ wipe_block_device(out->fd, info.len);
+
if (out->sparse) {
sparse_header.blk_sz = info.block_size,
sparse_header.total_blks = info.len / info.block_size,
struct output_file;
struct output_file *open_output_file(const char *filename, int gz, int sparse,
- int chunks, int crc);
+ int chunks, int crc, int wipe);
void write_data_block(struct output_file *out, u64 off, u8 *data, int len);
void write_data_file(struct output_file *out, u64 off, const char *file,
off64_t offset, int len);
--- /dev/null
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ext4_utils.h"
+#include "wipe.h"
+
+#if defined(__linux__)
+
+#include <linux/fs.h>
+#include <sys/ioctl.h>
+
+#ifndef BLKDISCARD
+#define BLKDISCARD _IO(0x12,119)
+#endif
+
+#ifndef BLKSECDISCARD
+#define BLKSECDISCARD _IO(0x12,125)
+#endif
+
+int wipe_block_device(int fd, int len)
+{
+ u64 range[2];
+ int ret;
+
+ range[0] = 0;
+ range[1] = len;
+ ret = ioctl(fd, BLKSECDISCARD, &range);
+ if (ret < 0) {
+ range[0] = 0;
+ range[1] = len;
+ ret = ioctl(fd, BLKDISCARD, &range);
+ if (ret < 0) {
+ error("Discard failed\n");
+ return 1;
+ } else {
+ warn("Wipe via secure discard failed, used discard instead\n");
+ return 0;
+ }
+ }
+
+ return 0;
+}
+#else
+int wipe_block_device(int fd)
+{
+ error("wipe not supported on non-linux platforms");
+ return 1;
+}
+#endif
+
--- /dev/null
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _WIPE_H_
+#define _WIPE_H_
+
+int wipe_block_device(int fd, int len);
+
+#endif