wipe.cpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * Copyright (C) 2011 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "ext4_utils/wipe.h"
  17. #include "ext4_utils/ext4_utils.h"
  18. #include <android-base/file.h>
  19. #if WIPE_IS_SUPPORTED
  20. #if defined(__linux__)
  21. #include <linux/fs.h>
  22. #include <sys/ioctl.h>
  23. #ifndef BLKDISCARD
  24. #define BLKDISCARD _IO(0x12,119)
  25. #endif
  26. #ifndef BLKSECDISCARD
  27. #define BLKSECDISCARD _IO(0x12,125)
  28. #endif
  29. int wipe_block_device(int fd, s64 len)
  30. {
  31. u64 range[2];
  32. int ret;
  33. if (!is_block_device_fd(fd)) {
  34. // Wiping only makes sense on a block device.
  35. return 0;
  36. }
  37. range[0] = 0;
  38. range[1] = len;
  39. ret = ioctl(fd, BLKSECDISCARD, &range);
  40. if (ret < 0) {
  41. range[0] = 0;
  42. range[1] = len;
  43. ret = ioctl(fd, BLKDISCARD, &range);
  44. if (ret < 0) {
  45. warn("Discard failed\n");
  46. return 1;
  47. } else {
  48. char buf[4096] = {0};
  49. if (!android::base::WriteFully(fd, buf, 4096)) {
  50. warn("Writing zeros failed\n");
  51. return 1;
  52. }
  53. fsync(fd);
  54. warn("Wipe via secure discard failed, used discard instead\n");
  55. return 0;
  56. }
  57. }
  58. return 0;
  59. }
  60. #else /* __linux__ */
  61. #error "Missing block device wiping implementation for this platform!"
  62. #endif
  63. #else /* WIPE_IS_SUPPORTED */
  64. int wipe_block_device(int fd __attribute__((unused)), s64 len __attribute__((unused)))
  65. {
  66. /* Wiping is not supported on this platform. */
  67. return 1;
  68. }
  69. #endif /* WIPE_IS_SUPPORTED */