1 /* 2 * Copyright (C) 2015 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 17 #include <stdio.h> 18 #include <unistd.h> 19 #include <sys/types.h> 20 #include <sys/stat.h> 21 #include <fcntl.h> 22 #include <sys/wait.h> 23 #include <errno.h> 24 #include <cutils/partition_utils.h> 25 #include <sys/mount.h> 26 #include "ext4_utils.h" 27 #include "ext4.h" 28 #include "make_ext4fs.h" 29 #include "fs_mgr_priv.h" 30 31 extern struct fs_info info; /* magic global from ext4_utils */ 32 extern void reset_ext4fs_info(); 33 34 static int format_ext4(char *fs_blkdev, char *fs_mnt_point) 35 { 36 unsigned int nr_sec; 37 int fd, rc = 0; 38 39 if ((fd = open(fs_blkdev, O_WRONLY, 0644)) < 0) { 40 ERROR("Cannot open block device. %s\n", strerror(errno)); 41 return -1; 42 } 43 44 if ((ioctl(fd, BLKGETSIZE, &nr_sec)) == -1) { 45 ERROR("Cannot get block device size. %s\n", strerror(errno)); 46 close(fd); 47 return -1; 48 } 49 50 /* Format the partition using the calculated length */ 51 reset_ext4fs_info(); 52 info.len = ((off64_t)nr_sec * 512); 53 54 /* Use make_ext4fs_internal to avoid wiping an already-wiped partition. */ 55 rc = make_ext4fs_internal(fd, NULL, NULL, fs_mnt_point, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL); 56 if (rc) { 57 ERROR("make_ext4fs returned %d.\n", rc); 58 } 59 close(fd); 60 61 return rc; 62 } 63 64 static int format_f2fs(char *fs_blkdev) 65 { 66 char * args[3]; 67 int pid; 68 int rc = 0; 69 70 args[0] = (char *)"/sbin/mkfs.f2fs"; 71 args[1] = fs_blkdev; 72 args[2] = (char *)0; 73 74 pid = fork(); 75 if (pid < 0) { 76 return pid; 77 } 78 if (!pid) { 79 /* This doesn't return */ 80 execv("/sbin/mkfs.f2fs", args); 81 exit(1); 82 } 83 for(;;) { 84 pid_t p = waitpid(pid, &rc, 0); 85 if (p != pid) { 86 ERROR("Error waiting for child process - %d\n", p); 87 rc = -1; 88 break; 89 } 90 if (WIFEXITED(rc)) { 91 rc = WEXITSTATUS(rc); 92 INFO("%s done, status %d\n", args[0], rc); 93 if (rc) { 94 rc = -1; 95 } 96 break; 97 } 98 ERROR("Still waiting for %s...\n", args[0]); 99 } 100 101 return rc; 102 } 103 104 int fs_mgr_do_format(struct fstab_rec *fstab) 105 { 106 int rc = -EINVAL; 107 108 ERROR("%s: Format %s as '%s'.\n", __func__, fstab->blk_device, fstab->fs_type); 109 110 if (!strncmp(fstab->fs_type, "f2fs", 4)) { 111 rc = format_f2fs(fstab->blk_device); 112 } else if (!strncmp(fstab->fs_type, "ext4", 4)) { 113 rc = format_ext4(fstab->blk_device, fstab->mount_point); 114 } else { 115 ERROR("File system type '%s' is not supported\n", fstab->fs_type); 116 } 117 118 return rc; 119 } 120